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
21struct 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
30struct 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
39BOOST_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
49BOOST_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
56BOOST_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) \
62BOOST_HOF_TEST_CHECK(tuple_transform(x, boost::hof::identity) == x); \
63TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(x, boost::hof::identity) == x);
64
65BOOST_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
72BOOST_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) \
81BOOST_HOF_TEST_CHECK(tuple_transform(x, boost::hof::compose(f, g)) == tuple_transform(tuple_transform(x, g), f)); \
82TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(x, boost::hof::compose(f, g)) == tuple_transform(tuple_transform(x, g), f));
83
84BOOST_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

source code of boost/libs/hof/test/tuple_transform.cpp