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 
79 namespace 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>
124  const char* get_type_name() {
126  }
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.
358  class BaseArchive {
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 
369  }
370  }; // class BaseArchive
371 
372 
373  /// Base class for input archive classes.
374  class BaseInputArchive : public BaseArchive {
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);
602  ArchiveSerializeImpl<Archive, T>::serialize(ar, const_cast<T&>(t));
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>
850  class archive_ptr {
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
Base class for output archive classes.
Definition: archive.h:382
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
const std::size_t bufsize
Definition: derivatives.cc:16
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition: derivatives.cc:72
std::vector< Fcwf > transform(World &world, std::vector< Fcwf > &a, Tensor< std::complex< double >> U)
Definition: fcwf.cc:477
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
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_v< Archive >, const Archive & > operator&(const Archive &ar, const T &t)
Redirect & to ArchiveImpl::wrap_store for output archives.
Definition: archive.h:810
std::ptrdiff_t fn_ptr_origin()
Definition: archive.cc:52
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
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
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
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_ptr< T > wrap_ptr(T *p)
Wrapper for pointers.
Definition: archive.h:882
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
auto to_rel_memfn_ptr(const T &fn)
converts nonstatic member function pointer to the relative equivalent
Definition: archive.h:259
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
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
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
ARCHIVE_REGISTER_TYPE_AND_PTR(A, 128)
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
constexpr bool has_freestanding_serialize_with_size_v
Definition: type_traits.h:416
constexpr bool has_freestanding_serialize_v
Definition: type_traits.h:408
constexpr bool is_default_serializable_v
Definition: type_traits.h:458
constexpr bool has_freestanding_default_serialize_v
Definition: type_traits.h:432
constexpr bool has_freestanding_default_serialize_with_size_v
Definition: type_traits.h:440
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_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 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 archive_array< T > &t)
Store the archive_array, wrapped by the preamble/postamble.
Definition: archive.h:1023
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
Default implementations of wrap_store and wrap_load.
Definition: archive.h:726
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 const Archive & wrap_load(const Archive &ar, const T &t)
Load an object sandwiched between its preamble and postamble.
Definition: archive.h:747
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:498
is std::true_type if T can be serialized to Archive without specialized serialize() method
Definition: type_traits.h:453
Checks if T is an input archive type.
Definition: type_traits.h:515
Checks if T is an output archive type.
Definition: type_traits.h:531
F allocator()
Definition: testcomplexfunctionsolver.cc:52
#define N
Definition: testconv.cc:37