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