• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2017 Paul Fultz II
3     tuple_for_each.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/unpack.hpp>
8 #include <boost/hof/proj.hpp>
9 #include <boost/hof/function.hpp>
10 #include <boost/hof/reveal.hpp>
11 #include "test.hpp"
12 
13 struct tuple_for_each_f
14 {
15     template<class Sequence, class F>
16     constexpr auto operator()(Sequence&& s, F && f) const BOOST_HOF_RETURNS
17     (
18         boost::hof::unpack(boost::hof::proj(boost::hof::forward<F>(f)))(boost::hof::forward<Sequence>(s)), boost::hof::forward<F>(f)
19     );
20 };
21 
BOOST_HOF_STATIC_FUNCTION(tuple_for_each)22 BOOST_HOF_STATIC_FUNCTION(tuple_for_each) = tuple_for_each_f{};
23 
BOOST_HOF_TEST_CASE()24 BOOST_HOF_TEST_CASE()
25 {
26     std::tuple<int, short, char> tp{ 1, 2, 3 };
27 
28     {
29         int s = 0;
30 
31         tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
32 
33         BOOST_HOF_TEST_CHECK( s == 123 );
34     }
35 
36     {
37         int s = 0;
38 
39         tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
40 
41         BOOST_HOF_TEST_CHECK( s == 123 );
42     }
43 }
BOOST_HOF_TEST_CASE()44 BOOST_HOF_TEST_CASE()
45 {
46     std::tuple<int, short, char> const tp{ 1, 2, 3 };
47 
48     {
49         int s = 0;
50 
51         tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
52 
53         BOOST_HOF_TEST_CHECK( s == 123 );
54     }
55 
56     {
57         int s = 0;
58 
59         tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
60 
61         BOOST_HOF_TEST_CHECK( s == 123 );
62     }
63 }
64 
65 // #if defined( __clang_major__ ) && __clang_major__ == 3 && __clang_minor__ < 8
66 // #else
BOOST_HOF_TEST_CASE()67 BOOST_HOF_TEST_CASE()
68 {
69     std::tuple<std::unique_ptr<int>, std::unique_ptr<int>, std::unique_ptr<int>> tp{ std::unique_ptr<int>(new int(1)), std::unique_ptr<int>(new int(2)), std::unique_ptr<int>(new int(3)) };
70 
71     int s = 0;
72 
73     tuple_for_each( std::move(tp), [&]( std::unique_ptr<int> p ){ s = s * 10 + *p; } );
74 
75     BOOST_HOF_TEST_CHECK( s == 123 );
76 }
77 
BOOST_HOF_TEST_CASE()78 BOOST_HOF_TEST_CASE()
79 {
80     auto tp = boost::hof::pack(1, 2, 3);
81 
82     {
83         int s = 0;
84 
85         tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
86 
87         BOOST_HOF_TEST_CHECK( s == 123 );
88     }
89 
90     {
91         int s = 0;
92 
93         tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
94 
95         BOOST_HOF_TEST_CHECK( s == 123 );
96     }
97 }
BOOST_HOF_TEST_CASE()98 BOOST_HOF_TEST_CASE()
99 {
100     const auto tp = boost::hof::pack(1, 2, 3);
101 
102     {
103         int s = 0;
104 
105         tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
106 
107         BOOST_HOF_TEST_CHECK( s == 123 );
108     }
109 
110     {
111         int s = 0;
112 
113         tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
114 
115         BOOST_HOF_TEST_CHECK( s == 123 );
116     }
117 }
118 // #endif
BOOST_HOF_TEST_CASE()119 BOOST_HOF_TEST_CASE()
120 {
121     std::pair<int, short> tp{ 1, 2 };
122 
123     {
124         int s = 0;
125 
126         tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
127 
128         BOOST_HOF_TEST_CHECK( s == 12 );
129     }
130 
131     {
132         int s = 0;
133 
134         tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
135 
136         BOOST_HOF_TEST_CHECK( s == 12 );
137     }
138 }
BOOST_HOF_TEST_CASE()139 BOOST_HOF_TEST_CASE()
140 {
141     std::pair<int, short> const tp{ 1, 2 };
142 
143     {
144         int s = 0;
145 
146         tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
147 
148         BOOST_HOF_TEST_CHECK( s == 12 );
149     }
150 
151     {
152         int s = 0;
153 
154         tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
155 
156         BOOST_HOF_TEST_CHECK( s == 12 );
157     }
158 }
BOOST_HOF_TEST_CASE()159 BOOST_HOF_TEST_CASE()
160 {
161     std::array<int, 3> tp{{ 1, 2, 3 }};
162 
163     {
164         int s = 0;
165 
166         tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
167 
168         BOOST_HOF_TEST_CHECK( s == 123 );
169     }
170 
171     {
172         int s = 0;
173 
174         tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
175 
176         BOOST_HOF_TEST_CHECK( s == 123 );
177     }
178 }
BOOST_HOF_TEST_CASE()179 BOOST_HOF_TEST_CASE()
180 {
181     std::array<int, 3> const tp{{ 1, 2, 3 }};
182 
183     {
184         int s = 0;
185 
186         tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
187 
188         BOOST_HOF_TEST_CHECK( s == 123 );
189     }
190 
191     {
192         int s = 0;
193 
194         tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
195 
196         BOOST_HOF_TEST_CHECK( s == 123 );
197     }
198 }
BOOST_HOF_TEST_CASE()199 BOOST_HOF_TEST_CASE()
200 {
201     std::tuple<> tp;
202 
203     BOOST_HOF_TEST_CHECK( tuple_for_each( tp, 11 ) == 11 );
204     BOOST_HOF_TEST_CHECK( tuple_for_each( std::move( tp ), 12 ) == 12 );
205 }
206 
BOOST_HOF_TEST_CASE()207 BOOST_HOF_TEST_CASE()
208 {
209     BOOST_HOF_TEST_CHECK( tuple_for_each( boost::hof::pack(), 11 ) == 11 );
210     BOOST_HOF_STATIC_TEST_CHECK( tuple_for_each( boost::hof::pack(), 11 ) == 11 );
211 }
BOOST_HOF_TEST_CASE()212 BOOST_HOF_TEST_CASE()
213 {
214     std::array<int, 0> tp;
215 
216     BOOST_HOF_TEST_CHECK( tuple_for_each( tp, 11 ) == 11 );
217     BOOST_HOF_TEST_CHECK( tuple_for_each( std::move( tp ), 12 ) == 12 );
218 }
219 
220 struct assert_is_integral
221 {
operator ()assert_is_integral222     template<class T> constexpr bool operator()( T ) const
223     {
224         BOOST_HOF_STATIC_TEST_CHECK( std::is_integral<T>::value );
225         return true;
226     }
227 };
228 
BOOST_HOF_TEST_CASE()229 BOOST_HOF_TEST_CASE()
230 {
231 #if !BOOST_HOF_HAS_CONSTEXPR_TUPLE
232     auto r = tuple_for_each( std::tuple<int, short, char>{1, 2, 3}, assert_is_integral() );
233 #else
234     constexpr auto r = tuple_for_each( std::tuple<int, short, char>{1, 2, 3}, assert_is_integral() );
235 #endif
236     (void)r;
237 }
238 
BOOST_HOF_TEST_CASE()239 BOOST_HOF_TEST_CASE()
240 {
241 #if !BOOST_HOF_HAS_CONSTEXPR_TUPLE
242     auto r = tuple_for_each( boost::hof::pack(1, 2, 3), assert_is_integral() );
243 #else
244     constexpr auto r = tuple_for_each( boost::hof::pack(1, 2, 3), assert_is_integral() );
245 #endif
246     (void)r;
247 }
248