// Copyright 2015-2017 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "utility_meta.hpp" namespace bh = boost::histogram; using namespace bh::detail; using namespace bh::literals; namespace mp11 = boost::mp11; struct VisitorTestFunctor { template T operator()(T&&); }; int main() { // literals { auto j0 = 0_c; auto j3 = 3_c; auto j10 = 10_c; auto j213 = 213_c; BOOST_TEST_TRAIT_TRUE((std::is_same)); BOOST_TEST_TRAIT_TRUE((std::is_same)); BOOST_TEST_EQ(decltype(j10)::value, 10); BOOST_TEST_EQ(decltype(j213)::value, 213); } // has_method_value { struct A {}; struct B { A value(int) const { return {}; } }; struct C { char value(int) const { return 0; } }; BOOST_TEST_TRAIT_FALSE((has_method_value)); BOOST_TEST_TRAIT_TRUE((has_method_value)); BOOST_TEST_TRAIT_FALSE((has_method_value)); BOOST_TEST_TRAIT_TRUE((has_method_value)); BOOST_TEST_TRAIT_FALSE((has_method_value)); } // has_method_options { struct A {}; struct B { void options() {} }; struct C { bh::axis::option_type options() const { return {}; } }; BOOST_TEST_TRAIT_FALSE((has_method_options)); BOOST_TEST_TRAIT_FALSE((has_method_options)); BOOST_TEST_TRAIT_TRUE((has_method_options)); } // has_method_metadata { struct A {}; struct B { void metadata(); }; BOOST_TEST_TRAIT_FALSE((has_method_metadata)); BOOST_TEST_TRAIT_TRUE((has_method_metadata)); } // has_method_resize { struct A {}; using B = std::vector; using C = std::map; BOOST_TEST_TRAIT_FALSE((has_method_resize)); BOOST_TEST_TRAIT_TRUE((has_method_resize)); BOOST_TEST_TRAIT_FALSE((has_method_resize)); } // has_method_size { struct A {}; using B = std::vector; using C = std::map; BOOST_TEST_TRAIT_FALSE((has_method_size)); BOOST_TEST_TRAIT_TRUE((has_method_size)); BOOST_TEST_TRAIT_TRUE((has_method_size)); } // has_method_clear { struct A {}; using B = std::vector; using C = std::map; using D = std::array; BOOST_TEST_TRAIT_FALSE((has_method_clear)); BOOST_TEST_TRAIT_TRUE((has_method_clear)); BOOST_TEST_TRAIT_TRUE((has_method_clear)); BOOST_TEST_TRAIT_FALSE((has_method_clear)); } // has_allocator { struct A {}; using B = std::vector; using C = std::map; using D = std::array; BOOST_TEST_TRAIT_FALSE((has_method_clear)); BOOST_TEST_TRAIT_TRUE((has_method_clear)); BOOST_TEST_TRAIT_TRUE((has_method_clear)); BOOST_TEST_TRAIT_FALSE((has_method_clear)); } // is_storage { struct A {}; using B = bh::adaptive_storage<>; BOOST_TEST_TRAIT_FALSE((is_storage)); BOOST_TEST_TRAIT_TRUE((is_storage)); } // is_indexable { struct A {}; using B = std::vector; using C = std::map; using D = std::map; BOOST_TEST_TRAIT_FALSE((is_indexable)); BOOST_TEST_TRAIT_TRUE((is_indexable)); BOOST_TEST_TRAIT_TRUE((is_indexable)); BOOST_TEST_TRAIT_FALSE((is_indexable)); } // is_transform { struct A {}; struct B { double forward(double); double inverse(double); }; BOOST_TEST_TRAIT_FALSE((is_transform)); BOOST_TEST_TRAIT_TRUE((is_transform)); } // is_vector_like { struct A {}; using B = std::vector; using C = std::array; using D = std::map; using E = std::deque; BOOST_TEST_TRAIT_FALSE((is_vector_like)); BOOST_TEST_TRAIT_TRUE((is_vector_like)); BOOST_TEST_TRAIT_FALSE((is_vector_like)); BOOST_TEST_TRAIT_FALSE((is_vector_like)); BOOST_TEST_TRAIT_TRUE((is_vector_like)); } // is_array_like { struct A {}; using B = std::vector; using C = std::array; using D = std::map; BOOST_TEST_TRAIT_FALSE((is_array_like)); BOOST_TEST_TRAIT_FALSE((is_array_like)); BOOST_TEST_TRAIT_TRUE((is_array_like)); BOOST_TEST_TRAIT_FALSE((is_array_like)); } // is_map_like { struct A {}; using B = std::vector; using C = std::array; using D = std::map; using E = std::unordered_map; BOOST_TEST_TRAIT_FALSE((is_map_like)); BOOST_TEST_TRAIT_FALSE((is_map_like)); BOOST_TEST_TRAIT_FALSE((is_map_like)); BOOST_TEST_TRAIT_TRUE((is_map_like)); BOOST_TEST_TRAIT_TRUE((is_map_like)); } // is_equal_comparable { struct A {}; struct B { bool operator==(const B&); }; BOOST_TEST_TRAIT_TRUE((is_equal_comparable)); BOOST_TEST_TRAIT_FALSE((is_equal_comparable)); BOOST_TEST_TRAIT_TRUE((is_equal_comparable)); } // is_axis { struct A {}; struct B { int operator()(double); unsigned size() const; }; struct C { int operator()(double); }; struct D { unsigned size(); }; using E = bh::axis::variant>; BOOST_TEST_TRAIT_FALSE((is_axis)); BOOST_TEST_TRAIT_TRUE((is_axis)); BOOST_TEST_TRAIT_FALSE((is_axis)); BOOST_TEST_TRAIT_FALSE((is_axis)); BOOST_TEST_TRAIT_FALSE((is_axis)); } // is_iterable { using A = std::vector; using B = int[3]; using C = std::initializer_list; BOOST_TEST_TRAIT_FALSE((is_iterable)); BOOST_TEST_TRAIT_TRUE((is_iterable)); BOOST_TEST_TRAIT_TRUE((is_iterable)); BOOST_TEST_TRAIT_TRUE((is_iterable)); } // is_streamable { struct Foo {}; BOOST_TEST_TRAIT_TRUE((is_streamable)); BOOST_TEST_TRAIT_TRUE((is_streamable)); BOOST_TEST_TRAIT_FALSE((is_streamable)); } // is_axis_variant { struct A {}; BOOST_TEST_TRAIT_FALSE((is_axis_variant)); BOOST_TEST_TRAIT_TRUE((is_axis_variant>)); BOOST_TEST_TRAIT_TRUE((is_axis_variant>>)); } // unqual { using T1 = int; using T2 = int&&; using T3 = const int; using T4 = const int&; using T5 = volatile int; using T6 = volatile int&&; using T7 = volatile const int; using T8 = volatile const int&; BOOST_TEST_TRAIT_TRUE((std::is_same, int>)); BOOST_TEST_TRAIT_TRUE((std::is_same, int>)); BOOST_TEST_TRAIT_TRUE((std::is_same, int>)); BOOST_TEST_TRAIT_TRUE((std::is_same, int>)); BOOST_TEST_TRAIT_TRUE((std::is_same, int>)); BOOST_TEST_TRAIT_TRUE((std::is_same, int>)); BOOST_TEST_TRAIT_TRUE((std::is_same, int>)); BOOST_TEST_TRAIT_TRUE((std::is_same, int>)); } // mp_size { using T1 = std::tuple; using T2 = const std::tuple; using T3 = std::tuple&; using T4 = const std::tuple&; BOOST_TEST_EQ(mp_size::value, 1); BOOST_TEST_EQ(mp_size::value, 2); BOOST_TEST_EQ(mp_size::value, 3); BOOST_TEST_EQ(mp_size::value, 4); } // copy_qualifiers { BOOST_TEST_TRAIT_TRUE((std::is_same, long>)); BOOST_TEST_TRAIT_TRUE((std::is_same, const long>)); BOOST_TEST_TRAIT_TRUE((std::is_same, long&>)); BOOST_TEST_TRAIT_TRUE((std::is_same, const long&>)); BOOST_TEST_TRAIT_TRUE((std::is_same, long&&>)); } // mp_set_union { using L1 = mp11::mp_list; using L2 = mp11::mp_list; using result = mp_set_union; using expected = mp11::mp_list; BOOST_TEST_TRAIT_TRUE((std::is_same)); } // mp_last { using L = mp11::mp_list; BOOST_TEST_TRAIT_TRUE((std::is_same, long>)); } // container_value_type { using T1 = std::vector; using U1 = container_value_type; using T2 = const std::vector&; using U2 = container_value_type; BOOST_TEST_TRAIT_TRUE((std::is_same)); BOOST_TEST_TRAIT_TRUE((std::is_same)); } // iterator_value_type { using T1 = const char*; using T2 = std::iterator; BOOST_TEST_TRAIT_TRUE((std::is_same, char>)); BOOST_TEST_TRAIT_TRUE((std::is_same, int>)); } // args_type { struct Foo { static int f1(char); int f2(long) const; }; BOOST_TEST_TRAIT_TRUE( (std::is_same, std::tuple>)); BOOST_TEST_TRAIT_TRUE( (std::is_same, std::tuple>)); } // visitor_return_type { using V1 = bh::axis::variant; using V2 = bh::axis::variant&; using V3 = const bh::axis::variant&; BOOST_TEST_TRAIT_TRUE( (std::is_same, char>)); BOOST_TEST_TRAIT_TRUE( (std::is_same, int&>)); BOOST_TEST_TRAIT_TRUE( (std::is_same, const long&>)); } // static_if { struct callable { int operator()() { return 1; }; }; struct not_callable {}; auto fcn = [](auto b, auto x) { return static_if([](auto x) { return x(); }, [](auto) { return 2; }, x); }; BOOST_TEST_EQ(fcn(std::true_type(), callable()), 1); BOOST_TEST_EQ(fcn(std::false_type(), not_callable()), 2); } // sub_tuple { auto a = std::make_tuple(1, 2, 3, 4); auto b = sub_tuple<1, 2>(a); BOOST_TEST_EQ(b, std::make_tuple(2, 3)); } // is_axis_vector { using A = std::vector>; using B = std::vector>>; using C = std::vector; using D = const std::vector>>; using E = const std::vector>>&; auto v = std::vector, bh::axis::integer<>>>(); BOOST_TEST_TRAIT_TRUE((is_axis_vector)); BOOST_TEST_TRAIT_TRUE((is_axis_vector)); BOOST_TEST_TRAIT_FALSE((is_axis_vector)); BOOST_TEST_TRAIT_TRUE((is_axis_vector)); BOOST_TEST_TRAIT_TRUE((is_axis_vector)); BOOST_TEST_TRAIT_TRUE((is_axis_vector)); BOOST_TEST_TRAIT_TRUE((is_axis_vector)); } // is_weight { struct A {}; using B = int; using C = decltype(bh::weight(1)); BOOST_TEST_TRAIT_FALSE((is_weight)); BOOST_TEST_TRAIT_FALSE((is_weight)); BOOST_TEST_TRAIT_TRUE((is_weight)); } // is_sample { struct A {}; using B = int; using C = decltype(bh::sample(1)); using D = decltype(bh::sample(1, 2.0)); BOOST_TEST_TRAIT_FALSE((is_sample)); BOOST_TEST_TRAIT_FALSE((is_sample)); BOOST_TEST_TRAIT_TRUE((is_sample)); BOOST_TEST_TRAIT_TRUE((is_sample)); } // has_fixed_size { struct A {}; using B = std::vector; using C = std::tuple; using D = std::array; BOOST_TEST_NOT(has_fixed_size::value); BOOST_TEST_NOT(has_fixed_size::value); BOOST_TEST(has_fixed_size::value); BOOST_TEST(has_fixed_size::value); } return boost::report_errors(); }