tuple_transform.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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. struct tuple_transform_f
  21. {
  22. template<class Sequence, class F>
  23. constexpr auto operator()(Sequence&& s, F f) const BOOST_HOF_RETURNS
  24. (
  25. boost::hof::unpack(boost::hof::proj(f, boost::hof::construct<std::tuple>()))(boost::hof::forward<Sequence>(s))
  26. );
  27. };
  28. struct pack_transform_f
  29. {
  30. template<class Sequence, class F>
  31. constexpr auto operator()(Sequence&& s, F f) const BOOST_HOF_RETURNS
  32. (
  33. boost::hof::unpack(boost::hof::proj(f, boost::hof::pack()))(boost::hof::forward<Sequence>(s))
  34. );
  35. };
  36. BOOST_HOF_STATIC_FUNCTION(tuple_transform) = tuple_transform_f{};
  37. // BOOST_HOF_STATIC_FUNCTION(pack_transform) = pack_transform_f{};
  38. #if !BOOST_HOF_HAS_CONSTEXPR_TUPLE
  39. #define TUPLE_TRANSFORM_STATIC_CHECK(...)
  40. #else
  41. #define TUPLE_TRANSFORM_STATIC_CHECK BOOST_HOF_STATIC_TEST_CHECK
  42. #endif
  43. BOOST_HOF_TEST_CASE()
  44. {
  45. auto t = std::make_tuple(1, 2);
  46. auto r = tuple_transform(t, [](int i) { return i*i; });
  47. BOOST_HOF_TEST_CHECK(r == std::make_tuple(1, 4));
  48. }
  49. BOOST_HOF_TEST_CASE()
  50. {
  51. TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(std::make_tuple(1, 2), boost::hof::_1 * boost::hof::_1) == std::make_tuple(1, 4));
  52. }
  53. #define TUPLE_TRANSFORM_CHECK_ID(x) \
  54. BOOST_HOF_TEST_CHECK(tuple_transform(x, boost::hof::identity) == x); \
  55. TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(x, boost::hof::identity) == x);
  56. BOOST_HOF_TEST_CASE()
  57. {
  58. TUPLE_TRANSFORM_CHECK_ID(std::make_tuple(1, 2));
  59. TUPLE_TRANSFORM_CHECK_ID(std::make_tuple(1));
  60. TUPLE_TRANSFORM_CHECK_ID(std::make_tuple());
  61. }
  62. BOOST_HOF_TEST_CASE()
  63. {
  64. auto x = tuple_transform(std::make_tuple(std::unique_ptr<int>(new int(3))), boost::hof::identity);
  65. auto y = std::make_tuple(std::unique_ptr<int>(new int(3)));
  66. BOOST_HOF_TEST_CHECK(x != y);
  67. BOOST_HOF_TEST_CHECK(tuple_transform(x, *boost::hof::_1) == tuple_transform(y, *boost::hof::_1));
  68. }
  69. #define TUPLE_TRANSFORM_CHECK_COMPOSE(x, f, g) \
  70. BOOST_HOF_TEST_CHECK(tuple_transform(x, boost::hof::compose(f, g)) == tuple_transform(tuple_transform(x, g), f)); \
  71. TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(x, boost::hof::compose(f, g)) == tuple_transform(tuple_transform(x, g), f));
  72. BOOST_HOF_TEST_CASE()
  73. {
  74. TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(1, 2, 3, 4), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1);
  75. TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(1, 2, 3), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1);
  76. TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(1), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1);
  77. TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1);
  78. }