From 7bc9bd8016f13717336a692465bab51130f462cc Mon Sep 17 00:00:00 2001 From: Hans Dembinski Date: Wed, 29 Mar 2017 21:15:43 +0200 Subject: [PATCH] polishing --- include/boost/histogram/axis.hpp | 14 +- include/boost/histogram/detail/weight.hpp | 30 +- include/boost/histogram/histogram.hpp | 5 +- .../histogram/histogram_dynamic_impl.hpp | 319 ------------------ include/boost/histogram/histogram_fwd.hpp | 7 +- .../histogram/histogram_ostream_operators.hpp | 2 +- .../boost/histogram/histogram_static_impl.hpp | 231 ------------- include/boost/histogram/serialization.hpp | 4 +- .../histogram/storage/adaptive_storage.hpp | 63 ++-- .../histogram/storage/container_storage.hpp | 20 +- src/python/histogram.cpp | 2 +- test/adaptive_storage_test.cpp | 6 +- test/dynamic_histogram_test.cpp | 62 ++-- test/static_histogram_test.cpp | 36 +- 14 files changed, 128 insertions(+), 673 deletions(-) delete mode 100644 include/boost/histogram/histogram_dynamic_impl.hpp delete mode 100644 include/boost/histogram/histogram_static_impl.hpp diff --git a/include/boost/histogram/axis.hpp b/include/boost/histogram/axis.hpp index 543ae218..e13ab04c 100644 --- a/include/boost/histogram/axis.hpp +++ b/include/boost/histogram/axis.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -192,7 +193,8 @@ private: * Very fast. Binning is a O(1) operation. */ template -class regular_axis : public axis_base { +class regular_axis : public axis_base, + boost::operators> { public: using value_type = RealType; using const_iterator = axis_iterator; @@ -265,7 +267,8 @@ private: * bins for this axis. Binning is a O(1) operation. */ template -class circular_axis : public axis_base { +class circular_axis : public axis_base, + boost::operators> { public: using value_type = RealType; using const_iterator = axis_iterator; @@ -326,7 +329,8 @@ private: * and the problem domain allows it, prefer a regular_axis. */ template -class variable_axis : public axis_base { +class variable_axis : public axis_base, + boost::operators> { public: using value_type = RealType; using const_iterator = axis_iterator; @@ -416,7 +420,7 @@ private: * Binning is a O(1) operation. This axis operates * faster than a regular_axis. */ -class integer_axis : public axis_base { +class integer_axis : public axis_base, boost::operators { public: using value_type = int; using const_iterator = axis_iterator; @@ -475,7 +479,7 @@ private: * There are no underflow/overflow bins for this axis. * Binning is a O(1) operation. */ -class category_axis : public axis_base { +class category_axis : public axis_base, boost::operators { public: using value_type = const std::string &; using const_iterator = axis_iterator; diff --git a/include/boost/histogram/detail/weight.hpp b/include/boost/histogram/detail/weight.hpp index bfd6a8a7..ed14ac9d 100644 --- a/include/boost/histogram/detail/weight.hpp +++ b/include/boost/histogram/detail/weight.hpp @@ -7,14 +7,12 @@ #ifndef _BOOST_HISTOGRAM_DETAIL_WEIGHT_HPP_ #define _BOOST_HISTOGRAM_DETAIL_WEIGHT_HPP_ -#include - namespace boost { namespace histogram { namespace detail { /// Used by nstore to hold a sum of weighted counts and a variance estimate -struct weight : boost::operators { +struct weight { double w, w2; weight() = default; weight(const weight &) = default; @@ -22,9 +20,9 @@ struct weight : boost::operators { weight &operator=(const weight &) = default; weight &operator=(weight &&) = default; - weight &operator+=(const weight &o) { - w += o.w; - w2 += o.w2; + weight &operator+=(const weight &rhs) { + w += rhs.w; + w2 += rhs.w2; return *this; } weight &operator++() { @@ -32,7 +30,17 @@ struct weight : boost::operators { ++w2; return *this; } - bool operator==(const weight &o) const { return w == o.w && w2 == o.w2; } + + bool operator==(const weight &rhs) const { + return w == rhs.w && w2 == rhs.w2; + } + bool operator!=(const weight &rhs) const { return !operator==(rhs); } + template bool operator==(const T &rhs) const { + return w == static_cast(rhs) && w2 == static_cast(rhs); + } + template bool operator!=(const T &rhs) const { + return !operator==(rhs); + } weight &add_weight(double t) { w += t; @@ -55,18 +63,10 @@ struct weight : boost::operators { } }; -template bool operator==(const weight &w, const T &t) { - return w.w == static_cast(t) && w.w2 == static_cast(t); -} - template bool operator==(const T &t, const weight &w) { return w == t; } -template bool operator!=(const weight &w, const T &t) { - return !(w == t); -} - template bool operator!=(const T &t, const weight &w) { return !(w == t); } diff --git a/include/boost/histogram/histogram.hpp b/include/boost/histogram/histogram.hpp index 9518bbda..e47a6e67 100644 --- a/include/boost/histogram/histogram.hpp +++ b/include/boost/histogram/histogram.hpp @@ -7,8 +7,7 @@ #ifndef _BOOST_HISTOGRAM_HISTOGRAM_HPP_ #define _BOOST_HISTOGRAM_HISTOGRAM_HPP_ -#include -#include -#include +#include +#include #endif diff --git a/include/boost/histogram/histogram_dynamic_impl.hpp b/include/boost/histogram/histogram_dynamic_impl.hpp deleted file mode 100644 index 36c15e88..00000000 --- a/include/boost/histogram/histogram_dynamic_impl.hpp +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright 2015-2016 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_DYNAMIC_IMPL_HPP_ -#define _BOOST_HISTOGRAM_HISTOGRAM_DYNAMIC_IMPL_HPP_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace histogram { - -template -class histogram { - static_assert(!mpl::empty::value, "at least one axis required"); - using size_pair = std::pair; - -public: - using axis_type = typename make_variant_over::type; - using value_type = typename Storage::value_type; - -private: - using axes_type = std::vector; - -public: - histogram() = default; - - template - explicit histogram(const Axes1 &... axes) : axes_({axis_type(axes)...}) { - storage_ = Storage(field_count()); - } - - template > - 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 - explicit histogram(const histogram &other) - : axes_(other.axes_.begin(), other.axes_.end()), - storage_(other.storage_) {} - - template - explicit histogram(histogram &&other) - : axes_(std::move(other.axes_)), storage_(std::move(other.storage_)) {} - - template - histogram &operator=(const histogram &other) { - if (static_cast(this) != static_cast(&other)) { - axes_ = other.axes_; - storage_ = other.storage_; - } - return *this; - } - - template - histogram &operator=(histogram &&other) { - if (static_cast(this) != static_cast(&other)) { - axes_ = std::move(other.axes_); - storage_ = std::move(other.storage_); - } - return *this; - } - - template - bool operator==(const histogram &other) const { - if (mpl::empty< - typename detail::intersection::type>::value) { - return false; - } - if (dim() != other.dim()) { - return false; - } - if (!axes_equal_to(other.axes_)) { - return false; - } - if (!(storage_ == other.storage_)) { - return false; - } - return true; - } - - template - histogram &operator+=(const histogram &other) { - static_assert( - !mpl::empty::type>::value, - "histograms lack common axes types"); - if (dim() != other.dim()) { - throw std::logic_error("dimensions of histograms differ"); - } - if (size() != other.size()) { - throw std::logic_error("sizes of histograms differ"); - } - if (!axes_equal_to(other.axes_)) { - throw std::logic_error("axes of histograms differ"); - } - storage_ += other.storage_; - return *this; - } - - template void fill(Values... values) { - BOOST_ASSERT_MSG(sizeof...(values) == dim(), - "number of arguments does not match histogram dimension"); - const auto p = - apply_lin(size_pair(0, 1), values...); - if (p.second) { - storage_.increase(p.first); - } - } - - template > - 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(size_pair(0, 1), begin); - if (p.second) { - storage_.increase(p.first); - } - } - - template 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(size_pair(0, 1), values...); - if (p.second) { - storage_.increase(p.first, w); - } - } - - template > - 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(size_pair(0, 1), begin); - if (p.second) { - storage_.increase(p.first, w); - } - } - - template 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(size_pair(0, 1), indices...); - if (p.second == 0) { - throw std::out_of_range("invalid index"); - } - return storage_.value(p.first); - } - - template > - 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(size_pair(0, 1), begin); - if (p.second == 0) { - throw std::out_of_range("invalid index"); - } - return storage_.value(p.first); - } - - template value_type variance(Indices... indices) const { - static_assert(detail::has_variance::value, - "Storage lacks variance support"); - BOOST_ASSERT_MSG(sizeof...(indices) == dim(), - "number of arguments does not match histogram dimension"); - const auto p = - apply_lin(size_pair(0, 1), indices...); - if (p.second == 0) { - throw std::out_of_range("invalid index"); - } - return storage_.variance(p.first); - } - - template > - value_type variance(Iterator begin, Iterator end) const { - static_assert(detail::has_variance::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(size_pair(0, 1), begin); - if (p.second == 0) { - throw std::out_of_range("invalid index"); - } - return storage_.variance(p.first); - } - - /// Number of axes (dimensions) of histogram - unsigned dim() const { return axes_.size(); } - - /// Total number of bins in the histogram (including underflow/overflow) - std::size_t size() const { return storage_.size(); } - - /// Sum of all counts in the histogram - double sum() const { - double result = 0.0; - for (std::size_t i = 0, n = size(); i < n; ++i) { - result += storage_.value(i); - } - return result; - } - - /// Return axis \a i - const axis_type &axis(unsigned i = 0) const { - BOOST_ASSERT_MSG(i < dim(), "axis index out of range"); - return axes_[i]; - } - - /// Return axis \a i (added for conformity with static_histogram interface) - template const axis_type &axis() const { - BOOST_ASSERT_MSG(N < dim(), "axis index out of range"); - return axes_[N]; - } - - /// Apply unary functor/function to each axis - template void for_each_axis(Unary &unary) const { - for (const auto &a : axes_) { - apply_visitor(detail::unary_visitor(unary), a); - } - } - -private: - axes_type axes_; - Storage storage_; - - std::size_t field_count() const { - detail::field_count fc; - for (const auto &a : axes_) { - apply_visitor(fc, a); - } - return fc.value; - } - - template - bool axes_equal_to(const A &other_axes) const { - detail::cmp_axis ca; - for (unsigned i = 0; i < dim(); ++i) { - if (!apply_visitor(ca, axes_[i], other_axes[i])) { - return false; - } - } - return true; - } - - template