From ffe3e4d68c8124af5f370ac510de14f55eabc43e Mon Sep 17 00:00:00 2001 From: Hans Dembinski Date: Sun, 29 Sep 2019 12:56:11 +0200 Subject: [PATCH] assert on and test invalid combinations of axis options (#227) --- include/boost/histogram/axis/category.hpp | 7 ++++--- include/boost/histogram/axis/integer.hpp | 16 ++++++++++++---- include/boost/histogram/axis/regular.hpp | 6 ++++++ include/boost/histogram/axis/variable.hpp | 13 ++++++++++--- test/Jamfile | 15 +++++++++++++-- test/axis_category_fail0.cpp | 14 ++++++++++++++ test/axis_category_fail1.cpp | 14 ++++++++++++++ test/axis_category_fail2.cpp | 15 +++++++++++++++ test/axis_integer_fail0.cpp | 15 +++++++++++++++ test/axis_integer_fail1.cpp | 15 +++++++++++++++ test/axis_integer_fail2.cpp | 15 +++++++++++++++ test/axis_integer_fail3.cpp | 15 +++++++++++++++ test/axis_integer_fail4.cpp | 15 +++++++++++++++ test/axis_regular_fail0.cpp | 14 ++++++++++++++ test/axis_regular_fail1.cpp | 15 +++++++++++++++ test/axis_variable_fail0.cpp | 14 ++++++++++++++ test/axis_variable_fail1.cpp | 16 ++++++++++++++++ test/histogram_fill_test.cpp | 12 +++++------- 18 files changed, 227 insertions(+), 19 deletions(-) create mode 100644 test/axis_category_fail0.cpp create mode 100644 test/axis_category_fail1.cpp create mode 100644 test/axis_category_fail2.cpp create mode 100644 test/axis_integer_fail0.cpp create mode 100644 test/axis_integer_fail1.cpp create mode 100644 test/axis_integer_fail2.cpp create mode 100644 test/axis_integer_fail3.cpp create mode 100644 test/axis_integer_fail4.cpp create mode 100644 test/axis_regular_fail0.cpp create mode 100644 test/axis_regular_fail1.cpp create mode 100644 test/axis_variable_fail0.cpp create mode 100644 test/axis_variable_fail1.cpp diff --git a/include/boost/histogram/axis/category.hpp b/include/boost/histogram/axis/category.hpp index 3a0197ee..3078e388 100644 --- a/include/boost/histogram/axis/category.hpp +++ b/include/boost/histogram/axis/category.hpp @@ -47,15 +47,16 @@ class category : public iterator_mixin; using options_type = detail::replace_default; + using allocator_type = Allocator; + using vector_type = std::vector; + 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 overflow"); - using allocator_type = Allocator; - using vector_type = std::vector; + "growing category axis cannot have entries in overflow bin"); public: explicit category(allocator_type alloc = {}) : vec_meta_(vector_type(alloc)) {} diff --git a/include/boost/histogram/axis/integer.hpp b/include/boost/histogram/axis/integer.hpp index 855e9584..83bf6886 100644 --- a/include/boost/histogram/axis/integer.hpp +++ b/include/boost/histogram/axis/integer.hpp @@ -50,10 +50,18 @@ class integer : public iterator_mixin> { using options_type = detail::replace_default; - static_assert(!options_type::test(option::circular) || - std::is_floating_point::value || - !options_type::test(option::overflow), - "integer axis with integral type cannot have overflow"); + 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"); + + static_assert(std::is_floating_point::value || + (!options_type::test(option::circular) && + !options_type::test(option::growth)) || + (!options_type::test(option::overflow) && + !options_type::test(option::underflow)), + "circular or growing integer axis with integral type " + "cannot have entries in underflow or overflow bins"); public: constexpr integer() = default; diff --git a/include/boost/histogram/axis/regular.hpp b/include/boost/histogram/axis/regular.hpp index bbc58012..d292a639 100644 --- a/include/boost/histogram/axis/regular.hpp +++ b/include/boost/histogram/axis/regular.hpp @@ -171,9 +171,15 @@ class regular : public iterator_mixin; 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; regular(const regular&) = default; diff --git a/include/boost/histogram/axis/variable.hpp b/include/boost/histogram/axis/variable.hpp index cd53821a..e9298863 100644 --- a/include/boost/histogram/axis/variable.hpp +++ b/include/boost/histogram/axis/variable.hpp @@ -46,9 +46,6 @@ namespace axis { */ template class variable : public iterator_mixin> { - static_assert(std::is_floating_point::value, - "variable axis requires floating point type"); - using value_type = Value; using metadata_type = detail::replace_default; using options_type = @@ -56,6 +53,16 @@ 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: explicit variable(allocator_type alloc = {}) : vec_meta_(vec_type{alloc}) {} variable(const variable&) = default; diff --git a/test/Jamfile b/test/Jamfile index ef87b9da..7a053af1 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -71,6 +71,18 @@ alias cxx17 : # check that useful error messages are produced when library is used incorrectly alias failure : + [ compile-fail axis_category_fail0.cpp ] + [ compile-fail axis_category_fail1.cpp ] + [ compile-fail axis_category_fail2.cpp ] + [ compile-fail axis_integer_fail0.cpp ] + [ compile-fail axis_integer_fail1.cpp ] + [ compile-fail axis_integer_fail2.cpp ] + [ compile-fail axis_integer_fail3.cpp ] + [ compile-fail axis_integer_fail4.cpp ] + [ compile-fail axis_regular_fail0.cpp ] + [ compile-fail axis_regular_fail1.cpp ] + [ compile-fail axis_variable_fail0.cpp ] + [ compile-fail axis_variable_fail1.cpp ] [ compile-fail make_histogram_fail0.cpp ] [ compile-fail make_histogram_fail1.cpp ] ; @@ -100,8 +112,7 @@ alias libserial : static off on ; -# "failure" not included in "all", because it is distracting -alias all : cxx14 cxx17 threading accumulators range units serialization ; +alias all : cxx14 cxx17 failure threading accumulators range units serialization ; alias minimal : cxx14 cxx17 threading ; explicit cxx14 ; diff --git a/test/axis_category_fail0.cpp b/test/axis_category_fail0.cpp new file mode 100644 index 00000000..cc6d1cce --- /dev/null +++ b/test/axis_category_fail0.cpp @@ -0,0 +1,14 @@ +// 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) + +#include + +using namespace boost::histogram; + +int main() { + // category axis cannot be circular + (void)axis::category({1, 2}); +} diff --git a/test/axis_category_fail1.cpp b/test/axis_category_fail1.cpp new file mode 100644 index 00000000..cda21cd6 --- /dev/null +++ b/test/axis_category_fail1.cpp @@ -0,0 +1,14 @@ +// 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) + +#include + +using namespace boost::histogram; + +int main() { + // category axis cannot have underflow + (void)axis::category({1, 2}); +} diff --git a/test/axis_category_fail2.cpp b/test/axis_category_fail2.cpp new file mode 100644 index 00000000..53d2de9d --- /dev/null +++ b/test/axis_category_fail2.cpp @@ -0,0 +1,15 @@ +// 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) + +#include + +using namespace boost::histogram; + +int main() { + // growing category axis cannot have entries in overflow bin + (void)axis::category({1, 2}); +} diff --git a/test/axis_integer_fail0.cpp b/test/axis_integer_fail0.cpp new file mode 100644 index 00000000..e9eb8614 --- /dev/null +++ b/test/axis_integer_fail0.cpp @@ -0,0 +1,15 @@ +// 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) + +#include + +using namespace boost::histogram; + +int main() { + // circular integer axis cannot be growing + (void)axis::integer(1, 2); +} diff --git a/test/axis_integer_fail1.cpp b/test/axis_integer_fail1.cpp new file mode 100644 index 00000000..2a1efad5 --- /dev/null +++ b/test/axis_integer_fail1.cpp @@ -0,0 +1,15 @@ +// 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) + +#include + +using namespace boost::histogram; + +int main() { + // circular integer axis cannot have entries in underflow or overflow bins + (void)axis::integer(1, 2); +} diff --git a/test/axis_integer_fail2.cpp b/test/axis_integer_fail2.cpp new file mode 100644 index 00000000..fcafc4d4 --- /dev/null +++ b/test/axis_integer_fail2.cpp @@ -0,0 +1,15 @@ +// 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) + +#include + +using namespace boost::histogram; + +int main() { + // circular integer axis cannot have entries in underflow or overflow bins + (void)axis::integer(1, 2); +} diff --git a/test/axis_integer_fail3.cpp b/test/axis_integer_fail3.cpp new file mode 100644 index 00000000..89717794 --- /dev/null +++ b/test/axis_integer_fail3.cpp @@ -0,0 +1,15 @@ +// 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) + +#include + +using namespace boost::histogram; + +int main() { + // growing integer axis cannot have entries in underflow or overflow bins + (void)axis::integer(1, 2); +} diff --git a/test/axis_integer_fail4.cpp b/test/axis_integer_fail4.cpp new file mode 100644 index 00000000..7b25eb30 --- /dev/null +++ b/test/axis_integer_fail4.cpp @@ -0,0 +1,15 @@ +// 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) + +#include + +using namespace boost::histogram; + +int main() { + // growing integer axis cannot have entries in underflow or overflow bins + (void)axis::integer(1, 2); +} diff --git a/test/axis_regular_fail0.cpp b/test/axis_regular_fail0.cpp new file mode 100644 index 00000000..579e13ca --- /dev/null +++ b/test/axis_regular_fail0.cpp @@ -0,0 +1,14 @@ +// 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) + +#include + +using namespace boost::histogram; + +int main() { + // regular axis requires a floating point value type + (void)axis::regular(1, 2, 3); +} diff --git a/test/axis_regular_fail1.cpp b/test/axis_regular_fail1.cpp new file mode 100644 index 00000000..e5263a16 --- /dev/null +++ b/test/axis_regular_fail1.cpp @@ -0,0 +1,15 @@ +// 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) + +#include + +using namespace boost::histogram; + +int main() { + // circular regular axis cannot be growing + (void)axis::regular(1, 2, 3); +} diff --git a/test/axis_variable_fail0.cpp b/test/axis_variable_fail0.cpp new file mode 100644 index 00000000..b98930cb --- /dev/null +++ b/test/axis_variable_fail0.cpp @@ -0,0 +1,14 @@ +// 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) + +#include + +using namespace boost::histogram; + +int main() { + // variable axis requires a floating point value type + (void)axis::variable({1, 2, 3}); +} diff --git a/test/axis_variable_fail1.cpp b/test/axis_variable_fail1.cpp new file mode 100644 index 00000000..2a9ea02f --- /dev/null +++ b/test/axis_variable_fail1.cpp @@ -0,0 +1,16 @@ +// 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) + +#include + +using namespace boost::histogram; + +int main() { + // circular variable axis cannot be growing + (void)axis::variable( + {1, 2, 3}); +} diff --git a/test/histogram_fill_test.cpp b/test/histogram_fill_test.cpp index 7c6e117e..c3a751f4 100644 --- a/test/histogram_fill_test.cpp +++ b/test/histogram_fill_test.cpp @@ -32,9 +32,7 @@ using boost::variant2::variant; using in = axis::integer; using in0 = axis::integer; -using ing = axis::integer; +using ing = axis::integer; struct axis2d { auto size() const { return axis::index_type{2}; } @@ -213,8 +211,8 @@ void run_tests() { for (auto&& xi : x) h(xi); h2.fill(x); - BOOST_TEST_EQ(h.size(), 23); - BOOST_TEST_EQ(h2.size(), 23); + BOOST_TEST_EQ(h.size(), 21); + BOOST_TEST_EQ(h2.size(), 21); BOOST_TEST_EQ(sum(h), sum(h2)); BOOST_TEST_EQ(h, h2); } @@ -235,8 +233,8 @@ void run_tests() { for (unsigned i = 0; i < ndata + 2; ++i) h(xy[0][i], xy[1][i]); h2.fill(xy); - BOOST_TEST_EQ(h.size(), 4 * 23); - BOOST_TEST_EQ(h2.size(), 4 * 23); + BOOST_TEST_EQ(h.size(), 4 * 21); + BOOST_TEST_EQ(h2.size(), 4 * 21); BOOST_TEST_EQ(sum(h), sum(h2)); BOOST_TEST_EQ(h, h2); }