unified both histogram classes

This commit is contained in:
Hans Dembinski
2017-03-28 23:21:21 +02:00
parent 45f461e49c
commit 493d6c7974
20 changed files with 356 additions and 226 deletions

View File

@@ -8,8 +8,7 @@
#define BOOST_HISTOGRAM_HPP_
#include <boost/histogram/axis.hpp>
#include <boost/histogram/dynamic_histogram.hpp>
#include <boost/histogram/static_histogram.hpp>
#include <boost/histogram/histogram.hpp>
#include <boost/histogram/storage/adaptive_storage.hpp>
#include <boost/histogram/storage/container_storage.hpp>
#include <boost/histogram/utility.hpp>

View File

@@ -11,7 +11,6 @@
#include <boost/histogram/detail/utility.hpp>
#include <boost/math/constants/constants.hpp>
#include <ostream>
#include <string>
namespace boost {
namespace histogram {

View File

@@ -19,12 +19,11 @@ namespace boost {
namespace histogram {
namespace detail {
template <typename T> struct has_weight_support {
template <typename T> struct has_variance {
template <typename> static std::false_type test(...);
template <typename C>
static decltype(std::declval<C &>().increase(0, 0.0),
std::declval<C &>().variance(0), std::true_type{})
static decltype(std::declval<C &>().variance(0), std::true_type{})
test(int);
static bool const value = decltype(test<T>(0))::value;
@@ -43,11 +42,6 @@ template <typename T, typename = decltype(std::begin(std::declval<T &>()),
std::end(std::declval<T &>()))>
struct is_sequence {};
struct histogram_tag {};
template <typename T, typename = typename T::histogram_tag>
struct is_histogram {};
template <typename S1, typename S2> struct intersection {
using type = typename std::conditional<
mpl::equal<S1, S2>::value, S1,
@@ -55,25 +49,6 @@ template <typename S1, typename S2> struct intersection {
type;
};
// // prefer dynamic over static storage, choose
// // static_storage with larger capacity
// template <typename Storage1,
// typename Storage2>
// struct select_storage {
// using type = typename std::conditional<
// (is_dynamic_storage<Storage1>::value ||
// is_dynamic_storage<Storage2>::value),
// typename std::conditional<
// is_dynamic_storage<Storage1>::value,
// Storage1, Storage2
// >::type,
// typename std::conditional<
// (std::numeric_limits<typename Storage1::value_t>::max() >
// std::numeric_limits<typename Storage2::value_t>::max()),
// Storage1, Storage2
// >::type
// >::type;
// };
} // namespace detail
} // namespace histogram
} // namespace boost

View File

@@ -15,14 +15,14 @@ namespace detail {
namespace {
template <typename Storage>
typename std::enable_if<has_weight_support<Storage>::value,
typename std::enable_if<has_variance<Storage>::value,
typename Storage::value_type>::type
variance_impl(const Storage &s, std::size_t i) {
return s.variance(i);
} // delegate to Storage implementation
template <typename Storage>
typename std::enable_if<!(has_weight_support<Storage>::value),
typename std::enable_if<!(has_variance<Storage>::value),
typename Storage::value_type>::type
variance_impl(const Storage &s, std::size_t i) {
return s.value(i);

View File

@@ -0,0 +1,14 @@
// Copyright 2015-2017 Hans Dembinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef _BOOST_HISTOGRAM_HISTOGRAM_HPP_
#define _BOOST_HISTOGRAM_HISTOGRAM_HPP_
#include <boost/histogram/histogram_fwd.hpp>
#include <boost/histogram/histogram_static_impl.hpp>
#include <boost/histogram/histogram_dynamic_impl.hpp>
#endif

View File

@@ -4,18 +4,17 @@
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef _BOOST_HISTOGRAM_DYNAMIC_HISTOGRAM_HPP_
#define _BOOST_HISTOGRAM_DYNAMIC_HISTOGRAM_HPP_
#ifndef _BOOST_HISTOGRAM_HISTOGRAM_DYNAMIC_IMPL_HPP_
#define _BOOST_HISTOGRAM_HISTOGRAM_DYNAMIC_IMPL_HPP_
#include <algorithm>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/histogram/histogram_fwd.hpp>
#include <boost/histogram/axis.hpp>
#include <boost/histogram/detail/axis_visitor.hpp>
#include <boost/histogram/detail/meta.hpp>
#include <boost/histogram/detail/utility.hpp>
#include <boost/histogram/detail/variance.hpp>
#include <boost/histogram/storage/adaptive_storage.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/variant.hpp>
@@ -28,12 +27,11 @@
namespace boost {
namespace histogram {
template <typename Axes = default_axes, typename Storage = adaptive_storage<>>
class dynamic_histogram {
template <typename Axes, typename Storage>
class histogram<true, Axes, Storage> {
static_assert(!mpl::empty<Axes>::value, "at least one axis required");
using pairs = std::pair<std::size_t, std::size_t>;
using size_pair = std::pair<std::size_t, std::size_t>;
public:
using histogram_tag = detail::histogram_tag;
using axis_type = typename make_variant_over<Axes>::type;
using value_type = typename Storage::value_type;
@@ -41,34 +39,34 @@ private:
using axes_type = std::vector<axis_type>;
public:
dynamic_histogram() = default;
histogram() = default;
template <typename... Axes1>
explicit dynamic_histogram(const Axes1 &... axes)
explicit histogram(const Axes1 &... axes)
: axes_({axis_type(axes)...}) {
storage_ = Storage(field_count());
}
template <typename Iterator, typename = detail::is_iterator<Iterator>>
dynamic_histogram(Iterator axes_begin, Iterator axes_end)
histogram(Iterator axes_begin, Iterator axes_end)
: axes_(std::distance(axes_begin, axes_end)) {
std::copy(axes_begin, axes_end, axes_.begin());
storage_ = Storage(field_count());
}
template <typename OtherAxes, typename OtherStorage>
explicit dynamic_histogram(
const dynamic_histogram<OtherAxes, OtherStorage> &other)
explicit histogram(
const histogram<true, OtherAxes, OtherStorage> &other)
: axes_(other.axes_.begin(), other.axes_.end()),
storage_(other.storage_) {}
template <typename OtherAxes, typename OtherStorage>
explicit dynamic_histogram(dynamic_histogram<OtherAxes, OtherStorage> &&other)
explicit histogram(histogram<true, OtherAxes, OtherStorage> &&other)
: axes_(std::move(other.axes_)), storage_(std::move(other.storage_)) {}
template <typename OtherAxes, typename OtherStorage>
dynamic_histogram &
operator=(const dynamic_histogram<OtherAxes, OtherStorage> &other) {
histogram &
operator=(const histogram<true, OtherAxes, OtherStorage> &other) {
if (static_cast<const void *>(this) != static_cast<const void *>(&other)) {
axes_ = other.axes_;
storage_ = other.storage_;
@@ -77,8 +75,8 @@ public:
}
template <typename OtherAxes, typename OtherStorage>
dynamic_histogram &
operator=(dynamic_histogram<OtherAxes, OtherStorage> &&other) {
histogram &
operator=(histogram<true, OtherAxes, OtherStorage> &&other) {
if (static_cast<const void *>(this) != static_cast<const void *>(&other)) {
axes_ = std::move(other.axes_);
storage_ = std::move(other.storage_);
@@ -88,7 +86,7 @@ public:
template <typename OtherAxes, typename OtherStorage>
bool
operator==(const dynamic_histogram<OtherAxes, OtherStorage> &other) const {
operator==(const histogram<true, OtherAxes, OtherStorage> &other) const {
if (mpl::empty<
typename detail::intersection<Axes, OtherAxes>::type>::value) {
return false;
@@ -105,13 +103,12 @@ public:
return true;
}
template <template <class, class> class Histogram, typename OtherAxes,
typename OtherStorage>
dynamic_histogram &
operator+=(const Histogram<OtherAxes, OtherStorage> &other) {
template <bool D, typename A, typename S>
histogram &
operator+=(const histogram<D, A, S> &other) {
static_assert(
!mpl::empty<
typename detail::intersection<Axes, OtherAxes>::type>::value,
typename detail::intersection<Axes, A>::type>::value,
"histograms lack common axes types");
if (dim() != other.dim()) {
throw std::logic_error("dimensions of histograms differ");
@@ -129,7 +126,7 @@ public:
template <typename... Values> void fill(Values... values) {
BOOST_ASSERT_MSG(sizeof...(values) == dim(),
"number of arguments does not match histogram dimension");
const auto p = apply_lin<detail::xlin, Values...>(pairs(0, 1), values...);
const auto p = apply_lin<detail::xlin, Values...>(size_pair(0, 1), values...);
if (p.second) {
storage_.increase(p.first);
}
@@ -139,33 +136,27 @@ public:
void fill(Iterator begin, Iterator end) {
BOOST_ASSERT_MSG(std::distance(begin, end) == dim(),
"number of arguments does not match histogram dimension");
const auto p = apply_lin_iter<detail::xlin>(pairs(0, 1), begin);
const auto p = apply_lin_iter<detail::xlin>(size_pair(0, 1), begin);
if (p.second) {
storage_.increase(p.first);
}
}
template <
bool has_weight_support = detail::has_weight_support<Storage>::value,
typename... Values>
typename std::enable_if<has_weight_support>::type wfill(value_type w,
Values... values) {
template <typename... Values>
void wfill(value_type w, Values... values) {
BOOST_ASSERT_MSG(sizeof...(values) == dim(),
"number of arguments does not match histogram dimension");
const auto p = apply_lin<detail::xlin, Values...>(pairs(0, 1), values...);
const auto p = apply_lin<detail::xlin, Values...>(size_pair(0, 1), values...);
if (p.second) {
storage_.increase(p.first, w);
}
}
template <
bool has_weight_support = detail::has_weight_support<Storage>::value,
typename Iterator, typename = detail::is_iterator<Iterator>>
typename std::enable_if<has_weight_support>::type
wfill(value_type w, Iterator begin, Iterator end) {
template <typename Iterator, typename = detail::is_iterator<Iterator>>
void wfill(value_type w, Iterator begin, Iterator end) {
BOOST_ASSERT_MSG(std::distance(begin, end) == dim(),
"number of arguments does not match histogram dimension");
const auto p = apply_lin_iter<detail::xlin>(pairs(0, 1), begin);
const auto p = apply_lin_iter<detail::xlin>(size_pair(0, 1), begin);
if (p.second) {
storage_.increase(p.first, w);
}
@@ -174,7 +165,7 @@ public:
template <typename... Indices> value_type value(Indices... indices) const {
BOOST_ASSERT_MSG(sizeof...(indices) == dim(),
"number of arguments does not match histogram dimension");
const auto p = apply_lin<detail::lin, Indices...>(pairs(0, 1), indices...);
const auto p = apply_lin<detail::lin, Indices...>(size_pair(0, 1), indices...);
if (p.second == 0) {
throw std::out_of_range("invalid index");
}
@@ -185,7 +176,7 @@ public:
value_type value(Iterator begin, Iterator end) const {
BOOST_ASSERT_MSG(std::distance(begin, end) == dim(),
"number of arguments does not match histogram dimension");
const auto p = apply_lin_iter<detail::lin>(pairs(0, 1), begin);
const auto p = apply_lin_iter<detail::lin>(size_pair(0, 1), begin);
if (p.second == 0) {
throw std::out_of_range("invalid index");
}
@@ -193,24 +184,26 @@ public:
}
template <typename... Indices> value_type variance(Indices... indices) const {
static_assert(detail::has_variance<Storage>::value, "Storage lacks variance support");
BOOST_ASSERT_MSG(sizeof...(indices) == dim(),
"number of arguments does not match histogram dimension");
const auto p = apply_lin<detail::lin, Indices...>(pairs(0, 1), indices...);
const auto p = apply_lin<detail::lin, Indices...>(size_pair(0, 1), indices...);
if (p.second == 0) {
throw std::out_of_range("invalid index");
}
return detail::variance(storage_, p.first);
return storage_.variance(p.first);
}
template <typename Iterator, typename = detail::is_iterator<Iterator>>
value_type variance(Iterator begin, Iterator end) const {
static_assert(detail::has_variance<Storage>::value, "Storage lacks variance support");
BOOST_ASSERT_MSG(std::distance(begin, end) == dim(),
"number of arguments does not match histogram dimension");
const auto p = apply_lin_iter<detail::lin>(pairs(0, 1), begin);
const auto p = apply_lin_iter<detail::lin>(size_pair(0, 1), begin);
if (p.second == 0) {
throw std::out_of_range("invalid index");
}
return detail::variance(storage_, p.first);
return storage_.variance(p.first);
}
/// Number of axes (dimensions) of histogram
@@ -271,19 +264,19 @@ private:
}
template <template <class, class> class Lin, typename Value>
struct lin_visitor : public static_visitor<pairs> {
mutable pairs pa;
struct lin_visitor : public static_visitor<size_pair> {
mutable size_pair pa;
const Value &val;
lin_visitor(const pairs& p, const Value &v)
lin_visitor(const size_pair& p, const Value &v)
: pa(p), val(v) {}
template <typename A> pairs operator()(const A &a) const {
template <typename A> size_pair operator()(const A &a) const {
Lin<A, Value>::apply(pa.first, pa.second, a, val);
return pa;
}
};
template <template <class, class> class Lin, typename First, typename... Rest>
pairs apply_lin(pairs&& p, const First &first,
size_pair apply_lin(size_pair&& p, const First &first,
const Rest &... rest) const {
p = apply_visitor(lin_visitor<Lin, First>(p, first),
axes_[dim() - 1 - sizeof...(Rest)]);
@@ -291,10 +284,10 @@ private:
}
template <template <class, class> class Lin>
pairs apply_lin(pairs&& p) const { return p; }
size_pair apply_lin(size_pair&& p) const { return p; }
template <template <class, class> class Lin, typename Iterator>
pairs apply_lin_iter(pairs&& p, Iterator iter) const {
size_pair apply_lin_iter(size_pair&& p, Iterator iter) const {
for (const auto &a : axes_) {
p = apply_visitor(lin_visitor<Lin, decltype(*iter)>(p, *iter), a);
++iter;
@@ -304,23 +297,23 @@ private:
friend struct storage_access;
template <typename OtherAxes, typename OtherStorage>
friend class dynamic_histogram;
template <bool D, typename A, typename S>
friend class histogram;
template <typename Archiv, typename OtherAxes, typename OtherStorage>
friend void serialize(Archiv &, dynamic_histogram<OtherAxes, OtherStorage> &,
template <typename Archiv, typename A, typename S>
friend void serialize(Archiv &, histogram<true, A, S> &,
unsigned);
};
template <typename... Axes>
inline dynamic_histogram<> make_dynamic_histogram(Axes &&... axes) {
return dynamic_histogram<>(std::forward<Axes>(axes)...);
inline histogram<true, default_axes> make_dynamic_histogram(Axes &&... axes) {
return histogram<true, default_axes>(std::forward<Axes>(axes)...);
}
template <typename Storage, typename... Axes>
inline dynamic_histogram<default_axes, Storage>
inline histogram<true, default_axes, Storage>
make_dynamic_histogram_with(Axes &&... axes) {
return dynamic_histogram<default_axes, Storage>(std::forward<Axes>(axes)...);
return histogram<true, default_axes, Storage>(std::forward<Axes>(axes)...);
}
} // namespace histogram
} // namespace boost

View File

@@ -0,0 +1,22 @@
// Copyright 2015-2017 Hans Dembinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef _BOOST_HISTOGRAM_HISTOGRAM_FWD_HPP_
#define _BOOST_HISTOGRAM_HISTOGRAM_FWD_HPP_
#include <boost/histogram/storage/adaptive_storage.hpp>
namespace boost {
namespace histogram {
template <bool Dynamic,
class Axes,
class Storage = adaptive_storage<> > class histogram;
} // namespace histogram
} // namespace boost
#endif

View File

@@ -8,8 +8,7 @@
#define _BOOST_HISTOGRAM_HISTOGRAM_OSTREAM_OPERATORS_HPP_
#include <boost/histogram/axis_ostream_operators.hpp>
#include <boost/histogram/detail/meta.hpp>
#include <boost/histogram/utility.hpp>
#include <boost/histogram/histogram_fwd.hpp>
#include <ostream>
namespace boost {
@@ -25,11 +24,9 @@ struct axis_ostream_visitor {
};
} // namespace detail
template <template <typename, typename> class Histogram, typename Axes,
typename Storage,
typename = detail::is_histogram<Histogram<Axes, Storage>>>
template <bool D, typename A, typename S>
inline std::ostream &operator<<(std::ostream &os,
const Histogram<Axes, Storage> &h) {
const histogram<D, A, S> &h) {
os << "histogram(";
detail::axis_ostream_visitor sh(os);
h.for_each_axis(sh);

View File

@@ -1,11 +1,11 @@
// Copyright 2015-2016 Hans Dembinski
// Copyright 2015-2017 Hans Dembinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef _BOOST_HISTOGRAM_STATIC_HISTOGRAM_HPP_
#define _BOOST_HISTOGRAM_STATIC_HISTOGRAM_HPP_
#ifndef _BOOST_HISTOGRAM_HISTOGRAM_STATIC_IMPL_HPP_
#define _BOOST_HISTOGRAM_HISTOGRAM_STATIC_IMPL_HPP_
#include <boost/config.hpp>
#include <boost/fusion/adapted/mpl.hpp>
@@ -18,11 +18,11 @@
#include <boost/fusion/include/sequence.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/fusion/sequence/comparison.hpp>
#include <boost/histogram/histogram_fwd.hpp>
#include <boost/histogram/axis.hpp>
#include <boost/histogram/detail/axis_visitor.hpp>
#include <boost/histogram/detail/meta.hpp>
#include <boost/histogram/detail/utility.hpp>
#include <boost/histogram/detail/variance.hpp>
#include <boost/histogram/storage/adaptive_storage.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/vector.hpp>
@@ -31,42 +31,41 @@
namespace boost {
namespace histogram {
template <typename Axes, typename Storage = adaptive_storage<>>
class static_histogram {
template <typename Axes, typename Storage>
class histogram<false, Axes, Storage> {
static_assert(!mpl::empty<Axes>::value, "at least one axis required");
using pairs = std::pair<std::size_t, std::size_t>;
using size_pair = std::pair<std::size_t, std::size_t>;
using axes_size = typename fusion::result_of::size<Axes>::type;
public:
using histogram_tag = detail::histogram_tag;
using value_type = typename Storage::value_type;
private:
using axes_type = typename fusion::result_of::as_vector<Axes>::type;
public:
static_histogram() = default;
histogram() = default;
template <typename... Axes1>
explicit static_histogram(const Axes1 &... axes) : axes_(axes...) {
explicit histogram(const Axes1 &... axes) : axes_(axes...) {
storage_ = Storage(field_count());
}
static_histogram(const static_histogram &other) = default;
static_histogram(static_histogram &&other) = default;
static_histogram &operator=(const static_histogram &other) = default;
static_histogram &operator=(static_histogram &&other) = default;
histogram(const histogram &other) = default;
histogram(histogram &&other) = default;
histogram &operator=(const histogram &other) = default;
histogram &operator=(histogram &&other) = default;
template <typename OtherStorage>
explicit static_histogram(const static_histogram<Axes, OtherStorage> &other)
template <typename S>
explicit histogram(const histogram<false, Axes, S> &other)
: axes_(other.axes_), storage_(other.storage_) {}
template <typename OtherStorage>
explicit static_histogram(static_histogram<Axes, OtherStorage> &&other)
template <typename S>
explicit histogram(histogram<false, Axes, S> &&other)
: axes_(std::move(other.axes_)), storage_(std::move(other.storage_)) {}
template <typename OtherStorage>
static_histogram &
operator=(const static_histogram<Axes, OtherStorage> &other) {
template <typename S>
histogram &
operator=(const histogram<false, Axes, S> &other) {
if (static_cast<const void *>(this) != static_cast<const void *>(&other)) {
axes_ = other.axes_;
storage_ = other.storage_;
@@ -74,8 +73,8 @@ public:
return *this;
}
template <typename OtherStorage>
static_histogram &operator=(static_histogram<Axes, OtherStorage> &&other) {
template <typename S>
histogram &operator=(histogram<false, Axes, S> &&other) {
if (static_cast<const void *>(this) != static_cast<const void *>(&other)) {
axes_ = std::move(other.axes_);
storage_ = std::move(other.storage_);
@@ -83,18 +82,18 @@ public:
return *this;
}
template <typename OtherAxes, typename OtherStorage>
template <typename A, typename S>
bool
operator==(const static_histogram<OtherAxes, OtherStorage> &other) const {
operator==(const histogram<false, A, S> &other) const {
if (!axes_equal_to(other.axes_)) {
return false;
}
return storage_ == other.storage_;
}
template <typename OtherStorage>
static_histogram &
operator+=(const static_histogram<Axes, OtherStorage> &other) {
template <typename S>
histogram &
operator+=(const histogram<false, Axes, S> &other) {
if (!axes_equal_to(other.axes_)) {
throw std::logic_error("axes of histograms differ");
}
@@ -103,31 +102,27 @@ public:
}
template <typename... Values> void fill(Values... values) {
static_assert(sizeof...(values) == dim(),
static_assert(sizeof...(values) == axes_size::value,
"number of arguments does not match histogram dimension");
const auto p = apply_lin<detail::xlin, Values...>(pairs(0, 1), values...);
const auto p = apply_lin<detail::xlin, Values...>(size_pair(0, 1), values...);
if (p.second) {
storage_.increase(p.first);
}
}
template <
bool has_weight_support = detail::has_weight_support<Storage>::value,
typename... Values>
typename std::enable_if<has_weight_support>::type wfill(value_type w,
Values... values) {
static_assert(sizeof...(values) == dim(),
template <typename... Values> void wfill(value_type w, Values... values) {
static_assert(sizeof...(values) == axes_size::value,
"number of arguments does not match histogram dimension");
const auto p = apply_lin<detail::xlin, Values...>(pairs(0, 1), values...);
const auto p = apply_lin<detail::xlin, Values...>(size_pair(0, 1), values...);
if (p.second) {
storage_.increase(p.first, w);
}
}
template <typename... Indices> value_type value(Indices... indices) const {
static_assert(sizeof...(indices) == dim(),
static_assert(sizeof...(indices) == axes_size::value,
"number of arguments does not match histogram dimension");
const auto p = apply_lin<detail::lin, Indices...>(pairs(0, 1), indices...);
const auto p = apply_lin<detail::lin, Indices...>(size_pair(0, 1), indices...);
if (p.second == 0) {
throw std::out_of_range("invalid index");
}
@@ -135,19 +130,18 @@ public:
}
template <typename... Indices> value_type variance(Indices... indices) const {
static_assert(sizeof...(indices) == dim(),
static_assert(detail::has_variance<Storage>::value, "Storage lacks variance support");
static_assert(sizeof...(indices) == axes_size::value,
"number of arguments does not match histogram dimension");
const auto p = apply_lin<detail::lin, Indices...>(pairs(0, 1), indices...);
const auto p = apply_lin<detail::lin, Indices...>(size_pair(0, 1), indices...);
if (p.second == 0) {
throw std::out_of_range("invalid index");
}
return detail::variance(storage_, p.first);
return storage_.variance(p.first);
}
/// Number of axes (dimensions) of histogram
static constexpr unsigned dim() {
return fusion::result_of::size<Axes>::type::value;
}
constexpr unsigned dim() const { return axes_size::value; }
/// Total number of bins in the histogram (including underflow/overflow)
std::size_t size() const { return storage_.size(); }
@@ -165,8 +159,7 @@ public:
typename std::add_const<
typename fusion::result_of::value_at_c<axes_type, N>::type>::type &
axis() const {
static_assert(N < fusion::result_of::size<axes_type>::value,
"axis index out of range");
static_assert(N < axes_size::value, "axis index out of range");
return fusion::at_c<N>(axes_);
}
@@ -185,8 +178,8 @@ private:
return fc.value;
}
template <typename OtherAxes>
bool axes_equal_to(const OtherAxes & /*unused*/) const {
template <typename A>
bool axes_equal_to(const A & /*unused*/) const {
return false;
}
@@ -195,38 +188,38 @@ private:
}
template <template <class, class> class Lin, typename First, typename... Rest>
pairs apply_lin(pairs&& p, const First &x,
size_pair apply_lin(size_pair&& p, const First &x,
const Rest &... rest) const {
Lin<typename fusion::result_of::value_at_c<
axes_type, (dim() - 1 - sizeof...(Rest))>::type,
axes_type, (axes_size::value - 1 - sizeof...(Rest))>::type,
First>::apply(p.first, p.second,
fusion::at_c<(dim() - 1 - sizeof...(Rest))>(axes_), x);
fusion::at_c<(axes_size::value - 1 - sizeof...(Rest))>(axes_), x);
return apply_lin<Lin, Rest...>(std::move(p), rest...);
}
template <template <class, class> class Lin>
pairs apply_lin(pairs&& p) const { return p; }
size_pair apply_lin(size_pair&& p) const { return p; }
template <typename OtherAxes, typename OtherStorage>
friend class static_histogram;
template <bool D, typename A, typename S>
friend class histogram;
template <class Archive, class OtherStorage, class OtherAxes>
friend void serialize(Archive &, static_histogram<OtherStorage, OtherAxes> &,
template <class Archive, class S, class A>
friend void serialize(Archive &, histogram<false, S, A> &,
unsigned);
};
/// default static type factory
template <typename... Axes>
inline static_histogram<mpl::vector<Axes...>>
inline histogram<false, mpl::vector<Axes...>>
make_static_histogram(const Axes &... axes) {
return static_histogram<mpl::vector<Axes...>>(axes...);
return histogram<false, mpl::vector<Axes...>>(axes...);
}
/// static type factory with variable storage type
template <typename Storage, typename... Axes>
inline static_histogram<mpl::vector<Axes...>, Storage>
inline histogram<false, mpl::vector<Axes...>, Storage>
make_static_histogram_with(const Axes &... axes) {
return static_histogram<mpl::vector<Axes...>, Storage>(axes...);
return histogram<false, mpl::vector<Axes...>, Storage>(axes...);
}
} // namespace histogram
} // namespace boost

View File

@@ -11,8 +11,7 @@
#include <boost/fusion/include/for_each.hpp>
#include <boost/histogram/detail/utility.hpp>
#include <boost/histogram/detail/weight.hpp>
#include <boost/histogram/dynamic_histogram.hpp>
#include <boost/histogram/static_histogram.hpp>
#include <boost/histogram/histogram.hpp>
#include <boost/histogram/storage/adaptive_storage.hpp>
#include <boost/histogram/storage/container_storage.hpp>
#include <boost/serialization/array.hpp>
@@ -177,16 +176,16 @@ template <typename Archive> struct serialize_helper {
};
} // namespace
template <class Archive, class Storage, class Axes>
inline void serialize(Archive &ar, static_histogram<Storage, Axes> &h,
template <class Archive, class S, class A>
inline void serialize(Archive &ar, histogram<false, S, A> &h,
unsigned /* version */) {
serialize_helper<Archive> sh(ar);
fusion::for_each(h.axes_, sh);
ar &h.storage_;
}
template <class Archive, class Storage, class Axes>
inline void serialize(Archive &ar, dynamic_histogram<Storage, Axes> &h,
template <class Archive, class S, class A>
inline void serialize(Archive &ar, histogram<true, S, A> &h,
unsigned /* version */) {
ar &h.axes_;
ar &h.storage_;

View File

@@ -160,7 +160,7 @@ public:
}
}
template <typename OtherStorage, typename = detail::is_storage<OtherStorage>>
template <typename OtherStorage>
adaptive_storage &operator=(const OtherStorage &rhs) {
if (static_cast<const void *>(this) != static_cast<const void *>(&rhs)) {
if (size() != rhs.size()) {
@@ -193,7 +193,7 @@ public:
return apply_visitor(variance_visitor(i), buffer_);
}
template <typename OtherStorage, typename = detail::is_storage<OtherStorage>>
template <typename OtherStorage>
adaptive_storage &operator+=(const OtherStorage &rhs) {
for (std::size_t i = 0, n = rhs.size(); i < n; ++i)
apply_visitor(add_visitor<typename OtherStorage::value_type>(
@@ -206,7 +206,7 @@ public:
return apply_visitor(bicmp_visitor(), buffer_, o.buffer_);
}
template <typename OtherStorage, typename = detail::is_storage<OtherStorage>>
template <typename OtherStorage>
bool operator==(const OtherStorage &o) const {
return apply_visitor(cmp_visitor<OtherStorage>(o), buffer_);
}

View File

@@ -50,7 +50,7 @@ public:
}
}
template <typename OtherStorage, typename = detail::is_storage<OtherStorage>>
template <typename OtherStorage>
container_storage &operator=(const OtherStorage &other) {
detail::init(container_, other.size());
for (std::size_t i = 0; i < container_.size(); ++i) {
@@ -61,9 +61,10 @@ public:
std::size_t size() const { return container_.size(); }
void increase(std::size_t i) { ++(container_[i]); }
void increase(std::size_t i, value_type w) { container_[i] += w; }
value_type value(std::size_t i) const { return container_[i]; }
template <typename OtherStorage, typename = detail::is_storage<OtherStorage>>
template <typename OtherStorage>
void operator+=(const OtherStorage &other) {
for (std::size_t i = 0; i < container_.size(); ++i) {
container_[i] += other.value(i);