#ifndef BOOST_HISTOGRAM_AXIS_TRAITS_HPP
#define BOOST_HISTOGRAM_AXIS_TRAITS_HPP
-#include <boost/core/ignore_unused.hpp>
#include <boost/histogram/axis/option.hpp>
#include <boost/histogram/detail/args_type.hpp>
#include <boost/histogram/detail/detect.hpp>
#include <boost/histogram/detail/static_if.hpp>
#include <boost/histogram/detail/try_cast.hpp>
#include <boost/histogram/detail/type_name.hpp>
-#include <boost/variant2/variant.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 <string>
#include <utility>
double{};
}
-static axis::null_type null_value;
-
struct variant_access {
template <class T, class Variant>
static auto get_if(Variant* v) noexcept {
}
};
+template <class A>
+decltype(auto) metadata_impl(A&& a, decltype(a.metadata(), 0)) {
+ return std::forward<A>(a).metadata();
+}
+
+template <class A>
+axis::null_type& metadata_impl(A&&, float) {
+ static axis::null_type null_value;
+ return null_value;
+}
+
} // namespace detail
namespace axis {
*/
template <class Axis>
constexpr unsigned options(const Axis& axis) noexcept {
- boost::ignore_unused(axis);
+ (void)axis;
return get_options<Axis>::value;
}
*/
template <class Axis>
constexpr bool inclusive(const Axis& axis) noexcept {
- boost::ignore_unused(axis);
+ (void)axis;
return is_inclusive<Axis>::value;
}
*/
template <class Axis>
constexpr bool ordered(const Axis& axis) noexcept {
- boost::ignore_unused(axis);
+ (void)axis;
return is_ordered<Axis>::value;
}
return axis.ordered();
}
+/** Returns true if axis is continuous or false.
+
+ See is_continuous for details.
+
+ @param axis any axis instance
+*/
+template <class Axis>
+constexpr bool continuous(const Axis& axis) noexcept {
+ (void)axis;
+ return is_continuous<Axis>::value;
+}
+
+// specialization for variant
+template <class... Ts>
+bool continuous(const variant<Ts...>& axis) noexcept {
+ return axis.continuous();
+}
+
/** Returns axis size plus any extra bins for under- and overflow.
@param axis any axis instance
*/
template <class Axis>
decltype(auto) metadata(Axis&& axis) noexcept {
- return detail::static_if<detail::has_method_metadata<std::decay_t<Axis>>>(
- [](auto&& a) -> decltype(auto) { return a.metadata(); },
- [](auto &&) -> mp11::mp_if<std::is_const<std::remove_reference_t<Axis>>,
- axis::null_type const&, axis::null_type&> {
- return detail::null_value;
- },
- std::forward<Axis>(axis));
+ return detail::metadata_impl(std::forward<Axis>(axis), 0);
}
/** Returns axis value for index.
template <class Result, class Axis>
Result value_as(const Axis& axis, real_index_type index) {
return detail::try_cast<Result, std::runtime_error>(
- value(axis, index)); // avoid conversion warning
+ axis::traits::value(axis, index)); // avoid conversion warning
}
/** Returns axis index for value.
@param axis any axis instance
*/
+// gcc workaround: must use unsigned int not unsigned as return type
template <class Axis>
-constexpr unsigned rank(const Axis& axis) {
- boost::ignore_unused(axis);
+constexpr unsigned int rank(const Axis& axis) {
+ (void)axis;
using T = value_type<Axis>;
// cannot use mp_eval_or since T could be a fixed-sized sequence
return mp11::mp_eval_if_not<detail::is_tuple<T>, mp11::mp_size_t<1>, mp11::mp_size,
}
// specialization for variant
+// gcc workaround: must use unsigned int not unsigned as return type
template <class... Ts>
-unsigned rank(const axis::variant<Ts...>& axis) {
- return detail::variant_access::visit([](const auto& a) { return rank(a); }, axis);
+unsigned int rank(const axis::variant<Ts...>& axis) {
+ return detail::variant_access::visit(
+ [](const auto& a) { return axis::traits::rank(a); }, axis);
}
/** Returns pair of axis index and shift for the value argument.
return a.update(detail::try_cast<value_type<Axis>, std::invalid_argument>(value));
},
[&value](auto& a) -> std::pair<index_type, index_type> {
- return {index(a, value), 0};
+ return {axis::traits::index(a, value), 0};
},
axis);
}