File indexing completed on 2025-01-18 09:38:12
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_HISTOGRAM_DETAIL_VARIANT_PROXY_HPP
0008 #define BOOST_HISTOGRAM_DETAIL_VARIANT_PROXY_HPP
0009
0010 #include <boost/core/nvp.hpp>
0011 #include <boost/histogram/axis/traits.hpp> // variant_access
0012 #include <boost/histogram/detail/static_if.hpp>
0013 #include <boost/mp11/algorithm.hpp> // mp_with_index, mp_find, mp_at
0014 #include <boost/mp11/list.hpp> // mp_size
0015 #include <boost/throw_exception.hpp>
0016 #include <stdexcept>
0017
0018 namespace boost {
0019 namespace histogram {
0020 namespace detail {
0021
0022
0023
0024
0025 template <class Variant>
0026 struct variant_proxy {
0027 Variant& variant;
0028
0029 template <class Archive>
0030 void serialize(Archive& ar, unsigned ) {
0031 detail::static_if_c<Archive::is_loading::value>(
0032 [this](auto& ar) {
0033 int which = 0;
0034 ar >> make_nvp("which", which);
0035 constexpr unsigned N = mp11::mp_size<Variant>::value;
0036 if (which < 0 || static_cast<unsigned>(which) >= N)
0037
0038 BOOST_THROW_EXCEPTION(
0039 std::runtime_error("variant has fewer types than stored version"));
0040 mp11::mp_with_index<N>(static_cast<unsigned>(which), [&ar, this](auto i) {
0041 using T = mp11::mp_at_c<Variant, i>;
0042 T value;
0043 ar >> make_nvp("value", value);
0044 this->variant = std::move(value);
0045 T* new_address = variant_access::template get_if<T>(&this->variant);
0046 ar.reset_object_address(new_address, &value);
0047 });
0048 },
0049 [this](auto& ar) {
0050 visit(
0051 [&ar](const auto& value) {
0052 using T = std::decay_t<decltype(value)>;
0053 const int which = static_cast<int>(mp11::mp_find<Variant, T>::value);
0054 ar << make_nvp("which", which);
0055 ar << make_nvp("value", value);
0056 },
0057 this->variant);
0058 },
0059 ar);
0060 }
0061 };
0062
0063 }
0064 }
0065 }
0066
0067 #endif