Fixes for latest compilers (#373)

This commit is contained in:
Hans Dembinski 2022-12-23 00:58:31 +01:00 committed by GitHub
parent 82e75c14b3
commit d475bc9b85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 70 additions and 62 deletions

View File

@ -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

View File

@ -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"

View File

@ -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 {

View File

@ -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).

View File

@ -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).

View File

@ -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).

View File

@ -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