// Copyright 2018 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 #include #include #include #include "std_ostream.hpp" #include "throw_exception.hpp" #include "utility_axis.hpp" using namespace boost::histogram::axis; int main() { // value_type { BOOST_TEST_TRAIT_SAME(traits::value_type>, int); BOOST_TEST_TRAIT_SAME(traits::value_type>, int); BOOST_TEST_TRAIT_SAME(traits::value_type>, double); } // is_continuous { BOOST_TEST_TRAIT_TRUE((traits::is_continuous>)); BOOST_TEST_TRAIT_FALSE((traits::is_continuous>)); BOOST_TEST_TRAIT_FALSE((traits::is_continuous>)); BOOST_TEST_TRAIT_TRUE((traits::is_continuous>)); } // is_reducible { struct not_reducible {}; struct reducible { reducible(const reducible&, index_type, index_type, unsigned); }; BOOST_TEST_TRAIT_TRUE((traits::is_reducible)); BOOST_TEST_TRAIT_FALSE((traits::is_reducible)); BOOST_TEST_TRAIT_TRUE((traits::is_reducible>)); BOOST_TEST_TRAIT_TRUE((traits::is_reducible>)); BOOST_TEST_TRAIT_TRUE((traits::is_reducible>)); BOOST_TEST_TRAIT_TRUE((traits::is_reducible>)); BOOST_TEST_TRAIT_FALSE((traits::is_reducible>)); } // static_is_inclusive { struct empty {}; struct with_opts_not_inclusive { static constexpr unsigned options() { return option::underflow | option::overflow; } static constexpr bool inclusive() { return false; } }; BOOST_TEST_TRAIT_FALSE((traits::static_is_inclusive)); BOOST_TEST_TRAIT_FALSE((traits::static_is_inclusive)); BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive>)); BOOST_TEST_TRAIT_FALSE( (traits::static_is_inclusive< regular>)); BOOST_TEST_TRAIT_FALSE( (traits::static_is_inclusive>)); BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive>)); BOOST_TEST_TRAIT_FALSE((traits::static_is_inclusive< variable>)); BOOST_TEST_TRAIT_FALSE((traits::static_is_inclusive< variable>)); BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive>)); BOOST_TEST_TRAIT_TRUE(( traits::static_is_inclusive>)); BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive< integer>)); BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive>)); BOOST_TEST_TRAIT_FALSE((traits::static_is_inclusive< integer>)); BOOST_TEST_TRAIT_FALSE((traits::static_is_inclusive< integer>)); BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive>)); BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive< category>)); BOOST_TEST_TRAIT_FALSE( (traits::static_is_inclusive>)); } // index, rank, value, width { auto a = integer<>(1, 3); BOOST_TEST_EQ(traits::index(a, 1), 0); BOOST_TEST_EQ(traits::rank(a), 1); BOOST_TEST_EQ(traits::value(a, 0), 1); BOOST_TEST_EQ(traits::width(a, 0), 0); BOOST_TEST_EQ(traits::width(a, 0), 0); auto b = integer(1, 3); BOOST_TEST_EQ(traits::index(b, 1), 0); BOOST_TEST_EQ(traits::rank(b), 1); BOOST_TEST_EQ(traits::value(b, 0), 1); BOOST_TEST_EQ(traits::width(b, 0), 1); BOOST_TEST(traits::static_options::test(option::underflow)); auto c = category{"red", "blue"}; BOOST_TEST_EQ(traits::index(c, "blue"), 1); BOOST_TEST_EQ(traits::rank(c), 1); BOOST_TEST_EQ(traits::value(c, 0), std::string("red")); BOOST_TEST_EQ(traits::width(c, 0), 0); struct D { index_type index(const std::tuple& args) const { return static_cast(std::get<0>(args) + std::get<1>(args)); } index_type size() const { return 5u; } } d; BOOST_TEST_EQ(traits::index(d, std::make_tuple(1, 2.0)), 3.0); BOOST_TEST_EQ(traits::rank(d), 2u); variant> v; v = a; BOOST_TEST_EQ(traits::rank(v), 1u); v = d; BOOST_TEST_EQ(traits::rank(v), 2u); } // static_options, options() { using A = integer<>; BOOST_TEST_EQ(traits::static_options::test(option::growth), false); auto expected = option::underflow | option::overflow; auto a = A{}; BOOST_TEST_EQ(traits::options(a), expected); BOOST_TEST_EQ(traits::options(static_cast(a)), expected); BOOST_TEST_EQ(traits::options(static_cast(a)), expected); BOOST_TEST_EQ(traits::options(std::move(a)), expected); using B = integer; BOOST_TEST_EQ(traits::static_options::test(option::growth), true); BOOST_TEST_EQ(traits::options(B{}), option::growth); struct growing { auto update(double) { return std::make_pair(0, 0); } }; using C = growing; BOOST_TEST_EQ(traits::static_options::test(option::growth), true); auto c = C{}; BOOST_TEST_EQ(traits::options(c), option::growth); BOOST_TEST_EQ(traits::options(static_cast(c)), option::growth); BOOST_TEST_EQ(traits::options(static_cast(c)), option::growth); BOOST_TEST_EQ(traits::options(std::move(c)), option::growth); struct notgrowing { auto index(double) { return 0; } }; using D = notgrowing; BOOST_TEST_EQ(traits::static_options::test(option::growth), false); auto d = D{}; BOOST_TEST_EQ(traits::options(d), option::none); BOOST_TEST_EQ(traits::options(static_cast(d)), option::none); BOOST_TEST_EQ(traits::options(static_cast(d)), option::none); BOOST_TEST_EQ(traits::options(std::move(d)), option::none); } // update { auto a = integer(); BOOST_TEST_EQ(traits::update(a, 0), (std::pair(0, -1))); BOOST_TEST_THROWS(traits::update(a, "foo"), std::invalid_argument); variant, integer<>> v(a); BOOST_TEST_EQ(traits::update(v, 0), (std::pair(0, 0))); } // metadata { struct None {}; struct Const { const int& metadata() const { return m; }; int m = 0; }; struct Both { const int& metadata() const { return m; }; int& metadata() { return m; }; int m = 0; }; None none; BOOST_TEST_TRAIT_SAME(decltype(traits::metadata(none)), null_type&); BOOST_TEST_TRAIT_SAME(decltype(traits::metadata(static_cast(none))), null_type&); BOOST_TEST_TRAIT_SAME(decltype(traits::metadata(static_cast(none))), const null_type&); Const c; BOOST_TEST_EQ(traits::metadata(c), 0); BOOST_TEST_EQ(traits::metadata(static_cast(c)), 0); BOOST_TEST_EQ(traits::metadata(static_cast(c)), 0); Both b; BOOST_TEST_EQ(traits::metadata(b), 0); BOOST_TEST_EQ(traits::metadata(static_cast(b)), 0); BOOST_TEST_EQ(traits::metadata(static_cast(b)), 0); } return boost::report_errors(); }