/* @copyright Louis Dionne 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ #include #include #include #include #include #include #include #include #include #include #include #include using namespace boost::hana; int main() { { //! [conversion] static_assert(to(just(1)) == make(1), ""); BOOST_HANA_CONSTANT_CHECK(to(nothing) == make()); BOOST_HANA_CONSTANT_CHECK(to(make_range(int_<3>, int_<6>)) == tuple_c); //! [conversion] }{ //! [fold.left] auto to_string = [](auto x) { std::ostringstream ss; ss << x; return ss.str(); }; auto f = [=](std::string s, auto element) { return "f(" + s + ", " + to_string(element) + ")"; }; // with an initial state BOOST_HANA_RUNTIME_CHECK( fold.left(make(2, '3', 4, 5.0), "1", f) == "f(f(f(f(1, 2), 3), 4), 5)" ); // without initial state BOOST_HANA_RUNTIME_CHECK( fold.left(make("1", 2, '3', 4, 5.0), f) == "f(f(f(f(1, 2), 3), 4), 5)" ); //! [fold.left] }{ //! [fold.right] auto to_string = [](auto x) { std::ostringstream ss; ss << x; return ss.str(); }; auto f = [=](auto element, std::string s) { return "f(" + to_string(element) + ", " + s + ")"; }; // with an initial state BOOST_HANA_RUNTIME_CHECK( fold.right(make(1, '2', 3.0, 4), "5", f) == "f(1, f(2, f(3, f(4, 5))))" ); // without initial state BOOST_HANA_RUNTIME_CHECK( fold.right(make(1, '2', 3.0, 4, "5"), f) == "f(1, f(2, f(3, f(4, 5))))" ); //! [fold.right] }{ //! [monadic_fold.right] BOOST_HANA_CONSTEXPR_LAMBDA auto safediv = [](auto x, auto y) { return eval_if(y == int_<0>, always(nothing), [=](auto _) { return just(_(x) / y); } ); }; // with an initial state BOOST_HANA_CONSTANT_CHECK( monadic_fold.right(tuple_c, int_<2>, safediv) == just(int_<1000> / (int_<8> / (int_<4> / int_<2>))) ); BOOST_HANA_CONSTANT_CHECK( monadic_fold.right(tuple_c, int_<0>, safediv) == nothing ); // without an initial state BOOST_HANA_CONSTANT_CHECK( monadic_fold.right(tuple_c, safediv) == just(int_<1000> / (int_<8> / (int_<4> / int_<2>))) ); BOOST_HANA_CONSTANT_CHECK( monadic_fold.right(tuple_c, safediv) == nothing ); //! [monadic_fold.right] }{ // [reverse_fold] auto to_string = [](auto x) { std::ostringstream ss; ss << x; return ss.str(); }; auto f = [=](std::string s, auto element) { return "f(" + s + ", " + to_string(element) + ")"; }; // With an initial state BOOST_HANA_RUNTIME_CHECK( reverse_fold(make(1, '2', 3.0, 4), "5", f) == "f(f(f(f(5, 4), 3), 2), 1)" ); // Without an initial state BOOST_HANA_RUNTIME_CHECK( reverse_fold(make(1, '2', 3.0, 4, "5"), f) == "f(f(f(f(5, 4), 3), 2), 1)" ); // [reverse_fold] }{ //! [for_each] std::stringstream ss; for_each(make(0, '1', "234", 5.5), [&](auto x) { ss << x << ' '; }); BOOST_HANA_RUNTIME_CHECK(ss.str() == "0 1 234 5.5 "); //! [for_each] }{ //! [length] BOOST_HANA_CONSTANT_CHECK(length(make()) == size_t<0>); BOOST_HANA_CONSTANT_CHECK(length(make(1, '2', 3.0)) == size_t<3>); BOOST_HANA_CONSTANT_CHECK(length(nothing) == size_t<0>); BOOST_HANA_CONSTANT_CHECK(length(just('x')) == size_t<1>); //! [length] }{ //! [size] BOOST_HANA_CONSTANT_CHECK(size(make()) == size_t<0>); BOOST_HANA_CONSTANT_CHECK(size(make(1, '2', 3.0)) == size_t<3>); BOOST_HANA_CONSTANT_CHECK(size(nothing) == size_t<0>); BOOST_HANA_CONSTANT_CHECK(size(just('x')) == size_t<1>); //! [size] }{ //! [product] BOOST_HANA_CONSTANT_CHECK( product<>(range(int_<1>, int_<6>)) == int_<1 * 2 * 3 * 4 * 5> ); BOOST_HANA_CONSTEXPR_CHECK( product<>(make(1, int_<3>, long_<-5>, 9)) == 1 * 3 * -5 * 9 ); BOOST_HANA_CONSTEXPR_CHECK( product(make(2ul, 3ul)) == 6ul ); //! [product] }{ //! [sum] BOOST_HANA_CONSTANT_CHECK( sum<>(range(int_<1>, int_<6>)) == int_<1 + 2 + 3 + 4 + 5> ); BOOST_HANA_CONSTEXPR_CHECK( sum<>(make(1, int_<3>, long_<-5>, 9)) == 1 + 3 - 5 + 9 ); BOOST_HANA_CONSTEXPR_CHECK( sum(make(1ul, 3ul)) == 4ul ); //! [sum] }{ //! [unpack] auto cheap_tie = [](auto& ...vars) { return partial(flip(unpack), [&vars...](auto ...values) { // Using an initializer list sequences the assignments. int dummy[] = {((vars = values), 0)...}; (void)dummy; }); }; int a = 0; char b = '\0'; double c = 0; cheap_tie(a, b, c)(make(1, '2', 3.3)); BOOST_HANA_RUNTIME_CHECK(a == 1 && b == '2' && c == 3.3); //! [unpack] }{ //! [fuse] BOOST_HANA_CONSTEXPR_LAMBDA auto add = [](auto x, auto y) { return x + y; }; // Would be `boost::fusion::make_fused(add)` in Boost.Fusion. BOOST_HANA_CONSTEXPR_LAMBDA auto add_seq = fuse(add); BOOST_HANA_CONSTEXPR_CHECK(add_seq(make(1, 2)) == add(1, 2)); //! [fuse] }{ //! [count_if] using namespace literals; BOOST_HANA_CONSTEXPR_LAMBDA auto odd = [](auto x) { return x % 2_c != 0_c; }; constexpr auto types = tuple_t; constexpr auto ints = tuple_c; BOOST_HANA_CONSTANT_CHECK(count_if(ints, odd) == size_t<2>); BOOST_HANA_CONSTANT_CHECK(count_if(types, trait) == size_t<1>); BOOST_HANA_CONSTANT_CHECK(count_if(types, _ == type) == size_t<2>); BOOST_HANA_CONSTANT_CHECK(count_if(types, _ == type) == size_t<0>); //! [count_if] }{ //! [count] constexpr auto types = tuple_t; constexpr auto ints = tuple_c; BOOST_HANA_CONSTANT_CHECK(count(ints, int_<2>) == size_t<4>); BOOST_HANA_CONSTEXPR_CHECK(count(ints, 2) == 4); BOOST_HANA_CONSTANT_CHECK(count(types, type) == size_t<2>); //! [count] }{ //! [maximum] // without a predicate BOOST_HANA_CONSTANT_CHECK( maximum(tuple_c) == int_<9> ); // with a predicate BOOST_HANA_CONSTANT_CHECK( maximum(tuple_c, [](auto x, auto y) { return x > y; }) == int_<-4> ); BOOST_HANA_CONSTEXPR_CHECK( maximum.by(ordering(length), make( make(), make(1, '2'), make(3.3, nullptr, 4) )) == make(3.3, nullptr, 4) ); //! [maximum] }{ //! [minimum] // without a predicate BOOST_HANA_CONSTANT_CHECK( minimum(tuple_c) == int_<-4> ); // with a predicate BOOST_HANA_CONSTANT_CHECK( minimum(tuple_c, [](auto x, auto y) { return x > y; }) == int_<9> ); BOOST_HANA_CONSTANT_CHECK( minimum.by(ordering(length), make( make(), make(1, '2'), make(3.3, nullptr, 4) )) == make() ); //! [minimum] } }