mirror of
https://github.com/boostorg/histogram.git
synced 2026-02-22 03:22:22 +00:00
make type of weight argument flexible, added sample type, some simplification to fill argument parsing
This commit is contained in:
@@ -18,7 +18,8 @@
|
||||
#include <boost/histogram/histogram_fwd.hpp>
|
||||
#include <boost/histogram/iterator.hpp>
|
||||
#include <boost/histogram/storage/operators.hpp>
|
||||
#include <boost/mpl/count.hpp>
|
||||
#include <boost/mpl/count_if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/empty.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
@@ -129,16 +130,19 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename... Args> void fill(Args &&... args) {
|
||||
using n_count = typename mpl::count<mpl::vector<Args...>, count>;
|
||||
using n_weight = typename mpl::count<mpl::vector<Args...>, weight>;
|
||||
template <typename... Args> void fill(const Args &... args) {
|
||||
using n_weight = typename mpl::count_if<mpl::vector<Args...>, detail::is_weight<mpl::_>>;
|
||||
using n_sample = typename mpl::count_if<mpl::vector<Args...>, detail::is_sample<mpl::_>>;
|
||||
static_assert(
|
||||
(n_count::value + n_weight::value) <= 1,
|
||||
"arguments may contain at most one instance of type count or weight");
|
||||
if (dim() != sizeof...(args) - n_count::value - n_weight::value)
|
||||
n_weight::value <= 1,
|
||||
"more than one weight argument is not allowed");
|
||||
static_assert(
|
||||
n_sample::value <= 1,
|
||||
"more than one sample argument is not allowed");
|
||||
if (dim() != sizeof...(args) - n_weight::value - n_sample::value)
|
||||
throw std::invalid_argument(
|
||||
"fill arguments does not match histogram dimension");
|
||||
fill_impl(mpl::int_<(n_count::value + 2 * n_weight::value)>(),
|
||||
fill_impl(mpl::bool_<n_weight::value>(), mpl::bool_<n_sample::value>(),
|
||||
args...);
|
||||
}
|
||||
|
||||
@@ -154,20 +158,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Iterator, typename = detail::is_iterator<Iterator>>
|
||||
void fill(Iterator begin, Iterator end, const count n) {
|
||||
if (dim() != std::distance(begin, end))
|
||||
throw std::invalid_argument(
|
||||
"fill iterator range does not match histogram dimension");
|
||||
std::size_t idx = 0, stride = 1;
|
||||
xlin_iter(idx, stride, begin);
|
||||
if (stride) {
|
||||
storage_.add(idx, n.value);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Iterator, typename = detail::is_iterator<Iterator>>
|
||||
void fill(Iterator begin, Iterator end, const weight w) {
|
||||
template <typename Iterator, typename T, typename = detail::is_iterator<Iterator>>
|
||||
void fill(Iterator begin, Iterator end, const detail::weight_t<T>& w) {
|
||||
if (dim() != std::distance(begin, end))
|
||||
throw std::invalid_argument(
|
||||
"fill iterator range does not match histogram dimension");
|
||||
@@ -311,32 +303,33 @@ private:
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void fill_impl(mpl::int_<0>, Args &&... args) {
|
||||
inline void fill_impl(mpl::false_, mpl::false_, const Args &... args) {
|
||||
std::size_t idx = 0, stride = 1;
|
||||
xlin<0>(idx, stride, args...);
|
||||
double w;
|
||||
xlin<0>(idx, stride, w, args...);
|
||||
if (stride) {
|
||||
storage_.increase(idx);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void fill_impl(mpl::int_<1>, Args &&... args) {
|
||||
inline void fill_impl(mpl::true_, mpl::false_, const Args &... args) {
|
||||
std::size_t idx = 0, stride = 1;
|
||||
unsigned n = 0;
|
||||
xlin_n<0>(idx, stride, n, args...);
|
||||
double w;
|
||||
xlin<0>(idx, stride, w, args...);
|
||||
if (stride) {
|
||||
storage_.add(idx, n);
|
||||
storage_.increase_by_weight(idx, w);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void fill_impl(mpl::int_<2>, Args &&... args) {
|
||||
std::size_t idx = 0, stride = 1;
|
||||
double w = 0.0;
|
||||
xlin_w<0>(idx, stride, w, args...);
|
||||
if (stride) {
|
||||
storage_.increase_by_weight(idx, w);
|
||||
}
|
||||
inline void fill_impl(mpl::false_, mpl::true_, const Args &... args) {
|
||||
// not implemented
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void fill_impl(mpl::true_, mpl::true_, const Args &... args) {
|
||||
// not implemented
|
||||
}
|
||||
|
||||
struct lin_visitor : public static_visitor<void> {
|
||||
@@ -382,57 +375,25 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned D> inline void xlin(std::size_t &, std::size_t &) const {}
|
||||
template <unsigned D> inline void xlin(std::size_t &, std::size_t &, double&) const {}
|
||||
|
||||
template <unsigned D, typename First, typename... Rest>
|
||||
inline void xlin(std::size_t &idx, std::size_t &stride, const First &first,
|
||||
inline void xlin(std::size_t &idx, std::size_t &stride, double& w, const First &first,
|
||||
const Rest &... rest) const {
|
||||
apply_visitor(xlin_visitor<First>{idx, stride, first}, axes_[D]);
|
||||
return xlin<D + 1>(idx, stride, rest...);
|
||||
return xlin<D + 1>(idx, stride, w, rest...);
|
||||
}
|
||||
|
||||
template <unsigned D>
|
||||
inline void xlin_w(std::size_t &, std::size_t &, double &) const {}
|
||||
|
||||
template <unsigned D, typename First, typename... Rest>
|
||||
inline typename enable_if<is_same<First, weight>>::type
|
||||
xlin_w(std::size_t &idx, std::size_t &stride, double &x, const First &first,
|
||||
template <unsigned D, typename T, typename... Rest>
|
||||
inline void xlin(std::size_t &idx, std::size_t &stride, double &w,
|
||||
const detail::weight_t<T> &first,
|
||||
const Rest &... rest) const {
|
||||
x = first.value;
|
||||
return xlin_w<D>(idx, stride, x, rest...);
|
||||
}
|
||||
|
||||
template <unsigned D, typename First, typename... Rest>
|
||||
inline typename disable_if<is_same<First, weight>>::type
|
||||
xlin_w(std::size_t &idx, std::size_t &stride, double &x, const First &first,
|
||||
const Rest &... rest) const {
|
||||
apply_visitor(xlin_visitor<First>{idx, stride, first},
|
||||
axes_[D]);
|
||||
return xlin_w<D + 1>(idx, stride, x, rest...);
|
||||
}
|
||||
|
||||
template <unsigned D>
|
||||
inline void xlin_n(std::size_t &, std::size_t &, unsigned &) const {}
|
||||
|
||||
template <unsigned D, typename First, typename... Rest>
|
||||
inline typename enable_if<is_same<First, count>>::type
|
||||
xlin_n(std::size_t &idx, std::size_t &stride, unsigned &x, const First &first,
|
||||
const Rest &... rest) const {
|
||||
x = first.value;
|
||||
return xlin_n<D>(idx, stride, x, rest...);
|
||||
}
|
||||
|
||||
template <unsigned D, typename First, typename... Rest>
|
||||
inline typename disable_if<is_same<First, count>>::type
|
||||
xlin_n(std::size_t &idx, std::size_t &stride, unsigned &x, const First &first,
|
||||
const Rest &... rest) const {
|
||||
apply_visitor(xlin_visitor<First>{idx, stride, first},
|
||||
axes_[D]);
|
||||
return xlin_n<D + 1>(idx, stride, x, rest...);
|
||||
w = first.value;
|
||||
return xlin<D>(idx, stride, w, rest...);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
void lin_iter(std::size_t &idx, std::size_t &stride, Iterator iter) const {
|
||||
inline void lin_iter(std::size_t &idx, std::size_t &stride, Iterator iter) const {
|
||||
for (const auto &a : axes_) {
|
||||
apply_visitor(lin_visitor(idx, stride, *iter), a);
|
||||
++iter;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define _BOOST_HISTOGRAM_HISTOGRAM_FWD_HPP_
|
||||
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
@@ -55,15 +56,27 @@ using dynamic_histogram = histogram<dynamic_tag, Axes, Storage>;
|
||||
template <class Axes, class Storage = adaptive_storage>
|
||||
using static_histogram = histogram<static_tag, Axes, Storage>;
|
||||
|
||||
struct weight {
|
||||
weight(double w) : value(w) {}
|
||||
double value;
|
||||
};
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct weight_t { T value;};
|
||||
template <typename T>
|
||||
struct is_weight : mpl::false_ {};
|
||||
template <typename T>
|
||||
struct is_weight<weight_t<T>> : mpl::true_ {};
|
||||
|
||||
struct count {
|
||||
count(unsigned n) : value(n) {}
|
||||
unsigned value;
|
||||
};
|
||||
template <typename T>
|
||||
struct sample_t { T value; };
|
||||
template <typename T>
|
||||
struct is_sample : mpl::false_ {};
|
||||
template <typename T>
|
||||
struct is_sample<sample_t<T>> : mpl::true_ {};
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
detail::weight_t<T> weight(T&& t) { return {t}; }
|
||||
|
||||
template <typename T>
|
||||
detail::sample_t<T> sample(T&& t) { return {t}; }
|
||||
|
||||
} // namespace histogram
|
||||
} // namespace boost
|
||||
|
||||
@@ -26,10 +26,11 @@
|
||||
#include <boost/histogram/histogram_fwd.hpp>
|
||||
#include <boost/histogram/iterator.hpp>
|
||||
#include <boost/histogram/storage/operators.hpp>
|
||||
#include <boost/mpl/count.hpp>
|
||||
#include <boost/mpl/count_if.hpp>
|
||||
#include <boost/mpl/empty.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
// forward declaration for serialization
|
||||
@@ -142,16 +143,18 @@ public:
|
||||
}
|
||||
|
||||
template <typename... Args> void fill(const Args &... args) {
|
||||
using n_count = typename mpl::count<mpl::vector<Args...>, count>;
|
||||
using n_weight = typename mpl::count<mpl::vector<Args...>, weight>;
|
||||
using n_weight = typename mpl::count_if<mpl::vector<Args...>, detail::is_weight<mpl::_>>;
|
||||
using n_sample = typename mpl::count_if<mpl::vector<Args...>, detail::is_sample<mpl::_>>;
|
||||
static_assert(
|
||||
(n_count::value + n_weight::value) <= 1,
|
||||
"arguments may contain at most one instance of type count or weight");
|
||||
n_weight::value <= 1,
|
||||
"more than one weight argument is not allowed");
|
||||
static_assert(
|
||||
n_sample::value <= 1,
|
||||
"more than one sample argument is not allowed");
|
||||
static_assert(sizeof...(args) ==
|
||||
(axes_size::value + n_count::value + n_weight::value),
|
||||
(axes_size::value + n_weight::value + n_sample::value),
|
||||
"number of arguments does not match histogram dimension");
|
||||
fill_impl(mpl::int_<(n_count::value + 2 * n_weight::value)>(),
|
||||
args...);
|
||||
fill_impl(mpl::bool_<n_weight::value>(), mpl::bool_<n_sample::value>(), args...);
|
||||
}
|
||||
|
||||
template <typename... Indices> value_type value(const Indices &... indices) const {
|
||||
@@ -263,31 +266,38 @@ private:
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void fill_impl(mpl::int_<0>, const Args &... args) {
|
||||
inline void fill_impl(mpl::false_, mpl::false_,
|
||||
const Args &... args) {
|
||||
std::size_t idx = 0, stride = 1;
|
||||
xlin<0>(idx, stride, args...);
|
||||
if (stride)
|
||||
double w;
|
||||
xlin<0>(idx, stride, w, args...);
|
||||
if (stride) {
|
||||
storage_.increase(idx);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void fill_impl(mpl::int_<1>, const Args &... args) {
|
||||
inline void fill_impl(mpl::true_, mpl::false_,
|
||||
const Args &... args) {
|
||||
std::size_t idx = 0, stride = 1;
|
||||
unsigned n = 0;
|
||||
xlin_n<0>(idx, stride, n, args...);
|
||||
if (stride)
|
||||
storage_.add(idx, n);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void fill_impl(mpl::int_<2>, const Args &... args) {
|
||||
std::size_t idx = 0, stride = 1;
|
||||
double w = 0.0;
|
||||
xlin_w<0>(idx, stride, w, args...);
|
||||
double w;
|
||||
xlin<0>(idx, stride, w, args...);
|
||||
if (stride)
|
||||
storage_.increase_by_weight(idx, w);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void fill_impl(mpl::false_, mpl::true_,
|
||||
const Args &... args) {
|
||||
// not implemented
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void fill_impl(mpl::true_, mpl::true_,
|
||||
const Args &... args) {
|
||||
// not implemented
|
||||
}
|
||||
|
||||
template <unsigned D> inline void lin(std::size_t &, std::size_t &) const noexcept {}
|
||||
|
||||
template <unsigned D, typename First, typename... Rest>
|
||||
@@ -297,51 +307,20 @@ private:
|
||||
return lin<D + 1>(idx, stride, rest...);
|
||||
}
|
||||
|
||||
template <unsigned D> inline void xlin(std::size_t &, std::size_t &) const {}
|
||||
template <unsigned D> inline void xlin(std::size_t &, std::size_t &, double&) const {}
|
||||
|
||||
template <unsigned D, typename First, typename... Rest>
|
||||
inline void xlin(std::size_t &idx, std::size_t &stride, const First &first,
|
||||
const Rest &... rest) const {
|
||||
inline void xlin(std::size_t &idx, std::size_t &stride, double& w,
|
||||
const First &first, const Rest &... rest) const {
|
||||
detail::xlin(idx, stride, fusion::at_c<D>(axes_), first);
|
||||
return xlin<D + 1>(idx, stride, rest...);
|
||||
return xlin<D + 1>(idx, stride, w, rest...);
|
||||
}
|
||||
|
||||
template <unsigned D>
|
||||
inline void xlin_w(std::size_t &, std::size_t &, double &) const {}
|
||||
|
||||
template <unsigned D, typename First, typename... Rest>
|
||||
inline typename disable_if<is_same<First, weight>>::type
|
||||
xlin_w(std::size_t &idx, std::size_t &stride, double &x, const First &first,
|
||||
Rest &&... rest) const {
|
||||
detail::xlin(idx, stride, fusion::at_c<D>(axes_), first);
|
||||
return xlin_w<D + 1>(idx, stride, x, rest...);
|
||||
}
|
||||
|
||||
template <unsigned D, typename First, typename... Rest>
|
||||
inline typename enable_if<is_same<First, weight>>::type
|
||||
xlin_w(std::size_t &idx, std::size_t &stride, double &x, const First &first,
|
||||
template <unsigned D, typename T, typename... Rest>
|
||||
inline void xlin(std::size_t &idx, std::size_t &stride, double &w, const detail::weight_t<T> &first,
|
||||
const Rest &... rest) const {
|
||||
x = first.value;
|
||||
return xlin_w<D>(idx, stride, x, rest...);
|
||||
}
|
||||
|
||||
template <unsigned D>
|
||||
inline void xlin_n(std::size_t &, std::size_t &, unsigned &) const {}
|
||||
|
||||
template <unsigned D, typename First, typename... Rest>
|
||||
inline typename disable_if<is_same<First, count>>::type
|
||||
xlin_n(std::size_t &idx, std::size_t &stride, unsigned &x, const First &first,
|
||||
const Rest &... rest) const {
|
||||
detail::xlin(idx, stride, fusion::at_c<D>(axes_), first);
|
||||
return xlin_n<D + 1>(idx, stride, x, rest...);
|
||||
}
|
||||
|
||||
template <unsigned D, typename First, typename... Rest>
|
||||
inline typename enable_if<is_same<First, count>>::type
|
||||
xlin_n(std::size_t &idx, std::size_t &stride, unsigned &x, const First &first,
|
||||
const Rest &... rest) const {
|
||||
x = first.value;
|
||||
return xlin_n<D>(idx, stride, x, rest...);
|
||||
w = first.value;
|
||||
return xlin<D>(idx, stride, w, rest...);
|
||||
}
|
||||
|
||||
struct shape_assign_visitor {
|
||||
|
||||
Reference in New Issue
Block a user