mirror of
https://github.com/boostorg/histogram.git
synced 2026-02-27 05:02:27 +00:00
refactoring
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
#ifndef BOOST_HISTOGRAM_HPP_
|
||||
#define BOOST_HISTOGRAM_HPP_
|
||||
|
||||
#include <boost/histogram/axis.hpp>
|
||||
#include <boost/histogram/axis/axis.hpp>
|
||||
#include <boost/histogram/histogram.hpp>
|
||||
#include <boost/histogram/literals.hpp>
|
||||
#include <boost/histogram/storage/adaptive_storage.hpp>
|
||||
|
||||
96
include/boost/histogram/arithmetic_operators.hpp
Normal file
96
include/boost/histogram/arithmetic_operators.hpp
Normal file
@@ -0,0 +1,96 @@
|
||||
// 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_ARITHMETIC_OPERATORS_HPP_
|
||||
#define _BOOST_HISTOGRAM_HISTOGRAM_ARITHMETIC_OPERATORS_HPP_
|
||||
|
||||
#include <boost/histogram/histogram_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
|
||||
template <template <class, class> class H, typename A, typename S>
|
||||
H<A, S> &&
|
||||
operator+(H<A, S> &&a,
|
||||
const H<A, S> &b) {
|
||||
a += b;
|
||||
return std::move(a);
|
||||
}
|
||||
|
||||
template <template <class, class> class H, typename A, typename S>
|
||||
H<A, S> &&
|
||||
operator+(H<A, S> &&a,
|
||||
H<A, S> &&b) {
|
||||
a += b;
|
||||
return std::move(a);
|
||||
}
|
||||
|
||||
template <template <class, class> class H, typename A, typename S>
|
||||
H<A, S> &&
|
||||
operator+(const H<A, S> &a,
|
||||
H<A, S> &&b) {
|
||||
b += a;
|
||||
return std::move(b);
|
||||
}
|
||||
|
||||
template <template <class, class> class H, typename A, typename S>
|
||||
H<A, S>
|
||||
operator+(const H<A, S> &a,
|
||||
const H<A, S> &b) {
|
||||
H<A, S> r(a);
|
||||
r += b;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <template <class, class> class H, typename A, typename S>
|
||||
H<A, S> &&
|
||||
operator*(H<A, S> &&a, const double x) {
|
||||
a *= x;
|
||||
return std::move(a);
|
||||
}
|
||||
|
||||
template <template <class, class> class H, typename A, typename S>
|
||||
H<A, S> &&
|
||||
operator*(const double x, H<A, S> &&b) {
|
||||
b *= x;
|
||||
return std::move(b);
|
||||
}
|
||||
|
||||
template <template <class, class> class H, typename A, typename S>
|
||||
H<A, S>
|
||||
operator*(const H<A, S> &a, const double x) {
|
||||
H<A, S> r(a);
|
||||
r *= x;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <template <class, class> class H, typename A, typename S>
|
||||
H<A, S>
|
||||
operator*(const double x, const H<A, S> &b) {
|
||||
H<A, S> r(b);
|
||||
r *= x;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <template <class, class> class H, typename A, typename S>
|
||||
H<A, S> &&
|
||||
operator/(H<A, S> &&a, const double x) {
|
||||
a /= x;
|
||||
return std::move(a);
|
||||
}
|
||||
|
||||
template <template <class, class> class H, typename A, typename S>
|
||||
H<A, S>
|
||||
operator/(const H<A, S> &a, const double x) {
|
||||
H<A, S> r(a);
|
||||
r /= x;
|
||||
return r;
|
||||
}
|
||||
|
||||
} // namespace histogram
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
196
include/boost/histogram/axis/any.hpp
Normal file
196
include/boost/histogram/axis/any.hpp
Normal file
@@ -0,0 +1,196 @@
|
||||
// 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_AXIS_ANY_HPP_
|
||||
#define _BOOST_HISTOGRAM_AXIS_ANY_HPP_
|
||||
|
||||
#include <boost/histogram/axis/iterator.hpp>
|
||||
#include <boost/histogram/interval.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <boost/histogram/detail/axis_visitor.hpp>
|
||||
#include <boost/mpl/contains.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
// forward declaration for serialization
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
class access;
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
namespace axis {
|
||||
|
||||
namespace detail {
|
||||
struct size : public static_visitor<int> {
|
||||
template <typename A> int operator()(const A &a) const { return a.size(); }
|
||||
};
|
||||
|
||||
struct shape : public static_visitor<int> {
|
||||
template <typename A> int operator()(const A &a) const { return a.shape(); }
|
||||
};
|
||||
|
||||
struct uoflow : public static_visitor<bool> {
|
||||
template <typename A> bool operator()(const A &a) const { return a.uoflow(); }
|
||||
};
|
||||
|
||||
struct get_label : public static_visitor<string_view> {
|
||||
template <typename A> ::boost::string_view operator()(const A& a) const { return a.label(); }
|
||||
};
|
||||
|
||||
struct set_label : public static_visitor<void> {
|
||||
const ::boost::string_view label;
|
||||
set_label(const ::boost::string_view x) : label(x) {}
|
||||
template <typename A> void operator()(A& a) const { a.label(label); }
|
||||
};
|
||||
|
||||
template <typename T> struct index : public static_visitor<int> {
|
||||
const T &t;
|
||||
explicit index(const T &arg) : t(arg) {}
|
||||
template <typename Axis> int operator()(const Axis &a) const {
|
||||
return impl(std::is_convertible<T, typename Axis::value_type>(), a);
|
||||
}
|
||||
template <typename Axis> int impl(std::true_type, const Axis& a) const {
|
||||
return a.index(t);
|
||||
}
|
||||
template <typename Axis> int impl(std::false_type, const Axis&) const {
|
||||
throw std::runtime_error("index argument not convertible to axis value type");
|
||||
}
|
||||
};
|
||||
|
||||
struct bin : public static_visitor<axis::interval<double>> {
|
||||
using double_interval = axis::interval<double>;
|
||||
const int i;
|
||||
bin(const int v) : i(v) {}
|
||||
template <typename A> double_interval operator()(const A &a) const {
|
||||
return impl(is_convertible<typename A::bin_type, double_interval>(),
|
||||
std::forward<typename A::bin_type>(a[i]));
|
||||
}
|
||||
template <typename B> double_interval impl(true_type, B &&b) const {
|
||||
return b;
|
||||
}
|
||||
template <typename B> double_interval impl(false_type, B &&) const {
|
||||
throw std::runtime_error("cannot convert bin_type to interval<double>");
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/// Polymorphic axis type
|
||||
template <typename Axes>
|
||||
class any : public make_variant_over<Axes>::type {
|
||||
using base_type = typename make_variant_over<Axes>::type;
|
||||
public:
|
||||
using types = typename base_type::types;
|
||||
using value_type = double;
|
||||
using bin_type = interval<double>;
|
||||
using const_iterator = axis_iterator<any>;
|
||||
|
||||
any() = default;
|
||||
any(const any& t) = default;
|
||||
any(any&& t) = default;
|
||||
any& operator=(const any& t) = default;
|
||||
any& operator=(any&& t) = default;
|
||||
|
||||
template <typename T, typename = typename std::enable_if<
|
||||
mpl::contains<Axes, T>::value
|
||||
>::type>
|
||||
any(const T& t) : base_type(t) {}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<
|
||||
mpl::contains<Axes, T>::value
|
||||
>::type>
|
||||
any& operator=(const T& t) {
|
||||
// ugly workaround for compiler bug
|
||||
return reinterpret_cast<any&>(base_type::operator=(t));
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<
|
||||
mpl::contains<Axes, T>::value
|
||||
>::type>
|
||||
any& operator=(T&& t) {
|
||||
// ugly workaround for compiler bug
|
||||
return reinterpret_cast<any&>(base_type::operator=(std::move(t)));
|
||||
}
|
||||
|
||||
int size() const {
|
||||
return apply_visitor(detail::size(), *this);
|
||||
}
|
||||
|
||||
int shape() const {
|
||||
return apply_visitor(detail::shape(), *this);
|
||||
}
|
||||
|
||||
bool uoflow() const {
|
||||
return apply_visitor(detail::uoflow(), *this);
|
||||
}
|
||||
|
||||
// note: this only works for axes with compatible value type
|
||||
int index(const value_type x) const {
|
||||
return apply_visitor(detail::index<value_type>(x), *this);
|
||||
}
|
||||
|
||||
string_view label() const {
|
||||
return apply_visitor(detail::get_label(), *this);
|
||||
}
|
||||
|
||||
void label(const string_view x) {
|
||||
return apply_visitor(detail::set_label(x), *this);
|
||||
}
|
||||
|
||||
// this only works for axes with compatible bin type
|
||||
// and will raise an error otherwise
|
||||
bin_type operator[](const int i) const {
|
||||
return apply_visitor(detail::bin(i), *this);
|
||||
}
|
||||
|
||||
bool operator==(const any& rhs) const {
|
||||
return base_type::operator==(static_cast<const base_type&>(rhs));
|
||||
}
|
||||
|
||||
const_iterator begin() const { return const_iterator(*this, 0); }
|
||||
|
||||
const_iterator end() const { return const_iterator(*this, size()); }
|
||||
|
||||
private:
|
||||
friend class ::boost::serialization::access;
|
||||
template <typename Archive> void serialize(Archive&, unsigned);
|
||||
};
|
||||
|
||||
// dynamic casts
|
||||
template <typename T, typename Axes>
|
||||
typename std::add_lvalue_reference<T>::type cast(any<Axes>& any) { return get<T>(any); }
|
||||
|
||||
template <typename T, typename Axes>
|
||||
const typename std::add_lvalue_reference<T>::type cast(const any<Axes>& any) { return get<T>(any); }
|
||||
|
||||
template <typename T, typename Axes>
|
||||
typename std::add_pointer<T>::type cast(any<Axes>* any) { return get<T>(&any); }
|
||||
|
||||
template <typename T, typename Axes>
|
||||
const typename std::add_pointer<T>::type cast(const any<Axes>* any) { return get<T>(&any); }
|
||||
|
||||
// pass-through versions for generic programming, i.e. when you switch to static histogram
|
||||
template <typename T>
|
||||
typename std::add_lvalue_reference<T>::type cast(T& t) { return t; }
|
||||
|
||||
template <typename T>
|
||||
const typename std::add_lvalue_reference<T>::type cast(const T& t) { return t; }
|
||||
|
||||
template <typename T>
|
||||
typename std::add_pointer<T>::type cast(T* t) { return t; }
|
||||
|
||||
template <typename T>
|
||||
const typename std::add_pointer<T>::type cast(const T* t) { return t; }
|
||||
|
||||
} // namespace axis
|
||||
} // namespace histogram
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -9,14 +9,10 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/bimap.hpp>
|
||||
#include <boost/histogram/histogram_fwd.hpp>
|
||||
#include <boost/histogram/axis/iterator.hpp>
|
||||
#include <boost/histogram/interval.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <boost/histogram/detail/axis_visitor.hpp>
|
||||
#include <boost/mpl/contains.hpp>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
@@ -25,7 +21,6 @@
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
// forward declaration for serialization
|
||||
namespace boost {
|
||||
@@ -36,41 +31,10 @@ class access;
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
|
||||
namespace axis {
|
||||
|
||||
enum class uoflow { off = false, on = true };
|
||||
|
||||
template <typename Axis>
|
||||
class axis_iterator
|
||||
: public iterator_facade<axis_iterator<Axis>,
|
||||
std::pair<int, typename Axis::bin_type>,
|
||||
random_access_traversal_tag,
|
||||
std::pair<int, typename Axis::bin_type>> {
|
||||
public:
|
||||
explicit axis_iterator(const Axis &axis, int idx) : axis_(axis), idx_(idx) {}
|
||||
|
||||
axis_iterator(const axis_iterator &o) = default;
|
||||
axis_iterator &operator=(const axis_iterator &o) = default;
|
||||
|
||||
private:
|
||||
void increment() noexcept { ++idx_; }
|
||||
void decrement() noexcept { --idx_; }
|
||||
void advance(int n) noexcept { idx_ += n; }
|
||||
int distance_to(const axis_iterator &other) const noexcept {
|
||||
return other.idx_ - idx_;
|
||||
}
|
||||
bool equal(const axis_iterator &other) const noexcept {
|
||||
return idx_ == other.idx_;
|
||||
}
|
||||
std::pair<int, typename Axis::bin_type> dereference() const {
|
||||
return std::make_pair(idx_, axis_[idx_]);
|
||||
}
|
||||
const Axis& axis_;
|
||||
int idx_;
|
||||
friend class boost::iterator_core_access;
|
||||
};
|
||||
|
||||
/// Base class for all axes.
|
||||
class axis_base {
|
||||
public:
|
||||
@@ -591,168 +555,6 @@ private:
|
||||
friend class ::boost::serialization::access;
|
||||
template <class Archive> void serialize(Archive &, unsigned);
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
struct size : public static_visitor<int> {
|
||||
template <typename A> int operator()(const A &a) const { return a.size(); }
|
||||
};
|
||||
|
||||
struct shape : public static_visitor<int> {
|
||||
template <typename A> int operator()(const A &a) const { return a.shape(); }
|
||||
};
|
||||
|
||||
struct uoflow : public static_visitor<bool> {
|
||||
template <typename A> bool operator()(const A &a) const { return a.uoflow(); }
|
||||
};
|
||||
|
||||
struct get_label : public static_visitor<string_view> {
|
||||
template <typename A> ::boost::string_view operator()(const A& a) const { return a.label(); }
|
||||
};
|
||||
|
||||
struct set_label : public static_visitor<void> {
|
||||
const ::boost::string_view label;
|
||||
set_label(const ::boost::string_view x) : label(x) {}
|
||||
template <typename A> void operator()(A& a) const { a.label(label); }
|
||||
};
|
||||
|
||||
template <typename T> struct index : public static_visitor<int> {
|
||||
const T &t;
|
||||
explicit index(const T &arg) : t(arg) {}
|
||||
template <typename Axis> int operator()(const Axis &a) const {
|
||||
return impl(std::is_convertible<T, typename Axis::value_type>(), a);
|
||||
}
|
||||
template <typename Axis> int impl(std::true_type, const Axis& a) const {
|
||||
return a.index(t);
|
||||
}
|
||||
template <typename Axis> int impl(std::false_type, const Axis&) const {
|
||||
throw std::runtime_error("index argument not convertible to axis value type");
|
||||
}
|
||||
};
|
||||
|
||||
struct bin : public static_visitor<axis::interval<double>> {
|
||||
using double_interval = axis::interval<double>;
|
||||
const int i;
|
||||
bin(const int v) : i(v) {}
|
||||
template <typename A> double_interval operator()(const A &a) const {
|
||||
return impl(is_convertible<typename A::bin_type, double_interval>(),
|
||||
std::forward<typename A::bin_type>(a[i]));
|
||||
}
|
||||
template <typename B> double_interval impl(true_type, B &&b) const {
|
||||
return b;
|
||||
}
|
||||
template <typename B> double_interval impl(false_type, B &&) const {
|
||||
throw std::runtime_error("cannot convert bin_type to interval<double>");
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/// Polymorphic axis type
|
||||
template <typename Axes = builtins>
|
||||
class any : public make_variant_over<Axes>::type {
|
||||
using base_type = typename make_variant_over<Axes>::type;
|
||||
public:
|
||||
using types = typename base_type::types;
|
||||
using value_type = double;
|
||||
using bin_type = interval<double>;
|
||||
using const_iterator = axis_iterator<any>;
|
||||
|
||||
any() = default;
|
||||
any(const any& t) = default;
|
||||
any(any&& t) = default;
|
||||
any& operator=(const any& t) = default;
|
||||
any& operator=(any&& t) = default;
|
||||
|
||||
template <typename T, typename = typename std::enable_if<
|
||||
mpl::contains<Axes, T>::value
|
||||
>::type>
|
||||
any(const T& t) : base_type(t) {}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<
|
||||
mpl::contains<Axes, T>::value
|
||||
>::type>
|
||||
any& operator=(const T& t) {
|
||||
// ugly workaround for compiler bug
|
||||
return reinterpret_cast<any&>(base_type::operator=(t));
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<
|
||||
mpl::contains<Axes, T>::value
|
||||
>::type>
|
||||
any& operator=(T&& t) {
|
||||
// ugly workaround for compiler bug
|
||||
return reinterpret_cast<any&>(base_type::operator=(std::move(t)));
|
||||
}
|
||||
|
||||
int size() const {
|
||||
return apply_visitor(detail::size(), *this);
|
||||
}
|
||||
|
||||
int shape() const {
|
||||
return apply_visitor(detail::shape(), *this);
|
||||
}
|
||||
|
||||
bool uoflow() const {
|
||||
return apply_visitor(detail::uoflow(), *this);
|
||||
}
|
||||
|
||||
// note: this only works for axes with compatible value type
|
||||
int index(const value_type x) const {
|
||||
return apply_visitor(detail::index<value_type>(x), *this);
|
||||
}
|
||||
|
||||
string_view label() const {
|
||||
return apply_visitor(detail::get_label(), *this);
|
||||
}
|
||||
|
||||
void label(const string_view x) {
|
||||
return apply_visitor(detail::set_label(x), *this);
|
||||
}
|
||||
|
||||
// this only works for axes with compatible bin type
|
||||
// and will raise an error otherwise
|
||||
bin_type operator[](const int i) const {
|
||||
return apply_visitor(detail::bin(i), *this);
|
||||
}
|
||||
|
||||
bool operator==(const any& rhs) const {
|
||||
return base_type::operator==(static_cast<const base_type&>(rhs));
|
||||
}
|
||||
|
||||
const_iterator begin() const { return const_iterator(*this, 0); }
|
||||
|
||||
const_iterator end() const { return const_iterator(*this, size()); }
|
||||
|
||||
private:
|
||||
friend class ::boost::serialization::access;
|
||||
template <typename Archive> void serialize(Archive&, unsigned);
|
||||
};
|
||||
|
||||
// dynamic casts
|
||||
template <typename T, typename Axes>
|
||||
typename std::add_lvalue_reference<T>::type cast(any<Axes>& any) { return get<T>(any); }
|
||||
|
||||
template <typename T, typename Axes>
|
||||
const typename std::add_lvalue_reference<T>::type cast(const any<Axes>& any) { return get<T>(any); }
|
||||
|
||||
template <typename T, typename Axes>
|
||||
typename std::add_pointer<T>::type cast(any<Axes>* any) { return get<T>(&any); }
|
||||
|
||||
template <typename T, typename Axes>
|
||||
const typename std::add_pointer<T>::type cast(const any<Axes>* any) { return get<T>(&any); }
|
||||
|
||||
// pass-through versions for generic programming, i.e. when you switch to static histogram
|
||||
template <typename T>
|
||||
typename std::add_lvalue_reference<T>::type cast(T& t) { return t; }
|
||||
|
||||
template <typename T>
|
||||
const typename std::add_lvalue_reference<T>::type cast(const T& t) { return t; }
|
||||
|
||||
template <typename T>
|
||||
typename std::add_pointer<T>::type cast(T* t) { return t; }
|
||||
|
||||
template <typename T>
|
||||
const typename std::add_pointer<T>::type cast(const T* t) { return t; }
|
||||
|
||||
} // namespace axis
|
||||
} // namespace histogram
|
||||
} // namespace boost
|
||||
47
include/boost/histogram/axis/iterator.hpp
Normal file
47
include/boost/histogram/axis/iterator.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// 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_AXIS_ITERATOR_HPP_
|
||||
#define _BOOST_HISTOGRAM_AXIS_ITERATOR_HPP_
|
||||
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace boost { namespace histogram { namespace axis {
|
||||
|
||||
template <typename Axis>
|
||||
class axis_iterator
|
||||
: public iterator_facade<axis_iterator<Axis>,
|
||||
std::pair<int, typename Axis::bin_type>,
|
||||
random_access_traversal_tag,
|
||||
std::pair<int, typename Axis::bin_type>> {
|
||||
public:
|
||||
explicit axis_iterator(const Axis &axis, int idx) : axis_(axis), idx_(idx) {}
|
||||
|
||||
axis_iterator(const axis_iterator &o) = default;
|
||||
axis_iterator &operator=(const axis_iterator &o) = default;
|
||||
|
||||
private:
|
||||
void increment() noexcept { ++idx_; }
|
||||
void decrement() noexcept { --idx_; }
|
||||
void advance(int n) noexcept { idx_ += n; }
|
||||
int distance_to(const axis_iterator &other) const noexcept {
|
||||
return other.idx_ - idx_;
|
||||
}
|
||||
bool equal(const axis_iterator &other) const noexcept {
|
||||
return idx_ == other.idx_;
|
||||
}
|
||||
std::pair<int, typename Axis::bin_type> dereference() const {
|
||||
return std::make_pair(idx_, axis_[idx_]);
|
||||
}
|
||||
const Axis& axis_;
|
||||
int idx_;
|
||||
friend class boost::iterator_core_access;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -9,7 +9,7 @@
|
||||
#ifndef _BOOST_HISTOGRAM_AXIS_OSTREAM_OPERATORS_HPP_
|
||||
#define _BOOST_HISTOGRAM_AXIS_OSTREAM_OPERATORS_HPP_
|
||||
|
||||
#include <boost/histogram/axis.hpp>
|
||||
#include <boost/histogram/axis/axis.hpp>
|
||||
#include <boost/histogram/detail/utility.hpp>
|
||||
#include <boost/histogram/interval.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/histogram/axis.hpp>
|
||||
#include <boost/histogram/axis/axis.hpp>
|
||||
#include <boost/histogram/axis/any.hpp>
|
||||
#include <boost/histogram/detail/axis_visitor.hpp>
|
||||
#include <boost/histogram/detail/meta.hpp>
|
||||
#include <boost/histogram/detail/utility.hpp>
|
||||
@@ -43,7 +44,7 @@ namespace boost {
|
||||
namespace histogram {
|
||||
|
||||
template <typename Axes, typename Storage>
|
||||
class histogram<Dynamic, Axes, Storage> {
|
||||
class dynamic_histogram {
|
||||
static_assert(!mpl::empty<Axes>::value, "at least one axis required");
|
||||
public:
|
||||
using any_axis_type = axis::any<Axes>;
|
||||
@@ -53,31 +54,45 @@ private:
|
||||
using axes_type = std::vector<any_axis_type>;
|
||||
|
||||
public:
|
||||
histogram() = default;
|
||||
histogram(const histogram &) = default;
|
||||
histogram(histogram &&) = default;
|
||||
histogram &operator=(const histogram &) = default;
|
||||
histogram &operator=(histogram &&) = default;
|
||||
dynamic_histogram() = default;
|
||||
dynamic_histogram(const dynamic_histogram &) = default;
|
||||
dynamic_histogram(dynamic_histogram &&) = default;
|
||||
dynamic_histogram &operator=(const dynamic_histogram &) = default;
|
||||
dynamic_histogram &operator=(dynamic_histogram &&) = default;
|
||||
|
||||
template <typename... Axes1>
|
||||
explicit histogram(const Axes1 &... axes) : axes_({any_axis_type(axes)...}) {
|
||||
explicit dynamic_histogram(const Axes1 &... axes) : axes_({any_axis_type(axes)...}) {
|
||||
storage_ = Storage(bincount_from_axes());
|
||||
}
|
||||
|
||||
template <typename Iterator, typename = detail::is_iterator<Iterator>>
|
||||
histogram(Iterator axes_begin, Iterator axes_end)
|
||||
: axes_(std::distance(axes_begin, axes_end)) {
|
||||
std::copy(axes_begin, axes_end, axes_.begin());
|
||||
dynamic_histogram(Iterator begin, Iterator end)
|
||||
: axes_(std::distance(begin, end)) {
|
||||
std::copy(begin, end, axes_.begin());
|
||||
storage_ = Storage(bincount_from_axes());
|
||||
}
|
||||
|
||||
template <typename D, typename A, typename S>
|
||||
explicit histogram(const histogram<D, A, S> &rhs) : storage_(rhs.storage_) {
|
||||
template <typename A, typename S>
|
||||
explicit dynamic_histogram(const static_histogram<A, S> &rhs) : storage_(rhs.storage_) {
|
||||
detail::axes_assign(axes_, rhs.axes_);
|
||||
}
|
||||
|
||||
template <typename D, typename A, typename S>
|
||||
histogram &operator=(const histogram<D, A, S> &rhs) {
|
||||
template <typename A, typename S>
|
||||
explicit dynamic_histogram(const dynamic_histogram<A, S> &rhs) : storage_(rhs.storage_) {
|
||||
detail::axes_assign(axes_, rhs.axes_);
|
||||
}
|
||||
|
||||
template <typename A, typename S>
|
||||
dynamic_histogram &operator=(const static_histogram<A, S> &rhs) {
|
||||
if (static_cast<const void *>(this) != static_cast<const void *>(&rhs)) {
|
||||
detail::axes_assign(axes_, rhs.axes_);
|
||||
storage_ = rhs.storage_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename A, typename S>
|
||||
dynamic_histogram &operator=(const dynamic_histogram<A, S> &rhs) {
|
||||
if (static_cast<const void *>(this) != static_cast<const void *>(&rhs)) {
|
||||
detail::axes_assign(axes_, rhs.axes_);
|
||||
storage_ = rhs.storage_;
|
||||
@@ -86,11 +101,11 @@ public:
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
explicit histogram(histogram<Dynamic, Axes, S> &&rhs)
|
||||
explicit dynamic_histogram(dynamic_histogram<Axes, S> &&rhs)
|
||||
: axes_(std::move(rhs.axes_)), storage_(std::move(rhs.storage_)) {}
|
||||
|
||||
template <typename S>
|
||||
histogram &operator=(histogram<Dynamic, Axes, S> &&rhs) {
|
||||
dynamic_histogram &operator=(dynamic_histogram<Axes, S> &&rhs) {
|
||||
if (static_cast<const void *>(this) != static_cast<const void *>(&rhs)) {
|
||||
axes_ = std::move(rhs.axes_);
|
||||
storage_ = std::move(rhs.storage_);
|
||||
@@ -98,30 +113,48 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename D, typename A, typename S>
|
||||
bool operator==(const histogram<D, A, S> &rhs) const noexcept {
|
||||
template <typename A, typename S>
|
||||
bool operator==(const static_histogram<A, S> &rhs) const noexcept {
|
||||
return detail::axes_equal(axes_, rhs.axes_) && storage_ == rhs.storage_;
|
||||
}
|
||||
|
||||
template <typename D, typename A, typename S>
|
||||
bool operator!=(const histogram<D, A, S> &rhs) const noexcept {
|
||||
template <typename A, typename S>
|
||||
bool operator==(const dynamic_histogram<A, S> &rhs) const noexcept {
|
||||
return detail::axes_equal(axes_, rhs.axes_) && storage_ == rhs.storage_;
|
||||
}
|
||||
|
||||
template <typename A, typename S>
|
||||
bool operator!=(const static_histogram<A, S> &rhs) const noexcept {
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
template <typename D, typename A, typename S>
|
||||
histogram &operator+=(const histogram<D, A, S> &rhs) {
|
||||
template <typename A, typename S>
|
||||
bool operator!=(const dynamic_histogram<A, S> &rhs) const noexcept {
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
template <typename A, typename S>
|
||||
dynamic_histogram &operator+=(const static_histogram<A, S> &rhs) {
|
||||
if (!detail::axes_equal(axes_, rhs.axes_))
|
||||
throw std::logic_error("axes of histograms differ");
|
||||
storage_ += rhs.storage_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
histogram &operator*=(const value_type rhs) {
|
||||
template <typename A, typename S>
|
||||
dynamic_histogram &operator+=(const dynamic_histogram<A, S> &rhs) {
|
||||
if (!detail::axes_equal(axes_, rhs.axes_))
|
||||
throw std::logic_error("axes of histograms differ");
|
||||
storage_ += rhs.storage_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
dynamic_histogram &operator*=(const value_type rhs) {
|
||||
storage_ *= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
histogram &operator/=(const value_type rhs) {
|
||||
dynamic_histogram &operator/=(const value_type rhs) {
|
||||
storage_ *= 1.0 / rhs;
|
||||
return *this;
|
||||
}
|
||||
@@ -259,13 +292,13 @@ public:
|
||||
}
|
||||
|
||||
/// Return a lower dimensional histogram
|
||||
template <int N, typename... Rest> histogram reduce_to(mpl::int_<N>, Rest...) const {
|
||||
template <int N, typename... Rest> dynamic_histogram reduce_to(mpl::int_<N>, Rest...) const {
|
||||
const auto b = detail::bool_mask<mpl::vector<mpl::int_<N>, Rest...>>(dim(), true);
|
||||
return reduce_impl(b);
|
||||
}
|
||||
|
||||
/// Return a lower dimensional histogram
|
||||
template <typename... Rest> histogram reduce_to(int n, Rest... rest) const {
|
||||
template <typename... Rest> dynamic_histogram reduce_to(int n, Rest... rest) const {
|
||||
std::vector<bool> b(dim(), false);
|
||||
for (const auto &i : {n, rest...})
|
||||
b[i] = true;
|
||||
@@ -274,7 +307,7 @@ public:
|
||||
|
||||
/// Return a lower dimensional histogram
|
||||
template <typename Iterator, typename = detail::is_iterator<Iterator>>
|
||||
histogram reduce_to(Iterator begin, Iterator end) const {
|
||||
dynamic_histogram reduce_to(Iterator begin, Iterator end) const {
|
||||
std::vector<bool> b(dim(), false);
|
||||
for (; begin != end; ++begin)
|
||||
b[*begin] = true;
|
||||
@@ -426,7 +459,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
histogram reduce_impl(const std::vector<bool> &b) const {
|
||||
dynamic_histogram reduce_impl(const std::vector<bool> &b) const {
|
||||
axes_type axes;
|
||||
std::vector<unsigned> n(b.size());
|
||||
auto axes_iter = axes_.begin();
|
||||
@@ -438,7 +471,7 @@ private:
|
||||
++axes_iter;
|
||||
++n_iter;
|
||||
}
|
||||
histogram h(axes.begin(), axes.end());
|
||||
dynamic_histogram h(axes.begin(), axes.end());
|
||||
detail::index_mapper m(n, b);
|
||||
do {
|
||||
detail::storage_add(h.storage_, storage_, m.second, m.first);
|
||||
@@ -446,43 +479,42 @@ private:
|
||||
return h;
|
||||
}
|
||||
|
||||
template <typename D, typename A, typename S> friend class histogram;
|
||||
template <typename A, typename S> friend class dynamic_histogram;
|
||||
template <typename A, typename S> friend class static_histogram;
|
||||
friend class ::boost::python::access;
|
||||
friend class ::boost::serialization::access;
|
||||
template <typename Archive> void serialize(Archive &, unsigned);
|
||||
};
|
||||
|
||||
template <typename... Axes>
|
||||
histogram<Dynamic, detail::combine_t<axis::builtins, mpl::vector<Axes...>>>
|
||||
dynamic_histogram<detail::combine_t<axis::builtins, mpl::vector<Axes...>>>
|
||||
make_dynamic_histogram(Axes &&... axes) {
|
||||
|
||||
return histogram<Dynamic,
|
||||
return dynamic_histogram<
|
||||
detail::combine_t<axis::builtins, mpl::vector<Axes...>>>(
|
||||
std::forward<Axes>(axes)...);
|
||||
}
|
||||
|
||||
template <typename Storage, typename... Axes>
|
||||
histogram<Dynamic, detail::combine_t<axis::builtins, mpl::vector<Axes...>>,
|
||||
dynamic_histogram<detail::combine_t<axis::builtins, mpl::vector<Axes...>>,
|
||||
Storage>
|
||||
make_dynamic_histogram_with(Axes &&... axes) {
|
||||
return histogram<
|
||||
Dynamic, detail::combine_t<axis::builtins, mpl::vector<Axes...>>, Storage>(
|
||||
return dynamic_histogram<
|
||||
detail::combine_t<axis::builtins, mpl::vector<Axes...>>, Storage>(
|
||||
std::forward<Axes>(axes)...);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename = detail::is_iterator<Iterator>>
|
||||
histogram<Dynamic, detail::combine_t<axis::builtins, typename Iterator::value_type::types>>
|
||||
dynamic_histogram<detail::combine_t<axis::builtins, typename Iterator::value_type::types>>
|
||||
make_dynamic_histogram(Iterator begin, Iterator end) {
|
||||
return histogram<
|
||||
Dynamic, detail::combine_t<axis::builtins, typename Iterator::value_type::types>>(
|
||||
return dynamic_histogram<detail::combine_t<axis::builtins, typename Iterator::value_type::types>>(
|
||||
begin, end);
|
||||
}
|
||||
|
||||
template <typename Storage, typename Iterator, typename = detail::is_iterator<Iterator>>
|
||||
histogram<Dynamic, detail::combine_t<axis::builtins, typename Iterator::value_type::types>, Storage>
|
||||
dynamic_histogram<detail::combine_t<axis::builtins, typename Iterator::value_type::types>, Storage>
|
||||
make_dynamic_histogram_with(Iterator begin, Iterator end) {
|
||||
return histogram<
|
||||
Dynamic, detail::combine_t<axis::builtins, typename Iterator::value_type::types>, Storage>(
|
||||
return dynamic_histogram<detail::combine_t<axis::builtins, typename Iterator::value_type::types>, Storage>(
|
||||
begin, end);
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#ifndef _BOOST_HISTOGRAM_HISTOGRAM_HPP_
|
||||
#define _BOOST_HISTOGRAM_HISTOGRAM_HPP_
|
||||
|
||||
#include <boost/histogram/histogram_impl_dynamic.hpp>
|
||||
#include <boost/histogram/histogram_impl_static.hpp>
|
||||
#include <boost/histogram/histogram_arithmetic_operators.hpp>
|
||||
#include <boost/histogram/dynamic_histogram.hpp>
|
||||
#include <boost/histogram/static_histogram.hpp>
|
||||
#include <boost/histogram/arithmetic_operators.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,96 +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_ARITHMETIC_OPERATORS_HPP_
|
||||
#define _BOOST_HISTOGRAM_HISTOGRAM_ARITHMETIC_OPERATORS_HPP_
|
||||
|
||||
#include <boost/histogram/histogram_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage> &&
|
||||
operator+(histogram<Variant, Axes, Storage> &&a,
|
||||
const histogram<Variant, Axes, Storage> &b) {
|
||||
a += b;
|
||||
return std::move(a);
|
||||
}
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage> &&
|
||||
operator+(histogram<Variant, Axes, Storage> &&a,
|
||||
histogram<Variant, Axes, Storage> &&b) {
|
||||
a += b;
|
||||
return std::move(a);
|
||||
}
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage> &&
|
||||
operator+(const histogram<Variant, Axes, Storage> &a,
|
||||
histogram<Variant, Axes, Storage> &&b) {
|
||||
b += a;
|
||||
return std::move(b);
|
||||
}
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage>
|
||||
operator+(const histogram<Variant, Axes, Storage> &a,
|
||||
const histogram<Variant, Axes, Storage> &b) {
|
||||
histogram<Variant, Axes, Storage> r(a);
|
||||
r += b;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage> &&
|
||||
operator*(histogram<Variant, Axes, Storage> &&a, const double x) {
|
||||
a *= x;
|
||||
return std::move(a);
|
||||
}
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage> &&
|
||||
operator*(const double x, histogram<Variant, Axes, Storage> &&b) {
|
||||
b *= x;
|
||||
return std::move(b);
|
||||
}
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage>
|
||||
operator*(const histogram<Variant, Axes, Storage> &a, const double x) {
|
||||
histogram<Variant, Axes, Storage> r(a);
|
||||
r *= x;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage>
|
||||
operator*(const double x, const histogram<Variant, Axes, Storage> &b) {
|
||||
histogram<Variant, Axes, Storage> r(b);
|
||||
r *= x;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage> &&
|
||||
operator/(histogram<Variant, Axes, Storage> &&a, const double x) {
|
||||
a /= x;
|
||||
return std::move(a);
|
||||
}
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage>
|
||||
operator/(const histogram<Variant, Axes, Storage> &a, const double x) {
|
||||
histogram<Variant, Axes, Storage> r(a);
|
||||
r /= x;
|
||||
return r;
|
||||
}
|
||||
|
||||
} // namespace histogram
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -7,17 +7,12 @@
|
||||
#ifndef _BOOST_HISTOGRAM_HISTOGRAM_FWD_HPP_
|
||||
#define _BOOST_HISTOGRAM_HISTOGRAM_FWD_HPP_
|
||||
|
||||
#include <boost/histogram/detail/meta.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
|
||||
using Static = std::integral_constant<int, 0>;
|
||||
using Dynamic = std::integral_constant<int, 1>;
|
||||
|
||||
class adaptive_storage;
|
||||
|
||||
namespace axis {
|
||||
@@ -43,10 +38,17 @@ using builtins =
|
||||
axis::regular<double, axis::transform::pow>, axis::circular<>,
|
||||
axis::variable<>, axis::integer<>,
|
||||
axis::category<>, axis::category<std::string>>;
|
||||
}
|
||||
|
||||
template <class Variant, class Axes, class Storage = adaptive_storage>
|
||||
class histogram;
|
||||
template <typename Axes = builtins>
|
||||
class any;
|
||||
|
||||
} // namespace axis
|
||||
|
||||
template <class Axes, class Storage = adaptive_storage>
|
||||
class static_histogram;
|
||||
|
||||
template <class Axes, class Storage = adaptive_storage>
|
||||
class dynamic_histogram;
|
||||
|
||||
struct weight {
|
||||
weight(double w) : value(w) {}
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
// (See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef _BOOST_HISTOGRAM_HISTOGRAM_OSTREAM_OPERATORS_HPP_
|
||||
#define _BOOST_HISTOGRAM_HISTOGRAM_OSTREAM_OPERATORS_HPP_
|
||||
#ifndef _BOOST_HISTOGRAM_OSTREAM_OPERATORS_HPP_
|
||||
#define _BOOST_HISTOGRAM_OSTREAM_OPERATORS_HPP_
|
||||
|
||||
#include <boost/histogram/axis_ostream_operators.hpp>
|
||||
#include <boost/histogram/histogram_fwd.hpp>
|
||||
#include <boost/histogram/axis/ostream_operators.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace boost {
|
||||
@@ -24,8 +23,8 @@ struct axis_ostream_visitor {
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <typename D, typename A, typename S>
|
||||
inline std::ostream &operator<<(std::ostream &os, const histogram<D, A, S> &h) {
|
||||
template <template <class, class> class H, typename A, typename S>
|
||||
inline std::ostream &operator<<(std::ostream &os, const H<A, S> &h) {
|
||||
os << "histogram(";
|
||||
detail::axis_ostream_visitor sh(os);
|
||||
h.for_each_axis(sh);
|
||||
@@ -192,7 +192,7 @@ void any<Axes>::serialize(Archive &ar, unsigned /* version */) {
|
||||
|
||||
template <class A, class S>
|
||||
template <class Archive>
|
||||
void histogram<Static, A, S>::serialize(Archive &ar, unsigned /* version */) {
|
||||
void static_histogram<A, S>::serialize(Archive &ar, unsigned /* version */) {
|
||||
detail::serialize_helper<Archive> sh(ar);
|
||||
fusion::for_each(axes_, sh);
|
||||
ar &storage_;
|
||||
@@ -200,7 +200,7 @@ void histogram<Static, A, S>::serialize(Archive &ar, unsigned /* version */) {
|
||||
|
||||
template <class A, class S>
|
||||
template <class Archive>
|
||||
void histogram<Dynamic, A, S>::serialize(Archive &ar, unsigned /* version */) {
|
||||
void dynamic_histogram<A, S>::serialize(Archive &ar, unsigned /* version */) {
|
||||
ar &axes_;
|
||||
ar &storage_;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <boost/fusion/include/sequence.hpp>
|
||||
#include <boost/fusion/sequence.hpp>
|
||||
#include <boost/fusion/sequence/comparison.hpp>
|
||||
#include <boost/histogram/axis.hpp>
|
||||
#include <boost/histogram/axis/axis.hpp>
|
||||
#include <boost/histogram/detail/axis_visitor.hpp>
|
||||
#include <boost/histogram/detail/meta.hpp>
|
||||
#include <boost/histogram/detail/utility.hpp>
|
||||
@@ -42,7 +42,7 @@ namespace boost {
|
||||
namespace histogram {
|
||||
|
||||
template <typename Axes, typename Storage>
|
||||
class histogram<Static, Axes, Storage> {
|
||||
class static_histogram {
|
||||
static_assert(!mpl::empty<Axes>::value, "at least one axis required");
|
||||
using axes_size = typename fusion::result_of::size<Axes>::type;
|
||||
|
||||
@@ -50,28 +50,33 @@ public:
|
||||
using axes_type = typename fusion::result_of::as_vector<Axes>::type;
|
||||
using value_type = typename Storage::value_type;
|
||||
|
||||
histogram() = default;
|
||||
histogram(const histogram &rhs) = default;
|
||||
histogram(histogram &&rhs) = default;
|
||||
histogram &operator=(const histogram &rhs) = default;
|
||||
histogram &operator=(histogram &&rhs) = default;
|
||||
static_histogram() = default;
|
||||
static_histogram(const static_histogram &rhs) = default;
|
||||
static_histogram(static_histogram &&rhs) = default;
|
||||
static_histogram &operator=(const static_histogram &rhs) = default;
|
||||
static_histogram &operator=(static_histogram &&rhs) = default;
|
||||
|
||||
template <typename... Axis>
|
||||
explicit histogram(const Axis &... axis) : axes_(axis...) {
|
||||
explicit static_histogram(const Axis &... axis) : axes_(axis...) {
|
||||
storage_ = Storage(bincount_from_axes());
|
||||
}
|
||||
|
||||
explicit histogram(axes_type &&axes) : axes_(std::move(axes)) {
|
||||
explicit static_histogram(axes_type &&axes) : axes_(std::move(axes)) {
|
||||
storage_ = Storage(bincount_from_axes());
|
||||
}
|
||||
|
||||
template <typename D, typename A, typename S>
|
||||
explicit histogram(const histogram<D, A, S> &rhs) : storage_(rhs.storage_) {
|
||||
template <typename S>
|
||||
explicit static_histogram(const static_histogram<Axes, S> &rhs) : storage_(rhs.storage_) {
|
||||
detail::axes_assign(axes_, rhs.axes_);
|
||||
}
|
||||
|
||||
template <typename D, typename A, typename S>
|
||||
histogram &operator=(const histogram<D, A, S> &rhs) {
|
||||
template <typename A, typename S>
|
||||
explicit static_histogram(const dynamic_histogram<A, S> &rhs) : storage_(rhs.storage_) {
|
||||
detail::axes_assign(axes_, rhs.axes_);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
static_histogram &operator=(const static_histogram<Axes, S> &rhs) {
|
||||
if (static_cast<const void *>(this) != static_cast<const void *>(&rhs)) {
|
||||
detail::axes_assign(axes_, rhs.axes_);
|
||||
storage_ = rhs.storage_;
|
||||
@@ -79,30 +84,62 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename D, typename A, typename S>
|
||||
bool operator==(const histogram<D, A, S> &rhs) const {
|
||||
template <typename A, typename S>
|
||||
static_histogram &operator=(const dynamic_histogram<A, S> &rhs) {
|
||||
if (static_cast<const void *>(this) != static_cast<const void *>(&rhs)) {
|
||||
detail::axes_assign(axes_, rhs.axes_);
|
||||
storage_ = rhs.storage_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename A, typename S>
|
||||
bool operator==(const static_histogram<A, S> &rhs) const noexcept {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
bool operator==(const static_histogram<Axes, S> &rhs) const noexcept {
|
||||
return detail::axes_equal(axes_, rhs.axes_) && storage_ == rhs.storage_;
|
||||
}
|
||||
|
||||
template <typename D, typename A, typename S>
|
||||
bool operator!=(const histogram<D, A, S> &rhs) const {
|
||||
template <typename A, typename S>
|
||||
bool operator==(const dynamic_histogram<A, S> &rhs) const noexcept {
|
||||
return detail::axes_equal(axes_, rhs.axes_) && storage_ == rhs.storage_;
|
||||
}
|
||||
|
||||
template <typename A, typename S>
|
||||
bool operator!=(const static_histogram<A, S> &rhs) const noexcept {
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
template <typename D, typename A, typename S>
|
||||
histogram &operator+=(const histogram<D, A, S> &rhs) {
|
||||
template <typename A, typename S>
|
||||
bool operator!=(const dynamic_histogram<A, S> &rhs) const noexcept {
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
static_histogram &operator+=(const static_histogram<Axes, S> &rhs) {
|
||||
if (!detail::axes_equal(axes_, rhs.axes_))
|
||||
throw std::logic_error("axes of histograms differ");
|
||||
storage_ += rhs.storage_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
histogram &operator*=(const value_type rhs) {
|
||||
template <typename A, typename S>
|
||||
static_histogram &operator+=(const dynamic_histogram<A, S> &rhs) {
|
||||
if (!detail::axes_equal(axes_, rhs.axes_))
|
||||
throw std::logic_error("axes of histograms differ");
|
||||
storage_ += rhs.storage_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
static_histogram &operator*=(const value_type rhs) {
|
||||
storage_ *= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
histogram &operator/=(const value_type rhs) {
|
||||
static_histogram &operator/=(const value_type rhs) {
|
||||
storage_ *= 1.0 / rhs;
|
||||
return *this;
|
||||
}
|
||||
@@ -199,8 +236,8 @@ public:
|
||||
/// Returns a lower-dimensional histogram
|
||||
template <int N, typename... Rest>
|
||||
auto reduce_to(mpl::int_<N>, Rest...) const
|
||||
-> histogram<Static, detail::axes_select<Axes, mpl::vector<mpl::int_<N>, Rest...>>, Storage> {
|
||||
using HR = histogram<Static, detail::axes_select<Axes, mpl::vector<mpl::int_<N>, Rest...>>, Storage>;
|
||||
-> static_histogram<detail::axes_select<Axes, mpl::vector<mpl::int_<N>, Rest...>>, Storage> {
|
||||
using HR = static_histogram<detail::axes_select<Axes, mpl::vector<mpl::int_<N>, Rest...>>, Storage>;
|
||||
typename HR::axes_type axes;
|
||||
detail::axes_assign_subset<mpl::vector<mpl::int_<N>, Rest...>>(axes, axes_);
|
||||
auto hr = HR(std::move(axes));
|
||||
@@ -323,25 +360,26 @@ private:
|
||||
} while (m.next());
|
||||
}
|
||||
|
||||
template <typename D, typename A, typename S> friend class histogram;
|
||||
template <typename A, typename S> friend class static_histogram;
|
||||
template <typename A, typename S> friend class dynamic_histogram;
|
||||
friend class ::boost::serialization::access;
|
||||
template <typename Archive> void serialize(Archive &, unsigned);
|
||||
};
|
||||
|
||||
/// default static type factory
|
||||
template <typename... Axis>
|
||||
inline histogram<Static, mpl::vector<Axis...>>
|
||||
inline static_histogram<mpl::vector<Axis...>>
|
||||
make_static_histogram(Axis &&... axis) {
|
||||
using h = histogram<Static, mpl::vector<Axis...>>;
|
||||
using h = static_histogram<mpl::vector<Axis...>>;
|
||||
auto axes = typename h::axes_type(std::forward<Axis>(axis)...);
|
||||
return h(std::move(axes));
|
||||
}
|
||||
|
||||
/// static type factory with variable storage type
|
||||
template <typename Storage, typename... Axis>
|
||||
inline histogram<Static, mpl::vector<Axis...>, Storage>
|
||||
inline static_histogram<mpl::vector<Axis...>, Storage>
|
||||
make_static_histogram_with(Axis &&... axis) {
|
||||
using h = histogram<Static, mpl::vector<Axis...>, Storage>;
|
||||
using h = static_histogram<mpl::vector<Axis...>, Storage>;
|
||||
auto axes = typename h::axes_type(std::forward<Axis>(axis)...);
|
||||
return h(std::move(axes));
|
||||
}
|
||||
Reference in New Issue
Block a user