| 1 | /*============================================================================= |
| 2 | Copyright (c) 2017 Paul Fultz II |
| 3 | tuple_transform.cpp |
| 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying |
| 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 6 | ==============================================================================*/ |
| 7 | #include <boost/hof/proj.hpp> |
| 8 | #include <boost/hof/construct.hpp> |
| 9 | #include <boost/hof/unpack.hpp> |
| 10 | #include <boost/hof/function.hpp> |
| 11 | #include <boost/hof/placeholders.hpp> |
| 12 | #include <boost/hof/compose.hpp> |
| 13 | // Disable static checks for gcc 4.7 |
| 14 | #ifndef BOOST_HOF_HAS_STATIC_TEST_CHECK |
| 15 | #if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 8) |
| 16 | #define BOOST_HOF_HAS_STATIC_TEST_CHECK 0 |
| 17 | #endif |
| 18 | #endif |
| 19 | #include "test.hpp" |
| 20 | |
| 21 | struct tuple_transform_f |
| 22 | { |
| 23 | template<class Sequence, class F> |
| 24 | constexpr auto operator()(Sequence&& s, F f) const BOOST_HOF_RETURNS |
| 25 | ( |
| 26 | boost::hof::unpack(boost::hof::proj(f, boost::hof::construct<std::tuple>()))(boost::hof::forward<Sequence>(s)) |
| 27 | ); |
| 28 | }; |
| 29 | |
| 30 | struct pack_transform_f |
| 31 | { |
| 32 | template<class Sequence, class F> |
| 33 | constexpr auto operator()(Sequence&& s, F f) const BOOST_HOF_RETURNS |
| 34 | ( |
| 35 | boost::hof::unpack(boost::hof::proj(f, boost::hof::pack()))(boost::hof::forward<Sequence>(s)) |
| 36 | ); |
| 37 | }; |
| 38 | |
| 39 | BOOST_HOF_STATIC_FUNCTION(tuple_transform) = tuple_transform_f{}; |
| 40 | // BOOST_HOF_STATIC_FUNCTION(pack_transform) = pack_transform_f{}; |
| 41 | |
| 42 | #if !BOOST_HOF_HAS_CONSTEXPR_TUPLE |
| 43 | #define TUPLE_TRANSFORM_STATIC_CHECK(...) |
| 44 | #else |
| 45 | #define TUPLE_TRANSFORM_STATIC_CHECK BOOST_HOF_STATIC_TEST_CHECK |
| 46 | |
| 47 | #endif |
| 48 | |
| 49 | BOOST_HOF_TEST_CASE() |
| 50 | { |
| 51 | auto t = std::make_tuple(args: 1, args: 2); |
| 52 | auto r = tuple_transform(t, [](int i) { return i*i; }); |
| 53 | BOOST_HOF_TEST_CHECK(r == std::make_tuple(1, 4)); |
| 54 | } |
| 55 | |
| 56 | BOOST_HOF_TEST_CASE() |
| 57 | { |
| 58 | TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(std::make_tuple(1, 2), boost::hof::_1 * boost::hof::_1) == std::make_tuple(1, 4)); |
| 59 | } |
| 60 | |
| 61 | #define TUPLE_TRANSFORM_CHECK_ID(x) \ |
| 62 | BOOST_HOF_TEST_CHECK(tuple_transform(x, boost::hof::identity) == x); \ |
| 63 | TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(x, boost::hof::identity) == x); |
| 64 | |
| 65 | BOOST_HOF_TEST_CASE() |
| 66 | { |
| 67 | TUPLE_TRANSFORM_CHECK_ID(std::make_tuple(1, 2)); |
| 68 | TUPLE_TRANSFORM_CHECK_ID(std::make_tuple(1)); |
| 69 | TUPLE_TRANSFORM_CHECK_ID(std::make_tuple()); |
| 70 | } |
| 71 | |
| 72 | BOOST_HOF_TEST_CASE() |
| 73 | { |
| 74 | auto x = tuple_transform(std::make_tuple(args: std::unique_ptr<int>(new int(3))), boost::hof::identity); |
| 75 | auto y = std::make_tuple(args: std::unique_ptr<int>(new int(3))); |
| 76 | BOOST_HOF_TEST_CHECK(x != y); |
| 77 | BOOST_HOF_TEST_CHECK(tuple_transform(x, *boost::hof::_1) == tuple_transform(y, *boost::hof::_1)); |
| 78 | } |
| 79 | |
| 80 | #define TUPLE_TRANSFORM_CHECK_COMPOSE(x, f, g) \ |
| 81 | BOOST_HOF_TEST_CHECK(tuple_transform(x, boost::hof::compose(f, g)) == tuple_transform(tuple_transform(x, g), f)); \ |
| 82 | TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(x, boost::hof::compose(f, g)) == tuple_transform(tuple_transform(x, g), f)); |
| 83 | |
| 84 | BOOST_HOF_TEST_CASE() |
| 85 | { |
| 86 | TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(1, 2, 3, 4), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1); |
| 87 | TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(1, 2, 3), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1); |
| 88 | TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(1), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1); |
| 89 | TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1); |
| 90 | } |
| 91 | |