File indexing completed on 2025-01-18 09:38:12
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_HISTOGRAM_DETAIL_REDUCE_COMMAND_HPP
0008 #define BOOST_HISTOGRAM_DETAIL_REDUCE_COMMAND_HPP
0009
0010 #include <boost/core/span.hpp>
0011 #include <boost/histogram/fwd.hpp>
0012 #include <boost/throw_exception.hpp>
0013 #include <cassert>
0014 #include <stdexcept>
0015 #include <string>
0016
0017 namespace boost {
0018 namespace histogram {
0019 namespace detail {
0020
0021 struct reduce_command {
0022 static constexpr unsigned unset = static_cast<unsigned>(-1);
0023 unsigned iaxis = unset;
0024 enum class range_t : char {
0025 none,
0026 indices,
0027 values,
0028 } range = range_t::none;
0029 union {
0030 axis::index_type index;
0031 double value;
0032 } begin{0}, end{0};
0033 unsigned merge = 0;
0034 bool crop = false;
0035
0036 bool is_ordered = true;
0037 bool use_underflow_bin = true;
0038 bool use_overflow_bin = true;
0039 };
0040
0041
0042
0043
0044
0045 inline void normalize_reduce_commands(span<reduce_command> out,
0046 span<const reduce_command> in) {
0047 unsigned iaxis = 0;
0048 for (const auto& o_in : in) {
0049 assert(o_in.merge > 0);
0050 if (o_in.iaxis != reduce_command::unset && o_in.iaxis >= out.size())
0051 BOOST_THROW_EXCEPTION(std::invalid_argument("invalid axis index"));
0052 auto& o_out = out.begin()[o_in.iaxis == reduce_command::unset ? iaxis : o_in.iaxis];
0053 if (o_out.merge == 0) {
0054 o_out = o_in;
0055 } else {
0056
0057 if (!((o_in.range == reduce_command::range_t::none) ^
0058 (o_out.range == reduce_command::range_t::none)) ||
0059 (o_out.merge > 1 && o_in.merge > 1))
0060 BOOST_THROW_EXCEPTION(std::invalid_argument(
0061 "multiple conflicting reduce commands for axis " +
0062 std::to_string(o_in.iaxis == reduce_command::unset ? iaxis : o_in.iaxis)));
0063 if (o_in.range != reduce_command::range_t::none) {
0064 o_out.range = o_in.range;
0065 o_out.begin = o_in.begin;
0066 o_out.end = o_in.end;
0067 } else {
0068 o_out.merge = o_in.merge;
0069 }
0070 }
0071 ++iaxis;
0072 }
0073
0074 iaxis = 0;
0075 for (auto& o : out) o.iaxis = iaxis++;
0076 }
0077
0078 }
0079 }
0080 }
0081
0082 #endif