diff --git a/.github/workflows/slow.yml b/.github/workflows/slow.yml index d2fc0493..ecf4b041 100644 --- a/.github/workflows/slow.yml +++ b/.github/workflows/slow.yml @@ -89,7 +89,7 @@ jobs: cd libs/histogram ../../b2 $B2_OPTS toolset=gcc-10 cxxstd=20 cxxflags="-O3 -funsafe-math-optimizations" test//all examples - clang10: + clang14: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -107,4 +107,4 @@ jobs: - name: Test cxxstd=17 ubsan asan run: | 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 diff --git a/Jamfile b/Jamfile index 0ed23810..de6e5312 100644 --- a/Jamfile +++ b/Jamfile @@ -18,6 +18,7 @@ project /boost//headers $(BOOST_ROOT) clang:"-pedantic -Wextra -Wsign-compare -Wstrict-aliasing -fstrict-aliasing -Wvexing-parse -Wfloat-conversion -fvisibility=hidden -fvisibility-inlines-hidden" + darwin:"-pedantic -Wextra -Wsign-compare -Wstrict-aliasing -fstrict-aliasing -Wvexing-parse -Wfloat-conversion -fvisibility=hidden -fvisibility-inlines-hidden" gcc:"-pedantic -Wextra -Wsign-compare -Wstrict-aliasing -fstrict-aliasing -Wfloat-conversion -fvisibility=hidden -fvisibility-inlines-hidden" msvc:"/bigobj" intel-win:"/bigobj" diff --git a/include/boost/histogram/accumulators/fraction.hpp b/include/boost/histogram/accumulators/fraction.hpp index acd1b2ea..81fd41c5 100644 --- a/include/boost/histogram/accumulators/fraction.hpp +++ b/include/boost/histogram/accumulators/fraction.hpp @@ -89,7 +89,8 @@ public: /// Return standard interval with 68.3 % confidence level (Wilson score interval). interval_type confidence_interval() const noexcept { - return utility::wilson_interval()(successes(), failures()); + return utility::wilson_interval()(static_cast(successes()), + static_cast(failures())); } bool operator==(const fraction& rhs) const noexcept { diff --git a/include/boost/histogram/axis/category.hpp b/include/boost/histogram/axis/category.hpp index bcaececc..0c705afb 100644 --- a/include/boost/histogram/axis/category.hpp +++ b/include/boost/histogram/axis/category.hpp @@ -52,14 +52,6 @@ class category : public iterator_mixin; - 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: constexpr category() = default; explicit category(allocator_type alloc) : vec_(alloc) {} @@ -76,7 +68,12 @@ public: category(It begin, It end, metadata_type meta = {}, options_type options = {}, allocator_type 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) BOOST_THROW_EXCEPTION( std::invalid_argument("end must be reachable by incrementing begin")); @@ -84,9 +81,11 @@ public: while (begin != end) vec_.emplace_back(*begin++); } - // kept for backward compatibility - template > - category(It begin, It end, metadata_type meta, allocator_type alloc) + // kept for backward compatibility; requires_allocator is a workaround for deduction + // guides in gcc>=11 + template , + class = detail::requires_allocator> + category(It begin, It end, metadata_type meta, A alloc) : category(begin, end, std::move(meta), {}, std::move(alloc)) {} /** Construct axis from iterable sequence of unique values. @@ -102,9 +101,11 @@ public: : category(std::begin(iterable), std::end(iterable), std::move(meta), options, std::move(alloc)) {} - // kept for backward compatibility - template > - category(const C& iterable, metadata_type meta, allocator_type alloc) + // kept for backward compatibility; requires_allocator is a workaround for deduction + // guides in gcc>=11 + template , + class = detail::requires_allocator> + category(const C& iterable, metadata_type meta, A alloc) : category(std::begin(iterable), std::end(iterable), std::move(meta), {}, std::move(alloc)) {} @@ -120,9 +121,10 @@ public: options_type options = {}, allocator_type alloc = {}) : category(list.begin(), list.end(), std::move(meta), options, std::move(alloc)) {} - // kept for backward compatibility - template - category(std::initializer_list list, metadata_type meta, allocator_type alloc) + // kept for backward compatibility; requires_allocator is a workaround for deduction + // guides in gcc>=11 + template > + category(std::initializer_list list, metadata_type meta, A alloc) : category(list.begin(), list.end(), std::move(meta), {}, std::move(alloc)) {} /// Constructor used by algorithm::reduce to shrink and rebin (not for users). diff --git a/include/boost/histogram/axis/regular.hpp b/include/boost/histogram/axis/regular.hpp index 403931f8..2fb5dee0 100644 --- a/include/boost/histogram/axis/regular.hpp +++ b/include/boost/histogram/axis/regular.hpp @@ -194,22 +194,9 @@ class regular : public iterator_mixin; - static_assert(std::is_nothrow_move_constructible::value, - "transform must be no-throw move constructible"); - static_assert(std::is_nothrow_move_assignable::value, - "transform must be no-throw move assignable"); - using unit_type = detail::get_unit_type; using internal_value_type = detail::get_scale_type; - static_assert(std::is_floating_point::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: constexpr regular() = default; @@ -229,7 +216,16 @@ public: , size_(static_cast(n)) , min_(this->forward(detail::get_scale(start))) , 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::value, + "transform must be no-throw move constructible"); + static_assert(std::is_nothrow_move_assignable::value, + "transform must be no-throw move assignable"); + static_assert(std::is_floating_point::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 (!std::isfinite(min_) || !std::isfinite(delta_)) BOOST_THROW_EXCEPTION( @@ -246,8 +242,8 @@ public: @param meta description of the axis (optional). @param options see boost::histogram::axis::option (optional). */ - regular(unsigned n, value_type start, value_type stop, metadata_type meta = {}, - options_type options = {}) + explicit regular(unsigned n, value_type start, value_type stop, metadata_type meta = {}, + options_type options = {}) : regular({}, n, start, stop, std::move(meta), options) {} /** Construct bins with the given step size over real transformed range @@ -265,8 +261,8 @@ public: (start + n * step). */ template - regular(transform_type trans, step_type step, value_type start, value_type stop, - metadata_type meta = {}, options_type options = {}) + explicit regular(transform_type trans, step_type step, value_type start, + value_type stop, metadata_type meta = {}, options_type options = {}) : regular(trans, static_cast(std::abs(stop - start) / step.value), start, start + static_cast(std::abs(stop - start) / step.value) * @@ -286,8 +282,8 @@ public: (start + n * step). */ template - regular(step_type step, value_type start, value_type stop, metadata_type meta = {}, - options_type options = {}) + explicit regular(step_type step, value_type start, value_type stop, + metadata_type meta = {}, options_type options = {}) : regular({}, step, start, stop, std::move(meta), options) {} /// Constructor used by algorithm::reduce to shrink and rebin (not for users). diff --git a/include/boost/histogram/axis/variable.hpp b/include/boost/histogram/axis/variable.hpp index d34df5ed..f866e098 100644 --- a/include/boost/histogram/axis/variable.hpp +++ b/include/boost/histogram/axis/variable.hpp @@ -64,16 +64,6 @@ class variable : public iterator_mixin; - static_assert( - std::is_floating_point::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: constexpr variable() = default; explicit variable(allocator_type alloc) : vec_(alloc) {} @@ -90,7 +80,14 @@ public: variable(It begin, It end, metadata_type meta = {}, options_type options = {}, allocator_type 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, + "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) BOOST_THROW_EXCEPTION(std::invalid_argument("bins > 0 required")); @@ -107,9 +104,11 @@ public: std::invalid_argument("input sequence must be strictly ascending")); } - // kept for backward compatibility - template > - variable(It begin, It end, metadata_type meta, allocator_type alloc) + // kept for backward compatibility; requires_allocator is a workaround for deduction + // guides in gcc>=11 + template , + class = detail::requires_allocator> + variable(It begin, It end, metadata_type meta, A alloc) : variable(begin, end, std::move(meta), {}, std::move(alloc)) {} /** 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, std::move(alloc)) {} - // kept for backward compatibility - template > - variable(const U& iterable, metadata_type meta, allocator_type alloc) + // kept for backward compatibility; requires_allocator is a workaround for deduction + // guides in gcc>=11 + template , + class = detail::requires_allocator> + variable(const U& iterable, metadata_type meta, A alloc) : variable(std::begin(iterable), std::end(iterable), std::move(meta), {}, std::move(alloc)) {} @@ -143,9 +144,10 @@ public: options_type options = {}, allocator_type alloc = {}) : variable(list.begin(), list.end(), std::move(meta), options, std::move(alloc)) {} - // kept for backward compatibility - template - variable(std::initializer_list list, metadata_type meta, allocator_type alloc) + // kept for backward compatibility; requires_allocator is a workaround for deduction + // guides in gcc>=11 + template > + variable(std::initializer_list list, metadata_type meta, A alloc) : variable(list.begin(), list.end(), std::move(meta), {}, std::move(alloc)) {} /// Constructor used by algorithm::reduce to shrink and rebin (not for users). diff --git a/include/boost/histogram/detail/detect.hpp b/include/boost/histogram/detail/detect.hpp index 2e5a3348..68cc9b70 100644 --- a/include/boost/histogram/detail/detect.hpp +++ b/include/boost/histogram/detail/detect.hpp @@ -93,6 +93,8 @@ BOOST_HISTOGRAM_DETAIL_DETECT(is_iterator, BOOST_HISTOGRAM_DETAIL_DETECT(is_streamable, (std::declval() << t)); +BOOST_HISTOGRAM_DETAIL_DETECT(is_allocator, (&T::allocate, &T::deallocate)); + BOOST_HISTOGRAM_DETAIL_DETECT(has_operator_preincrement, ++t); BOOST_HISTOGRAM_DETAIL_DETECT_BINARY(has_operator_equal, (cref() == u)); @@ -164,7 +166,8 @@ template using is_sequence_of_any_axis = mp11::mp_and, is_any_axis>>; -// poor-mans concept checks +// Poor-mans concept checks. +// These must be structs not aliases, so their names pop up in compiler errors. template >::value>> struct requires_storage {}; @@ -204,6 +207,9 @@ template , U>::value>> struct requires_transform {}; +template >::value>> +struct requires_allocator {}; + } // namespace detail } // namespace histogram } // namespace boost