Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <cassert> 7 : #include <optional> 8 : #include <pup_stl.h> 9 : #include <utility> 10 : #include <variant> 11 : 12 : #include "Utilities/Gsl.hpp" 13 : #include "Utilities/TMPL.hpp" 14 : 15 : namespace PUP { 16 : /// \ingroup ParallelGroup 17 : /// Serialization of std::optional for Charm++ 18 : template <typename T> 19 : void pup(er& p, std::optional<T>& t) { // NOLINT 20 : bool valid = false; 21 : if (p.isUnpacking()) { 22 : p | valid; 23 : if (valid) { 24 : // default construct in a manner that doesn't require a copy. 25 : // This is necessary when holding objects like pair<const Key, unique_ptr> 26 : // in unordered map-type structures. The reason this case is tricky is 27 : // because the const Key is non-movable while the unique_ptr is 28 : // non-copyable. Our only option is in-place construction. 29 : t.emplace(); 30 : p | *t; 31 : } else { 32 : t.reset(); 33 : } 34 : } else { 35 : valid = t.has_value(); 36 : p | valid; 37 : if (valid) { 38 : p | *t; 39 : } 40 : } 41 : } 42 : 43 : /// \ingroup ParallelGroup 44 : /// Serialization of std::optional for Charm++ 45 : template <typename T> 46 : void operator|(er& p, std::optional<T>& t) { // NOLINT 47 : pup(p, t); 48 : } 49 : 50 : /// \ingroup ParallelGroup 51 : /// Serialization of std::variant for Charm++ 52 : template <typename... Ts> 53 : void pup(er& p, std::variant<Ts...>& t) { // NOLINT 54 : // clang tidy: complains about pointer decay, I don't understand the error 55 : // since nothing here is doing anything with pointers. 56 : assert(not t.valueless_by_exception()); // NOLINT 57 : 58 : size_t current_index = 0; 59 : size_t send_index = t.index(); 60 : p | send_index; 61 : 62 : const auto pup_helper = [¤t_index, &p, send_index, &t](auto type_v) { 63 : using type = tmpl::type_from<decltype(type_v)>; 64 : if (UNLIKELY(current_index == send_index)) { 65 : if (p.isUnpacking()) { 66 : type temp{}; 67 : p | temp; 68 : t = std::move(temp); 69 : } else { 70 : p | std::get<type>(t); 71 : } 72 : } 73 : ++current_index; 74 : }; 75 : EXPAND_PACK_LEFT_TO_RIGHT(pup_helper(tmpl::type_<Ts>{})); 76 : } 77 : 78 : /// \ingroup ParallelGroup 79 : /// Serialization of std::variant for Charm++ 80 : template <typename... Ts> 81 : void operator|(er& p, std::variant<Ts...>& t) { // NOLINT 82 : pup(p, t); 83 : } 84 : } // namespace PUP