MADNESS 0.10.1
archive.h
Go to the documentation of this file.
1/*
2 This file is part of MADNESS.
3
4 Copyright (C) 2007,2010 Oak Ridge National Laboratory
5
6 This program 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 2 of the License, or
9 (at your option) any later version.
10
11 This program 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 this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 For more information please contact:
21
22 Robert J. Harrison
23 Oak Ridge National Laboratory
24 One Bethel Valley Road
25 P.O. Box 2008, MS-6367
26
27 email: harrisonrj@ornl.gov
28 tel: 865-241-3937
29 fax: 865-572-0680
30*/
31
32#ifndef MADNESS_WORLD_ARCHIVE_H__INCLUDED
33#define MADNESS_WORLD_ARCHIVE_H__INCLUDED
34
35/**
36 \file archive.h
37 \brief Interface templates for the archives (serialization).
38 \ingroup serialization
39*/
40
41#include <algorithm>
42#include <type_traits>
43#include <complex>
44#include <iostream>
45#include <cassert>
46#include <cstdio>
47#include <cstddef>
48#include <cstring>
49#include <array>
50#include <vector>
51#include <map>
52#include <set>
53#include <list>
54#include <optional>
55#include <tuple>
56#include <madness/config.h>
57//#include <madness/world/worldprofile.h>
60
61/// \todo Brief description needed.
62#define ARCHIVE_COOKIE "archive"
63
64/// Major version number for archive.
65#define ARCHIVE_MAJOR_VERSION 0
66/// Minor version number for archive.
67#define ARCHIVE_MINOR_VERSION 1
68
69//#define MAD_ARCHIVE_DEBUG_ENABLE
70
71/// Macro for helping debug archive tools.
72#ifdef MAD_ARCHIVE_DEBUG_ENABLE
73#define MAD_ARCHIVE_DEBUG(s) s
74//using std::endl;
75#else
76#define MAD_ARCHIVE_DEBUG(s)
77#endif
78
79namespace madness {
80
81 // Forward declarations
82 template <typename T> class Tensor;
83
84 namespace archive {
85
86 // Forward declarations
87 template <class>
88 class archive_array;
89 template <class T>
90 inline archive_array<T> wrap(const T*, unsigned int);
91 template <class T>
92 inline archive_array<unsigned char> wrap_opaque(const T*, unsigned int);
93 template <class T>
94 inline archive_array<unsigned char> wrap_opaque(const T&);
95
96 /// \addtogroup serialization
97 /// @{
98
99 // There are 64 empty slots for user types. Free space for
100 // registering user types begins at cookie=128.
101
102
103
104 /// The list of type names for use in archives.
105 extern const char *archive_type_names[256];
106
107 /// Initializes the type names for the archives.
108 // Implemented in archive_type_names.cc
110
111 /// Used to enable type checking inside archives.
112
113 /// \tparam T The data type.
114 template <typename T>
116 static const unsigned char cookie = 255; ///< Numeric ID for the type; 255 indicates unknown type.
117 };
118
119 /// Returns the name of the type, or unknown if not registered.
120
121 /// \tparam T The data type.
122 /// \return The name of the type.
123 template <typename T>
127
128 /// Used to associate a type with a cookie value inside archive.
129
130 /// Makes a specialization of \c archive_typeinfo for type \c T that
131 /// specifies the correct cookie value.
132 /// \param[in] T The type.
133 /// \param[in] cooky The cookie value.
134#define ARCHIVE_REGISTER_TYPE(T, cooky) \
135 template <> \
136 struct archive_typeinfo< T > { \
137 static const unsigned char cookie = cooky; \
138 }
139
140
141 /// Used to associate a type and a pointer to the type with a cookie value inside archive.
142
143 /// \param[in] T The type.
144 /// \param[in] cooky The cookie value.
145#define ARCHIVE_REGISTER_TYPE_AND_PTR(T, cooky) \
146 ARCHIVE_REGISTER_TYPE(T, cooky); \
147 ARCHIVE_REGISTER_TYPE(T*, cooky+64)
148
149
150 /// Alias for \c archive_type_names.
151#define ATN ::madness::archive::archive_type_names
152 /// Alias for \c archive_typeinfo.
153#define ATI ::madness::archive::archive_typeinfo
154
155
156 /// Used to associate names with types.
157
158 /// \param[in] T The type.
159#define ARCHIVE_REGISTER_TYPE_NAME(T) \
160 if (strcmp( ATN[ATI< T >::cookie], "invalid") ) { \
161 std::cout << "archive_register_type_name: slot/cookie already in use! " << #T << " " << ATN[ATI< T >::cookie] << std::endl; \
162 MADNESS_EXCEPTION("archive_register_type_name: slot/cookie already in use!", 0); \
163 } \
164 ATN[ATI< T >::cookie] = #T
165
166
167 /// Used to associate names with types and pointers to that type.
168
169 /// \param[in] T The type.
170#define ARCHIVE_REGISTER_TYPE_AND_PTR_NAMES(T) \
171 ARCHIVE_REGISTER_TYPE_NAME(T); \
172 ARCHIVE_REGISTER_TYPE_NAME(T*)
173
174
175
176#ifndef DOXYGEN_SHOULD_SKIP_THIS
177 // **********
178 // Register standard types and "common" MADNESS types.
179 //
180 // doxygen interprets these all as functions, not as calls to a macro.
181 // Thus, we force doxygen to skip this block.
182
183 ARCHIVE_REGISTER_TYPE_AND_PTR(unsigned char,0);
184 ARCHIVE_REGISTER_TYPE_AND_PTR(unsigned short,1);
185 ARCHIVE_REGISTER_TYPE_AND_PTR(unsigned int,2);
186 ARCHIVE_REGISTER_TYPE_AND_PTR(unsigned long,3);
187 ARCHIVE_REGISTER_TYPE_AND_PTR(unsigned long long,4);
188 ARCHIVE_REGISTER_TYPE_AND_PTR(signed char,5);
189 ARCHIVE_REGISTER_TYPE_AND_PTR(char,5); // Needed, but why?
190 ARCHIVE_REGISTER_TYPE_AND_PTR(signed short,6);
191 ARCHIVE_REGISTER_TYPE_AND_PTR(signed int,7);
192 ARCHIVE_REGISTER_TYPE_AND_PTR(signed long,8);
193 ARCHIVE_REGISTER_TYPE_AND_PTR(signed long long,9);
197 ARCHIVE_REGISTER_TYPE_AND_PTR(long double,13);
198 ARCHIVE_REGISTER_TYPE_AND_PTR(std::complex<float>,14);
199 ARCHIVE_REGISTER_TYPE_AND_PTR(std::complex<double>,15);
200
201 ARCHIVE_REGISTER_TYPE_AND_PTR(std::vector<char>,20);
202 ARCHIVE_REGISTER_TYPE_AND_PTR(std::vector<unsigned char>,21);
203 ARCHIVE_REGISTER_TYPE_AND_PTR(std::vector<short>,22);
204 ARCHIVE_REGISTER_TYPE_AND_PTR(std::vector<unsigned short>,23);
205 ARCHIVE_REGISTER_TYPE_AND_PTR(std::vector<int>,24);
206 ARCHIVE_REGISTER_TYPE_AND_PTR(std::vector<unsigned int>,25);
207 ARCHIVE_REGISTER_TYPE_AND_PTR(std::vector<long>,26);
208 ARCHIVE_REGISTER_TYPE_AND_PTR(std::vector<unsigned long>,27);
209 ARCHIVE_REGISTER_TYPE_AND_PTR(std::vector<bool>,28);
210 ARCHIVE_REGISTER_TYPE_AND_PTR(std::vector<float>,29);
211 ARCHIVE_REGISTER_TYPE_AND_PTR(std::vector<double>,30);
212
213 ARCHIVE_REGISTER_TYPE_AND_PTR(std::string,31);
214
215 ARCHIVE_REGISTER_TYPE_AND_PTR(Tensor<int>,32);
216 ARCHIVE_REGISTER_TYPE_AND_PTR(Tensor<long>,33);
217 ARCHIVE_REGISTER_TYPE_AND_PTR(Tensor<float>,34);
218 ARCHIVE_REGISTER_TYPE_AND_PTR(Tensor<double>,35);
219 ARCHIVE_REGISTER_TYPE_AND_PTR(Tensor< std::complex<float> >,36);
220 ARCHIVE_REGISTER_TYPE_AND_PTR(Tensor< std::complex<double> >,37);
221 // **********
222#endif
223
224 /// \name function pointer serialization
225 /// \note relative function pointers are represented by std::ptrdiff_t , with
226 /// member function pointers represented by std::array<std::ptrdiff_t, N> (with
227 /// N=2 on most common platforms, and a type-dependent constant on some (Microsoft))
228 /// @{
229 /// \return function pointer to serve as the reference for computing relative pointers
230 /// \note the value returned by this function is a pointer to a non-virtual member function,
231 /// this helps on the platforms that use the parity to distinguish non-virtual and virtual pointers (e.g. Itanium ABI)
232 std::ptrdiff_t fn_ptr_origin();
233
234 /// \brief converts function or (free or static member) function pointer to the relative function pointer
235 /// \param[in] fn a function or function pointer
236 template <typename T, typename = std::enable_if_t<std::is_function<T>::value || is_function_pointer<T>::value>>
237 std::ptrdiff_t to_rel_fn_ptr(const T& fn) {
238 std::ptrdiff_t retval;
239 if
240#if __cplusplus >= 201703L
241 constexpr
242#endif
243 (std::is_function<T>::value) {
244 static_assert(sizeof(std::ptrdiff_t) == sizeof(T*));
245 retval = reinterpret_cast<std::ptrdiff_t>(&fn) - fn_ptr_origin();
246 }
247 else {
248#if __cplusplus >= 201703L
249 static_assert(sizeof(std::ptrdiff_t) == sizeof(T));
250#endif
251 retval = reinterpret_cast<std::ptrdiff_t>(fn) - fn_ptr_origin();
252 }
253 return retval; // To silence stupid Intel 19* compiler
254 }
255
256 /// \brief converts nonstatic member function pointer to the relative equivalent
257 /// \param[in] fn a member function pointer
258 template <typename T, typename = std::enable_if_t<std::is_member_function_pointer<T>::value>>
259 auto to_rel_memfn_ptr(const T& fn) {
260
261#if MADNESS_CXX_ABI == MADNESS_CXX_ABI_GenericItanium || MADNESS_CXX_ABI == MADNESS_CXX_ABI_GenericARM
262 static_assert(sizeof(T) % sizeof(ptrdiff_t) == 0);
263 using result_t = std::array<std::ptrdiff_t, sizeof(T) / sizeof(ptrdiff_t)>;
264#elif MADNESS_CXX_ABI == MADNESS_CXX_ABI_Microsoft
265 // T will consist of std::ptrdiff_t and up to 3 ints:
266 // static_assert((sizeof(T) - sizeof(ptrdiff_t)) % sizeof(int) == 0);
267 // using result_t = std::pair<std::ptrdiff_t, std::array<int, (sizeof(T) - sizeof(ptrdiff_t))/sizeof(int)>>;
268 //
269 // ... but due to padding it's sufficient to just represent as array of std::ptrdiff_t
270 static_assert(sizeof(T) % sizeof(ptrdiff_t) == 0);
271 using result_t = std::array<std::ptrdiff_t, sizeof(T) / sizeof(ptrdiff_t)>;
272#endif
273
274 result_t result;
275 std::memcpy(&result, &fn, sizeof(result_t));
276// typedef union {T abs_ptr; result_t rel_ptr; } cast_t;
277// cast_t caster = {fn};
278// result_t result = caster.rel_ptr;
279
280 // ABI-dependent code:
281#if MADNESS_CXX_ABI == MADNESS_CXX_ABI_GenericItanium
282 // http://itanium-cxx-abi.github.io/cxx-abi/abi.html#member-pointers
283 if (result[0] == 0) { // 0 = null ptr, set adjustment to std::numeric_limits<std::ptrdiff_t>::min() to indicate this
284 result[1] = std::numeric_limits<std::ptrdiff_t>::min();
285 }
286 else if ((result[0] & 1) == 0) { // even pointer = real ptr; odd pointer -> virtual function (does not need translation)
287 result[0] -= fn_ptr_origin();
288 }
289#elif MADNESS_CXX_ABI == MADNESS_CXX_ABI_GenericARM
290 // https://developer.arm.com/docs/ihi0041/latest
291 const auto even_adj = (result[1] & 1) == 0;
292 if (even_adj) {
293 if (result[0] == 0) { // {0,even} = null ptr, set ptr to std::numeric_limits<std::ptrdiff_t>::min() to indicate this
294 result[0] = std::numeric_limits<std::ptrdiff_t>::min();
295 } else { // {nonzero,even} = real ptr
296 result[0] -= fn_ptr_origin();
297 }
298 } else { // odd adjustment -> virtual function (does not need translation)
299 }
300#elif MADNESS_CXX_ABI == MADNESS_CXX_ABI_Microsoft
301 // details are https://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible and http://www.openrce.org/articles/files/jangrayhood.pdf
302 // but I still don't understand them completely, so assume everything is kosher
303#warning "Support for serializing member function pointers in Microsoft ABI is not complete"
304#endif
305
306 return result;
307 }
308
309 /// \brief converts relative free or static member function pointer to the absolute function pointer
310 /// \param[in] fn a relative function pointer
311 /// \return absolute function pointer
312 /// \sa to_rel_fn_ptr
313 template <typename T, typename = std::enable_if_t<is_function_pointer_v<T>>>
314 T to_abs_fn_ptr(std::ptrdiff_t rel_fn_ptr) {
315 static_assert(sizeof(std::ptrdiff_t) == sizeof(T));
316 return reinterpret_cast<T>(rel_fn_ptr + fn_ptr_origin());
317 }
318
319 /// \brief converts relative (nonstatic) member function pointer to the absolute function pointer
320 /// \param[in] fn a relative function pointer
321 /// \return absolute function pointer
322 /// \sa to_rel_memfn_ptr
323 /// \note see notes in to_rel_memfn_ptr re: Microsoft ABI
324 template <typename T, std::size_t N, typename = std::enable_if_t<std::is_member_function_pointer<std::remove_reference_t<T>>::value>>
325 auto to_abs_memfn_ptr(std::array<std::ptrdiff_t, N> rel_fn_ptr) {
326 // ABI-dependent code
327#if MADNESS_CXX_ABI == MADNESS_CXX_ABI_GenericItanium
328 if (rel_fn_ptr[0] == 0 && rel_fn_ptr[1] == std::numeric_limits<std::ptrdiff_t>::min()) { // null ptr
329 rel_fn_ptr[1] = 0;
330 }
331 else if ((rel_fn_ptr[0] & 1) == 0) { // nonvirtual relative ptr is even since fn_ptr_origin is guaranteed to be even also
332 rel_fn_ptr[0] += fn_ptr_origin();
333 }
334#elif MADNESS_CXX_ABI == MADNESS_CXX_ABI_GenericARM
335 const auto even_adj = (rel_fn_ptr[1] & 1) == 0;
336 if (even_adj) {
337 if (rel_fn_ptr[0] == std::numeric_limits<std::ptrdiff_t>::min()) { // null ptr
338 rel_fn_ptr[0] = 0;
339 } else { // real ptr
340 rel_fn_ptr[0] += fn_ptr_origin();
341 }
342 } else { // odd adjustment -> virtual function (does not need translation)
343 }
344#elif MADNESS_CXX_ABI == MADNESS_CXX_ABI_Microsoft // nothing yet done here
345#endif
346 using result_t = std::remove_reference_t<T>;
347 result_t result;
348 std::memcpy(&result, &rel_fn_ptr, sizeof(result_t));
349 return result;
350// typedef union {result_t abs_ptr; std::array<std::ptrdiff_t, N> rel_ptr; } cast_t;
351// cast_t caster = { .rel_ptr = rel_fn_ptr};
352// return caster.abs_ptr;
353 }
354
355 ///@}
356
357 /// Base class for all archive classes.
359 public:
360 static constexpr bool is_archive = true; ///< Flag to determine if this object is an archive.
361 static constexpr bool is_input_archive = false; ///< Flag to determine if this object is an input archive.
362 static constexpr bool is_output_archive = false; ///< Flag to determine if this object is an output archive.
363 using is_loading = std::false_type; ///< Type used by Boost.Serialization to determine if this object is an input archive.
364 using is_saving = std::false_type; ///< Type used by Boost.Serialization to determine if this object is an output archive.
365 static constexpr bool is_parallel_archive = false; ///< Flag to determine if this object is a parallel archive.
366
370 }; // class BaseArchive
371
372
373 /// Base class for input archive classes.
375 public:
376 static constexpr bool is_input_archive = true; ///< Flag to determine if this object is an input archive.
377 using is_loading = std::true_type; ///< Type used by Boost.Serialization to determine if this object is an input archive.
378 }; // class BaseInputArchive
379
380
381 /// Base class for output archive classes.
383 public:
384 static constexpr bool is_output_archive = true; ///< Flag to determine if this object is an output archive.
385 using is_saving = std::true_type; ///< Type used by Boost.Serialization to determine if this object is an output archive.
386 }; // class BaseOutputArchive
387
388
389 /// Serialize an array of fundamental stuff.
390
391 /// The function only appears (via \c enable_if) if \c T is
392 /// serializable and \c Archive is an output archive.
393 /// \tparam Archive The archive type.
394 /// \tparam T The type of data in the array.
395 /// \param[in] ar The archive.
396 /// \param[in] t Pointer to the start of the array.
397 /// \param[in] n Number of data items to be serialized.
398 template <class Archive, class T>
399 typename std::enable_if_t< is_output_archive<Archive>::value &&
401 is_function_pointer_v<T>, void>
402 default_serialize(const Archive& ar, const T* t, unsigned int n) {
403 MAD_ARCHIVE_DEBUG(std::cout << "serialize fund array" << std::endl);
404 // transform function pointers to relative pointers
405 std::vector<std::ptrdiff_t> t_rel(n);
406 std::transform(t, t+n, begin(t_rel), [](auto& fn_ptr) {
407 return to_rel_fn_ptr(fn_ptr);
408 });
409 ar.store(t_rel.data(), n);
410 }
411
412 template <class Archive, class T>
413 typename std::enable_if_t< is_output_archive<Archive>::value &&
415 std::is_member_function_pointer<T>::value, void>
416 default_serialize(const Archive& ar, const T* t, unsigned int n) {
417 MAD_ARCHIVE_DEBUG(std::cout << "serialize fund array" << std::endl);
418 using rel_memfn_ptr_t = decltype(to_rel_memfn_ptr(t[0]));
419 static_assert(sizeof(rel_memfn_ptr_t) % sizeof(std::ptrdiff_t) == 0);
420 constexpr std::size_t memfn_ptr_width = sizeof(rel_memfn_ptr_t) / sizeof(std::ptrdiff_t);
421 std::vector<rel_memfn_ptr_t> t_rel(n);
422 std::transform(t, t+n, begin(t_rel), [](auto& fn_ptr) {
423 return to_rel_memfn_ptr(fn_ptr);
424 });
425 ar.store(reinterpret_cast<std::ptrdiff_t*>(t_rel.data()), n * memfn_ptr_width);
426 }
427
428 template <class Archive, class T>
429 typename std::enable_if_t< is_output_archive<Archive>::value &&
430 !(is_function_pointer_v<T> || std::is_member_function_pointer<T>::value) &&
432 , void>
433 default_serialize(const Archive& ar, const T* t, unsigned int n) {
434 MAD_ARCHIVE_DEBUG(std::cout << "serialize fund array" << std::endl);
435 ar.store(t, n);
436 }
437
438
439 /// Deserialize an array of fundamental stuff.
440
441 /// The function only appears (via \c enable_if) if \c T is
442 /// serializable and \c Archive is an input archive.
443 /// \tparam Archive The archive type.
444 /// \tparam T The type of data in the array.
445 /// \param[in] ar The archive.
446 /// \param[in] t Pointer to the start of the array.
447 /// \param[in] n Number of data items to be deserialized.
448 template <class Archive, class T>
449 typename std::enable_if_t< is_input_archive<Archive>::value &&
451 is_function_pointer_v<T>, void>
452 default_serialize(const Archive& ar, const T* t, unsigned int n) {
453 MAD_ARCHIVE_DEBUG(std::cout << "deserialize fund array" << std::endl);
454 // transform function pointers to relative offsets
455 std::vector<std::ptrdiff_t> t_rel(n);
456 ar.load(t_rel.data(),n);
457 std::transform(begin(t_rel), end(t_rel), (T*)t, [](auto& fn_ptr_rel) {
458 return to_abs_fn_ptr<T>(fn_ptr_rel);
459 });
460 }
461
462 template <class Archive, class T>
463 typename std::enable_if_t< is_input_archive<Archive>::value &&
465 std::is_member_function_pointer<T>::value, void>
466 default_serialize(const Archive& ar, const T* t, unsigned int n) {
467 MAD_ARCHIVE_DEBUG(std::cout << "deserialize fund array" << std::endl);
468 using rel_memfn_ptr_t = decltype(to_rel_memfn_ptr(t[0]));
469 static_assert(sizeof(rel_memfn_ptr_t) % sizeof(std::ptrdiff_t) == 0);
470 constexpr std::size_t memfn_ptr_width = sizeof(rel_memfn_ptr_t) / sizeof(std::ptrdiff_t);
471 std::vector<rel_memfn_ptr_t> t_rel(n);
472 ar.load(reinterpret_cast<std::ptrdiff_t*>(t_rel.data()), n * memfn_ptr_width);
473 std::transform(begin(t_rel), end(t_rel), (T*)t, [](auto& memfn_ptr_rel) {
474 return to_abs_memfn_ptr<T>(memfn_ptr_rel);
475 });
476 }
477
478 template <class Archive, class T>
479 typename std::enable_if_t< is_input_archive<Archive>::value && is_default_serializable<Archive,T>::value &&
480 !(is_function_pointer_v<T> || std::is_member_function_pointer<T>::value), void>
481 default_serialize(const Archive& ar, const T* t, unsigned int n) {
482 MAD_ARCHIVE_DEBUG(std::cout << "deserialize fund array" << std::endl);
483 ar.load((T*) t,n);
484 }
485
486 /// Serialize (or deserialize) an array of non-fundamental stuff.
487
488 /// The function only appears (via \c enable_if) if \c T is
489 /// not serializable and \c Archive is an archive.
490 /// \tparam Archive The archive type.
491 /// \tparam T The type of data in the array.
492 /// \param[in] ar The archive.
493 /// \param[in] t Pointer to the start of the array.
494 /// \param[in] n Number of data items to be serialized.
495 template <class Archive, class T>
496 typename std::enable_if_t< ! is_default_serializable<Archive,T>::value && is_archive<Archive>::value, void>
497 serialize(const Archive& ar, const T* t, unsigned int n) {
498 MAD_ARCHIVE_DEBUG(std::cout << "(de)serialize non-fund array" << std::endl);
499 for (unsigned int i=0; i<n; ++i)
500 ar & t[i];
501 }
502
503
504 /// Default implementation of the pre/postamble for type checking.
505
506 /// \tparam Archive The archive class.
507 /// \tparam T The type to serialized or to expect upon deserialization.
508 template <class Archive, class T>
510 /// Deserialize a cookie and check the type.
511
512 /// \param[in] ar The archive.
513 static inline void preamble_load(const Archive& ar) {
514 unsigned char ck = archive_typeinfo<T>::cookie;
515 unsigned char cookie;
516 ar.load(&cookie, 1); // cannot use >>
517 if (cookie != ck) {
518 const std::size_t bufsize=255;
519 char msg[bufsize];
520 std::snprintf(msg,bufsize,"InputArchive type mismatch: expected cookie "
521 "%u (%s) but got %u (%s) instead",
522 ck, archive_type_names[ck],
523 cookie,archive_type_names[cookie]);
524 std::cerr << msg << std::endl;
525 MADNESS_EXCEPTION(msg, static_cast<int>(cookie));
526 }
527 else {
528 MAD_ARCHIVE_DEBUG(std::cout << "read cookie " << archive_type_names[cookie] << std::endl);
529 }
530 }
531
532 /// Serialize a cookie for type checking.
533
534 /// \param[in] ar The archive.
535 static inline void preamble_store(const Archive& ar) {
536 unsigned char ck = archive_typeinfo<T>::cookie;
537 ar.store(&ck, 1); // cannot use <<
538 MAD_ARCHIVE_DEBUG(std::cout << "wrote cookie " << archive_type_names[ck] << std::endl);
539 }
540
541 /// By default there is no postamble.
542 static inline void postamble_load(const Archive& /*ar*/) {}
543
544 /// By default there is no postamble.
545 static inline void postamble_store(const Archive& /*ar*/) {}
546 };
547
548
549 /// Default symmetric serialization of a non-fundamental type that has `serialize` method
550
551 /// \tparam Archive The archive type.
552 /// \tparam T The type to symmetrically serialize.
553 template <class Archive, class T, typename Enabler>
555 /// Serializes the type.
556
557 /// \param[in] ar The archive.
558 /// \param[in,out] t The data.
559 template <typename A = Archive, typename U = T, typename = std::enable_if_t<has_member_serialize_v<U,A>>>
560 static inline void serialize(const Archive& ar, T& t) {
561 constexpr auto has_serialize = has_member_serialize_v<T,Archive>;
562 if constexpr (has_serialize)
563 t.serialize(ar);
564 else { // this is never instantiated
565 constexpr auto T_has_serialize_method = !has_serialize;
566 static_assert(T_has_serialize_method);
567 }
568 }
569 };
570
571
572 /// Redirect `serialize(ar, t)` to `serialize(ar, &t, 1)` for fundamental types.
573
574 /// The function only appears (due to \c enable_if) if \c T is
575 /// serializable and \c Archive is an archive.
576 /// \tparam Archive The archive type.
577 /// \tparam T The data type.
578 /// \param[in] ar The archive.
579 /// \param[in] t The data to be serialized.
580 template <class Archive, class T>
581 inline
582 std::enable_if_t< is_default_serializable<Archive,T>::value && is_archive<Archive>::value, void>
583 default_serialize(const Archive& ar, const T& t) {
584 MAD_ARCHIVE_DEBUG(std::cout << "default_serialize(ar,t) -> default_serialize(ar,&t,1)" << std::endl);
585 default_serialize(ar, &t, 1);
586 }
587
588
589 /// Redirect `serialize(ar,t)` to \c ArchiveSerializeImpl for non-fundamental types.
590
591 /// The function only appears (due to \c enable_if) if \c T is not
592 /// serializable and \c Archive is an archive.
593 /// \tparam Archive The archive type.
594 /// \tparam T The data type.
595 /// \param[in] ar The archive.
596 /// \param[in] t The data to be serialized.
597 template <class Archive, class T>
598 inline
599 std::enable_if_t< (!is_default_serializable<Archive,T>::value && has_nonmember_serialize_v<T, Archive>) && is_archive<Archive>::value, void >
600 serialize(const Archive& ar, const T& t) {
601 MAD_ARCHIVE_DEBUG(std::cout << "serialize(ar,t) -> ArchiveSerializeImpl" << std::endl);
603 }
604
605
606 /// Default store of an object via `serialize(ar, t)`.
607
608 /// \tparam Archive The archive type.
609 /// \tparam T The data type.
610 template <class Archive, class T, typename Enabler>
612
613 template <typename A = Archive, typename U = T>
614 static inline std::enable_if_t<is_output_archive_v<A> &&
615 !std::is_function<U>::value &&
616 (has_member_serialize_v<U,A> ||
617 has_nonmember_serialize_v<U,A> ||
618 has_freestanding_serialize_v<U, A> ||
619 has_freestanding_default_serialize_v<U, A>),
620 void>
621 store(const A& ar, const U& t) {
622 MAD_ARCHIVE_DEBUG(std::cout << "store(ar,t) default" << std::endl);
623 if constexpr (has_member_serialize_v<U,A>) {
624 const_cast<U&>(t).serialize(ar);
625 }
626 else if constexpr (has_nonmember_serialize_v<U,A>) {
627 ArchiveSerializeImpl<A, U>::serialize(ar, const_cast<U&>(t));
628 }
629 else if constexpr (has_freestanding_serialize_v<U, A>) {
630 serialize(ar, const_cast<U&>(t));
631 }
632 else if constexpr (has_freestanding_default_serialize_v<U, A>) {
633 default_serialize(ar, const_cast<U&>(t));
634 }
635 else // unreachable
636 assert(false);
637 }
638
639 /// Store function reference as a function pointer
640
641 /// \param[in] ar The archive.
642 /// \param[in] t The data.
643 template <typename A = Archive, typename U = T,
644 typename = std::enable_if_t<is_output_archive_v<A> &&
645 std::is_function<U>::value>>
646 static inline void store(const Archive& ar, const U& t) {
647 MAD_ARCHIVE_DEBUG(std::cout << "store(ar,t) default" << std::endl);
648 // convert function to function ptr
649 std::add_pointer_t<U> fn_ptr = &t;
650 if constexpr (has_freestanding_default_serialize_v<std::add_pointer_t<U>,A>)
651 default_serialize(ar,fn_ptr);
652 else if constexpr (has_freestanding_serialize_v<std::add_pointer_t<U>,A>)
653 serialize(ar,fn_ptr);
654 else
655 assert(false);
656 }
657
658 };
659
660
661 /// Default load of an object via `serialize(ar, t)`.
662
663 /// \tparam Archive The archive type.
664 /// \tparam T The data type.
665 template <class Archive, class T, typename Enabler>
667 /// Load an object.
668
669 /// \param[in] ar The archive.
670 /// \param[in] t The data.
671 template <typename A = Archive,
672 typename U = T,
673 typename = std::enable_if_t<is_input_archive_v<A> &&
674 (has_member_serialize_v<U,A> ||
675 has_nonmember_serialize_v<U,A> ||
676 has_freestanding_serialize_v<U, A> ||
677 has_freestanding_default_serialize_v<U, A>)>>
678 static inline void load(const A& ar, const U& t) {
679 MAD_ARCHIVE_DEBUG(std::cout << "load(ar,t) default" << std::endl);
680 if constexpr (has_member_serialize_v<U,A>) {
681 const_cast<U&>(t).serialize(ar);
682 }
683 else if constexpr (has_nonmember_serialize_v<U,A>) {
684 ArchiveSerializeImpl<A, U>::serialize(ar, const_cast<U&>(t));
685 }
686 else if constexpr (has_freestanding_serialize_v<U, A>) {
687 serialize(ar, const_cast<U&>(t));
688 }
689 else if constexpr (has_freestanding_default_serialize_v<U, A>) {
690 default_serialize(ar, const_cast<U&>(t));
691 }
692 else // unreachable
693 assert(false);
694 }
695
696 /// Load function reference stored as function pointer
697
698 /// \param[in] ar The archive.
699 /// \param[in] t The data.
700 template <typename A = Archive, typename U = T,
701 typename = std::enable_if_t<is_input_archive_v<A> &&
702 std::is_function<U>::value>>
703 static inline void load(const Archive& ar, U& t) {
704 MAD_ARCHIVE_DEBUG(std::cout << "load(ar,t) default" << std::endl);
705 // convert function ptr to function ref
706 std::add_pointer_t<U> fn_ptr;
707 if constexpr (has_freestanding_default_serialize_v<std::add_pointer_t<U>,A>)
708 default_serialize(ar,fn_ptr);
709 else if constexpr (has_freestanding_serialize_v<std::add_pointer_t<U>,A>)
710 serialize(ar,fn_ptr);
711 else
712 assert(false);
713 t = *fn_ptr;
714 }
715
716 };
717
718
719 /// Default implementations of \c wrap_store and \c wrap_load.
720
721 /// "Wrapping" refers to the addition of the type's preamble and
722 /// postamble around the data to provide runtime type-checking.
723 /// \tparam Archive The archive type.
724 /// \tparam T The data type.
725 template <class Archive, class T, typename Enabler>
726 struct ArchiveImpl {
727 /// Store an object sandwiched between its preamble and postamble.
728
729 /// \param[in] ar The archive.
730 /// \param[in] t The data.
731 /// \return The archive.
732 template <typename A = Archive, typename = std::enable_if_t<is_output_archive_v<A> && has_nonmember_store_v<T,Archive>>>
733 static inline const Archive& wrap_store(const Archive& ar, const T& t) {
734 MAD_ARCHIVE_DEBUG(std::cout << "wrap_store for default" << std::endl);
738 return ar;
739 }
740
741 /// Load an object sandwiched between its preamble and postamble.
742
743 /// \param[in] ar The archive.
744 /// \param[in] t The data.
745 /// \return The archive.
746 template <typename A = Archive, typename = std::enable_if_t<is_input_archive_v<A> && has_nonmember_load_v<T,Archive>>>
747 static inline const Archive& wrap_load(const Archive& ar, const T& t) {
748 MAD_ARCHIVE_DEBUG(std::cout << "wrap_load for default" << std::endl);
750 ArchiveLoadImpl<Archive,T>::load(ar,const_cast<T&>(t)); // Loses constness here!
752 return ar;
753 }
754 };
755
756
757 /// Redirect \c << to \c ArchiveImpl::wrap_store for output archives.
758
759 /// The function only appears (due to \c enable_if) if \c Archive
760 /// is an output archive.
761 /// \tparam Archive The archive type.
762 /// \tparam T The data type.
763 /// \param[in] ar The archive.
764 /// \param[in] t The data.
765 template <class Archive, class T>
766 inline
767 std::enable_if_t<is_output_archive_v<Archive>, const Archive&>
768 operator<<(const Archive& ar, const T& t) {
769 // assert that T is serializable
770 if constexpr (!is_serializable_v<Archive,T>) {
771 constexpr bool T_is_serializable = is_serializable_v<Archive,T>;
772 static_assert(T_is_serializable, "T is neither trivially serializable not provided serialization methods");
773 }
774 //PROFILE_FUNC;
776 }
777
778 /// Redirect \c >> to `ArchiveImpl::wrap_load` for input archives.
779
780 /// The function only appears (due to \c enable_if) if \c Archive
781 /// is an input archive.
782 /// \tparam Archive The archive type.
783 /// \tparam T The data type.
784 /// \param[in] ar The archive.
785 /// \param[in] t The data.
786 template <class Archive, class T>
787 inline
788 std::enable_if_t<is_input_archive_v<Archive>, const Archive&>
789 operator>>(const Archive& ar, const T& t) {
790 // assert that T is serializable
791 if constexpr (!is_serializable_v<Archive,T>) {
792 constexpr bool T_is_serializable = is_serializable_v<Archive,T>;
793 static_assert(T_is_serializable, "T is neither trivially serializable not provided serialization methods");
794 }
795 //PROFILE_FUNC;
797 }
798
799 /// Redirect \c & to `ArchiveImpl::wrap_store` for output archives.
800
801 /// The function only appears (due to \c enable_if) if \c Archive
802 /// is an output archive.
803 /// \tparam Archive The archive type.
804 /// \tparam T The data type.
805 /// \param[in] ar The archive.
806 /// \param[in] t The data.
807 template <class Archive, class T>
808 inline
809 std::enable_if_t<is_output_archive_v<Archive>, const Archive&>
810 operator&(const Archive& ar, const T& t) {
811 // assert that T is serializable
812 if constexpr (!is_serializable_v<Archive,T>) {
813 constexpr bool T_is_serializable = is_serializable_v<Archive,T>;
814 static_assert(T_is_serializable, "T is neither trivially serializable not provided serialization methods");
815 }
816 //PROFILE_FUNC;
818 }
819
820 /// Redirect \c & to `ArchiveImpl::wrap_load` for input archives.
821
822 /// The function only appears (due to \c enable_if) if \c Archive
823 /// is an input archive.
824 /// \tparam Archive The archive type.
825 /// \tparam T The data type.
826 /// \param[in] ar The archive.
827 /// \param[in] t The data.
828 template <class Archive, class T>
829 inline
830 std::enable_if_t<is_input_archive_v<Archive>, const Archive&>
831 operator&(const Archive& ar, const T& t) {
832 // assert that T is serializable
833 if constexpr (!is_serializable_v<Archive,T>) {
834 constexpr bool T_is_serializable = is_serializable_v<Archive,T>;
835 static_assert(T_is_serializable, "T is neither trivially serializable not provided serialization methods");
836 }
837 //PROFILE_FUNC;
839 }
840
841
842 // -----------------------------------------------------------------
843
844 /// Wrapper for an opaque pointer for serialization purposes.
845
846 /// Performs a bitwise copy of the pointer without any remapping.
847 /// \tparam T The type of object being pointed to.
848 /// \todo Verify this documentation.
849 template <class T>
851 public:
852 T* ptr; ///< The pointer.
853
854 /// Constructor specifying \c nullptr by default.
855
856 /// \param[in] t The pointer.
857 archive_ptr(T* t = nullptr)
858 : ptr(t) {}
859
860 /// Dereference the pointer.
861
862 /// \return The dereferenced pointer.
864 return *ptr;
865 }
866
867 /// Serialize the pointer.
868
869 /// \tparam Archive The archive type.
870 /// \param[in] ar The archive.
871 template <class Archive>
872 void serialize(const Archive& ar) {ar & wrap_opaque(&ptr, 1);}
873 };
874
875
876 /// Wrapper for pointers.
877
878 /// \tparam T The type of object being pointed to.
879 /// \param[in] p The pointer.
880 /// \return The wrapped pointer.
881 template <class T>
883 return archive_ptr<T>(p);
884 }
885
886 /// Wrapper for dynamic arrays and pointers.
887
888 /// \tparam T The type of object being pointed to.
889 template <class T>
891 public:
892 const T* ptr; ///< The pointer.
893 unsigned int n; ///< The number of objects in the array.
894
895 /// Constructor specifying a memory location and size.
896
897 /// \param[in] ptr The pointer.
898 /// \param[in] n The number of objects in the array.
899 archive_array(const T *ptr, unsigned int n) : ptr(ptr), n(n) {}
900
901 /// Constructor specifying no array and of 0 length.
902 archive_array() : ptr(nullptr), n(0) {}
903 };
904
905
906 /// Factory function to wrap a dynamically allocated pointer as a typed \c archive_array.
907
908 /// \tparam T The data type.
909 /// \param[in] ptr The pointer.
910 /// \param[in] n The number of data elements in the array.
911 /// \return The wrapped pointer.
912 template <class T>
913 inline archive_array<T> wrap(const T* ptr, unsigned int n) {
914 return archive_array<T>(ptr,n);
915 }
916
917
918 /// Factory function to wrap a pointer to contiguous data as an opaque (\c uchar) \c archive_array.
919
920 /// \tparam T The data type.
921 /// \param[in] ptr The pointer.
922 /// \param[in] n The number of data elements in the array.
923 /// \return The wrapped pointer, as an opaque \c archive_array.
924 template <class T>
925 inline archive_array<unsigned char> wrap_opaque(const T* ptr, unsigned int n) {
926 return archive_array<unsigned char>((unsigned char*) ptr, n*sizeof(T));
927 }
928
929 /// Factory function to wrap a contiguous scalar as an opaque (\c uchar) \c archive_array.
930
931 /// \tparam T The data type.
932 /// \param[in] t The data.
933 /// \return The wrapped data.
934 template <class T>
936 return archive_array<unsigned char>((unsigned char*) &t,sizeof(t));
937 }
938
939
940 /// Serialize a function pointer.
941
942 /// \tparam Archive The archive type.
943 /// \tparam resT The function's return type.
944 /// \tparam paramT Parameter pack for the function's arguments.
945 template <class Archive, typename resT, typename... paramT>
946 struct ArchiveSerializeImpl<Archive, resT(*)(paramT...), std::enable_if_t<!is_default_serializable_v<Archive, resT(*)(paramT...)> >> {
947 /// Serialize the function pointer.
948
949 /// \param[in] ar The archive.
950 /// \param[in] fn The function pointer.
951 template <typename A = Archive, typename = std::enable_if_t<is_output_archive<A>::value>>
952 static inline void serialize(const A& ar, resT(*(&fn))(paramT...)) {
953 ar &wrap_opaque(to_rel_fn_ptr(fn));
954 }
955
956 template <typename A = Archive>
957 static inline std::enable_if_t<!is_output_archive<A>::value, void> serialize(const A& ar, resT(*(&fn))(paramT...)) {
958 std::ptrdiff_t rel_fn_ptr{};
959 ar & wrap_opaque(rel_fn_ptr);
960 fn = to_abs_fn_ptr<std::remove_reference_t<decltype(fn)>>(rel_fn_ptr);
961 }
962 };
963
964
965 /// Serialize a member function pointer.
966
967 /// \tparam Archive The archive type.
968 /// \tparam resT The member function's return type.
969 /// \tparam objT The object type.
970 /// \tparam paramT Parameter pack for the member function's arguments.
971 template <class Archive, typename resT, typename objT, typename... paramT>
972 struct ArchiveSerializeImpl<Archive, resT(objT::*)(paramT...),
973 std::enable_if_t<!is_default_serializable_v<Archive, resT(objT::*)(paramT...)>>> {
974 /// Serialize the member function pointer.
975
976 /// \param[in] ar The archive.
977 /// \param[in] memfn The member function pointer.
978 template <typename A = Archive, typename = std::enable_if_t<is_output_archive<A>::value>>
979 static inline void serialize(const A& ar, resT(objT::*(&memfn))(paramT...)) {
980 ar &wrap_opaque(to_rel_memfn_ptr(memfn));
981 }
982
983 template <typename A = Archive>
984 static inline std::enable_if_t<!is_output_archive<A>::value, void> serialize(const A& ar, resT(objT::*(&memfn))(paramT...)) {
985 using rel_memfn_ptr_t = decltype(to_rel_memfn_ptr(memfn));
986 rel_memfn_ptr_t rel_fn_ptr{};
987 ar & wrap_opaque(rel_fn_ptr);
988 memfn = to_abs_memfn_ptr<decltype(memfn)>(rel_fn_ptr);
989 }
990 };
991
992 /// Serialize a const member function pointer.
993
994 /// \tparam Archive The archive type.
995 /// \tparam resT The const member function's return type.
996 /// \tparam objT The object type.
997 /// \tparam paramT Parameter pack for the const member function's arguments.
998 template <class Archive, typename resT, typename objT, typename... paramT>
999 struct ArchiveSerializeImpl<Archive, resT(objT::*)(paramT...) const,
1000 std::enable_if_t<!is_default_serializable_v<Archive, resT(objT::*)(paramT...) const>>
1001 > {
1002 /// Serialize the const member function pointer.
1003
1004 /// \param[in] ar The archive.
1005 /// \param[in] memfn The const member function pointer.
1006 static inline void serialize(const Archive& ar, resT(objT::*memfn)(paramT...) const) {
1007 ar & wrap_opaque(memfn);
1008 }
1009 };
1010
1011
1012 /// Partial specialization of \c ArchiveImpl for \c archive_array.
1013
1014 /// \tparam Archive The archive type.
1015 /// \tparam T The data type in the \c archive_array.
1016 template <class Archive, class T>
1017 struct ArchiveImpl< Archive, archive_array<T> > {
1018 /// Store the \c archive_array, wrapped by the preamble/postamble.
1019
1020 /// \param[in] ar The archive.
1021 /// \param[in] t The \c archive_array.
1022 /// \return The archive.
1023 static inline const Archive& wrap_store(const Archive& ar, const archive_array<T>& t) {
1024 MAD_ARCHIVE_DEBUG(std::cout << "wrap_store for archive_array" << std::endl);
1026 //ar << t.n;
1027 //ArchivePrePostImpl<Archive,T>::preamble_store(ar);
1028 if constexpr (has_freestanding_serialize_with_size_v<std::add_pointer_t<T>, Archive>)
1029 serialize(ar,(T *) t.ptr,t.n);
1030 else if constexpr (has_freestanding_default_serialize_with_size_v<std::add_pointer_t<T>, Archive>)
1031 default_serialize(ar,(T *) t.ptr,t.n);
1032 else
1033 assert(false);
1034 //ArchivePrePostImpl<Archive,T>::postamble_store(ar);
1036 return ar;
1037 }
1038
1039 /// Load the \c archive_array, using the preamble and postamble to perform runtime type-checking.
1040
1041 /// \param[in] ar The archive.
1042 /// \param[out] t The \c archive_array.
1043 /// \return The archive.
1044 static inline const Archive& wrap_load(const Archive& ar, const archive_array<T>& t) {
1045 MAD_ARCHIVE_DEBUG(std::cout << "wrap_load for archive_array" << std::endl);
1047 //unsigned int n;
1048 //ar >> n;
1049 //if (n != t.n)
1050 // MADNESS_EXCEPTION("deserializing archive_array: dimension mismatch", n);
1051 //ArchivePrePostImpl<Archive,T>::preamble_load(ar);
1052 if constexpr (has_freestanding_serialize_with_size_v<std::add_pointer_t<T>, Archive>)
1053 serialize(ar,(T *) t.ptr,t.n);
1054 else if constexpr (has_freestanding_default_serialize_with_size_v<std::add_pointer_t<T>, Archive>)
1055 default_serialize(ar,(T *) t.ptr,t.n);
1056 else
1057 assert(false);
1058 //ArchivePrePostImpl<Archive,T>::postamble_load(ar);
1060 return ar;
1061 }
1062 };
1063
1064
1065 /// Partial specialization of \c ArchiveImpl for fixed-dimension arrays that redirects to \c archive_array.
1066
1067 /// \tparam Archive The archive type.
1068 /// \tparam T The data type.
1069 /// \tparam n The array size.
1070 template <class Archive, class T, std::size_t n>
1071 struct ArchiveImpl<Archive, T[n], std::enable_if_t<!std::is_same_v<T,char> && is_serializable_v<Archive, T>>> {
1072 /// Store the array, wrapped by the preamble/postamble.
1073
1074 /// \param[in] ar The archive.
1075 /// \param[in] t The array.
1076 /// \return The archive.
1077 static inline const Archive& wrap_store(const Archive& ar, const T(&t)[n]) {
1078 MAD_ARCHIVE_DEBUG(std::cout << "wrap_store for array" << std::endl);
1079 ar << wrap(&t[0],n);
1080 return ar;
1081 }
1082
1083 /// Load the array, using the preamble and postamble to perform runtime type-checking.
1084
1085 /// \param[in] ar The archive.
1086 /// \param[out] t The array.
1087 /// \return The archive.
1088 static inline const Archive& wrap_load(const Archive& ar, const T(&t)[n]) {
1089 MAD_ARCHIVE_DEBUG(std::cout << "wrap_load for array" << std::endl);
1090 ar >> wrap(&t[0],n);
1091 return ar;
1092 }
1093 };
1094
1095
1096 /// Serialize a complex number.
1097
1098 /// \tparam Archive The archive type.
1099 /// \tparam T The data type underlying the complex number.
1100 template <class Archive, typename T>
1101 struct ArchiveStoreImpl< Archive, std::complex<T>, std::enable_if_t<is_serializable_v<Archive, T>> > {
1102 /// Store a complex number.
1103
1104 /// \param[in] ar The archive.
1105 /// \param[in] c The complex number.
1106 static inline void store(const Archive& ar, const std::complex<T>& c) {
1107 MAD_ARCHIVE_DEBUG(std::cout << "serialize complex number" << std::endl);
1108 ar & c.real() & c.imag();
1109 }
1110 };
1111
1112
1113 /// Deserialize a complex number.
1114
1115 /// \tparam Archive the archive type.
1116 /// \tparam T The data type underlying the complex number.
1117 template <class Archive, typename T>
1118 struct ArchiveLoadImpl< Archive, std::complex<T>, std::enable_if_t<is_serializable_v<Archive, T>> > {
1119 /// Load a complex number.
1120
1121 /// \param[in] ar The archive.
1122 /// \param[out] c The complex number.
1123 static inline void load(const Archive& ar, std::complex<T>& c) {
1124 MAD_ARCHIVE_DEBUG(std::cout << "deserialize complex number" << std::endl);
1125 T r = 0, i = 0;
1126 ar & r & i;
1127 c = std::complex<T>(r,i);
1128 }
1129 };
1130
1131 /// Serialize a \c std::allocator.
1132
1133 /// This is a no-op.
1134 /// \tparam Archive the archive type.
1135 /// \tparam T The data type allocated by the \c allocator.
1136 template <class Archive, typename T>
1137 struct ArchiveStoreImpl< Archive, std::allocator<T>, std::enable_if_t<!is_future<T>::value && is_serializable_v<Archive, T>> > {
1138
1139 /// Storing a \c std::allocator is a no-op
1140
1141 /// \param[in] ar The archive.
1142 /// \param[in] v The \c allocator.
1143 static inline void store(const Archive& ar, const std::allocator<T>& v) {
1144 }
1145 };
1146
1147
1148 /// Deserialize a \c std::allocator.
1149
1150 /// This is a no-op.
1151 /// \tparam Archive the archive type.
1152 /// \tparam T The data type alllocated by in the \c allocator.
1153 template <class Archive, typename T>
1154 struct ArchiveLoadImpl< Archive, std::allocator<T>, std::enable_if_t<!is_future<T>::value && is_serializable_v<Archive, T>> > {
1155
1156 /// Loading a \c std::allocator is a no-op
1157
1158 /// \param[in] ar The archive.
1159 /// \param[out] v The \c allocator.
1160 static void load(const Archive& ar, std::allocator<T>& v) {
1161 }
1162 };
1163
1164 /// Serialize a \c std::vector.
1165
1166 /// \tparam Archive the archive type.
1167 /// \tparam T The data type stored in the \c vector.
1168 /// \tparam Alloc The allocator type.
1169 template <class Archive, typename T, typename Alloc>
1170 struct ArchiveStoreImpl< Archive, std::vector<T, Alloc>, std::enable_if_t<!is_future<T>::value && is_serializable_v<Archive, T>> > {
1171
1172 /// Store a \c std::vector of plain data.
1173
1174 /// \param[in] ar The archive.
1175 /// \param[in] v The \c vector.
1176 static inline void store(const Archive& ar, const std::vector<T, Alloc>& v) {
1177 MAD_ARCHIVE_DEBUG(std::cout << "serialize std::vector of plain data" << std::endl);
1178 if constexpr (!std::allocator_traits<Alloc>::is_always_equal::value) {
1179 ar & v.get_allocator();
1180 }
1181 ar & v.size();
1182 ar & wrap(v.data(),v.size());
1183 }
1184 };
1185
1186
1187 /// Deserialize a \c std::vector. Clears and resizes as necessary.
1188
1189 /// \tparam Archive the archive type.
1190 /// \tparam T The data type stored in the \c vector.
1191 /// \tparam Alloc The allocator type.
1192 template <class Archive, typename T, typename Alloc>
1193 struct ArchiveLoadImpl< Archive, std::vector<T, Alloc>, std::enable_if_t<!is_future<T>::value && is_serializable_v<Archive, T>> > {
1194
1195 /// Load a \c std::vector.
1196
1197 /// Clears and resizes the \c vector as necessary.
1198 /// \param[in] ar The archive.
1199 /// \param[out] v The \c vector.
1200 static void load(const Archive& ar, std::vector<T, Alloc>& v) {
1201 MAD_ARCHIVE_DEBUG(std::cout << "deserialize std::vector of plain data" << std::endl);
1202 if constexpr (!std::allocator_traits<Alloc>::is_always_equal::value) {
1203 Alloc allocator;
1204 ar & allocator;
1205 v = std::vector<T, Alloc>(allocator);
1206 }
1207 std::size_t n = 0ul;
1208 ar & n;
1209 if (n != v.size()) {
1210 v.clear();
1211 v.resize(n);
1212 }
1213 ar & wrap((T *) v.data(),n);
1214 }
1215
1216 };
1217
1218
1219 /// Serialize a \c std::vector<bool> (as a plain array of bool).
1220
1221 /// \tparam Archive The archive type.
1222 /// \tparam Alloc The allocator type.
1223 template <class Archive, typename Alloc>
1224 struct ArchiveStoreImpl< Archive, std::vector<bool, Alloc> > {
1225 /// Store a \c vector<bool>.
1226
1227 /// \param[in] ar The archive.
1228 /// \param[in] v The \c vector.
1229 static inline void store(const Archive& ar, const std::vector<bool, Alloc>& v) {
1230 MAD_ARCHIVE_DEBUG(std::cout << "serialize std::vector<bool>" << std::endl);
1231 if constexpr (!std::allocator_traits<Alloc>::is_always_equal::value) {
1232 ar & v.get_allocator();
1233 }
1234 std::size_t n = v.size();
1235 bool* b = new bool[n];
1236 for (std::size_t i=0; i<n; ++i) b[i] = v[i];
1237 ar & n & wrap(b,v.size());
1238 delete [] b;
1239 }
1240 };
1241
1242
1243 /// Deserialize a std::vector<bool>. Clears and resizes as necessary.
1244
1245 /// \tparam Archive The archive type.
1246 /// \tparam Alloc The allocator type.
1247 template <class Archive, typename Alloc>
1248 struct ArchiveLoadImpl< Archive, std::vector<bool, Alloc> > {
1249 /// Load a \c vector<bool>.
1250
1251 /// Clears and resizes the \c vector as necessary.
1252 /// \param[in] ar The archive.
1253 /// \param[out] v The \c vector.
1254 static void load(const Archive& ar, std::vector<bool, Alloc>& v) {
1255 MAD_ARCHIVE_DEBUG(std::cout << "deserialize std::vector<bool>" << std::endl);
1256 if constexpr (!std::allocator_traits<Alloc>::is_always_equal::value) {
1257 Alloc allocator;
1258 ar & allocator;
1259 v = std::vector<bool, Alloc>(allocator);
1260 }
1261 std::size_t n = 0ul;
1262 ar & n;
1263 if (n != v.size()) {
1264 v.clear();
1265 v.resize(n);
1266 }
1267 bool* b = new bool[n];
1268 ar & wrap(b,v.size());
1269 for (std::size_t i=0; i<n; ++i) v[i] = b[i];
1270 delete [] b;
1271 }
1272 };
1273
1274 /// Serialize a \c std::array.
1275
1276 /// \tparam Archive the archive type.
1277 /// \tparam T The data type stored in the \c std::array.
1278 /// \tparam N The size of the \c std::array.
1279 template <class Archive, typename T, std::size_t N>
1280 struct ArchiveStoreImpl< Archive, std::array<T, N>, std::enable_if_t<is_serializable_v<Archive, T>> > {
1281
1282 /// Store a \c std::array.
1283
1284 /// \param[in] ar The archive.
1285 /// \param[in] v The array object to be serialized.
1286 static inline void store(const Archive& ar, const std::array<T, N>& v) {
1287 MAD_ARCHIVE_DEBUG(std::cout << "serialize std::array<T," << N << ">, with T plain data" << std::endl);
1288 ar & v.size();
1289 ar & wrap(v.data(),v.size());
1290 }
1291
1292 };
1293
1294 /// Deserialize a \c std::array. \c MADNESS_ASSERT 's that the size matches.
1295
1296 /// \tparam Archive the archive type.
1297 /// \tparam T The data type stored in the \c std::array.
1298 /// \tparam N The size of the \c std::array.
1299 template <class Archive, typename T, std::size_t N>
1300 struct ArchiveLoadImpl< Archive, std::array<T, N>, std::enable_if_t<is_serializable_v<Archive, T>> > {
1301
1302 /// Load a \c std::array.
1303
1304 /// \param[in] ar The archive.
1305 /// \param[out] v The array to be deserialized.
1306 static void load(const Archive& ar, std::array<T, N>& v) {
1307 MAD_ARCHIVE_DEBUG(std::cout << "deserialize std::array<T," << N << ">, with T plain data" << std::endl);
1308 std::size_t n = 0ul;
1309 ar & n;
1310 MADNESS_ASSERT(n == v.size());
1311 ar & wrap((T *) v.data(),n);
1312 }
1313
1314 };
1315
1316 /// Serialize a 'std::string'.
1317
1318 /// \tparam Archive The archive type.
1319 template <class Archive>
1320 struct ArchiveStoreImpl< Archive, std::string > {
1321 /// Store a string.
1322
1323 /// \param[in] ar The archive.
1324 /// \param[in] v The string.
1325 static void store(const Archive& ar, const std::string& v) {
1326 MAD_ARCHIVE_DEBUG(std::cout << "serialize std::string" << std::endl);
1327 ar & v.size();
1328 ar & wrap((const char*) v.data(),v.size());
1329 }
1330 };
1331
1332
1333 /// Deserialize a std::string. Clears and resizes as necessary.
1334
1335 /// \tparam Archive The archive type.
1336 template <class Archive>
1337 struct ArchiveLoadImpl< Archive, std::string > {
1338 /// Load a string.
1339
1340 /// Clears and resizes the string as necessary.
1341 /// \param[in] ar The archive.
1342 /// \param[out] v The string.
1343 static void load(const Archive& ar, std::string& v) {
1344 MAD_ARCHIVE_DEBUG(std::cout << "deserialize std::string" << std::endl);
1345 std::size_t n = 0ul;
1346 ar & n;
1347 if (n != v.size()) {
1348 v.clear();
1349 v.resize(n);
1350 }
1351 ar & wrap((char*) v.data(),n);
1352 }
1353 };
1354
1355
1356 /// Serialize (deserialize) an std::pair.
1357
1358 /// \tparam Archive The archive type.
1359 /// \tparam T The first data type in the pair.
1360 /// \tparam Q The second data type in the pair.
1361 template <class Archive, typename T, typename Q>
1362 struct ArchiveSerializeImpl< Archive, std::pair<T, Q>, std::enable_if_t<is_serializable_v<Archive, T> && is_serializable_v<Archive, Q>> > {
1363 /// Serialize the \c pair.
1364
1365 /// \param[in] ar The archive.
1366 /// \param[in,out] t The \c pair.
1367 static inline void serialize(const Archive& ar, std::pair<T,Q>& t) {
1368 MAD_ARCHIVE_DEBUG(std::cout << "(de)serialize std::pair" << std::endl);
1369 ar & t.first & t.second;
1370 }
1371 };
1372
1373 /// Serialize (deserialize) an std::optional.
1374
1375 /// \tparam Archive The archive type.
1376 /// \tparam T The data type stored in the optional object
1377 template <class Archive, typename T>
1378 struct ArchiveSerializeImpl< Archive, std::optional<T>, std::enable_if_t<is_serializable_v<Archive, T>> > {
1379 /// Serialize the \c std::optional.
1380
1381 /// \param[in] ar The archive.
1382 /// \param[in,out] t The \c optional.
1383 static inline void serialize(const Archive& ar, std::optional<T>& t) {
1384 MAD_ARCHIVE_DEBUG(std::cout << "(de)serialize std::optional" << std::endl);
1385 if constexpr (is_output_archive_v<Archive>) { // serialize
1386 ar & t.has_value();
1387 if (t.has_value())
1388 ar & t.value();
1389 } else {
1390 bool has_value;
1391 ar & has_value;
1392 if (has_value) {
1393 T value;
1394 ar & value;
1395 t = std::move(value);
1396 }
1397 }
1398 }
1399 };
1400
1401 namespace {
1402
1403 template <size_t idx, class Archive, typename... Types>
1404 struct tuple_serialize_helper;
1405
1406 template <class Archive, typename... Types>
1407 struct tuple_serialize_helper<0,Archive,Types...> {
1408 static void exec(const Archive& ar, std::tuple<Types...>& t) {
1409 ar & std::get<0>(t);
1410 }
1411 };
1412 template <size_t idx, class Archive, typename... Types>
1413 struct tuple_serialize_helper {
1414 static void exec(const Archive& ar, std::tuple<Types...>& t) {
1415 ar & std::get<idx>(t);
1416 tuple_serialize_helper<idx-1,Archive,Types...>::exec(ar,t);
1417 }
1418 };
1419
1420 };
1421
1422 /// Serialize (deserialize) a std::tuple
1423
1424 /// \tparam Archive The archive type.
1425 /// \tparam Types The tuple payload
1426 template <class Archive, typename... Types>
1427 struct ArchiveSerializeImpl< Archive, std::tuple<Types...>, std::enable_if_t<(is_serializable_v<Archive, Types> && ... ) >> {
1428 /// Serialize the \c std::tuple.
1429
1430 /// \param[in] ar The archive.
1431 /// \param[in,out] t The \c tuple.
1432 static inline void serialize(const Archive& ar, std::tuple<Types...>& t) {
1433 MAD_ARCHIVE_DEBUG(std::cout << "(de)serialize std::tuple" << std::endl);
1434 constexpr auto size = std::tuple_size<std::tuple<Types...>>::value;
1435 tuple_serialize_helper<size-1,Archive,Types...>::exec(ar, t);
1436 }
1437 };
1438
1439 /// Serialize an \c std::map.
1440
1441 /// \tparam Archive The archive type.
1442 /// \tparam T The map's key type.
1443 /// \tparam Q The map's data type.
1444 /// \tparam Compare The map's comparer type.
1445 /// \tparam Alloc The map's allocator type.
1446 template <class Archive, typename T, typename Q, typename Compare, typename Alloc>
1447 struct ArchiveStoreImpl< Archive, std::map<T,Q,Compare,Alloc>, std::enable_if_t<is_serializable_v<Archive, T> && is_serializable_v<Archive, Q>> > {
1448 /// Store a \c map.
1449
1450 /// \param[in] ar The archive.
1451 /// \param[in] t The \c map.
1452 static void store(const Archive& ar, const std::map<T,Q,Compare,Alloc>& t) {
1453 MAD_ARCHIVE_DEBUG(std::cout << "serialize std::map" << std::endl);
1454 if constexpr (!std::allocator_traits<Alloc>::is_always_equal::value) {
1455 ar & t.get_allocator();
1456 }
1457 ar << t.size();
1458 for (auto p = t.begin();
1459 p != t.end(); ++p) {
1460 // Fun and games here since IBM's iterator (const or
1461 // otherwise) gives us a const qualified key
1462 // (p->first) which buggers up the type matching
1463 // unless the user defines pair(T,Q) and pair(const
1464 // T,Q) to have cookie (which is tedious).
1465 std::pair<T,Q> pp = *p;
1466 ar & pp;
1467 }
1468 }
1469 };
1470
1471
1472 /// Deserialize an \c std::map. The \c map is \em not cleared; duplicate elements are replaced.
1473
1474 /// \tparam Archive The archive type.
1475 /// \tparam T The map's key type.
1476 /// \tparam Q The map's data type.
1477 /// \tparam Compare The map's comparer type.
1478 /// \tparam Alloc The map's allocator type.
1479 template <class Archive, typename T, typename Q, typename Compare, typename Alloc>
1480 struct ArchiveLoadImpl< Archive, std::map<T,Q,Compare,Alloc>, std::enable_if_t<is_serializable_v<Archive, T> && is_serializable_v<Archive, Q>> > {
1481 /// Load a \c map.
1482
1483 /// The \c map is \em not cleared; duplicate elements are replaced.
1484 /// \param[in] ar The archive.
1485 /// \param[out] t The \c map.
1486 static void load(const Archive& ar, std::map<T,Q,Compare,Alloc>& t) {
1487 MAD_ARCHIVE_DEBUG(std::cout << "deserialize std::map" << std::endl);
1488 if constexpr (!std::allocator_traits<Alloc>::is_always_equal::value) {
1489 Alloc allocator;
1490 ar & allocator;
1491 t = std::map<T,Q,Compare,Alloc>(allocator);
1492 }
1493 else
1494 t.clear();
1495 std::size_t n = 0;
1496 ar & n;
1497 while (n--) {
1498 std::pair<T,Q> p;
1499 ar & p;
1500 t.emplace(std::move(p.first), std::move(p.second));
1501 }
1502 }
1503 };
1504
1505
1506 /// Serialize a \c std::set.
1507
1508 /// \tparam Archive the archive type.
1509 /// \tparam T The data type stored in the \c set.
1510 /// \tparam Compare The comparison operator.
1511 /// \tparam Alloc The allocator.
1512 template <class Archive, typename T, typename Compare, typename Alloc>
1513 struct ArchiveStoreImpl< Archive, std::set<T, Compare, Alloc>, std::enable_if_t<!is_future<T>::value && is_serializable_v<Archive, T>> > {
1514
1515 /// Store a \c std::set.
1516
1517 /// \param[in] ar The archive.
1518 /// \param[in] s The \c set.
1519 static inline void store(const Archive& ar, const std::set<T, Compare, Alloc>& s) {
1520 MAD_ARCHIVE_DEBUG(std::cout << "serialize std::set" << std::endl);
1521 if constexpr (!std::allocator_traits<Alloc>::is_always_equal::value) {
1522 ar & s.get_allocator();
1523 }
1524 ar << s.size();
1525 for (const auto &i : s)
1526 ar << i;
1527 }
1528 };
1529
1530
1531 /// Deserialize a \c std::set. Clears and resizes as necessary.
1532
1533 /// \tparam Archive the archive type.
1534 /// \tparam T The data type stored in the \c set.
1535 /// \tparam Compare The comparison operator.
1536 /// \tparam Alloc The allocator.
1537 template <class Archive, typename T, typename Compare, typename Alloc>
1538 struct ArchiveLoadImpl< Archive, std::set<T, Compare, Alloc>, std::enable_if_t<!is_future<T>::value && is_serializable_v<Archive, T>> > {
1539
1540 /// Load a \c std::set.
1541 /// \param[in] ar The archive.
1542 /// \param[out] s The \c set.
1543 static void load(const Archive& ar, std::set<T, Compare, Alloc>& s) {
1544 MAD_ARCHIVE_DEBUG(std::cout << "deserialize std::set" << std::endl);
1545 if constexpr (!std::allocator_traits<Alloc>::is_always_equal::value) {
1546 Alloc allocator;
1547 ar & allocator;
1548 s = std::set<T, Compare, Alloc>(allocator);
1549 }
1550 std::size_t size=0;
1551 ar >> size;
1552 s.clear();
1553 auto hint = s.begin();
1554 for (std::size_t i = 0; i < size; ++i)
1555 {
1556 typename std::set<T, Compare, Alloc>::key_type key=0;
1557 ar >> key;
1558 hint = s.emplace_hint(hint, std::move(key));
1559 }
1560 }
1561
1562 };
1563
1564
1565 /// Serialize a \c std::list.
1566
1567 /// \tparam Archive the archive type.
1568 /// \tparam T The data type stored in the \c list.
1569 /// \tparam Alloc The allocator.
1570 template <class Archive, typename T, typename Alloc>
1571 struct ArchiveStoreImpl< Archive, std::list<T,Alloc>, std::enable_if_t<!is_future<T>::value && is_serializable_v<Archive, T>> > {
1572
1573 /// Store a \c std::list.
1574
1575 /// \param[in] ar The archive.
1576 /// \param[in] s The \c list.
1577 static inline void store(const Archive& ar, const std::list<T, Alloc>& s) {
1578 MAD_ARCHIVE_DEBUG(std::cout << "serialize std::list" << std::endl);
1579 if constexpr (!std::allocator_traits<Alloc>::is_always_equal::value) {
1580 ar & s.get_allocator();
1581 }
1582 ar << s.size();
1583 for (const auto &i : s)
1584 ar << i;
1585 }
1586 };
1587
1588
1589 /// Deserialize a \c std::list. Clears and resizes as necessary.
1590
1591 /// \tparam Archive the archive type.
1592 /// \tparam T The data type stored in the \c list.
1593 /// \tparam Alloc The allocator.
1594 template <class Archive, typename T, typename Alloc>
1595 struct ArchiveLoadImpl< Archive, std::list<T, Alloc>, std::enable_if_t<!is_future<T>::value && is_serializable_v<Archive, T>> > {
1596
1597 /// Load a \c std::list.
1598 /// \param[in] ar The archive.
1599 /// \param[out] s The \c list.
1600 static void load(const Archive& ar, std::list<T, Alloc>& s) {
1601 MAD_ARCHIVE_DEBUG(std::cout << "deserialize std::list" << std::endl);
1602 if constexpr (!std::allocator_traits<Alloc>::is_always_equal::value) {
1603 Alloc allocator;
1604 ar & allocator;
1605 s = std::list<T, Alloc>(allocator);
1606 }
1607 std::size_t size=0;
1608 ar >> size;
1609 s.clear();
1610 for (std::size_t i = 0; i < size; ++i)
1611 {
1612 T elem;
1613 ar >> elem;
1614 s.emplace_back(std::move(elem));
1615 }
1616 }
1617
1618 };
1619
1620 /// @}
1621
1622} // namespace madness::archive
1623} // namespace madness
1624
1625#endif // MADNESS_WORLD_ARCHIVE_H__INCLUDED
#define MAD_ARCHIVE_DEBUG(s)
Macro for helping debug archive tools.
Definition archive.h:76
Definition test_ar.cc:118
Base class for all archive classes.
Definition archive.h:358
std::false_type is_loading
Type used by Boost.Serialization to determine if this object is an input archive.
Definition archive.h:363
BaseArchive()
Definition archive.h:367
std::false_type is_saving
Type used by Boost.Serialization to determine if this object is an output archive.
Definition archive.h:364
static constexpr bool is_parallel_archive
Flag to determine if this object is a parallel archive.
Definition archive.h:365
Base class for input archive classes.
Definition archive.h:374
std::true_type is_loading
Type used by Boost.Serialization to determine if this object is an input archive.
Definition archive.h:377
Base class for output archive classes.
Definition archive.h:382
std::true_type is_saving
Type used by Boost.Serialization to determine if this object is an output archive.
Definition archive.h:385
Wrapper for dynamic arrays and pointers.
Definition archive.h:890
archive_array()
Constructor specifying no array and of 0 length.
Definition archive.h:902
unsigned int n
The number of objects in the array.
Definition archive.h:893
const T * ptr
The pointer.
Definition archive.h:892
archive_array(const T *ptr, unsigned int n)
Constructor specifying a memory location and size.
Definition archive.h:899
Wrapper for an opaque pointer for serialization purposes.
Definition archive.h:850
archive_ptr(T *t=nullptr)
Constructor specifying nullptr by default.
Definition archive.h:857
T * ptr
The pointer.
Definition archive.h:852
void serialize(const Archive &ar)
Serialize the pointer.
Definition archive.h:872
T & operator*()
Dereference the pointer.
Definition archive.h:863
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition derivatives.cc:72
const std::size_t bufsize
Definition derivatives.cc:16
auto T(World &world, response_space &f) -> response_space
Definition global_functions.cc:34
archive_array< unsigned char > wrap_opaque(const T *, unsigned int)
Factory function to wrap a pointer to contiguous data as an opaque (uchar) archive_array.
Definition archive.h:925
const char * archive_type_names[256]
The list of type names for use in archives.
Definition archive_type_names.cc:46
archive_ptr< T > wrap_ptr(T *p)
Wrapper for pointers.
Definition archive.h:882
std::ptrdiff_t fn_ptr_origin()
Definition archive.cc:52
std::ptrdiff_t to_rel_fn_ptr(const T &fn)
converts function or (free or static member) function pointer to the relative function pointer
Definition archive.h:237
const char * get_type_name()
Returns the name of the type, or unknown if not registered.
Definition archive.h:124
std::enable_if_t< is_output_archive< Archive >::value &&is_default_serializable< Archive, T >::value &&is_function_pointer_v< T >, void > default_serialize(const Archive &ar, const T *t, unsigned int n)
Serialize an array of fundamental stuff.
Definition archive.h:402
T to_abs_fn_ptr(std::ptrdiff_t rel_fn_ptr)
converts relative free or static member function pointer to the absolute function pointer
Definition archive.h:314
archive_array< T > wrap(const T *, unsigned int)
Factory function to wrap a dynamically allocated pointer as a typed archive_array.
Definition archive.h:913
std::enable_if_t< is_input_archive_v< Archive >, const Archive & > operator>>(const Archive &ar, const T &t)
Redirect >> to ArchiveImpl::wrap_load for input archives.
Definition archive.h:789
auto to_rel_memfn_ptr(const T &fn)
converts nonstatic member function pointer to the relative equivalent
Definition archive.h:259
std::enable_if_t< is_output_archive_v< Archive >, const Archive & > operator<<(const Archive &ar, const T &t)
Redirect << to ArchiveImpl::wrap_store for output archives.
Definition archive.h:768
std::enable_if_t< is_output_archive_v< Archive >, const Archive & > operator&(const Archive &ar, const T &t)
Redirect & to ArchiveImpl::wrap_store for output archives.
Definition archive.h:810
auto to_abs_memfn_ptr(std::array< std::ptrdiff_t, N > rel_fn_ptr)
converts relative (nonstatic) member function pointer to the absolute function pointer
Definition archive.h:325
std::enable_if_t< ! is_default_serializable< Archive, T >::value &&is_archive< Archive >::value, void > serialize(const Archive &ar, const T *t, unsigned int n)
Serialize (or deserialize) an array of non-fundamental stuff.
Definition archive.h:497
#define ARCHIVE_REGISTER_TYPE_AND_PTR(T, cooky)
Used to associate a type and a pointer to the type with a cookie value inside archive.
Definition archive.h:145
void archive_initialize_type_names()
Initializes the type names for the archives.
Definition archive_type_names.cc:53
static const double v
Definition hatom_sf_dirac.cc:20
Defines madness::MadnessException for exception handling.
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition madness_exception.h:119
#define MADNESS_ASSERT(condition)
Assert a condition that should be free of side-effects since in release builds this might be a no-op.
Definition madness_exception.h:134
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
constexpr bool is_default_serializable_v
Definition type_traits.h:465
Definition mraimpl.h:50
static const double b
Definition nonlinschro.cc:119
static const double c
Definition relops.cc:10
Definition hatom_sf_dirac.cc:91
static const Archive & wrap_load(const Archive &ar, const T(&t)[n])
Load the array, using the preamble and postamble to perform runtime type-checking.
Definition archive.h:1088
static const Archive & wrap_store(const Archive &ar, const T(&t)[n])
Store the array, wrapped by the preamble/postamble.
Definition archive.h:1077
static const Archive & wrap_load(const Archive &ar, const archive_array< T > &t)
Load the archive_array, using the preamble and postamble to perform runtime type-checking.
Definition archive.h:1044
static const Archive & wrap_store(const Archive &ar, const archive_array< T > &t)
Store the archive_array, wrapped by the preamble/postamble.
Definition archive.h:1023
Default implementations of wrap_store and wrap_load.
Definition archive.h:726
static const Archive & wrap_load(const Archive &ar, const T &t)
Load an object sandwiched between its preamble and postamble.
Definition archive.h:747
static const Archive & wrap_store(const Archive &ar, const T &t)
Store an object sandwiched between its preamble and postamble.
Definition archive.h:733
static void load(const Archive &ar, std::allocator< T > &v)
Loading a std::allocator is a no-op.
Definition archive.h:1160
static void load(const Archive &ar, std::array< T, N > &v)
Load a std::array.
Definition archive.h:1306
static void load(const Archive &ar, std::complex< T > &c)
Load a complex number.
Definition archive.h:1123
static void load(const Archive &ar, std::string &v)
Load a string.
Definition archive.h:1343
static void load(const Archive &ar, std::vector< T, Alloc > &v)
Load a std::vector.
Definition archive.h:1200
static void load(const Archive &ar, std::vector< bool, Alloc > &v)
Load a vector<bool>.
Definition archive.h:1254
Default load of an object via serialize(ar, t).
Definition archive.h:666
static void load(const A &ar, const U &t)
Load an object.
Definition archive.h:678
static void load(const Archive &ar, U &t)
Load function reference stored as function pointer.
Definition archive.h:703
Default implementation of the pre/postamble for type checking.
Definition archive.h:509
static void preamble_load(const Archive &ar)
Deserialize a cookie and check the type.
Definition archive.h:513
static void postamble_store(const Archive &)
By default there is no postamble.
Definition archive.h:545
static void postamble_load(const Archive &)
By default there is no postamble.
Definition archive.h:542
static void preamble_store(const Archive &ar)
Serialize a cookie for type checking.
Definition archive.h:535
static void serialize(const A &ar, resT(*(&fn))(paramT...))
Serialize the function pointer.
Definition archive.h:952
static std::enable_if_t<!is_output_archive< A >::value, void > serialize(const A &ar, resT(*(&fn))(paramT...))
Definition archive.h:957
static void serialize(const Archive &ar, resT(objT::*memfn)(paramT...) const)
Serialize the const member function pointer.
Definition archive.h:1006
static void serialize(const A &ar, resT(objT::*(&memfn))(paramT...))
Serialize the member function pointer.
Definition archive.h:979
static std::enable_if_t<!is_output_archive< A >::value, void > serialize(const A &ar, resT(objT::*(&memfn))(paramT...))
Definition archive.h:984
static void serialize(const Archive &ar, std::optional< T > &t)
Serialize the std::optional.
Definition archive.h:1383
static void serialize(const Archive &ar, std::tuple< Types... > &t)
Serialize the std::tuple.
Definition archive.h:1432
Default symmetric serialization of a non-fundamental type that has serialize method.
Definition archive.h:554
static void serialize(const Archive &ar, T &t)
Serializes the type.
Definition archive.h:560
static void store(const Archive &ar, const std::allocator< T > &v)
Storing a std::allocator is a no-op.
Definition archive.h:1143
static void store(const Archive &ar, const std::array< T, N > &v)
Store a std::array.
Definition archive.h:1286
static void store(const Archive &ar, const std::complex< T > &c)
Store a complex number.
Definition archive.h:1106
static void store(const Archive &ar, const std::list< T, Alloc > &s)
Store a std::list.
Definition archive.h:1577
static void store(const Archive &ar, const std::map< T, Q, Compare, Alloc > &t)
Store a map.
Definition archive.h:1452
static void store(const Archive &ar, const std::set< T, Compare, Alloc > &s)
Store a std::set.
Definition archive.h:1519
static void store(const Archive &ar, const std::string &v)
Store a string.
Definition archive.h:1325
static void store(const Archive &ar, const std::vector< T, Alloc > &v)
Store a std::vector of plain data.
Definition archive.h:1176
static void store(const Archive &ar, const std::vector< bool, Alloc > &v)
Store a vector<bool>.
Definition archive.h:1229
Default store of an object via serialize(ar, t).
Definition archive.h:611
static void store(const Archive &ar, const U &t)
Store function reference as a function pointer.
Definition archive.h:646
static std::enable_if_t< is_output_archive_v< A > &&!std::is_function< U >::value &&(has_member_serialize_v< U, A >||has_nonmember_serialize_v< U, A >||has_freestanding_serialize_v< U, A >||has_freestanding_default_serialize_v< U, A >), void > store(const A &ar, const U &t)
Definition archive.h:621
Used to enable type checking inside archives.
Definition archive.h:115
static const unsigned char cookie
Numeric ID for the type; 255 indicates unknown type.
Definition archive.h:116
Checks if T is an archive type.
Definition type_traits.h:505
is std::true_type if T can be serialized to Archive without specialized serialize() method
Definition type_traits.h:460
Checks if T is an input archive type.
Definition type_traits.h:522
Checks if T is an output archive type.
Definition type_traits.h:538
#define N
Definition testconv.cc:37