mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-11 13:14:06 +00:00
fixed reduce function
This commit is contained in:
parent
7e8b2bb403
commit
c07162e7a8
@ -91,9 +91,10 @@ private:
|
||||
friend class boost::iterator_core_access;
|
||||
};
|
||||
|
||||
/// Common base class for axes.
|
||||
/// Common base class for all axes.
|
||||
template <bool UOFlow> class axis_base;
|
||||
|
||||
/// Specialization with overflow/underflow bins.
|
||||
template <> class axis_base<true> {
|
||||
public:
|
||||
/// Returns the number of bins, excluding overflow/underflow.
|
||||
@ -149,6 +150,7 @@ private:
|
||||
template <class Archive> void serialize(Archive &, unsigned);
|
||||
};
|
||||
|
||||
/// Specialization without overflow/underflow bins.
|
||||
template <> class axis_base<false> {
|
||||
public:
|
||||
/// Returns the number of bins, excluding overflow/underflow.
|
||||
|
@ -21,7 +21,7 @@ inline std::ostream &operator<<(std::ostream &os, const regular<RealType> &a) {
|
||||
os << "regular(" << a.bins() << ", " << a[0] << ", " << a[a.bins()];
|
||||
if (!a.label().empty()) {
|
||||
os << ", label=";
|
||||
detail::escape(os, a.label());
|
||||
::boost::histogram::detail::escape(os, a.label());
|
||||
}
|
||||
if (!a.uoflow()) {
|
||||
os << ", uoflow=False";
|
||||
@ -41,7 +41,7 @@ inline std::ostream &operator<<(std::ostream &os, const circular<RealType> &a) {
|
||||
}
|
||||
if (!a.label().empty()) {
|
||||
os << ", label=";
|
||||
detail::escape(os, a.label());
|
||||
::boost::histogram::detail::escape(os, a.label());
|
||||
}
|
||||
os << ")";
|
||||
return os;
|
||||
@ -55,7 +55,7 @@ inline std::ostream &operator<<(std::ostream &os, const variable<RealType> &a) {
|
||||
}
|
||||
if (!a.label().empty()) {
|
||||
os << ", label=";
|
||||
detail::escape(os, a.label());
|
||||
::boost::histogram::detail::escape(os, a.label());
|
||||
}
|
||||
if (!a.uoflow()) {
|
||||
os << ", uoflow=False";
|
||||
@ -68,7 +68,7 @@ inline std::ostream &operator<<(std::ostream &os, const integer &a) {
|
||||
os << "integer(" << a[0] << ", " << a[a.bins() - 1];
|
||||
if (!a.label().empty()) {
|
||||
os << ", label=";
|
||||
detail::escape(os, a.label());
|
||||
::boost::histogram::detail::escape(os, a.label());
|
||||
}
|
||||
if (!a.uoflow()) {
|
||||
os << ", uoflow=False";
|
||||
@ -80,12 +80,12 @@ inline std::ostream &operator<<(std::ostream &os, const integer &a) {
|
||||
inline std::ostream &operator<<(std::ostream &os, const category &a) {
|
||||
os << "category(";
|
||||
for (int i = 0; i < a.bins(); ++i) {
|
||||
detail::escape(os, a[i]);
|
||||
::boost::histogram::detail::escape(os, a[i]);
|
||||
os << (i == (a.bins() - 1) ? "" : ", ");
|
||||
}
|
||||
if (!a.label().empty()) {
|
||||
os << ", label=";
|
||||
detail::escape(os, a.label());
|
||||
::boost::histogram::detail::escape(os, a.label());
|
||||
}
|
||||
os << ")";
|
||||
return os;
|
||||
|
@ -50,23 +50,23 @@ template <typename MainVector, typename AuxVector> struct combine {
|
||||
mpl::back_inserter<MainVector>>::type;
|
||||
};
|
||||
|
||||
struct bool_mask_helper {
|
||||
struct bool_mask_op {
|
||||
std::vector<bool> &b;
|
||||
bool v;
|
||||
template <typename N> void operator()(const N &) const { b[N::value] = v; }
|
||||
};
|
||||
|
||||
template <typename Ns> std::vector<bool> bool_mask(std::size_t n, bool v) {
|
||||
template <typename Ns> std::vector<bool> bool_mask(unsigned n, bool v) {
|
||||
std::vector<bool> b(n, !v);
|
||||
mpl::for_each<Ns>(bool_mask_helper{b, v});
|
||||
mpl::for_each<Ns>(bool_mask_op{b, v});
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename Axes, typename Ns> struct axes_assign_subset_helper {
|
||||
template <typename Axes, typename Ns> struct axes_assign_subset_op {
|
||||
const Axes &axes_;
|
||||
template <typename I, typename R>
|
||||
auto operator()(const I &, R &r) const -> typename mpl::next<I>::type {
|
||||
using I2 = typename mpl::at_c<Ns, I::value>::type;
|
||||
template <int N, typename R>
|
||||
auto operator()(mpl::int_<N>, R &r) const -> mpl::int_<N+1> {
|
||||
using I2 = typename mpl::at_c<Ns, N>::type;
|
||||
r = fusion::at_c<I2::value>(axes_);
|
||||
return {};
|
||||
}
|
||||
@ -75,17 +75,17 @@ template <typename Axes, typename Ns> struct axes_assign_subset_helper {
|
||||
template <typename Ns, typename Axes1, typename Axes>
|
||||
void axes_assign_subset(Axes1 &axes1, const Axes &axes) {
|
||||
fusion::fold(axes1, mpl::int_<0>(),
|
||||
axes_assign_subset_helper<Axes, Ns>{axes});
|
||||
axes_assign_subset_op<Axes, Ns>{axes});
|
||||
}
|
||||
|
||||
template <typename... Ns> struct unique_sorted {
|
||||
using type = typename mpl::unique<
|
||||
typename mpl::sort<typename mpl::vector<Ns...>::type>::type>::type;
|
||||
};
|
||||
template <typename Ns>
|
||||
using unique_sorted =
|
||||
typename mpl::unique<typename mpl::sort<Ns>::type,
|
||||
std::is_same<mpl::_1, mpl::_2>>::type;
|
||||
|
||||
template <typename Axes, typename Numbers> struct axes_select {
|
||||
using type = typename mpl::transform<Numbers, mpl::at<Axes, mpl::_1>>::type;
|
||||
};
|
||||
template <typename Axes, typename Numbers>
|
||||
using axes_select =
|
||||
typename mpl::transform<Numbers, mpl::at<Axes, mpl::_1>>::type;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace histogram
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define _BOOST_HISTOGRAM_HISTOGRAM_FWD_HPP_
|
||||
|
||||
#include <boost/histogram/detail/meta.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <set>
|
||||
#include <type_traits>
|
||||
|
||||
@ -41,19 +42,17 @@ private:
|
||||
unsigned value;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <typename Ns> struct keep_static { using type = Ns; };
|
||||
struct keep_dynamic : std::set<unsigned> {};
|
||||
} // namespace detail
|
||||
|
||||
template <typename... Ns>
|
||||
auto keep(Ns...)
|
||||
-> detail::keep_static<typename detail::unique_sorted<Ns...>::type> {
|
||||
inline auto keep(Ns...) -> detail::unique_sorted<mpl::vector<Ns...>> {
|
||||
return {};
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
using keep_dynamic = std::set<unsigned>;
|
||||
} // namespace detail
|
||||
|
||||
template <typename Iterator, typename = detail::is_iterator<Iterator>>
|
||||
detail::keep_dynamic keep(Iterator begin, Iterator end) {
|
||||
inline detail::keep_dynamic keep(Iterator begin, Iterator end) {
|
||||
detail::keep_dynamic s;
|
||||
std::copy(begin, end, s.begin());
|
||||
return s;
|
||||
|
@ -364,9 +364,8 @@ private:
|
||||
return h;
|
||||
}
|
||||
|
||||
template <typename Ns>
|
||||
friend histogram reduce(const histogram &h, const detail::keep_static<Ns> &) {
|
||||
const auto b = detail::bool_mask<Ns>(h.dim(), true);
|
||||
template <typename Keep> friend histogram reduce(const histogram &h, Keep) {
|
||||
const auto b = detail::bool_mask<Keep>(h.dim(), true);
|
||||
return h.reduce_impl(b);
|
||||
}
|
||||
|
||||
|
@ -156,10 +156,10 @@ public:
|
||||
void reset() { storage_ = std::move(Storage(storage_.size())); }
|
||||
|
||||
/// Get N-th axis
|
||||
template <unsigned N>
|
||||
template <int N>
|
||||
constexpr typename std::add_const<
|
||||
typename fusion::result_of::value_at_c<axes_type, N>::type>::type &
|
||||
axis(std::integral_constant<unsigned, N>) const {
|
||||
axis(mpl::int_<N>) const {
|
||||
static_assert(N < axes_size::value, "axis index out of range");
|
||||
return fusion::at_c<N>(axes_);
|
||||
}
|
||||
@ -277,16 +277,14 @@ private:
|
||||
} while (m.next());
|
||||
}
|
||||
|
||||
template <typename Ns>
|
||||
friend auto reduce(const histogram &h, const detail::keep_static<Ns> &)
|
||||
-> histogram<Static, typename detail::axes_select<Axes, Ns>::type,
|
||||
Storage> {
|
||||
using HR = histogram<Static, typename detail::axes_select<Axes, Ns>::type,
|
||||
Storage>;
|
||||
template <typename Keep>
|
||||
friend auto reduce(const histogram &h, Keep)
|
||||
-> histogram<Static, detail::axes_select<Axes, Keep>, Storage> {
|
||||
using HR = histogram<Static, detail::axes_select<Axes, Keep>, Storage>;
|
||||
typename HR::axes_type axes;
|
||||
detail::axes_assign_subset<Ns>(axes, h.axes_);
|
||||
detail::axes_assign_subset<Keep>(axes, h.axes_);
|
||||
auto hr = HR(std::move(axes));
|
||||
const auto b = detail::bool_mask<Ns>(h.dim(), true);
|
||||
const auto b = detail::bool_mask<Keep>(h.dim(), true);
|
||||
h.reduce_impl(hr, b);
|
||||
return hr;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifndef _BOOST_HISTOGRAM_LITERALS_HPP_
|
||||
#define _BOOST_HISTOGRAM_LITERALS_HPP_
|
||||
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
@ -14,28 +15,27 @@ namespace histogram {
|
||||
namespace literals {
|
||||
namespace detail {
|
||||
template <char C> struct char2int;
|
||||
template <> struct char2int<'0'> { static constexpr unsigned value = 0; };
|
||||
template <> struct char2int<'1'> { static constexpr unsigned value = 1; };
|
||||
template <> struct char2int<'2'> { static constexpr unsigned value = 2; };
|
||||
template <> struct char2int<'3'> { static constexpr unsigned value = 3; };
|
||||
template <> struct char2int<'4'> { static constexpr unsigned value = 4; };
|
||||
template <> struct char2int<'5'> { static constexpr unsigned value = 5; };
|
||||
template <> struct char2int<'6'> { static constexpr unsigned value = 6; };
|
||||
template <> struct char2int<'7'> { static constexpr unsigned value = 7; };
|
||||
template <> struct char2int<'8'> { static constexpr unsigned value = 8; };
|
||||
template <> struct char2int<'9'> { static constexpr unsigned value = 9; };
|
||||
template <> struct char2int<'0'> { static constexpr int value = 0; };
|
||||
template <> struct char2int<'1'> { static constexpr int value = 1; };
|
||||
template <> struct char2int<'2'> { static constexpr int value = 2; };
|
||||
template <> struct char2int<'3'> { static constexpr int value = 3; };
|
||||
template <> struct char2int<'4'> { static constexpr int value = 4; };
|
||||
template <> struct char2int<'5'> { static constexpr int value = 5; };
|
||||
template <> struct char2int<'6'> { static constexpr int value = 6; };
|
||||
template <> struct char2int<'7'> { static constexpr int value = 7; };
|
||||
template <> struct char2int<'8'> { static constexpr int value = 8; };
|
||||
template <> struct char2int<'9'> { static constexpr int value = 9; };
|
||||
|
||||
template <unsigned N> constexpr unsigned parse() { return N; }
|
||||
template <int N> constexpr int parse() { return N; }
|
||||
|
||||
template <unsigned N, char First, char... Rest> constexpr unsigned parse() {
|
||||
template <int N, char First, char... Rest> constexpr int parse() {
|
||||
return parse<N * 10 + char2int<First>::value, Rest...>();
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <char... Digits>
|
||||
auto operator"" _c() -> decltype(
|
||||
std::integral_constant<unsigned, detail::parse<0, Digits...>()>()) {
|
||||
return std::integral_constant<unsigned, detail::parse<0, Digits...>()>();
|
||||
auto operator"" _c() -> decltype(mpl::int_<detail::parse<0u, Digits...>()>()) {
|
||||
return mpl::int_<detail::parse<0u, Digits...>()>();
|
||||
}
|
||||
|
||||
} // namespace literals
|
||||
|
@ -7,57 +7,57 @@
|
||||
#ifndef BOOST_HISTOGRAM_UTILITY_HPP_
|
||||
#define BOOST_HISTOGRAM_UTILITY_HPP_
|
||||
|
||||
#include <boost/histogram/detail/axis_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
#include <boost/histogram/detail/axis_visitor.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
|
||||
template <typename A> int bins(const A &a) { return a.bins(); }
|
||||
template <typename A> inline int bins(const A &a) { return a.bins(); }
|
||||
|
||||
template <typename... Axes> int bins(const boost::variant<Axes...> &a) {
|
||||
template <typename... Axes> inline int bins(const boost::variant<Axes...> &a) {
|
||||
return apply_visitor(detail::bins(), a);
|
||||
}
|
||||
|
||||
template <typename A> int shape(const A &a) { return a.shape(); }
|
||||
template <typename A> inline int shape(const A &a) { return a.shape(); }
|
||||
|
||||
template <typename... Axes> int shape(const boost::variant<Axes...> &a) {
|
||||
template <typename... Axes> inline int shape(const boost::variant<Axes...> &a) {
|
||||
return apply_visitor(detail::shape(), a);
|
||||
}
|
||||
|
||||
template <typename A, typename V> int index(const A &a, const V v) {
|
||||
template <typename A, typename V> inline int index(const A &a, const V v) {
|
||||
return a.index(v);
|
||||
}
|
||||
|
||||
template <typename... Axes, typename V>
|
||||
int index(const boost::variant<Axes...> &a, const V v) {
|
||||
inline int index(const boost::variant<Axes...> &a, const V v) {
|
||||
return apply_visitor(detail::index<V>(v), a);
|
||||
}
|
||||
|
||||
template <typename A> typename A::value_type left(const A &a, const int i) {
|
||||
template <typename A> inline typename A::value_type left(const A &a, const int i) {
|
||||
return a[i];
|
||||
}
|
||||
|
||||
template <typename... Axes>
|
||||
double left(const boost::variant<Axes...> &a, const int i) {
|
||||
inline double left(const boost::variant<Axes...> &a, const int i) {
|
||||
return apply_visitor(detail::left(i), a);
|
||||
}
|
||||
|
||||
template <typename A> typename A::value_type right(const A &a, const int i) {
|
||||
template <typename A> inline typename A::value_type right(const A &a, const int i) {
|
||||
return left(a, i + 1);
|
||||
}
|
||||
|
||||
template <typename... Axes>
|
||||
double right(const boost::variant<Axes...> &a, const int i) {
|
||||
inline double right(const boost::variant<Axes...> &a, const int i) {
|
||||
return apply_visitor(detail::right(i), a);
|
||||
}
|
||||
|
||||
template <typename A> double center(const A &a, const int i) {
|
||||
template <typename A> inline double center(const A &a, const int i) {
|
||||
return 0.5 * (left(a, i) + right(a, i));
|
||||
}
|
||||
|
||||
template <typename... Axes>
|
||||
double center(const boost::variant<Axes...> &a, const int i) {
|
||||
inline double center(const boost::variant<Axes...> &a, const int i) {
|
||||
return apply_visitor(detail::center(i), a);
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,16 @@ auto make_histogram(Dynamic, Axes &&... axes)
|
||||
return make_dynamic_histogram_with<S>(std::forward<Axes>(axes)...);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
bool axis_equal(Static, const T& t, const U& u) {
|
||||
return t == u;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
bool axis_equal(Dynamic, const T& t, const U& u) {
|
||||
return t == T(u);
|
||||
}
|
||||
|
||||
template <typename Type> void run_tests() {
|
||||
|
||||
// init_0
|
||||
@ -573,21 +583,88 @@ template <typename Type> void run_tests() {
|
||||
// reduce
|
||||
{
|
||||
auto h1 = make_histogram<adaptive_storage<>>(Type(), axis::integer(0, 1),
|
||||
axis::integer(2, 3));
|
||||
h1.fill(0, 2);
|
||||
h1.fill(0, 3);
|
||||
axis::integer(0, 2));
|
||||
h1.fill(0, 0);
|
||||
h1.fill(0, 1);
|
||||
h1.fill(1, 0);
|
||||
h1.fill(1, 1);
|
||||
h1.fill(1, 2);
|
||||
h1.fill(1, 3);
|
||||
h1.fill(1, 3);
|
||||
BOOST_TEST_EQ(h1.dim(), 2);
|
||||
BOOST_TEST_EQ(h1.sum(), 5);
|
||||
auto h2 = reduce(h1, keep(1_c));
|
||||
BOOST_TEST_EQ(h2.dim(), 1);
|
||||
BOOST_TEST_EQ(h2.sum(), 5);
|
||||
BOOST_TEST_EQ(h2.value(0), 2);
|
||||
BOOST_TEST_EQ(h2.value(1), 3);
|
||||
BOOST_TEST_EQ(left(h2.axis(), 0), 2.0);
|
||||
BOOST_TEST_EQ(left(h2.axis(), 1), 3.0);
|
||||
|
||||
auto h1_0 = reduce(h1, keep(0_c));
|
||||
BOOST_TEST_EQ(h1_0.dim(), 1);
|
||||
BOOST_TEST_EQ(h1_0.sum(), 5);
|
||||
BOOST_TEST_EQ(h1_0.value(0), 2);
|
||||
BOOST_TEST_EQ(h1_0.value(1), 3);
|
||||
BOOST_TEST_EQ(left(h1_0.axis(), 0), 0.0);
|
||||
BOOST_TEST_EQ(left(h1_0.axis(), 1), 1.0);
|
||||
BOOST_TEST(axis_equal(Type(), h1_0.axis(), axis::integer(0, 1)));
|
||||
|
||||
auto h1_1 = reduce(h1, keep(1_c));
|
||||
BOOST_TEST_EQ(h1_1.dim(), 1);
|
||||
BOOST_TEST_EQ(h1_1.sum(), 5);
|
||||
BOOST_TEST_EQ(h1_1.value(0), 2);
|
||||
BOOST_TEST_EQ(h1_1.value(1), 2);
|
||||
BOOST_TEST_EQ(h1_1.value(2), 1);
|
||||
BOOST_TEST(axis_equal(Type(), h1_1.axis(), axis::integer(0, 2)));
|
||||
|
||||
auto h2 = make_histogram<adaptive_storage<>>(
|
||||
Type(), axis::integer(0, 1), axis::integer(0, 2), axis::integer(0, 3));
|
||||
h2.fill(0, 0, 0);
|
||||
h2.fill(0, 1, 0);
|
||||
h2.fill(0, 1, 1);
|
||||
h2.fill(0, 0, 2);
|
||||
h2.fill(1, 0, 2);
|
||||
|
||||
auto h2_0 = reduce(h2, keep(0_c));
|
||||
BOOST_TEST_EQ(h2_0.dim(), 1);
|
||||
BOOST_TEST_EQ(h2_0.sum(), 5);
|
||||
BOOST_TEST_EQ(h2_0.value(0), 4);
|
||||
BOOST_TEST_EQ(h2_0.value(1), 1);
|
||||
BOOST_TEST(axis_equal(Type(), h2_0.axis(), axis::integer(0, 1)));
|
||||
|
||||
auto h2_1 = reduce(h2, keep(1_c));
|
||||
BOOST_TEST_EQ(h2_1.dim(), 1);
|
||||
BOOST_TEST_EQ(h2_1.sum(), 5);
|
||||
BOOST_TEST_EQ(h2_1.value(0), 3);
|
||||
BOOST_TEST_EQ(h2_1.value(1), 2);
|
||||
BOOST_TEST(axis_equal(Type(), h2_1.axis(), axis::integer(0, 2)));
|
||||
|
||||
auto h2_2 = reduce(h2, keep(2_c));
|
||||
BOOST_TEST_EQ(h2_2.dim(), 1);
|
||||
BOOST_TEST_EQ(h2_2.sum(), 5);
|
||||
BOOST_TEST_EQ(h2_2.value(0), 2);
|
||||
BOOST_TEST_EQ(h2_2.value(1), 1);
|
||||
BOOST_TEST_EQ(h2_2.value(2), 2);
|
||||
BOOST_TEST(axis_equal(Type(), h2_2.axis(), axis::integer(0, 3)));
|
||||
|
||||
auto h2_01 = reduce(h2, keep(0_c, 1_c));
|
||||
BOOST_TEST_EQ(h2_01.dim(), 2);
|
||||
BOOST_TEST_EQ(h2_01.sum(), 5);
|
||||
BOOST_TEST_EQ(h2_01.value(0, 0), 2);
|
||||
BOOST_TEST_EQ(h2_01.value(0, 1), 2);
|
||||
BOOST_TEST_EQ(h2_01.value(1, 0), 1);
|
||||
BOOST_TEST(axis_equal(Type(), h2_01.axis(0_c), axis::integer(0, 1)));
|
||||
BOOST_TEST(axis_equal(Type(), h2_01.axis(1_c), axis::integer(0, 2)));
|
||||
|
||||
auto h2_02 = reduce(h2, keep(0_c, 2_c));
|
||||
BOOST_TEST_EQ(h2_02.dim(), 2);
|
||||
BOOST_TEST_EQ(h2_02.sum(), 5);
|
||||
BOOST_TEST_EQ(h2_02.value(0, 0), 2);
|
||||
BOOST_TEST_EQ(h2_02.value(0, 1), 1);
|
||||
BOOST_TEST_EQ(h2_02.value(0, 2), 1);
|
||||
BOOST_TEST_EQ(h2_02.value(1, 2), 1);
|
||||
BOOST_TEST(axis_equal(Type(), h2_02.axis(0_c), axis::integer(0, 1)));
|
||||
BOOST_TEST(axis_equal(Type(), h2_02.axis(1_c), axis::integer(0, 3)));
|
||||
|
||||
auto h2_12 = reduce(h2, keep(1_c, 2_c));
|
||||
BOOST_TEST_EQ(h2_12.dim(), 2);
|
||||
BOOST_TEST_EQ(h2_12.sum(), 5);
|
||||
BOOST_TEST_EQ(h2_12.value(0, 0), 1);
|
||||
BOOST_TEST_EQ(h2_12.value(1, 0), 1);
|
||||
BOOST_TEST_EQ(h2_12.value(1, 1), 1);
|
||||
BOOST_TEST_EQ(h2_12.value(0, 2), 2);
|
||||
BOOST_TEST(axis_equal(Type(), h2_12.axis(0_c), axis::integer(0, 2)));
|
||||
BOOST_TEST(axis_equal(Type(), h2_12.axis(1_c), axis::integer(0, 3)));
|
||||
}
|
||||
}
|
||||
|
||||
|
22
test/meta_test.cpp
Normal file
22
test/meta_test.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/histogram/detail/meta.hpp>
|
||||
#include <boost/mpl/equal.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/mpl/sort.hpp>
|
||||
#include <boost/mpl/unique.hpp>
|
||||
#include <boost/mpl/vector_c.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::mpl;
|
||||
namespace bhd = boost::histogram::detail;
|
||||
|
||||
int main() {
|
||||
typedef vector_c<int, 2, 1, 1, 3> numbers;
|
||||
typedef vector_c<int, 1, 2, 3> expected;
|
||||
using result = bhd::unique_sorted<numbers>;
|
||||
|
||||
BOOST_MPL_ASSERT((equal<result, expected, equal_to<_, _>>));
|
||||
return boost::report_errors();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user