mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-09 23:04:07 +00:00
fix axis::traits::update
This commit is contained in:
parent
3b0bd331ba
commit
ac79060944
@ -15,7 +15,11 @@
|
||||
#include <boost/histogram/detail/try_cast.hpp>
|
||||
#include <boost/histogram/detail/type_name.hpp>
|
||||
#include <boost/histogram/fwd.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
@ -50,6 +54,44 @@ decltype(auto) value_method_switch(I&& i, D&& d, const A& a) {
|
||||
|
||||
static axis::null_type null_value;
|
||||
|
||||
struct variant_access {
|
||||
template <class T, class T0, class Variant>
|
||||
static auto get_if_impl(mp11::mp_list<T, T0>, Variant* v) noexcept {
|
||||
return variant2::get_if<T>(&(v->impl));
|
||||
}
|
||||
|
||||
template <class T, class T0, class Variant>
|
||||
static auto get_if_impl(mp11::mp_list<T, T0*>, Variant* v) noexcept {
|
||||
auto tp = variant2::get_if<mp11::mp_if<std::is_const<T0>, const T*, T*>>(&(v->impl));
|
||||
return tp ? *tp : nullptr;
|
||||
}
|
||||
|
||||
template <class T, class Variant>
|
||||
static auto get_if(Variant* v) noexcept {
|
||||
using T0 = mp11::mp_first<std::decay_t<Variant>>;
|
||||
return get_if_impl(mp11::mp_list<T, T0>{}, v);
|
||||
}
|
||||
|
||||
template <class T0, class Visitor, class Variant>
|
||||
static decltype(auto) visit_impl(mp11::mp_identity<T0>, Visitor&& vis, Variant&& v) {
|
||||
return variant2::visit(std::forward<Visitor>(vis), v.impl);
|
||||
}
|
||||
|
||||
template <class T0, class Visitor, class Variant>
|
||||
static decltype(auto) visit_impl(mp11::mp_identity<T0*>, Visitor&& vis, Variant&& v) {
|
||||
return variant2::visit(
|
||||
[&vis](auto&& x) -> decltype(auto) { return std::forward<Visitor>(vis)(*x); },
|
||||
v.impl);
|
||||
}
|
||||
|
||||
template <class Visitor, class Variant>
|
||||
static decltype(auto) visit(Visitor&& vis, Variant&& v) {
|
||||
using T0 = mp11::mp_first<std::decay_t<Variant>>;
|
||||
return visit_impl(mp11::mp_identity<T0>{}, std::forward<Visitor>(vis),
|
||||
std::forward<Variant>(v));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
namespace axis {
|
||||
@ -199,7 +241,7 @@ std::pair<index_type, index_type> update(Axis& axis, const U& value) noexcept(
|
||||
// specialization for variant
|
||||
template <class... Ts, class U>
|
||||
std::pair<index_type, index_type> update(variant<Ts...>& axis, const U& value) {
|
||||
return axis.update(value);
|
||||
return visit([&value](auto& a) { return a.update(value); }, axis);
|
||||
}
|
||||
|
||||
/** Returns bin width at axis index.
|
||||
|
@ -27,49 +27,6 @@
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
namespace detail {
|
||||
|
||||
struct variant_access {
|
||||
template <class T, class T0, class Variant>
|
||||
static auto get_if_impl(mp11::mp_list<T, T0>, Variant* v) noexcept {
|
||||
return boost::variant2::get_if<T>(&(v->impl));
|
||||
}
|
||||
|
||||
template <class T, class T0, class Variant>
|
||||
static auto get_if_impl(mp11::mp_list<T, T0*>, Variant* v) noexcept {
|
||||
auto tp =
|
||||
boost::variant2::get_if<mp11::mp_if<std::is_const<T0>, const T*, T*>>(&(v->impl));
|
||||
return tp ? *tp : nullptr;
|
||||
}
|
||||
|
||||
template <class T, class Variant>
|
||||
static auto get_if(Variant* v) noexcept {
|
||||
using T0 = mp11::mp_first<std::decay_t<Variant>>;
|
||||
return get_if_impl(mp11::mp_list<T, T0>{}, v);
|
||||
}
|
||||
|
||||
template <class T0, class Visitor, class Variant>
|
||||
static decltype(auto) visit_impl(mp11::mp_identity<T0>, Visitor&& vis, Variant&& v) {
|
||||
return boost::variant2::visit(std::forward<Visitor>(vis), v.impl);
|
||||
}
|
||||
|
||||
template <class T0, class Visitor, class Variant>
|
||||
static decltype(auto) visit_impl(mp11::mp_identity<T0*>, Visitor&& vis, Variant&& v) {
|
||||
return boost::variant2::visit(
|
||||
[&vis](auto&& x) -> decltype(auto) { return std::forward<Visitor>(vis)(*x); },
|
||||
v.impl);
|
||||
}
|
||||
|
||||
template <class Visitor, class Variant>
|
||||
static decltype(auto) visit(Visitor&& vis, Variant&& v) {
|
||||
using T0 = mp11::mp_first<std::decay_t<Variant>>;
|
||||
return visit_impl(mp11::mp_identity<T0>{}, std::forward<Visitor>(vis),
|
||||
std::forward<Variant>(v));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
namespace axis {
|
||||
|
||||
/// Polymorphic axis type
|
||||
|
@ -90,6 +90,9 @@ int main() {
|
||||
auto a = integer<int, null_type, option::growth_t>();
|
||||
BOOST_TEST_EQ(traits::update(a, 0), (std::pair<index_type, index_type>(0, -1)));
|
||||
BOOST_TEST_THROWS(traits::update(a, "foo"), std::invalid_argument);
|
||||
|
||||
variant<integer<int, null_type, option::growth_t>, integer<>> v(a);
|
||||
BOOST_TEST_EQ(traits::update(v, 0), (std::pair<index_type, index_type>(0, 0)));
|
||||
}
|
||||
|
||||
// metadata
|
||||
|
Loading…
x
Reference in New Issue
Block a user