assert on and test invalid combinations of axis options (#227)

This commit is contained in:
Hans Dembinski 2019-09-29 12:56:11 +02:00 committed by GitHub
parent 93ed93b484
commit ffe3e4d68c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 227 additions and 19 deletions

View File

@ -47,15 +47,16 @@ class category : public iterator_mixin<category<Value, MetaData, Options, Alloca
using value_type = Value; using value_type = Value;
using metadata_type = detail::replace_default<MetaData, std::string>; using metadata_type = detail::replace_default<MetaData, std::string>;
using options_type = detail::replace_default<Options, option::overflow_t>; using options_type = detail::replace_default<Options, option::overflow_t>;
using allocator_type = Allocator;
using vector_type = std::vector<value_type, allocator_type>;
static_assert(!options_type::test(option::underflow), static_assert(!options_type::test(option::underflow),
"category axis cannot have underflow"); "category axis cannot have underflow");
static_assert(!options_type::test(option::circular), static_assert(!options_type::test(option::circular),
"category axis cannot be circular"); "category axis cannot be circular");
static_assert(!(options_type::test(option::growth) && static_assert(!(options_type::test(option::growth) &&
options_type::test(option::overflow)), options_type::test(option::overflow)),
"growing category axis cannot have overflow"); "growing category axis cannot have entries in overflow bin");
using allocator_type = Allocator;
using vector_type = std::vector<value_type, allocator_type>;
public: public:
explicit category(allocator_type alloc = {}) : vec_meta_(vector_type(alloc)) {} explicit category(allocator_type alloc = {}) : vec_meta_(vector_type(alloc)) {}

View File

@ -50,10 +50,18 @@ class integer : public iterator_mixin<integer<Value, MetaData, Options>> {
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(!options_type::test(option::circular) || static_assert(
std::is_floating_point<value_type>::value || (!options_type::test(option::circular) && !options_type::test(option::growth)) ||
!options_type::test(option::overflow), (options_type::test(option::circular) ^ options_type::test(option::growth)),
"integer axis with integral type cannot have overflow"); "circular and growth options are mutually exclusive");
static_assert(std::is_floating_point<value_type>::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: public:
constexpr integer() = default; constexpr integer() = default;

View File

@ -171,9 +171,15 @@ class regular : public iterator_mixin<regular<Value, Transform, MetaData, Option
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, static_assert(std::is_floating_point<internal_value_type>::value,
"regular axis requires floating point type"); "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;
regular(const regular&) = default; regular(const regular&) = default;

View File

@ -46,9 +46,6 @@ namespace axis {
*/ */
template <class Value, class MetaData, class Options, class Allocator> template <class Value, class MetaData, class Options, class Allocator>
class variable : public iterator_mixin<variable<Value, MetaData, Options, Allocator>> { class variable : public iterator_mixin<variable<Value, MetaData, Options, Allocator>> {
static_assert(std::is_floating_point<Value>::value,
"variable axis requires floating point type");
using value_type = Value; using value_type = Value;
using metadata_type = detail::replace_default<MetaData, std::string>; using metadata_type = detail::replace_default<MetaData, std::string>;
using options_type = using options_type =
@ -56,6 +53,16 @@ class variable : public iterator_mixin<variable<Value, MetaData, Options, Alloca
using allocator_type = Allocator; using allocator_type = Allocator;
using vec_type = std::vector<Value, allocator_type>; using vec_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:
explicit variable(allocator_type alloc = {}) : vec_meta_(vec_type{alloc}) {} explicit variable(allocator_type alloc = {}) : vec_meta_(vec_type{alloc}) {}
variable(const variable&) = default; variable(const variable&) = default;

View File

@ -71,6 +71,18 @@ alias cxx17 :
# check that useful error messages are produced when library is used incorrectly # check that useful error messages are produced when library is used incorrectly
alias failure : 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_fail0.cpp ]
[ compile-fail make_histogram_fail1.cpp ] [ compile-fail make_histogram_fail1.cpp ]
; ;
@ -100,8 +112,7 @@ alias libserial :
<link>static <warnings>off <rtti>on <link>static <warnings>off <rtti>on
; ;
# "failure" not included in "all", because it is distracting alias all : cxx14 cxx17 failure threading accumulators range units serialization ;
alias all : cxx14 cxx17 threading accumulators range units serialization ;
alias minimal : cxx14 cxx17 threading ; alias minimal : cxx14 cxx17 threading ;
explicit cxx14 ; explicit cxx14 ;

View File

@ -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 <boost/histogram/axis/category.hpp>
using namespace boost::histogram;
int main() {
// category axis cannot be circular
(void)axis::category<int, boost::use_default, axis::option::circular_t>({1, 2});
}

View File

@ -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 <boost/histogram/axis/category.hpp>
using namespace boost::histogram;
int main() {
// category axis cannot have underflow
(void)axis::category<int, boost::use_default, axis::option::underflow_t>({1, 2});
}

View File

@ -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 <boost/histogram/axis/category.hpp>
using namespace boost::histogram;
int main() {
// growing category axis cannot have entries in overflow bin
(void)axis::category<int, boost::use_default,
decltype(axis::option::growth | axis::option::overflow)>({1, 2});
}

View File

@ -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 <boost/histogram/axis/integer.hpp>
using namespace boost::histogram;
int main() {
// circular integer axis cannot be growing
(void)axis::integer<int, boost::use_default,
decltype(axis::option::circular | axis::option::growth)>(1, 2);
}

View File

@ -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 <boost/histogram/axis/integer.hpp>
using namespace boost::histogram;
int main() {
// circular integer axis cannot have entries in underflow or overflow bins
(void)axis::integer<int, boost::use_default,
decltype(axis::option::circular | axis::option::underflow)>(1, 2);
}

View File

@ -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 <boost/histogram/axis/integer.hpp>
using namespace boost::histogram;
int main() {
// circular integer axis cannot have entries in underflow or overflow bins
(void)axis::integer<int, boost::use_default,
decltype(axis::option::circular | axis::option::overflow)>(1, 2);
}

View File

@ -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 <boost/histogram/axis/integer.hpp>
using namespace boost::histogram;
int main() {
// growing integer axis cannot have entries in underflow or overflow bins
(void)axis::integer<int, boost::use_default,
decltype(axis::option::growth | axis::option::underflow)>(1, 2);
}

View File

@ -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 <boost/histogram/axis/integer.hpp>
using namespace boost::histogram;
int main() {
// growing integer axis cannot have entries in underflow or overflow bins
(void)axis::integer<int, boost::use_default,
decltype(axis::option::growth | axis::option::overflow)>(1, 2);
}

View File

@ -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 <boost/histogram/axis/regular.hpp>
using namespace boost::histogram;
int main() {
// regular axis requires a floating point value type
(void)axis::regular<int>(1, 2, 3);
}

View File

@ -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 <boost/histogram/axis/regular.hpp>
using namespace boost::histogram;
int main() {
// circular regular axis cannot be growing
(void)axis::regular<double, boost::use_default, boost::use_default,
decltype(axis::option::circular | axis::option::growth)>(1, 2, 3);
}

View File

@ -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 <boost/histogram/axis/variable.hpp>
using namespace boost::histogram;
int main() {
// variable axis requires a floating point value type
(void)axis::variable<int>({1, 2, 3});
}

View File

@ -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 <boost/histogram/axis/variable.hpp>
using namespace boost::histogram;
int main() {
// circular variable axis cannot be growing
(void)axis::variable<double, boost::use_default,
decltype(axis::option::circular | axis::option::growth)>(
{1, 2, 3});
}

View File

@ -32,9 +32,7 @@ using boost::variant2::variant;
using in = axis::integer<int, axis::null_type>; using in = axis::integer<int, axis::null_type>;
using in0 = axis::integer<int, axis::null_type, axis::option::none_t>; using in0 = axis::integer<int, axis::null_type, axis::option::none_t>;
using ing = axis::integer<int, axis::null_type, using ing = axis::integer<int, axis::null_type, axis::option::growth_t>;
decltype(axis::option::growth | axis::option::underflow |
axis::option::overflow)>;
struct axis2d { struct axis2d {
auto size() const { return axis::index_type{2}; } auto size() const { return axis::index_type{2}; }
@ -213,8 +211,8 @@ void run_tests() {
for (auto&& xi : x) h(xi); for (auto&& xi : x) h(xi);
h2.fill(x); h2.fill(x);
BOOST_TEST_EQ(h.size(), 23); BOOST_TEST_EQ(h.size(), 21);
BOOST_TEST_EQ(h2.size(), 23); BOOST_TEST_EQ(h2.size(), 21);
BOOST_TEST_EQ(sum(h), sum(h2)); BOOST_TEST_EQ(sum(h), sum(h2));
BOOST_TEST_EQ(h, 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]); for (unsigned i = 0; i < ndata + 2; ++i) h(xy[0][i], xy[1][i]);
h2.fill(xy); h2.fill(xy);
BOOST_TEST_EQ(h.size(), 4 * 23); BOOST_TEST_EQ(h.size(), 4 * 21);
BOOST_TEST_EQ(h2.size(), 4 * 23); BOOST_TEST_EQ(h2.size(), 4 * 21);
BOOST_TEST_EQ(sum(h), sum(h2)); BOOST_TEST_EQ(sum(h), sum(h2));
BOOST_TEST_EQ(h, h2); BOOST_TEST_EQ(h, h2);
} }