fix axis::traits::update

This commit is contained in:
Hans Dembinski 2019-07-12 09:58:48 +02:00 committed by GitHub
parent 3b0bd331ba
commit ac79060944
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 44 deletions

View File

@ -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.

View File

@ -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

View File

@ -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