• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 // Copyright 2017 Peter Dimov.
3 //
4 // Distributed under the Boost Software License, Version 1.0.
5 //
6 // See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt
8 
9 #include <boost/mp11/detail/config.hpp>
10 
11 #if BOOST_MP11_MSVC
12 # pragma warning( disable: 4503 ) // decorated name length exceeded
13 # pragma warning( disable: 4307 ) // '*': integral constant overflow
14 # pragma warning( disable: 4244 ) // conversion from size_t to uint32_t
15 # pragma warning( disable: 4267 ) // conversion from size_t to uint32_t
16 #endif
17 
18 #include <boost/mp11/algorithm.hpp>
19 #include <boost/mp11/list.hpp>
20 #include <boost/core/lightweight_test.hpp>
21 #include <tuple>
22 #include <cstdint>
23 
24 #if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
25 # define CONSTEXPR14 constexpr
26 #else
27 # define CONSTEXPR14
28 #endif
29 
30 struct F
31 {
32     int s;
33 
operator ()F34     CONSTEXPR14 void operator()( int ) { s = s * 10 + 1; }
operator ()F35     CONSTEXPR14 void operator()( short ) { s = s * 10 + 2; }
operator ()F36     CONSTEXPR14 void operator()( char ) { s = s * 10 + 3; }
37 };
38 
39 struct G
40 {
41     std::uint32_t s;
operator ()G42     CONSTEXPR14 void operator()( std::uint32_t i ) { s = s * 3 + i; }
43 };
44 
45 using boost::mp11::mp_list;
46 using boost::mp11::mp_for_each;
47 using boost::mp11::mp_iota_c;
48 
main()49 int main()
50 {
51     BOOST_TEST_EQ( (mp_for_each<mp_list<>>( 11 )), 11 );
52     BOOST_TEST_EQ( (mp_for_each<mp_list<int>>( F{0} ).s), 1 );
53     BOOST_TEST_EQ( (mp_for_each<mp_list<int, short>>( F{0} ).s), 12 );
54     BOOST_TEST_EQ( (mp_for_each<mp_list<int, short, char>>( F{0} ).s), 123 );
55 
56     BOOST_TEST_EQ( (mp_for_each<std::tuple<>>( 11 )), 11 );
57     BOOST_TEST_EQ( (mp_for_each<std::tuple<int>>( F{0} ).s), 1 );
58     BOOST_TEST_EQ( (mp_for_each<std::tuple<int, short>>( F{0} ).s), 12 );
59     BOOST_TEST_EQ( (mp_for_each<std::tuple<int, short, char>>( F{0} ).s), 123 );
60 
61     BOOST_TEST_EQ( (mp_for_each<std::pair<int, short>>( F{0} ).s), 12 );
62 
63 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
64 #else
65 
66     using L = mp_iota_c<1089>;
67     std::uint32_t const R = 598075296;
68 
69     BOOST_TEST_EQ( (mp_for_each<L>( G{0} ).s), R );
70 
71     {
72         G g{0};
73         mp_for_each<L>( g );
74         BOOST_TEST_EQ( g.s, R );
75     }
76 
77 #endif
78 
79 #if defined( BOOST_MP11_NO_CONSTEXPR ) || ( !defined(_MSC_VER) && !defined( __GLIBCXX__ ) && __cplusplus < 201400L )
80 #else
81 
82     static_assert( mp_for_each<mp_list<>>( 11 ) == 11, "mp_for_each<mp_list<>>( 11 ) == 11" );
83     static_assert( mp_for_each<std::tuple<>>( 12 ) == 12, "mp_for_each<std::tuple<>>( 12 ) == 12" );
84 
85 #endif
86 
87 #if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
88 
89     constexpr auto r1 = mp_for_each<mp_list<int, short, char>>( F{0} );
90     static_assert( r1.s == 123, "r1.s == 123" );
91 
92     constexpr auto r2 = mp_for_each<std::tuple<int, short, char>>( F{0} );
93     static_assert( r2.s == 123, "r2.s == 123" );
94 
95     constexpr auto r3 = mp_for_each<std::pair<int, short>>( F{0} );
96     static_assert( r3.s == 12, "r3.s == 12" );
97 
98     constexpr auto r4 = mp_for_each<L>( G{0} );
99     static_assert( r4.s == R, "r4.s == R" );
100 
101 #endif
102 
103     return boost::report_errors();
104 }
105