mp_for_each.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright 2017 Peter Dimov.
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. //
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. #include <boost/mp11/detail/config.hpp>
  8. #if BOOST_MP11_MSVC
  9. # pragma warning( disable: 4503 ) // decorated name length exceeded
  10. # pragma warning( disable: 4307 ) // '*': integral constant overflow
  11. #endif
  12. #include <boost/mp11/algorithm.hpp>
  13. #include <boost/mp11/list.hpp>
  14. #include <boost/core/lightweight_test.hpp>
  15. #include <tuple>
  16. #include <cstdint>
  17. #if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
  18. # define CONSTEXPR14 constexpr
  19. #else
  20. # define CONSTEXPR14
  21. #endif
  22. struct F
  23. {
  24. int s;
  25. CONSTEXPR14 void operator()( int ) { s = s * 10 + 1; }
  26. CONSTEXPR14 void operator()( short ) { s = s * 10 + 2; }
  27. CONSTEXPR14 void operator()( char ) { s = s * 10 + 3; }
  28. };
  29. struct G
  30. {
  31. std::uint32_t s;
  32. CONSTEXPR14 void operator()( std::uint32_t i ) { s = s * 3 + i; }
  33. };
  34. using boost::mp11::mp_list;
  35. using boost::mp11::mp_for_each;
  36. using boost::mp11::mp_iota_c;
  37. int main()
  38. {
  39. BOOST_TEST_EQ( (mp_for_each<mp_list<>>( 11 )), 11 );
  40. BOOST_TEST_EQ( (mp_for_each<mp_list<int>>( F{0} ).s), 1 );
  41. BOOST_TEST_EQ( (mp_for_each<mp_list<int, short>>( F{0} ).s), 12 );
  42. BOOST_TEST_EQ( (mp_for_each<mp_list<int, short, char>>( F{0} ).s), 123 );
  43. BOOST_TEST_EQ( (mp_for_each<std::tuple<>>( 11 )), 11 );
  44. BOOST_TEST_EQ( (mp_for_each<std::tuple<int>>( F{0} ).s), 1 );
  45. BOOST_TEST_EQ( (mp_for_each<std::tuple<int, short>>( F{0} ).s), 12 );
  46. BOOST_TEST_EQ( (mp_for_each<std::tuple<int, short, char>>( F{0} ).s), 123 );
  47. BOOST_TEST_EQ( (mp_for_each<std::pair<int, short>>( F{0} ).s), 12 );
  48. #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
  49. #else
  50. using L = mp_iota_c<1089>;
  51. std::uint32_t const R = 598075296;
  52. BOOST_TEST_EQ( (mp_for_each<L>( G{0} ).s), R );
  53. {
  54. G g{0};
  55. mp_for_each<L>( g );
  56. BOOST_TEST_EQ( g.s, R );
  57. }
  58. #endif
  59. #if defined( BOOST_MP11_NO_CONSTEXPR ) || ( !defined( __GLIBCXX__ ) && __cplusplus < 201400L )
  60. #else
  61. static_assert( mp_for_each<mp_list<>>( 11 ) == 11, "mp_for_each<mp_list<>>( 11 ) == 11" );
  62. static_assert( mp_for_each<std::tuple<>>( 12 ) == 12, "mp_for_each<std::tuple<>>( 12 ) == 12" );
  63. #endif
  64. #if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
  65. constexpr auto r1 = mp_for_each<mp_list<int, short, char>>( F{0} );
  66. static_assert( r1.s == 123, "r1.s == 123" );
  67. constexpr auto r2 = mp_for_each<std::tuple<int, short, char>>( F{0} );
  68. static_assert( r2.s == 123, "r2.s == 123" );
  69. constexpr auto r3 = mp_for_each<std::pair<int, short>>( F{0} );
  70. static_assert( r3.s == 12, "r3.s == 12" );
  71. constexpr auto r4 = mp_for_each<L>( G{0} );
  72. static_assert( r4.s == R, "r4.s == R" );
  73. #endif
  74. return boost::report_errors();
  75. }