Better deduction guides for axis types and histogram

This commit is contained in:
Hans Dembinski 2019-10-27 17:27:26 +01:00 committed by GitHub
parent 8b9561fb10
commit 3b18d9075b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 235 additions and 176 deletions

View File

@ -166,15 +166,13 @@ private:
#if __cpp_deduction_guides >= 201606
template <class T>
category(std::initializer_list<T>)->category<T>;
category(std::initializer_list<const char*>)->category<std::string>;
template <class T>
category(std::initializer_list<T>, const char*)->category<T>;
category(std::initializer_list<T>)
->category<detail::replace_cstring<std::decay_t<T>>, null_type>;
template <class T, class M>
category(std::initializer_list<T>, const M&)->category<T, M>;
category(std::initializer_list<T>, M)
->category<detail::replace_cstring<std::decay_t<T>>,
detail::replace_cstring<std::decay_t<M>>>;
#endif

View File

@ -13,7 +13,7 @@
#include <boost/histogram/axis/option.hpp>
#include <boost/histogram/detail/convert_integer.hpp>
#include <boost/histogram/detail/limits.hpp>
#include <boost/histogram/detail/replace_default.hpp>
#include <boost/histogram/detail/replace_type.hpp>
#include <boost/histogram/detail/static_if.hpp>
#include <boost/histogram/fwd.hpp>
#include <boost/throw_exception.hpp>
@ -200,13 +200,12 @@ private:
#if __cpp_deduction_guides >= 201606
template <class T>
integer(T, T)->integer<detail::convert_integer<T, index_type>>;
template <class T>
integer(T, T, const char*)->integer<detail::convert_integer<T, index_type>>;
integer(T, T)->integer<detail::convert_integer<T, index_type>, null_type>;
template <class T, class M>
integer(T, T, M)->integer<detail::convert_integer<T, index_type>, M>;
integer(T, T, M)
->integer<detail::convert_integer<T, index_type>,
detail::replace_type<std::decay_t<M>, const char*, std::string>>;
#endif

View File

@ -9,7 +9,7 @@
#include <boost/core/empty_value.hpp>
#include <boost/histogram/detail/relaxed_equal.hpp>
#include <boost/histogram/detail/replace_default.hpp>
#include <boost/histogram/detail/replace_type.hpp>
#include <string>
#include <type_traits>

View File

@ -15,7 +15,7 @@
#include <boost/histogram/axis/option.hpp>
#include <boost/histogram/detail/convert_integer.hpp>
#include <boost/histogram/detail/relaxed_equal.hpp>
#include <boost/histogram/detail/replace_default.hpp>
#include <boost/histogram/detail/replace_type.hpp>
#include <boost/histogram/fwd.hpp>
#include <boost/mp11/utility.hpp>
#include <boost/throw_exception.hpp>
@ -68,13 +68,13 @@ namespace transform {
/// Identity transform for equidistant bins.
struct id {
/// Pass-through.
template <typename T>
template <class T>
static T forward(T&& x) noexcept {
return std::forward<T>(x);
}
/// Pass-through.
template <typename T>
template <class T>
static T inverse(T&& x) noexcept {
return std::forward<T>(x);
}
@ -86,13 +86,13 @@ struct id {
/// Log transform for equidistant bins in log-space.
struct log {
/// Returns log(x) of external value x.
template <typename T>
template <class T>
static T forward(T x) {
return std::log(x);
}
/// Returns exp(x) for internal value x.
template <typename T>
template <class T>
static T inverse(T x) {
return std::exp(x);
}
@ -104,13 +104,13 @@ struct log {
/// Sqrt transform for equidistant bins in sqrt-space.
struct sqrt {
/// Returns sqrt(x) of external value x.
template <typename T>
template <class T>
static T forward(T x) {
return std::sqrt(x);
}
/// Returns x^2 of internal value x.
template <typename T>
template <class T>
static T inverse(T x) {
return x * x;
}
@ -128,13 +128,13 @@ struct pow {
pow() = default;
/// Returns pow(x, power) of external value x.
template <typename T>
template <class T>
auto forward(T x) const {
return std::pow(x, power);
}
/// Returns pow(x, 1/power) of external value x.
template <typename T>
template <class T>
auto inverse(T x) const {
return std::pow(x, 1.0 / power);
}
@ -151,7 +151,7 @@ struct pow {
#ifndef BOOST_HISTOGRAM_DOXYGEN_INVOKED
// Type envelope to mark value as step size
template <typename T>
template <class T>
struct step_type {
T value;
};
@ -160,7 +160,7 @@ struct step_type {
/**
Helper function to mark argument as step size.
*/
template <typename T>
template <class T>
step_type<T> step(T t) {
return step_type<T>{t};
}
@ -391,22 +391,21 @@ private:
#if __cpp_deduction_guides >= 201606
template <class T>
regular(unsigned, T, T)->regular<detail::convert_integer<T, double>>;
template <class T>
regular(unsigned, T, T, const char*)->regular<detail::convert_integer<T, double>>;
regular(unsigned, T, T)
->regular<detail::convert_integer<T, double>, transform::id, null_type>;
template <class T, class M>
regular(unsigned, T, T, M)->regular<detail::convert_integer<T, double>, transform::id, M>;
regular(unsigned, T, T, M)
->regular<detail::convert_integer<T, double>, transform::id,
detail::replace_cstring<std::decay_t<M>>>;
template <class Tr, class T>
regular(Tr, unsigned, T, T)->regular<detail::convert_integer<T, double>, Tr>;
template <class Tr, class T>
regular(Tr, unsigned, T, T, const char*)->regular<detail::convert_integer<T, double>, Tr>;
template <class Tr, class T, class = detail::requires_transform<Tr, T>>
regular(Tr, unsigned, T, T)->regular<detail::convert_integer<T, double>, Tr, null_type>;
template <class Tr, class T, class M>
regular(Tr, unsigned, T, T, M)->regular<detail::convert_integer<T, double>, Tr, M>;
regular(Tr, unsigned, T, T, M)
->regular<detail::convert_integer<T, double>, Tr,
detail::replace_cstring<std::decay_t<M>>>;
#endif

View File

@ -17,7 +17,7 @@
#include <boost/histogram/detail/convert_integer.hpp>
#include <boost/histogram/detail/detect.hpp>
#include <boost/histogram/detail/limits.hpp>
#include <boost/histogram/detail/replace_default.hpp>
#include <boost/histogram/detail/replace_type.hpp>
#include <boost/histogram/fwd.hpp>
#include <boost/throw_exception.hpp>
#include <cmath>
@ -213,29 +213,28 @@ private:
#if __cpp_deduction_guides >= 201606
template <class U, class T = detail::convert_integer<U, double>>
variable(std::initializer_list<U>)->variable<T>;
template <class T>
variable(std::initializer_list<T>)
->variable<detail::convert_integer<T, double>, null_type>;
template <class U, class T = detail::convert_integer<U, double>>
variable(std::initializer_list<U>, const char*)->variable<T>;
template <class T, class M>
variable(std::initializer_list<T>, M)
->variable<detail::convert_integer<T, double>,
detail::replace_type<std::decay_t<M>, const char*, std::string>>;
template <class U, class M, class T = detail::convert_integer<U, double>>
variable(std::initializer_list<U>, M)->variable<T, M>;
template <class Iterable, class = detail::requires_iterable<Iterable>>
variable(Iterable)
->variable<
detail::convert_integer<
std::decay_t<decltype(*std::begin(std::declval<Iterable&>()))>, double>,
null_type>;
template <class Iterable,
class T = detail::convert_integer<
std::decay_t<decltype(*std::begin(std::declval<Iterable&>()))>, double>>
variable(Iterable)->variable<T>;
template <class Iterable,
class T = detail::convert_integer<
std::decay_t<decltype(*std::begin(std::declval<Iterable&>()))>, double>>
variable(Iterable, const char*)->variable<T>;
template <class Iterable, class M,
class T = detail::convert_integer<
std::decay_t<decltype(*std::begin(std::declval<Iterable&>()))>, double>>
variable(Iterable, M)->variable<T, M>;
template <class Iterable, class M>
variable(Iterable, M)
->variable<
detail::convert_integer<
std::decay_t<decltype(*std::begin(std::declval<Iterable&>()))>, double>,
detail::replace_type<std::decay_t<M>, const char*, std::string>>;
#endif

View File

@ -57,7 +57,9 @@ BOOST_HISTOGRAM_DETAIL_DETECT(has_allocator, &T::get_allocator);
BOOST_HISTOGRAM_DETAIL_DETECT(is_indexable, (std::declval<T&>()[0]));
BOOST_HISTOGRAM_DETAIL_DETECT(is_transform, (&T::forward, &T::inverse));
BOOST_HISTOGRAM_DETAIL_DETECT_BINARY(
is_transform,
(std::declval<T&>().inverse(std::declval<T&>().forward(std::declval<U>()))));
BOOST_HISTOGRAM_DETAIL_DETECT(is_indexable_container, (std::declval<T>()[0], &T::size,
std::begin(std::declval<T>()),
@ -135,7 +137,9 @@ using is_storage = mp11::mp_and<is_indexable_container<T>, has_method_reset<T>,
has_threading_support<T>>;
template <class T>
using is_adaptible = mp11::mp_or<is_vector_like<T>, is_array_like<T>, is_map_like<T>>;
using is_adaptible =
mp11::mp_and<mp11::mp_not<is_storage<T>>,
mp11::mp_or<is_vector_like<T>, is_array_like<T>, is_map_like<T>>>;
template <class T>
struct is_tuple_impl : mp11::mp_false {};
@ -179,6 +183,9 @@ using is_sequence_of_any_axis =
mp11::mp_and<is_iterable<T>, is_any_axis<mp11::mp_first<T>>>;
// poor-mans concept checks
template <class T, class = std::enable_if_t<is_storage<std::decay_t<T>>::value>>
struct requires_storage {};
template <class T, class _ = std::decay_t<T>,
class = std::enable_if_t<(is_storage<_>::value || is_adaptible<_>::value)>>
struct requires_storage_or_adaptible {};
@ -214,6 +221,10 @@ struct requires_axes {};
template <class T, class U, class = std::enable_if_t<std::is_convertible<T, U>::value>>
struct requires_convertible {};
template <class T, class U,
class = std::enable_if_t<is_transform<std::decay_t<T>, U>::value>>
struct requires_transform {};
} // namespace detail
} // namespace histogram
} // namespace boost

View File

@ -1,25 +0,0 @@
// Copyright 2015-2019 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_DETAIL_REPLACE_DEFAULT_HPP
#define BOOST_HISTOGRAM_DETAIL_REPLACE_DEFAULT_HPP
#include <boost/core/use_default.hpp>
#include <type_traits>
namespace boost {
namespace histogram {
namespace detail {
template <class T, class Default>
using replace_default =
std::conditional_t<std::is_same<T, boost::use_default>::value, Default, T>;
} // namespace detail
} // namespace histogram
} // namespace boost
#endif

View File

@ -0,0 +1,31 @@
// Copyright 2019 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_DETAIL_REPLACE_TYPE_HPP
#define BOOST_HISTOGRAM_DETAIL_REPLACE_TYPE_HPP
#include <boost/core/use_default.hpp>
#include <string>
#include <type_traits>
namespace boost {
namespace histogram {
namespace detail {
template <class T, class From, class To>
using replace_type = std::conditional_t<std::is_same<T, From>::value, To, T>;
template <class T, class Default>
using replace_default = replace_type<T, boost::use_default, Default>;
template <class T>
using replace_cstring = replace_type<T, const char*, std::string>;
} // namespace detail
} // namespace histogram
} // namespace boost
#endif

View File

@ -99,17 +99,21 @@ public:
return *this;
}
template <class A, class S>
histogram(A&& a, S&& s)
template <class A, class = detail::requires_axes<A>>
histogram(A&& a, Storage s)
: axes_(std::forward<A>(a))
, storage_(std::forward<S>(s))
, storage_(std::move(s))
, offset_(detail::offset(axes_)) {
detail::throw_if_axes_is_too_large(axes_);
storage_.reset(detail::bincount(axes_));
}
template <class A, class = detail::requires_axes<A>>
explicit histogram(A&& a) : histogram(std::forward<A>(a), storage_type()) {}
explicit histogram(Axes axes) : histogram(axes, storage_type()) {}
template <class... As, class = detail::requires_axes<std::tuple<std::decay_t<As>...>>>
explicit histogram(As&&... as)
: histogram(std::tuple<std::decay_t<As>...>(std::forward<As>(as)...),
storage_type()) {}
/// Number of axes (dimensions).
constexpr unsigned rank() const noexcept { return detail::axes_rank(axes_); }
@ -571,12 +575,25 @@ auto operator/(const histogram<A, S>& h, double x) {
#if __cpp_deduction_guides >= 201606
template <class Axes>
histogram(Axes&& axes)->histogram<std::decay_t<Axes>, default_storage>;
template <class... Axes, class = detail::requires_axes<std::tuple<std::decay_t<Axes>...>>>
histogram(Axes...)->histogram<std::tuple<std::decay_t<Axes>...>>;
template <class Axes, class Storage>
histogram(Axes&& axes, Storage&& storage)
->histogram<std::decay_t<Axes>, std::decay_t<Storage>>;
template <class... Axes, class S, class = detail::requires_storage_or_adaptible<S>>
histogram(std::tuple<Axes...>, S)
->histogram<std::tuple<Axes...>, std::conditional_t<detail::is_adaptible<S>::value,
storage_adaptor<S>, S>>;
template <class Iterable, class = detail::requires_iterable<Iterable>,
class = detail::requires_any_axis<typename Iterable::value_type>>
histogram(Iterable)->histogram<std::vector<typename Iterable::value_type>>;
template <class Iterable, class S, class = detail::requires_iterable<Iterable>,
class = detail::requires_any_axis<typename Iterable::value_type>,
class = detail::requires_storage_or_adaptible<S>>
histogram(Iterable, S)
->histogram<
std::vector<typename Iterable::value_type>,
std::conditional_t<detail::is_adaptible<S>::value, storage_adaptor<S>, S>>;
#endif

View File

@ -102,7 +102,7 @@ boost_test(TYPE run SOURCES detail_operators_test.cpp
LIBRARIES Boost::histogram Boost::core)
boost_test(TYPE run SOURCES detail_relaxed_equal_test.cpp
LIBRARIES Boost::histogram Boost::core)
boost_test(TYPE run SOURCES detail_replace_default_test.cpp
boost_test(TYPE run SOURCES detail_replace_type_test.cpp
LIBRARIES Boost::histogram Boost::core)
boost_test(TYPE run SOURCES detail_safe_comparison_test.cpp
LIBRARIES Boost::histogram Boost::core)

View File

@ -62,7 +62,7 @@ alias cxx14 :
[ run detail_large_int_test.cpp ]
[ run detail_operators_test.cpp ]
[ run detail_relaxed_equal_test.cpp ]
[ run detail_replace_default_test.cpp ]
[ run detail_replace_type_test.cpp ]
[ run detail_safe_comparison_test.cpp ]
[ run detail_static_if_test.cpp ]
[ run detail_tuple_slice_test.cpp ]

View File

@ -9,7 +9,6 @@
#include <boost/histogram/accumulators/weighted_sum.hpp>
#include <boost/histogram/axis.hpp>
#include <boost/histogram/axis/ostream.hpp>
#include "throw_exception.hpp"
#include <boost/histogram/histogram.hpp>
#include <boost/histogram/ostream.hpp>
#include <boost/histogram/storage_adaptor.hpp>
@ -18,101 +17,129 @@
#include <type_traits>
#include <vector>
#include "std_ostream.hpp"
#include "throw_exception.hpp"
using namespace boost::histogram;
namespace tr = axis::transform;
// tests requires a C++17 compatible compiler
#define TEST BOOST_TEST_TRAIT_SAME
int main() {
{
axis::regular a(1, 0.0, 1.0);
axis::regular b(1, 0, 1);
axis::regular c(1, 0.0f, 1.0f);
axis::regular d(1, 0, 1, "foo");
axis::regular e(1, 0, 1, axis::null_type{});
axis::regular f(tr::sqrt(), 1, 0, 1);
axis::regular g(tr::sqrt(), 1, 0, 1, "foo");
axis::regular h(tr::sqrt(), 1, 0, 1, axis::null_type{});
using axis::null_type;
BOOST_TEST_TRAIT_SAME(decltype(a), axis::regular<>);
BOOST_TEST_TRAIT_SAME(decltype(b), axis::regular<>);
BOOST_TEST_TRAIT_SAME(decltype(c), axis::regular<float>);
BOOST_TEST_TRAIT_SAME(decltype(d), axis::regular<>);
BOOST_TEST_TRAIT_SAME(decltype(e), axis::regular<double, tr::id, axis::null_type>);
BOOST_TEST_TRAIT_SAME(decltype(f), axis::regular<double, tr::sqrt>);
BOOST_TEST_TRAIT_SAME(decltype(g), axis::regular<double, tr::sqrt>);
BOOST_TEST_TRAIT_SAME(decltype(h), axis::regular<double, tr::sqrt, axis::null_type>);
{
using axis::regular;
BOOST_TEST_TRAIT_SAME(decltype(regular(1, 0.0, 1.0)),
regular<double, tr::id, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(regular(1, 0, 1)), regular<double, tr::id, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(regular(1, 0.0f, 1.0f)),
regular<float, tr::id, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(regular(1, 0, 1, 0)), regular<double, tr::id, int>);
BOOST_TEST_TRAIT_SAME(decltype(regular(1, 0.0f, 1.0f, "x")),
regular<float, tr::id, std::string>);
BOOST_TEST_TRAIT_SAME(decltype(regular(tr::sqrt(), 1, 0, 1)),
regular<double, tr::sqrt, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(regular(tr::sqrt(), 1, 0.0f, 1.0f, "x")),
regular<float, tr::sqrt, std::string>);
BOOST_TEST_TRAIT_SAME(decltype(regular(tr::sqrt(), 1, 0, 1, 0)),
regular<double, tr::sqrt, int>);
}
{
axis::integer a(1, 2);
axis::integer b(1l, 2l);
axis::integer c(1.0, 2.0);
axis::integer d(1.0f, 2.0f);
axis::integer e(1, 2, "foo");
axis::integer f(1, 2, axis::null_type{});
BOOST_TEST_TRAIT_SAME(decltype(a), axis::integer<int>);
BOOST_TEST_TRAIT_SAME(decltype(b), axis::integer<int>);
BOOST_TEST_TRAIT_SAME(decltype(c), axis::integer<double>);
BOOST_TEST_TRAIT_SAME(decltype(d), axis::integer<float>);
BOOST_TEST_TRAIT_SAME(decltype(e), axis::integer<int>);
BOOST_TEST_TRAIT_SAME(decltype(f), axis::integer<int, axis::null_type>);
using axis::integer;
BOOST_TEST_TRAIT_SAME(decltype(integer(1, 2)), integer<int, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(integer(1l, 2l)), integer<int, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(integer(1.0, 2.0)), integer<double, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(integer(1.0f, 2.0f)), integer<float, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(integer(1, 2, "foo")), integer<int, std::string>);
BOOST_TEST_TRAIT_SAME(decltype(integer(1, 2, 0)), integer<int, int>);
}
{
axis::variable a{-1, 1};
axis::variable b{-1.f, 1.f};
axis::variable c{-1.0, 1.0};
axis::variable d({-1, 1}, "foo");
axis::variable e({-1, 1}, axis::null_type{});
using axis::variable;
BOOST_TEST_TRAIT_SAME(decltype(variable{-1.0f, 1.0f}), variable<float, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(variable{-1, 0, 1, 2}), variable<double, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(variable{-1.0, 1.0}), variable<double, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(variable({-1, 0, 1}, "foo")),
variable<double, std::string>);
BOOST_TEST_TRAIT_SAME(decltype(variable({-1, 1}, 0)), variable<double, int>);
std::vector<int> vi{{-1, 1}};
std::vector<float> vf{{-1.f, 1.f}};
axis::variable f(vi);
axis::variable g(vf);
axis::variable h(vi, "foo");
axis::variable i(vi, axis::null_type{});
BOOST_TEST_TRAIT_SAME(decltype(a), axis::variable<>);
BOOST_TEST_TRAIT_SAME(decltype(b), axis::variable<float>);
BOOST_TEST_TRAIT_SAME(decltype(c), axis::variable<>);
BOOST_TEST_TRAIT_SAME(decltype(d), axis::variable<>);
BOOST_TEST_TRAIT_SAME(decltype(e), axis::variable<double, axis::null_type>);
BOOST_TEST_TRAIT_SAME(decltype(f), axis::variable<>);
BOOST_TEST_TRAIT_SAME(decltype(g), axis::variable<float>);
BOOST_TEST_TRAIT_SAME(decltype(h), axis::variable<>);
BOOST_TEST_TRAIT_SAME(decltype(i), axis::variable<double, axis::null_type>);
BOOST_TEST_TRAIT_SAME(decltype(variable(std::vector<int>{{-1, 1}})),
variable<double, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(variable(std::vector<float>{{-1.0f, 1.0f}})),
variable<float, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(variable(std::vector<int>{{-1, 1}}, "foo")),
variable<double, std::string>);
BOOST_TEST_TRAIT_SAME(decltype(variable(std::vector<int>{{-1, 1}}, 0)),
variable<double, int>);
}
{
axis::category a{1, 2};
axis::category b{"x", "y"};
axis::category c({1, 2}, "foo");
axis::category d({1, 2}, axis::null_type{});
BOOST_TEST_TRAIT_SAME(decltype(a), axis::category<int>);
BOOST_TEST_TRAIT_SAME(decltype(b), axis::category<std::string>);
BOOST_TEST_TRAIT_SAME(decltype(c), axis::category<int>);
BOOST_TEST_TRAIT_SAME(decltype(d), axis::category<int, axis::null_type>);
using axis::category;
BOOST_TEST_TRAIT_SAME(decltype(category{1, 2}), category<int, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(category{"x", "y"}), category<std::string, null_type>);
BOOST_TEST_TRAIT_SAME(decltype(category({1, 2}, "foo")), category<int, std::string>);
BOOST_TEST_TRAIT_SAME(decltype(category({1, 2}, 0)), category<int, int>);
}
{
auto a0 = axis::regular(3, -1, 1, axis::null_type{});
auto a1 = axis::integer(0, 4, axis::null_type{});
auto a = histogram(std::make_tuple(a0, a1));
BOOST_TEST_EQ(a.rank(), 2);
BOOST_TEST_EQ(a.axis(0), a0);
BOOST_TEST_EQ(a.axis(1), a1);
auto a2 = axis::regular(5, 0, 5, axis::null_type{});
// don't use deduction guides for vector, support depends on stdc++ version
std::vector<decltype(a0)> axes{{a0, a2}};
auto b = histogram(axes, weight_storage());
BOOST_TEST_EQ(b.rank(), 2);
BOOST_TEST_EQ(b.axis(0), a0);
BOOST_TEST_EQ(b.axis(1), a2);
auto h = histogram(axis::regular(3, -1, 1), axis::integer(0, 4));
BOOST_TEST_TRAIT_SAME(decltype(h),
histogram<std::tuple<axis::regular<double, tr::id, null_type>,
axis::integer<int, null_type>>>);
BOOST_TEST_EQ(h.axis(0), axis::regular(3, -1, 1));
BOOST_TEST_EQ(h.axis(1), axis::integer(0, 4));
}
{
auto h = histogram(std::tuple(axis::regular(3, -1, 1), axis::integer(0, 4)),
weight_storage());
BOOST_TEST_TRAIT_SAME(decltype(h),
histogram<std::tuple<axis::regular<double, tr::id, null_type>,
axis::integer<int, null_type>>,
weight_storage>);
BOOST_TEST_EQ(h.axis(0), axis::regular(3, -1, 1));
BOOST_TEST_EQ(h.axis(1), axis::integer(0, 4));
}
{
auto a0 = axis::regular(5, 0, 5);
auto a1 = axis::regular(3, -1, 1);
auto axes = {a0, a1};
auto h = histogram(axes);
BOOST_TEST_TRAIT_SAME(
decltype(h), histogram<std::vector<axis::regular<double, tr::id, null_type>>>);
BOOST_TEST_EQ(h.rank(), 2);
BOOST_TEST_EQ(h.axis(0), a0);
BOOST_TEST_EQ(h.axis(1), a1);
}
{
auto a0 = axis::regular(5, 0, 5);
auto a1 = axis::regular(3, -1, 1);
auto axes = {a0, a1};
auto h = histogram(axes, weight_storage());
BOOST_TEST_TRAIT_SAME(
decltype(h),
histogram<std::vector<axis::regular<double, tr::id, null_type>>, weight_storage>);
BOOST_TEST_EQ(h.rank(), 2);
BOOST_TEST_EQ(h.axis(0), a0);
BOOST_TEST_EQ(h.axis(1), a1);
}
{
auto a0 = axis::regular(5, 0, 5);
auto a1 = axis::regular(3, -1, 1);
auto axes = std::vector<decltype(a0)>{{a0, a1}};
auto h = histogram(axes);
BOOST_TEST_TRAIT_SAME(
decltype(h), histogram<std::vector<axis::regular<double, tr::id, null_type>>>);
BOOST_TEST_EQ(h.rank(), 2);
BOOST_TEST_EQ(h.axis(0), a0);
BOOST_TEST_EQ(h.axis(1), a1);
}
return boost::report_errors();
}

View File

@ -155,12 +155,13 @@ int main() {
{
struct A {};
struct B {
double forward(double);
double inverse(double);
double forward(A);
A inverse(double);
};
BOOST_TEST_TRAIT_FALSE((is_transform<A>));
BOOST_TEST_TRAIT_TRUE((is_transform<B>));
BOOST_TEST_TRAIT_FALSE((is_transform<A, double>));
BOOST_TEST_TRAIT_TRUE((is_transform<B, A>));
BOOST_TEST_TRAIT_TRUE((is_transform<axis::transform::id, double>));
}
// is_vector_like

View File

@ -6,13 +6,15 @@
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/histogram/detail/replace_default.hpp>
#include <boost/histogram/detail/replace_type.hpp>
#include "std_ostream.hpp"
using namespace boost::histogram::detail;
int main() {
BOOST_TEST_TRAIT_SAME(replace_type<long, char, int>, long);
BOOST_TEST_TRAIT_SAME(replace_type<char, char, int>, int);
BOOST_TEST_TRAIT_SAME(replace_default<boost::use_default, char>, char);
BOOST_TEST_TRAIT_SAME(replace_default<int, char>, int);