PupStlCpp17.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <optional>
7 #include <pup_stl.h>
8 #include <utility>
9 #include <variant>
10 
11 #include "Utilities/Gsl.hpp"
12 #include "Utilities/TMPL.hpp"
13 
14 namespace PUP {
15 /// \ingroup ParallelGroup
16 /// Serialization of std::optional for Charm++
17 template <typename T>
18 void pup(er& p, std::optional<T>& t) noexcept { // NOLINT
19  bool valid = false;
20  if (p.isUnpacking()) {
21  p | valid;
22  if (valid) {
23  T value{};
24  p | value;
25  t = std::move(value);
26  } else {
27  t.reset();
28  }
29  } else {
30  valid = t.has_value();
31  p | valid;
32  if (valid) {
33  p | *t;
34  }
35  }
36 }
37 
38 /// \ingroup ParallelGroup
39 /// Serialization of std::optional for Charm++
40 template <typename T>
41 void operator|(er& p, std::optional<T>& t) noexcept { // NOLINT
42  pup(p, t);
43 }
44 
45 /// \ingroup ParallelGroup
46 /// Serialization of std::variant for Charm++
47 template <typename... Ts>
48 void pup(er& p, std::variant<Ts...>& t) noexcept { // NOLINT
49  // clang tidy: complains about pointer decay, I don't understand the error
50  // since nothing here is doing anything with pointers.
51  assert(not t.valueless_by_exception()); // NOLINT
52 
53  size_t current_index = 0;
54  size_t send_index = t.index();
55  p | send_index;
56 
57  const auto pup_helper = [&current_index, &p, send_index,
58  &t](auto type_v) noexcept {
59  using type = tmpl::type_from<decltype(type_v)>;
60  if (UNLIKELY(current_index == send_index)) {
61  if (p.isUnpacking()) {
62  type temp{};
63  p | temp;
64  t = std::move(temp);
65  } else {
66  p | std::get<type>(t);
67  }
68  }
69  ++current_index;
70  };
71  EXPAND_PACK_LEFT_TO_RIGHT(pup_helper(tmpl::type_<Ts>{}));
72 }
73 
74 /// \ingroup ParallelGroup
75 /// Serialization of std::variant for Charm++
76 template <typename... Ts>
77 void operator|(er& p, std::variant<Ts...>& t) noexcept { // NOLINT
78  pup(p, t);
79 }
80 } // namespace PUP
EXPAND_PACK_LEFT_TO_RIGHT
#define EXPAND_PACK_LEFT_TO_RIGHT(...)
Expand a parameter pack evaluating the terms from left to right.
Definition: TMPL.hpp:563
utility
UNLIKELY
#define UNLIKELY(x)
Definition: Gsl.hpp:73
Gsl.hpp
optional
TMPL.hpp
variant