mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-12 13:41:48 +00:00
switched to lazy interval_view to improve performance
This commit is contained in:
parent
8cb08efa7b
commit
fe4bd1701d
@ -7,10 +7,10 @@
|
|||||||
#ifndef _BOOST_HISTOGRAM_AXIS_ANY_HPP_
|
#ifndef _BOOST_HISTOGRAM_AXIS_ANY_HPP_
|
||||||
#define _BOOST_HISTOGRAM_AXIS_ANY_HPP_
|
#define _BOOST_HISTOGRAM_AXIS_ANY_HPP_
|
||||||
|
|
||||||
|
#include <boost/histogram/axis/interval.hpp>
|
||||||
#include <boost/histogram/axis/iterator.hpp>
|
#include <boost/histogram/axis/iterator.hpp>
|
||||||
#include <boost/histogram/detail/axis_visitor.hpp>
|
#include <boost/histogram/detail/axis_visitor.hpp>
|
||||||
#include <boost/histogram/detail/cat.hpp>
|
#include <boost/histogram/detail/cat.hpp>
|
||||||
#include <boost/histogram/interval.hpp>
|
|
||||||
#include <boost/mpl/contains.hpp>
|
#include <boost/mpl/contains.hpp>
|
||||||
#include <boost/utility/string_view.hpp>
|
#include <boost/utility/string_view.hpp>
|
||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
@ -54,36 +54,47 @@ struct set_label : public static_visitor<void> {
|
|||||||
template <typename A> void operator()(A &a) const { a.label(label); }
|
template <typename A> void operator()(A &a) const { a.label(label); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> struct index : public static_visitor<int> {
|
struct index : public static_visitor<int> {
|
||||||
const T &t;
|
const double x;
|
||||||
explicit index(const T &arg) : t(arg) {}
|
explicit index(const double arg) : x(arg) {}
|
||||||
template <typename Axis> int operator()(const Axis &a) const {
|
template <typename Axis> int operator()(const Axis &a) const {
|
||||||
return impl(std::is_convertible<T, typename Axis::value_type>(), a);
|
return impl(std::is_convertible<double, typename Axis::value_type>(), a);
|
||||||
}
|
}
|
||||||
template <typename Axis> int impl(std::true_type, const Axis &a) const {
|
template <typename Axis> int impl(std::true_type, const Axis &a) const {
|
||||||
return a.index(t);
|
return a.index(x);
|
||||||
}
|
}
|
||||||
template <typename Axis> int impl(std::false_type, const Axis &) const {
|
template <typename Axis> int impl(std::false_type, const Axis &) const {
|
||||||
throw std::runtime_error(::boost::histogram::detail::cat(
|
throw std::runtime_error(::boost::histogram::detail::cat(
|
||||||
"fill argument not convertible to axis value type: ",
|
"cannot convert value_type ",
|
||||||
boost::typeindex::type_id<Axis>().pretty_name(), ", ",
|
boost::typeindex::type_id<typename Axis::value_type>().pretty_name(),
|
||||||
boost::typeindex::type_id<T>().pretty_name()));
|
" of ",
|
||||||
|
boost::typeindex::type_id<Axis>().pretty_name(),
|
||||||
|
" to double")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bin : public static_visitor<axis::interval<double>> {
|
struct eval : public static_visitor<std::function<double(int)>> {
|
||||||
using double_interval = axis::interval<double>;
|
template <typename Axis> std::function<double(int)> operator()(const Axis &a) const {
|
||||||
const int i;
|
return impl(std::integral_constant<bool,
|
||||||
bin(const int v) : i(v) {}
|
(std::is_convertible<typename Axis::value_type, double>::value &&
|
||||||
template <typename A> double_interval operator()(const A &a) const {
|
std::is_same<
|
||||||
return impl(is_convertible<typename A::bin_type, double_interval>(),
|
typename Axis::bin_type,
|
||||||
std::forward<typename A::bin_type>(a[i]));
|
interval_view<typename Axis::value_type>
|
||||||
|
>::value)
|
||||||
|
>(), a);
|
||||||
}
|
}
|
||||||
template <typename B> double_interval impl(true_type, B &&b) const {
|
template <typename Axis> std::function<double(int)> impl(std::true_type, const Axis &a) const {
|
||||||
return b;
|
return [&a](int i) -> double { return a[i].lower(); } ;
|
||||||
}
|
}
|
||||||
template <typename B> double_interval impl(false_type, B &&) const {
|
template <typename Axis> std::function<double(int)> impl(std::false_type, const Axis &) const {
|
||||||
throw std::runtime_error("cannot convert bin_type to interval<double>");
|
throw std::runtime_error(::boost::histogram::detail::cat(
|
||||||
|
"cannot convert bin_type ",
|
||||||
|
boost::typeindex::type_id<typename Axis::bin_type>().pretty_name(),
|
||||||
|
" of ",
|
||||||
|
boost::typeindex::type_id<Axis>().pretty_name(),
|
||||||
|
" to interval_view<double>")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@ -95,7 +106,7 @@ template <typename Axes> class any : public make_variant_over<Axes>::type {
|
|||||||
public:
|
public:
|
||||||
using types = typename base_type::types;
|
using types = typename base_type::types;
|
||||||
using value_type = double;
|
using value_type = double;
|
||||||
using bin_type = interval<double>;
|
using bin_type = interval_view<double>;
|
||||||
using const_iterator = iterator_over<any>;
|
using const_iterator = iterator_over<any>;
|
||||||
using const_reverse_iterator = reverse_iterator_over<any>;
|
using const_reverse_iterator = reverse_iterator_over<any>;
|
||||||
|
|
||||||
@ -112,15 +123,15 @@ public:
|
|||||||
template <typename T, typename = typename std::enable_if<
|
template <typename T, typename = typename std::enable_if<
|
||||||
mpl::contains<types, T>::value>::type>
|
mpl::contains<types, T>::value>::type>
|
||||||
any &operator=(const T &t) {
|
any &operator=(const T &t) {
|
||||||
// ugly workaround for compiler bug
|
base_type::operator=(t);
|
||||||
return reinterpret_cast<any &>(base_type::operator=(t));
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename = typename std::enable_if<
|
template <typename T, typename = typename std::enable_if<
|
||||||
mpl::contains<types, T>::value>::type>
|
mpl::contains<types, T>::value>::type>
|
||||||
any &operator=(T &&t) {
|
any &operator=(T &&t) {
|
||||||
// ugly workaround for compiler bug
|
base_type::operator=(std::move(t));
|
||||||
return reinterpret_cast<any &>(base_type::operator=(std::move(t)));
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
int size() const { return apply_visitor(detail::size(), *this); }
|
int size() const { return apply_visitor(detail::size(), *this); }
|
||||||
@ -131,7 +142,7 @@ public:
|
|||||||
|
|
||||||
// note: this only works for axes with compatible value type
|
// note: this only works for axes with compatible value type
|
||||||
int index(const value_type x) const {
|
int index(const value_type x) const {
|
||||||
return apply_visitor(detail::index<value_type>(x), *this);
|
return apply_visitor(detail::index(x), *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
string_view label() const {
|
string_view label() const {
|
||||||
@ -143,9 +154,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this only works for axes with compatible bin type
|
// this only works for axes with compatible bin type
|
||||||
// and will raise an error otherwise
|
// and will throw a runtime_error otherwise
|
||||||
bin_type operator[](const int i) const {
|
bin_type operator[](const int i) const {
|
||||||
return apply_visitor(detail::bin(i), *this);
|
auto eval = apply_visitor(detail::eval(), *this);
|
||||||
|
return bin_type(i, eval);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const any &rhs) const {
|
bool operator==(const any &rhs) const {
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <boost/bimap.hpp>
|
#include <boost/bimap.hpp>
|
||||||
|
#include <boost/histogram/axis/interval.hpp>
|
||||||
#include <boost/histogram/axis/iterator.hpp>
|
#include <boost/histogram/axis/iterator.hpp>
|
||||||
#include <boost/histogram/detail/meta.hpp>
|
#include <boost/histogram/detail/meta.hpp>
|
||||||
#include <boost/histogram/interval.hpp>
|
|
||||||
#include <boost/math/constants/constants.hpp>
|
#include <boost/math/constants/constants.hpp>
|
||||||
#include <boost/utility/string_view.hpp>
|
#include <boost/utility/string_view.hpp>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -36,7 +36,7 @@ namespace axis {
|
|||||||
|
|
||||||
enum class uoflow { off = false, on = true };
|
enum class uoflow { off = false, on = true };
|
||||||
|
|
||||||
/// Base class for all axes, uses CRTP.
|
/// Base class for all axes, uses CRTP to inject iterator logic.
|
||||||
template <typename Derived> class axis_base {
|
template <typename Derived> class axis_base {
|
||||||
public:
|
public:
|
||||||
using const_iterator = iterator_over<Derived>;
|
using const_iterator = iterator_over<Derived>;
|
||||||
@ -102,7 +102,7 @@ private:
|
|||||||
template <class Archive> void serialize(Archive &, unsigned);
|
template <class Archive> void serialize(Archive &, unsigned);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Base class for axes with overflow/underflow bins, uses CRTP.
|
/// Base class for axes with optional under-/overflow bins, uses CRTP.
|
||||||
template <typename Derived> class axis_base_uoflow : public axis_base<Derived> {
|
template <typename Derived> class axis_base_uoflow : public axis_base<Derived> {
|
||||||
using base_type = axis_base<Derived>;
|
using base_type = axis_base<Derived>;
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
axis_base_uoflow(unsigned n, string_view label, enum uoflow uo)
|
axis_base_uoflow(unsigned n, string_view label, enum uoflow uo)
|
||||||
: base_type(n, label), shape_(n + 2u * static_cast<unsigned>(uo)) {}
|
: base_type(n, label), shape_(n + 2 * static_cast<int>(uo)) {}
|
||||||
|
|
||||||
axis_base_uoflow() = default;
|
axis_base_uoflow() = default;
|
||||||
axis_base_uoflow(const axis_base_uoflow &) = default;
|
axis_base_uoflow(const axis_base_uoflow &) = default;
|
||||||
@ -202,7 +202,7 @@ class regular : public axis_base_uoflow<regular<RealType, Transform>>,
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type = RealType;
|
using value_type = RealType;
|
||||||
using bin_type = interval<value_type>;
|
using bin_type = interval_view<value_type>;
|
||||||
|
|
||||||
/** Construct axis with n bins over real range [lower, upper).
|
/** Construct axis with n bins over real range [lower, upper).
|
||||||
*
|
*
|
||||||
@ -241,9 +241,9 @@ public:
|
|||||||
: -1;
|
: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the starting edge of the bin.
|
/// Returns the bin interval.
|
||||||
bin_type operator[](int idx) const noexcept {
|
bin_type operator[](int idx) const noexcept {
|
||||||
auto eval = [this](int i) {
|
return bin_type(idx, [this](int i) {
|
||||||
const auto n = base_type::size();
|
const auto n = base_type::size();
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
return this->inverse(-std::numeric_limits<value_type>::infinity());
|
return this->inverse(-std::numeric_limits<value_type>::infinity());
|
||||||
@ -251,8 +251,7 @@ public:
|
|||||||
return this->inverse(std::numeric_limits<value_type>::infinity());
|
return this->inverse(std::numeric_limits<value_type>::infinity());
|
||||||
const auto z = value_type(i) / n;
|
const auto z = value_type(i) / n;
|
||||||
return this->inverse((1.0 - z) * min_ + z * (min_ + delta_ * n));
|
return this->inverse((1.0 - z) * min_ + z * (min_ + delta_ * n));
|
||||||
};
|
});
|
||||||
return {eval(idx), eval(idx + 1)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const regular &o) const noexcept {
|
bool operator==(const regular &o) const noexcept {
|
||||||
@ -260,6 +259,7 @@ public:
|
|||||||
min_ == o.min_ && delta_ == o.delta_;
|
min_ == o.min_ && delta_ == o.delta_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Access properties of the transform.
|
||||||
const Transform &transform() const noexcept {
|
const Transform &transform() const noexcept {
|
||||||
return static_cast<const Transform &>(*this);
|
return static_cast<const Transform &>(*this);
|
||||||
}
|
}
|
||||||
@ -283,7 +283,7 @@ class circular : public axis_base<circular<RealType>> {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type = RealType;
|
using value_type = RealType;
|
||||||
using bin_type = interval<value_type>;
|
using bin_type = interval_view<value_type>;
|
||||||
|
|
||||||
/** Constructor for n bins with an optional offset.
|
/** Constructor for n bins with an optional offset.
|
||||||
*
|
*
|
||||||
@ -313,11 +313,10 @@ public:
|
|||||||
|
|
||||||
/// Returns the starting edge of the bin.
|
/// Returns the starting edge of the bin.
|
||||||
bin_type operator[](int idx) const {
|
bin_type operator[](int idx) const {
|
||||||
auto eval = [this](int i) {
|
return bin_type(idx, [this](int i) {
|
||||||
const value_type z = value_type(i) / base_type::size();
|
const value_type z = value_type(i) / base_type::size();
|
||||||
return z * perimeter_ + phase_;
|
return z * perimeter_ + phase_;
|
||||||
};
|
});
|
||||||
return {eval(idx), eval(idx + 1)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const circular &o) const noexcept {
|
bool operator==(const circular &o) const noexcept {
|
||||||
@ -346,7 +345,7 @@ class variable : public axis_base_uoflow<variable<RealType>> {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type = RealType;
|
using value_type = RealType;
|
||||||
using bin_type = interval<value_type>;
|
using bin_type = interval_view<value_type>;
|
||||||
|
|
||||||
/** Construct an axis from bin edges.
|
/** Construct an axis from bin edges.
|
||||||
*
|
*
|
||||||
@ -397,7 +396,7 @@ public:
|
|||||||
|
|
||||||
/// Returns the starting edge of the bin.
|
/// Returns the starting edge of the bin.
|
||||||
bin_type operator[](int idx) const {
|
bin_type operator[](int idx) const {
|
||||||
auto eval = [this](int i) {
|
return bin_type(idx, [this](int i) {
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
return -std::numeric_limits<value_type>::infinity();
|
return -std::numeric_limits<value_type>::infinity();
|
||||||
}
|
}
|
||||||
@ -405,8 +404,7 @@ public:
|
|||||||
return std::numeric_limits<value_type>::infinity();
|
return std::numeric_limits<value_type>::infinity();
|
||||||
}
|
}
|
||||||
return x_[i];
|
return x_[i];
|
||||||
};
|
});
|
||||||
return {eval(idx), eval(idx + 1)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const variable &o) const noexcept {
|
bool operator==(const variable &o) const noexcept {
|
||||||
@ -434,7 +432,7 @@ class integer : public axis_base_uoflow<integer<IntType>> {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type = IntType;
|
using value_type = IntType;
|
||||||
using bin_type = interval<value_type>;
|
using bin_type = interval_view<value_type>;
|
||||||
|
|
||||||
/** Construct axis over a semi-open integer interval [lower, upper).
|
/** Construct axis over a semi-open integer interval [lower, upper).
|
||||||
*
|
*
|
||||||
@ -465,7 +463,7 @@ public:
|
|||||||
|
|
||||||
/// Returns the integer that is mapped to the bin index.
|
/// Returns the integer that is mapped to the bin index.
|
||||||
bin_type operator[](int idx) const {
|
bin_type operator[](int idx) const {
|
||||||
auto eval = [this](int i) {
|
return bin_type(idx, [this](int i) {
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
return -std::numeric_limits<value_type>::max();
|
return -std::numeric_limits<value_type>::max();
|
||||||
}
|
}
|
||||||
@ -473,8 +471,7 @@ public:
|
|||||||
return std::numeric_limits<value_type>::max();
|
return std::numeric_limits<value_type>::max();
|
||||||
}
|
}
|
||||||
return min_ + i;
|
return min_ + i;
|
||||||
};
|
});
|
||||||
return {eval(idx), eval(idx + 1)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const integer &o) const noexcept {
|
bool operator==(const integer &o) const noexcept {
|
||||||
|
46
include/boost/histogram/axis/interval.hpp
Normal file
46
include/boost/histogram/axis/interval.hpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// 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_AXIS_INTERVAL_HPP_
|
||||||
|
#define _BOOST_HISTOGRAM_AXIS_INTERVAL_HPP_
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace histogram {
|
||||||
|
namespace axis {
|
||||||
|
|
||||||
|
template <typename T> class interval_view {
|
||||||
|
public:
|
||||||
|
interval_view(int idx, std::function<T(int)> eval) : idx_(idx), eval_(eval) {}
|
||||||
|
|
||||||
|
interval_view(const interval_view &) = default;
|
||||||
|
interval_view &operator=(const interval_view &) = default;
|
||||||
|
interval_view(interval_view &&) = default;
|
||||||
|
interval_view &operator=(interval_view &&) = default;
|
||||||
|
|
||||||
|
T lower() const noexcept { return eval_(idx_); }
|
||||||
|
T upper() const noexcept { return eval_(idx_ + 1); }
|
||||||
|
T width() const noexcept { return upper() - lower(); }
|
||||||
|
|
||||||
|
bool operator==(const interval_view &rhs) const noexcept {
|
||||||
|
return lower() == rhs.lower() && upper() == rhs.upper();
|
||||||
|
}
|
||||||
|
bool operator!=(const interval_view &rhs) const noexcept {
|
||||||
|
return !operator==(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const int idx_;
|
||||||
|
const std::function<T(int)> eval_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace axis
|
||||||
|
} // namespace histogram
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif
|
@ -10,8 +10,8 @@
|
|||||||
#define _BOOST_HISTOGRAM_AXIS_OSTREAM_OPERATORS_HPP_
|
#define _BOOST_HISTOGRAM_AXIS_OSTREAM_OPERATORS_HPP_
|
||||||
|
|
||||||
#include <boost/histogram/axis/axis.hpp>
|
#include <boost/histogram/axis/axis.hpp>
|
||||||
|
#include <boost/histogram/axis/interval.hpp>
|
||||||
#include <boost/histogram/detail/utility.hpp>
|
#include <boost/histogram/detail/utility.hpp>
|
||||||
#include <boost/histogram/interval.hpp>
|
|
||||||
#include <boost/math/constants/constants.hpp>
|
#include <boost/math/constants/constants.hpp>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
@ -26,6 +26,12 @@ inline string_view to_string(const transform::sqrt &) { return {"_sqrt", 5}; }
|
|||||||
inline string_view to_string(const transform::cos &) { return {"_cos", 4}; }
|
inline string_view to_string(const transform::cos &) { return {"_cos", 4}; }
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline std::ostream &operator<<(std::ostream &os, const interval_view<T> &i) {
|
||||||
|
os << "[" << i.lower() << ", " << i.upper() << ")";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename RealType, typename Transform>
|
template <typename RealType, typename Transform>
|
||||||
inline std::ostream &operator<<(std::ostream &os,
|
inline std::ostream &operator<<(std::ostream &os,
|
||||||
const regular<RealType, Transform> &a) {
|
const regular<RealType, Transform> &a) {
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include <boost/fusion/include/is_sequence.hpp>
|
#include <boost/fusion/include/is_sequence.hpp>
|
||||||
#include <boost/fusion/include/size.hpp>
|
#include <boost/fusion/include/size.hpp>
|
||||||
#include <boost/fusion/support/is_sequence.hpp>
|
#include <boost/fusion/support/is_sequence.hpp>
|
||||||
#include <boost/histogram/interval.hpp>
|
#include <boost/histogram/axis/interval.hpp>
|
||||||
#include <boost/mpl/bool.hpp>
|
#include <boost/mpl/bool.hpp>
|
||||||
#include <boost/mpl/contains.hpp>
|
#include <boost/mpl/contains.hpp>
|
||||||
#include <boost/variant/get.hpp>
|
#include <boost/variant/get.hpp>
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
// 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_INTERVAL_HPP_
|
|
||||||
#define _BOOST_HISTOGRAM_INTERVAL_HPP_
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace histogram {
|
|
||||||
namespace axis {
|
|
||||||
|
|
||||||
template <typename T> class interval {
|
|
||||||
public:
|
|
||||||
interval() = default;
|
|
||||||
interval(const interval &) = default;
|
|
||||||
interval &operator=(const interval &) = default;
|
|
||||||
interval(interval &&) = default;
|
|
||||||
interval &operator=(interval &&) = default;
|
|
||||||
|
|
||||||
interval(const T &x, const T &y) : a(x), b(y) {}
|
|
||||||
interval(T &&x, T &&y) : a(std::move(x)), b(std::move(y)) {}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
interval(const interval<U> &i) : a(i.lower()), b(i.upper()) {}
|
|
||||||
|
|
||||||
const T &lower() const noexcept { return a; }
|
|
||||||
const T &upper() const noexcept { return b; }
|
|
||||||
|
|
||||||
bool operator==(const interval &i) const noexcept {
|
|
||||||
return a == i.a && b == i.b;
|
|
||||||
}
|
|
||||||
bool operator!=(const interval &i) const noexcept { return !operator==(i); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
T a, b;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace axis
|
|
||||||
} // namespace histogram
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif
|
|
@ -55,25 +55,14 @@ generic_iterator make_generic_iterator(bp::object self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct axis_interval_to_python
|
struct axis_interval_view_to_python
|
||||||
{
|
{
|
||||||
static PyObject* convert(const bha::interval<T> &i)
|
static PyObject* convert(const bha::interval_view<T> &i)
|
||||||
{
|
{
|
||||||
return bp::incref(bp::make_tuple(i.lower(), i.upper()).ptr());
|
return bp::incref(bp::make_tuple(i.lower(), i.upper()).ptr());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct pair_int_axis_interval_to_python
|
|
||||||
{
|
|
||||||
static PyObject* convert(const std::pair<int, bha::interval<T>> &p)
|
|
||||||
{
|
|
||||||
return bp::incref(bp::make_tuple(
|
|
||||||
p.first, bp::make_tuple(p.second.lower(), p.second.upper())
|
|
||||||
).ptr());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bp::object variable_init(bp::tuple args, bp::dict kwargs) {
|
bp::object variable_init(bp::tuple args, bp::dict kwargs) {
|
||||||
bp::object self = args[0];
|
bp::object self = args[0];
|
||||||
|
|
||||||
@ -263,23 +252,13 @@ void register_axis_types() {
|
|||||||
docstring_options dopt(true, true, false);
|
docstring_options dopt(true, true, false);
|
||||||
|
|
||||||
to_python_converter<
|
to_python_converter<
|
||||||
bha::interval<int>,
|
bha::interval_view<int>,
|
||||||
axis_interval_to_python<int>
|
axis_interval_view_to_python<int>
|
||||||
>();
|
>();
|
||||||
|
|
||||||
to_python_converter<
|
to_python_converter<
|
||||||
bha::interval<double>,
|
bha::interval_view<double>,
|
||||||
axis_interval_to_python<double>
|
axis_interval_view_to_python<double>
|
||||||
>();
|
|
||||||
|
|
||||||
to_python_converter<
|
|
||||||
std::pair<int, bha::interval<int>>,
|
|
||||||
pair_int_axis_interval_to_python<int>
|
|
||||||
>();
|
|
||||||
|
|
||||||
to_python_converter<
|
|
||||||
std::pair<int, bha::interval<double>>,
|
|
||||||
pair_int_axis_interval_to_python<double>
|
|
||||||
>();
|
>();
|
||||||
|
|
||||||
class_<generic_iterator>("generic_iterator", init<object>())
|
class_<generic_iterator>("generic_iterator", init<object>())
|
||||||
|
@ -23,18 +23,6 @@
|
|||||||
#define BOOST_TEST_NOT(expr) BOOST_TEST(!(expr))
|
#define BOOST_TEST_NOT(expr) BOOST_TEST(!(expr))
|
||||||
#define BOOST_TEST_IS_CLOSE(a, b, eps) BOOST_TEST(std::abs(a - b) < eps)
|
#define BOOST_TEST_IS_CLOSE(a, b, eps) BOOST_TEST(std::abs(a - b) < eps)
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace histogram {
|
|
||||||
namespace axis {
|
|
||||||
template <typename T>
|
|
||||||
std::ostream &operator<<(std::ostream &os, const interval<T> &i) {
|
|
||||||
os << "[" << i.lower() << ", " << i.upper() << ")";
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
} // namespace axis
|
|
||||||
} // namespace histogram
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
template <typename Axis>
|
template <typename Axis>
|
||||||
void test_axis_iterator(const Axis &a, int begin, int end) {
|
void test_axis_iterator(const Axis &a, int begin, int end) {
|
||||||
auto it = a.begin();
|
auto it = a.begin();
|
||||||
@ -239,6 +227,7 @@ int main() {
|
|||||||
test_axis_iterator(axis::integer<>(0, 4, ""), 0, 4);
|
test_axis_iterator(axis::integer<>(0, 4, ""), 0, 4);
|
||||||
test_axis_iterator(axis::category<>({A, B, C}, ""), 0, 3);
|
test_axis_iterator(axis::category<>({A, B, C}, ""), 0, 3);
|
||||||
test_axis_iterator(any_axis_type(axis::regular<>(5, 0, 1)), 0, 5);
|
test_axis_iterator(any_axis_type(axis::regular<>(5, 0, 1)), 0, 5);
|
||||||
|
BOOST_TEST_THROWS(any_axis_type(axis::category<>({A, B, C}))[0], std::runtime_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// any_axis_type_copyable
|
// any_axis_type_copyable
|
||||||
|
@ -882,8 +882,7 @@ int main() {
|
|||||||
{
|
{
|
||||||
enum { A, B };
|
enum { A, B };
|
||||||
auto c = make_dynamic_histogram(axis::category<>({A, B}));
|
auto c = make_dynamic_histogram(axis::category<>({A, B}));
|
||||||
BOOST_TEST_THROWS(c.axis()[0].lower(), std::runtime_error);
|
BOOST_TEST_THROWS(c.axis()[0], std::runtime_error);
|
||||||
BOOST_TEST_THROWS(c.axis()[0].upper(), std::runtime_error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// reduce
|
// reduce
|
||||||
|
Loading…
x
Reference in New Issue
Block a user