mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-09 23:04:07 +00:00
Better deduction guides for axis types and histogram
This commit is contained in:
parent
8b9561fb10
commit
3b18d9075b
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
31
include/boost/histogram/detail/replace_type.hpp
Normal file
31
include/boost/histogram/detail/replace_type.hpp
Normal 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
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 ]
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user