mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-09 14:57:57 +00:00
Fixes for latest compilers (#373)
This commit is contained in:
parent
82e75c14b3
commit
d475bc9b85
4
.github/workflows/slow.yml
vendored
4
.github/workflows/slow.yml
vendored
@ -89,7 +89,7 @@ jobs:
|
|||||||
cd libs/histogram
|
cd libs/histogram
|
||||||
../../b2 $B2_OPTS toolset=gcc-10 cxxstd=20 cxxflags="-O3 -funsafe-math-optimizations" test//all examples
|
../../b2 $B2_OPTS toolset=gcc-10 cxxstd=20 cxxflags="-O3 -funsafe-math-optimizations" test//all examples
|
||||||
|
|
||||||
clang10:
|
clang14:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@ -107,4 +107,4 @@ jobs:
|
|||||||
- name: Test cxxstd=17 ubsan asan
|
- name: Test cxxstd=17 ubsan asan
|
||||||
run: |
|
run: |
|
||||||
cd libs/histogram
|
cd libs/histogram
|
||||||
../../b2 $B2_OPTS toolset=clang-10 cxxstd=17 variant=histogram_ubasan test//all
|
../../b2 $B2_OPTS toolset=clang-14 cxxstd=17 variant=histogram_ubasan test//all
|
||||||
|
1
Jamfile
1
Jamfile
@ -18,6 +18,7 @@ project
|
|||||||
<implicit-dependency>/boost//headers
|
<implicit-dependency>/boost//headers
|
||||||
<include>$(BOOST_ROOT)
|
<include>$(BOOST_ROOT)
|
||||||
<toolset>clang:<cxxflags>"-pedantic -Wextra -Wsign-compare -Wstrict-aliasing -fstrict-aliasing -Wvexing-parse -Wfloat-conversion -fvisibility=hidden -fvisibility-inlines-hidden"
|
<toolset>clang:<cxxflags>"-pedantic -Wextra -Wsign-compare -Wstrict-aliasing -fstrict-aliasing -Wvexing-parse -Wfloat-conversion -fvisibility=hidden -fvisibility-inlines-hidden"
|
||||||
|
<toolset>darwin:<cxxflags>"-pedantic -Wextra -Wsign-compare -Wstrict-aliasing -fstrict-aliasing -Wvexing-parse -Wfloat-conversion -fvisibility=hidden -fvisibility-inlines-hidden"
|
||||||
<toolset>gcc:<cxxflags>"-pedantic -Wextra -Wsign-compare -Wstrict-aliasing -fstrict-aliasing -Wfloat-conversion -fvisibility=hidden -fvisibility-inlines-hidden"
|
<toolset>gcc:<cxxflags>"-pedantic -Wextra -Wsign-compare -Wstrict-aliasing -fstrict-aliasing -Wfloat-conversion -fvisibility=hidden -fvisibility-inlines-hidden"
|
||||||
<toolset>msvc:<cxxflags>"/bigobj"
|
<toolset>msvc:<cxxflags>"/bigobj"
|
||||||
<toolset>intel-win:<cxxflags>"/bigobj"
|
<toolset>intel-win:<cxxflags>"/bigobj"
|
||||||
|
@ -89,7 +89,8 @@ public:
|
|||||||
|
|
||||||
/// Return standard interval with 68.3 % confidence level (Wilson score interval).
|
/// Return standard interval with 68.3 % confidence level (Wilson score interval).
|
||||||
interval_type confidence_interval() const noexcept {
|
interval_type confidence_interval() const noexcept {
|
||||||
return utility::wilson_interval<real_type>()(successes(), failures());
|
return utility::wilson_interval<real_type>()(static_cast<real_type>(successes()),
|
||||||
|
static_cast<real_type>(failures()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const fraction& rhs) const noexcept {
|
bool operator==(const fraction& rhs) const noexcept {
|
||||||
|
@ -52,14 +52,6 @@ class category : public iterator_mixin<category<Value, MetaData, Options, Alloca
|
|||||||
using allocator_type = Allocator;
|
using allocator_type = Allocator;
|
||||||
using vector_type = std::vector<value_type, allocator_type>;
|
using vector_type = std::vector<value_type, allocator_type>;
|
||||||
|
|
||||||
static_assert(!options_type::test(option::underflow),
|
|
||||||
"category axis cannot have underflow");
|
|
||||||
static_assert(!options_type::test(option::circular),
|
|
||||||
"category axis cannot be circular");
|
|
||||||
static_assert(!(options_type::test(option::growth) &&
|
|
||||||
options_type::test(option::overflow)),
|
|
||||||
"growing category axis cannot have entries in overflow bin");
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr category() = default;
|
constexpr category() = default;
|
||||||
explicit category(allocator_type alloc) : vec_(alloc) {}
|
explicit category(allocator_type alloc) : vec_(alloc) {}
|
||||||
@ -76,7 +68,12 @@ public:
|
|||||||
category(It begin, It end, metadata_type meta = {}, options_type options = {},
|
category(It begin, It end, metadata_type meta = {}, options_type options = {},
|
||||||
allocator_type alloc = {})
|
allocator_type alloc = {})
|
||||||
: metadata_base(std::move(meta)), vec_(alloc) {
|
: metadata_base(std::move(meta)), vec_(alloc) {
|
||||||
(void)options;
|
// static_asserts were moved here from class scope to satisfy deduction in gcc>=11
|
||||||
|
static_assert(!options.test(option::underflow),
|
||||||
|
"category axis cannot have underflow");
|
||||||
|
static_assert(!options.test(option::circular), "category axis cannot be circular");
|
||||||
|
static_assert(!(options.test(option::growth) && options.test(option::overflow)),
|
||||||
|
"growing category axis cannot have entries in overflow bin");
|
||||||
if (std::distance(begin, end) < 0)
|
if (std::distance(begin, end) < 0)
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
std::invalid_argument("end must be reachable by incrementing begin"));
|
std::invalid_argument("end must be reachable by incrementing begin"));
|
||||||
@ -84,9 +81,11 @@ public:
|
|||||||
while (begin != end) vec_.emplace_back(*begin++);
|
while (begin != end) vec_.emplace_back(*begin++);
|
||||||
}
|
}
|
||||||
|
|
||||||
// kept for backward compatibility
|
// kept for backward compatibility; requires_allocator is a workaround for deduction
|
||||||
template <class It, class = detail::requires_iterator<It>>
|
// guides in gcc>=11
|
||||||
category(It begin, It end, metadata_type meta, allocator_type alloc)
|
template <class It, class A, class = detail::requires_iterator<It>,
|
||||||
|
class = detail::requires_allocator<A>>
|
||||||
|
category(It begin, It end, metadata_type meta, A alloc)
|
||||||
: category(begin, end, std::move(meta), {}, std::move(alloc)) {}
|
: category(begin, end, std::move(meta), {}, std::move(alloc)) {}
|
||||||
|
|
||||||
/** Construct axis from iterable sequence of unique values.
|
/** Construct axis from iterable sequence of unique values.
|
||||||
@ -102,9 +101,11 @@ public:
|
|||||||
: category(std::begin(iterable), std::end(iterable), std::move(meta), options,
|
: category(std::begin(iterable), std::end(iterable), std::move(meta), options,
|
||||||
std::move(alloc)) {}
|
std::move(alloc)) {}
|
||||||
|
|
||||||
// kept for backward compatibility
|
// kept for backward compatibility; requires_allocator is a workaround for deduction
|
||||||
template <class C, class = detail::requires_iterable<C>>
|
// guides in gcc>=11
|
||||||
category(const C& iterable, metadata_type meta, allocator_type alloc)
|
template <class C, class A, class = detail::requires_iterable<C>,
|
||||||
|
class = detail::requires_allocator<A>>
|
||||||
|
category(const C& iterable, metadata_type meta, A alloc)
|
||||||
: category(std::begin(iterable), std::end(iterable), std::move(meta), {},
|
: category(std::begin(iterable), std::end(iterable), std::move(meta), {},
|
||||||
std::move(alloc)) {}
|
std::move(alloc)) {}
|
||||||
|
|
||||||
@ -120,9 +121,10 @@ public:
|
|||||||
options_type options = {}, allocator_type alloc = {})
|
options_type options = {}, allocator_type alloc = {})
|
||||||
: category(list.begin(), list.end(), std::move(meta), options, std::move(alloc)) {}
|
: category(list.begin(), list.end(), std::move(meta), options, std::move(alloc)) {}
|
||||||
|
|
||||||
// kept for backward compatibility
|
// kept for backward compatibility; requires_allocator is a workaround for deduction
|
||||||
template <class U>
|
// guides in gcc>=11
|
||||||
category(std::initializer_list<U> list, metadata_type meta, allocator_type alloc)
|
template <class U, class A, class = detail::requires_allocator<A>>
|
||||||
|
category(std::initializer_list<U> list, metadata_type meta, A alloc)
|
||||||
: category(list.begin(), list.end(), std::move(meta), {}, std::move(alloc)) {}
|
: category(list.begin(), list.end(), std::move(meta), {}, std::move(alloc)) {}
|
||||||
|
|
||||||
/// Constructor used by algorithm::reduce to shrink and rebin (not for users).
|
/// Constructor used by algorithm::reduce to shrink and rebin (not for users).
|
||||||
|
@ -194,22 +194,9 @@ class regular : public iterator_mixin<regular<Value, Transform, MetaData, Option
|
|||||||
using options_type =
|
using options_type =
|
||||||
detail::replace_default<Options, decltype(option::underflow | option::overflow)>;
|
detail::replace_default<Options, decltype(option::underflow | option::overflow)>;
|
||||||
|
|
||||||
static_assert(std::is_nothrow_move_constructible<transform_type>::value,
|
|
||||||
"transform must be no-throw move constructible");
|
|
||||||
static_assert(std::is_nothrow_move_assignable<transform_type>::value,
|
|
||||||
"transform must be no-throw move assignable");
|
|
||||||
|
|
||||||
using unit_type = detail::get_unit_type<value_type>;
|
using unit_type = detail::get_unit_type<value_type>;
|
||||||
using internal_value_type = detail::get_scale_type<value_type>;
|
using internal_value_type = detail::get_scale_type<value_type>;
|
||||||
|
|
||||||
static_assert(std::is_floating_point<internal_value_type>::value,
|
|
||||||
"regular axis requires floating point type");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
(!options_type::test(option::circular) && !options_type::test(option::growth)) ||
|
|
||||||
(options_type::test(option::circular) ^ options_type::test(option::growth)),
|
|
||||||
"circular and growth options are mutually exclusive");
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr regular() = default;
|
constexpr regular() = default;
|
||||||
|
|
||||||
@ -229,7 +216,16 @@ public:
|
|||||||
, size_(static_cast<index_type>(n))
|
, size_(static_cast<index_type>(n))
|
||||||
, min_(this->forward(detail::get_scale(start)))
|
, min_(this->forward(detail::get_scale(start)))
|
||||||
, delta_(this->forward(detail::get_scale(stop)) - min_) {
|
, delta_(this->forward(detail::get_scale(stop)) - min_) {
|
||||||
(void)options;
|
// static_asserts were moved here from class scope to satisfy deduction in gcc>=11
|
||||||
|
static_assert(std::is_nothrow_move_constructible<transform_type>::value,
|
||||||
|
"transform must be no-throw move constructible");
|
||||||
|
static_assert(std::is_nothrow_move_assignable<transform_type>::value,
|
||||||
|
"transform must be no-throw move assignable");
|
||||||
|
static_assert(std::is_floating_point<internal_value_type>::value,
|
||||||
|
"regular axis requires floating point type");
|
||||||
|
static_assert((!options.test(option::circular) && !options.test(option::growth)) ||
|
||||||
|
(options.test(option::circular) ^ options.test(option::growth)),
|
||||||
|
"circular and growth options are mutually exclusive");
|
||||||
if (size() == 0) BOOST_THROW_EXCEPTION(std::invalid_argument("bins > 0 required"));
|
if (size() == 0) BOOST_THROW_EXCEPTION(std::invalid_argument("bins > 0 required"));
|
||||||
if (!std::isfinite(min_) || !std::isfinite(delta_))
|
if (!std::isfinite(min_) || !std::isfinite(delta_))
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
@ -246,8 +242,8 @@ public:
|
|||||||
@param meta description of the axis (optional).
|
@param meta description of the axis (optional).
|
||||||
@param options see boost::histogram::axis::option (optional).
|
@param options see boost::histogram::axis::option (optional).
|
||||||
*/
|
*/
|
||||||
regular(unsigned n, value_type start, value_type stop, metadata_type meta = {},
|
explicit regular(unsigned n, value_type start, value_type stop, metadata_type meta = {},
|
||||||
options_type options = {})
|
options_type options = {})
|
||||||
: regular({}, n, start, stop, std::move(meta), options) {}
|
: regular({}, n, start, stop, std::move(meta), options) {}
|
||||||
|
|
||||||
/** Construct bins with the given step size over real transformed range
|
/** Construct bins with the given step size over real transformed range
|
||||||
@ -265,8 +261,8 @@ public:
|
|||||||
(start + n * step).
|
(start + n * step).
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
regular(transform_type trans, step_type<T> step, value_type start, value_type stop,
|
explicit regular(transform_type trans, step_type<T> step, value_type start,
|
||||||
metadata_type meta = {}, options_type options = {})
|
value_type stop, metadata_type meta = {}, options_type options = {})
|
||||||
: regular(trans, static_cast<index_type>(std::abs(stop - start) / step.value),
|
: regular(trans, static_cast<index_type>(std::abs(stop - start) / step.value),
|
||||||
start,
|
start,
|
||||||
start + static_cast<index_type>(std::abs(stop - start) / step.value) *
|
start + static_cast<index_type>(std::abs(stop - start) / step.value) *
|
||||||
@ -286,8 +282,8 @@ public:
|
|||||||
(start + n * step).
|
(start + n * step).
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
regular(step_type<T> step, value_type start, value_type stop, metadata_type meta = {},
|
explicit regular(step_type<T> step, value_type start, value_type stop,
|
||||||
options_type options = {})
|
metadata_type meta = {}, options_type options = {})
|
||||||
: regular({}, step, start, stop, std::move(meta), options) {}
|
: regular({}, step, start, stop, std::move(meta), options) {}
|
||||||
|
|
||||||
/// Constructor used by algorithm::reduce to shrink and rebin (not for users).
|
/// Constructor used by algorithm::reduce to shrink and rebin (not for users).
|
||||||
|
@ -64,16 +64,6 @@ class variable : public iterator_mixin<variable<Value, MetaData, Options, Alloca
|
|||||||
using allocator_type = Allocator;
|
using allocator_type = Allocator;
|
||||||
using vector_type = std::vector<Value, allocator_type>;
|
using vector_type = std::vector<Value, allocator_type>;
|
||||||
|
|
||||||
static_assert(
|
|
||||||
std::is_floating_point<value_type>::value,
|
|
||||||
"current version of variable axis requires floating point type; "
|
|
||||||
"if you need a variable axis with an integral type, please submit an issue");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
(!options_type::test(option::circular) && !options_type::test(option::growth)) ||
|
|
||||||
(options_type::test(option::circular) ^ options_type::test(option::growth)),
|
|
||||||
"circular and growth options are mutually exclusive");
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr variable() = default;
|
constexpr variable() = default;
|
||||||
explicit variable(allocator_type alloc) : vec_(alloc) {}
|
explicit variable(allocator_type alloc) : vec_(alloc) {}
|
||||||
@ -90,7 +80,14 @@ public:
|
|||||||
variable(It begin, It end, metadata_type meta = {}, options_type options = {},
|
variable(It begin, It end, metadata_type meta = {}, options_type options = {},
|
||||||
allocator_type alloc = {})
|
allocator_type alloc = {})
|
||||||
: metadata_base(std::move(meta)), vec_(std::move(alloc)) {
|
: metadata_base(std::move(meta)), vec_(std::move(alloc)) {
|
||||||
(void)options;
|
// static_asserts were moved here from class scope to satisfy deduction in gcc>=11
|
||||||
|
static_assert(
|
||||||
|
std::is_floating_point<value_type>::value,
|
||||||
|
"current version of variable axis requires floating point type; "
|
||||||
|
"if you need a variable axis with an integral type, please submit an issue");
|
||||||
|
static_assert((!options.test(option::circular) && !options.test(option::growth)) ||
|
||||||
|
(options.test(option::circular) ^ options.test(option::growth)),
|
||||||
|
"circular and growth options are mutually exclusive");
|
||||||
|
|
||||||
if (std::distance(begin, end) < 2)
|
if (std::distance(begin, end) < 2)
|
||||||
BOOST_THROW_EXCEPTION(std::invalid_argument("bins > 0 required"));
|
BOOST_THROW_EXCEPTION(std::invalid_argument("bins > 0 required"));
|
||||||
@ -107,9 +104,11 @@ public:
|
|||||||
std::invalid_argument("input sequence must be strictly ascending"));
|
std::invalid_argument("input sequence must be strictly ascending"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// kept for backward compatibility
|
// kept for backward compatibility; requires_allocator is a workaround for deduction
|
||||||
template <class It, class = detail::requires_iterator<It>>
|
// guides in gcc>=11
|
||||||
variable(It begin, It end, metadata_type meta, allocator_type alloc)
|
template <class It, class A, class = detail::requires_iterator<It>,
|
||||||
|
class = detail::requires_allocator<A>>
|
||||||
|
variable(It begin, It end, metadata_type meta, A alloc)
|
||||||
: variable(begin, end, std::move(meta), {}, std::move(alloc)) {}
|
: variable(begin, end, std::move(meta), {}, std::move(alloc)) {}
|
||||||
|
|
||||||
/** Construct variable axis from iterable range of bin edges.
|
/** Construct variable axis from iterable range of bin edges.
|
||||||
@ -125,9 +124,11 @@ public:
|
|||||||
: variable(std::begin(iterable), std::end(iterable), std::move(meta), options,
|
: variable(std::begin(iterable), std::end(iterable), std::move(meta), options,
|
||||||
std::move(alloc)) {}
|
std::move(alloc)) {}
|
||||||
|
|
||||||
// kept for backward compatibility
|
// kept for backward compatibility; requires_allocator is a workaround for deduction
|
||||||
template <class U, class = detail::requires_iterable<U>>
|
// guides in gcc>=11
|
||||||
variable(const U& iterable, metadata_type meta, allocator_type alloc)
|
template <class U, class A, class = detail::requires_iterable<U>,
|
||||||
|
class = detail::requires_allocator<A>>
|
||||||
|
variable(const U& iterable, metadata_type meta, A alloc)
|
||||||
: variable(std::begin(iterable), std::end(iterable), std::move(meta), {},
|
: variable(std::begin(iterable), std::end(iterable), std::move(meta), {},
|
||||||
std::move(alloc)) {}
|
std::move(alloc)) {}
|
||||||
|
|
||||||
@ -143,9 +144,10 @@ public:
|
|||||||
options_type options = {}, allocator_type alloc = {})
|
options_type options = {}, allocator_type alloc = {})
|
||||||
: variable(list.begin(), list.end(), std::move(meta), options, std::move(alloc)) {}
|
: variable(list.begin(), list.end(), std::move(meta), options, std::move(alloc)) {}
|
||||||
|
|
||||||
// kept for backward compatibility
|
// kept for backward compatibility; requires_allocator is a workaround for deduction
|
||||||
template <class U>
|
// guides in gcc>=11
|
||||||
variable(std::initializer_list<U> list, metadata_type meta, allocator_type alloc)
|
template <class U, class A, class = detail::requires_allocator<A>>
|
||||||
|
variable(std::initializer_list<U> list, metadata_type meta, A alloc)
|
||||||
: variable(list.begin(), list.end(), std::move(meta), {}, std::move(alloc)) {}
|
: variable(list.begin(), list.end(), std::move(meta), {}, std::move(alloc)) {}
|
||||||
|
|
||||||
/// Constructor used by algorithm::reduce to shrink and rebin (not for users).
|
/// Constructor used by algorithm::reduce to shrink and rebin (not for users).
|
||||||
|
@ -93,6 +93,8 @@ BOOST_HISTOGRAM_DETAIL_DETECT(is_iterator,
|
|||||||
|
|
||||||
BOOST_HISTOGRAM_DETAIL_DETECT(is_streamable, (std::declval<std::ostream&>() << t));
|
BOOST_HISTOGRAM_DETAIL_DETECT(is_streamable, (std::declval<std::ostream&>() << t));
|
||||||
|
|
||||||
|
BOOST_HISTOGRAM_DETAIL_DETECT(is_allocator, (&T::allocate, &T::deallocate));
|
||||||
|
|
||||||
BOOST_HISTOGRAM_DETAIL_DETECT(has_operator_preincrement, ++t);
|
BOOST_HISTOGRAM_DETAIL_DETECT(has_operator_preincrement, ++t);
|
||||||
|
|
||||||
BOOST_HISTOGRAM_DETAIL_DETECT_BINARY(has_operator_equal, (cref<T>() == u));
|
BOOST_HISTOGRAM_DETAIL_DETECT_BINARY(has_operator_equal, (cref<T>() == u));
|
||||||
@ -164,7 +166,8 @@ template <class T>
|
|||||||
using is_sequence_of_any_axis =
|
using is_sequence_of_any_axis =
|
||||||
mp11::mp_and<is_iterable<T>, is_any_axis<mp11::mp_first<T>>>;
|
mp11::mp_and<is_iterable<T>, is_any_axis<mp11::mp_first<T>>>;
|
||||||
|
|
||||||
// poor-mans concept checks
|
// Poor-mans concept checks.
|
||||||
|
// These must be structs not aliases, so their names pop up in compiler errors.
|
||||||
template <class T, class = std::enable_if_t<is_storage<std::decay_t<T>>::value>>
|
template <class T, class = std::enable_if_t<is_storage<std::decay_t<T>>::value>>
|
||||||
struct requires_storage {};
|
struct requires_storage {};
|
||||||
|
|
||||||
@ -204,6 +207,9 @@ template <class T, class U,
|
|||||||
class = std::enable_if_t<is_transform<std::decay_t<T>, U>::value>>
|
class = std::enable_if_t<is_transform<std::decay_t<T>, U>::value>>
|
||||||
struct requires_transform {};
|
struct requires_transform {};
|
||||||
|
|
||||||
|
template <class T, class = std::enable_if_t<is_allocator<std::decay_t<T>>::value>>
|
||||||
|
struct requires_allocator {};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace histogram
|
} // namespace histogram
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
Loading…
x
Reference in New Issue
Block a user