mirror of
https://github.com/boostorg/histogram.git
synced 2026-01-30 07:52:11 +00:00
missing files
This commit is contained in:
321
include/boost/histogram/histogram_impl_dynamic.hpp
Normal file
321
include/boost/histogram/histogram_impl_dynamic.hpp
Normal file
@@ -0,0 +1,321 @@
|
||||
// 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 <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/mpl/empty.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
|
||||
template <typename Axes, typename Storage>
|
||||
class histogram<Dynamic, Axes, Storage> {
|
||||
static_assert(!mpl::empty<Axes>::value, "at least one axis required");
|
||||
using size_pair = std::pair<std::size_t, std::size_t>;
|
||||
|
||||
public:
|
||||
using axis_type = typename make_variant_over<Axes>::type;
|
||||
using value_type = typename Storage::value_type;
|
||||
|
||||
private:
|
||||
using axes_type = std::vector<axis_type>;
|
||||
|
||||
public:
|
||||
histogram() = default;
|
||||
|
||||
template <typename... Axes1>
|
||||
explicit histogram(const Axes1 &... axes) : axes_({axis_type(axes)...}) {
|
||||
storage_ = Storage(field_count());
|
||||
}
|
||||
|
||||
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());
|
||||
storage_ = Storage(field_count());
|
||||
}
|
||||
|
||||
template <typename A, typename S>
|
||||
explicit histogram(const histogram<Dynamic, A, S> &rhs)
|
||||
: axes_(rhs.axes_.begin(), rhs.axes_.end()), storage_(rhs.storage_) {}
|
||||
|
||||
template <typename A, typename S>
|
||||
explicit histogram(histogram<Dynamic, A, S> &&rhs)
|
||||
: axes_(std::move(rhs.axes_)), storage_(std::move(rhs.storage_)) {}
|
||||
|
||||
template <typename A, typename S>
|
||||
histogram &operator=(const histogram<Dynamic, A, S> &rhs) {
|
||||
if (static_cast<const void *>(this) != static_cast<const void *>(&rhs)) {
|
||||
axes_ = rhs.axes_;
|
||||
storage_ = rhs.storage_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename A, typename S>
|
||||
histogram &operator=(histogram<Dynamic, A, S> &&rhs) {
|
||||
if (static_cast<const void *>(this) != static_cast<const void *>(&rhs)) {
|
||||
axes_ = std::move(rhs.axes_);
|
||||
storage_ = std::move(rhs.storage_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename A, typename S>
|
||||
bool operator==(const histogram<Dynamic, A, S> &rhs) const {
|
||||
if (mpl::empty<typename detail::intersection<Axes, A>::type>::value) {
|
||||
return false;
|
||||
}
|
||||
if (dim() != rhs.dim()) {
|
||||
return false;
|
||||
}
|
||||
if (!axes_equal_to(rhs.axes_)) {
|
||||
return false;
|
||||
}
|
||||
if (!(storage_ == rhs.storage_)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename A, typename S>
|
||||
bool operator!=(const histogram<Dynamic, A, S> &rhs) const {
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
template <type D, typename A, typename S>
|
||||
histogram &operator+=(const histogram<D, A, S> &rhs) {
|
||||
static_assert(
|
||||
!mpl::empty<typename detail::intersection<Axes, A>::type>::value,
|
||||
"histograms lack common axes types");
|
||||
if (dim() != rhs.dim()) {
|
||||
throw std::logic_error("dimensions of histograms differ");
|
||||
}
|
||||
if (size() != rhs.size()) {
|
||||
throw std::logic_error("sizes of histograms differ");
|
||||
}
|
||||
if (!axes_equal_to(rhs.axes_)) {
|
||||
throw std::logic_error("axes of histograms differ");
|
||||
}
|
||||
storage_ += rhs.storage_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
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...>(size_pair(0, 1), values...);
|
||||
if (p.second) {
|
||||
storage_.increase(p.first);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Iterator, typename = detail::is_iterator<Iterator>>
|
||||
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>(size_pair(0, 1), begin);
|
||||
if (p.second) {
|
||||
storage_.increase(p.first);
|
||||
}
|
||||
}
|
||||
|
||||
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...>(size_pair(0, 1), values...);
|
||||
if (p.second) {
|
||||
storage_.increase(p.first, w);
|
||||
}
|
||||
}
|
||||
|
||||
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>(size_pair(0, 1), begin);
|
||||
if (p.second) {
|
||||
storage_.increase(p.first, w);
|
||||
}
|
||||
}
|
||||
|
||||
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...>(size_pair(0, 1), indices...);
|
||||
if (p.second == 0) {
|
||||
throw std::out_of_range("invalid index");
|
||||
}
|
||||
return storage_.value(p.first);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename = detail::is_iterator<Iterator>>
|
||||
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>(size_pair(0, 1), begin);
|
||||
if (p.second == 0) {
|
||||
throw std::out_of_range("invalid index");
|
||||
}
|
||||
return storage_.value(p.first);
|
||||
}
|
||||
|
||||
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...>(size_pair(0, 1), indices...);
|
||||
if (p.second == 0) {
|
||||
throw std::out_of_range("invalid index");
|
||||
}
|
||||
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>(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 <unsigned N = 0u> 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 <typename Unary> void for_each_axis(Unary &unary) const {
|
||||
for (const auto &a : axes_) {
|
||||
apply_visitor(detail::unary_visitor<Unary>(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 <typename A> bool axes_equal_to(const A &rhs) const {
|
||||
detail::cmp_axis ca;
|
||||
for (unsigned i = 0; i < dim(); ++i) {
|
||||
if (!apply_visitor(ca, axes_[i], rhs[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <template <class, class> class Lin, typename Value>
|
||||
struct lin_visitor : public static_visitor<size_pair> {
|
||||
mutable size_pair pa;
|
||||
const Value &val;
|
||||
lin_visitor(const size_pair &p, const Value &v) : pa(p), val(v) {}
|
||||
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>
|
||||
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)]);
|
||||
return apply_lin<Lin, Rest...>(std::move(p), rest...);
|
||||
}
|
||||
|
||||
template <template <class, class> class Lin>
|
||||
size_pair apply_lin(size_pair &&p) const {
|
||||
return p;
|
||||
}
|
||||
|
||||
template <template <class, class> class Lin, typename Iterator>
|
||||
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;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
friend struct storage_access;
|
||||
|
||||
template <type D, typename A, typename S> friend class histogram;
|
||||
|
||||
template <typename Archiv, typename A, typename S>
|
||||
friend void serialize(Archiv &, histogram<Dynamic, A, S> &, unsigned);
|
||||
};
|
||||
|
||||
template <typename... Axes>
|
||||
inline histogram<Dynamic, default_axes> make_dynamic_histogram(Axes &&... axes) {
|
||||
return histogram<Dynamic, default_axes>(std::forward<Axes>(axes)...);
|
||||
}
|
||||
|
||||
template <typename Storage, typename... Axes>
|
||||
inline histogram<Dynamic, default_axes, Storage>
|
||||
make_dynamic_histogram_with(Axes &&... axes) {
|
||||
return histogram<Dynamic, default_axes, Storage>(std::forward<Axes>(axes)...);
|
||||
}
|
||||
} // namespace histogram
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
235
include/boost/histogram/histogram_impl_static.hpp
Normal file
235
include/boost/histogram/histogram_impl_static.hpp
Normal file
@@ -0,0 +1,235 @@
|
||||
// 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_IMPL_STATIC_HPP_
|
||||
#define _BOOST_HISTOGRAM_HISTOGRAM_IMPL_STATIC_HPP_
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/fusion/adapted/mpl.hpp>
|
||||
#include <boost/fusion/algorithm.hpp>
|
||||
#include <boost/fusion/container/vector/convert.hpp>
|
||||
#include <boost/fusion/include/algorithm.hpp>
|
||||
#include <boost/fusion/include/as_vector.hpp>
|
||||
#include <boost/fusion/include/comparison.hpp>
|
||||
#include <boost/fusion/include/mpl.hpp>
|
||||
#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/storage/adaptive_storage.hpp>
|
||||
#include <boost/mpl/empty.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
|
||||
template <typename Axes, typename Storage>
|
||||
class histogram<Static, Axes, Storage> {
|
||||
static_assert(!mpl::empty<Axes>::value, "at least one axis required");
|
||||
using size_pair = std::pair<std::size_t, std::size_t>;
|
||||
using axes_size = typename fusion::result_of::size<Axes>::type;
|
||||
|
||||
public:
|
||||
using value_type = typename Storage::value_type;
|
||||
|
||||
private:
|
||||
using axes_type = typename fusion::result_of::as_vector<Axes>::type;
|
||||
|
||||
public:
|
||||
histogram() = default;
|
||||
|
||||
template <typename... Axes1>
|
||||
explicit histogram(const Axes1 &... axes) : axes_(axes...) {
|
||||
storage_ = Storage(field_count());
|
||||
}
|
||||
|
||||
histogram(const histogram &rhs) = default;
|
||||
histogram(histogram &&rhs) = default;
|
||||
histogram &operator=(const histogram &rhs) = default;
|
||||
histogram &operator=(histogram &&rhs) = default;
|
||||
|
||||
template <typename S>
|
||||
explicit histogram(const histogram<Static, Axes, S> &rhs)
|
||||
: axes_(rhs.axes_), storage_(rhs.storage_) {}
|
||||
|
||||
template <typename S>
|
||||
explicit histogram(histogram<Static, Axes, S> &&rhs)
|
||||
: axes_(std::move(rhs.axes_)), storage_(std::move(rhs.storage_)) {}
|
||||
|
||||
template <typename S>
|
||||
histogram &operator=(const histogram<Static, Axes, S> &rhs) {
|
||||
if (static_cast<const void *>(this) != static_cast<const void *>(&rhs)) {
|
||||
axes_ = rhs.axes_;
|
||||
storage_ = rhs.storage_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename S> histogram &operator=(histogram<Static, Axes, S> &&rhs) {
|
||||
if (static_cast<const void *>(this) != static_cast<const void *>(&rhs)) {
|
||||
axes_ = std::move(rhs.axes_);
|
||||
storage_ = std::move(rhs.storage_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename A, typename S>
|
||||
bool operator==(const histogram<Static, A, S> &rhs) const {
|
||||
if (!axes_equal_to(rhs.axes_)) {
|
||||
return false;
|
||||
}
|
||||
return storage_ == rhs.storage_;
|
||||
}
|
||||
|
||||
template <typename A, typename S>
|
||||
bool operator!=(const histogram<Static, A, S> &rhs) const {
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
histogram &operator+=(const histogram<Static, Axes, S> &rhs) {
|
||||
if (!axes_equal_to(rhs.axes_)) {
|
||||
throw std::logic_error("axes of histograms differ");
|
||||
}
|
||||
storage_ += rhs.storage_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename... Values> void fill(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...>(size_pair(0, 1), values...);
|
||||
if (p.second) {
|
||||
storage_.increase(p.first);
|
||||
}
|
||||
}
|
||||
|
||||
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...>(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) == axes_size::value,
|
||||
"number of arguments does not match histogram dimension");
|
||||
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 storage_.value(p.first);
|
||||
}
|
||||
|
||||
template <typename... Indices> value_type variance(Indices... indices) const {
|
||||
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...>(size_pair(0, 1), indices...);
|
||||
if (p.second == 0) {
|
||||
throw std::out_of_range("invalid index");
|
||||
}
|
||||
return storage_.variance(p.first);
|
||||
}
|
||||
|
||||
/// Number of axes (dimensions) of histogram
|
||||
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(); }
|
||||
|
||||
/// 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;
|
||||
}
|
||||
|
||||
template <unsigned N = 0>
|
||||
typename std::add_const<
|
||||
typename fusion::result_of::value_at_c<axes_type, N>::type>::type &
|
||||
axis() const {
|
||||
static_assert(N < axes_size::value, "axis index out of range");
|
||||
return fusion::at_c<N>(axes_);
|
||||
}
|
||||
|
||||
/// Apply unary functor/function to each axis
|
||||
template <typename Unary> void for_each_axis(Unary &unary) const {
|
||||
fusion::for_each(axes_, unary);
|
||||
}
|
||||
|
||||
private:
|
||||
axes_type axes_;
|
||||
Storage storage_;
|
||||
|
||||
std::size_t field_count() const {
|
||||
detail::field_count fc;
|
||||
fusion::for_each(axes_, fc);
|
||||
return fc.value;
|
||||
}
|
||||
|
||||
template <typename A> bool axes_equal_to(const A & /*unused*/) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool axes_equal_to(const axes_type &other_axes) const {
|
||||
return axes_ == other_axes;
|
||||
}
|
||||
|
||||
template <template <class, class> class Lin, typename First, typename... Rest>
|
||||
size_pair apply_lin(size_pair &&p, const First &x,
|
||||
const Rest &... rest) const {
|
||||
Lin<typename fusion::result_of::value_at_c<
|
||||
axes_type, (axes_size::value - 1 - sizeof...(Rest))>::type,
|
||||
First>::apply(p.first, p.second,
|
||||
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>
|
||||
size_pair apply_lin(size_pair &&p) const {
|
||||
return p;
|
||||
}
|
||||
|
||||
template <type D, typename A, typename S> friend class histogram;
|
||||
|
||||
template <class Archive, class S, class A>
|
||||
friend void serialize(Archive &, histogram<Static, S, A> &, unsigned);
|
||||
};
|
||||
|
||||
/// default static type factory
|
||||
template <typename... Axes>
|
||||
inline histogram<Static, mpl::vector<Axes...>>
|
||||
make_static_histogram(const Axes &... axes) {
|
||||
return histogram<Static, mpl::vector<Axes...>>(axes...);
|
||||
}
|
||||
|
||||
/// static type factory with variable storage type
|
||||
template <typename Storage, typename... Axes>
|
||||
inline histogram<Static, mpl::vector<Axes...>, Storage>
|
||||
make_static_histogram_with(const Axes &... axes) {
|
||||
return histogram<Static, mpl::vector<Axes...>, Storage>(axes...);
|
||||
}
|
||||
} // namespace histogram
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user