1+ from hypothesis import strategies as st , given , settings , event , assume
2+
3+ def unpack (l ):
4+ return ", " .join ([str (i ) for i in l ])
5+
6+ small_ints = st .integers (min_value = - 100 , max_value = 100 )
7+
8+ @st .composite
9+ def tuples (draw , children ):
10+ values = draw (st .lists (children ))
11+ return f"stdx::make_tuple({ unpack (values )} )"
12+
13+ @st .composite
14+ def list_trees (draw , leaves = st .integers ()):
15+ l = draw (st .recursive (leaves , lambda children : st .lists (children )))
16+ if not isinstance (l , list ):
17+ l = [l ]
18+ return l
19+
20+ def as_tuple_tree (value ):
21+ if isinstance (value , list ):
22+ values = [as_tuple_tree (v ) for v in value ]
23+ return f"stdx::make_tuple({ unpack (values )} )"
24+ else :
25+ return value
26+
27+ @st .composite
28+ def tuple_trees (draw , leaves = st .integers ()):
29+ return draw (st .recursive (leaves , lambda children : tuples (children )))
30+
31+ @settings (deadline = 10000 )
32+ @given (tuple_trees (small_ints ))
33+ def test_tuple_trees (compile , t ):
34+ assert compile (f"""
35+ #include <stdx/tuple.hpp>
36+
37+ constexpr auto t = { t } ;
38+
39+ int main() {{
40+ return 0;
41+ }}
42+ """ )
43+
44+ @settings (deadline = 10000 )
45+ @given (list_trees (small_ints ))
46+ def test_tuple_size (compile , l ):
47+ t = as_tuple_tree (l )
48+ assert compile (f"""
49+ #include <stdx/tuple.hpp>
50+
51+ constexpr auto t = { t } ;
52+ static_assert(stdx::tuple_size_v<decltype(t)> == { len (l )} );
53+ static_assert(std::size(t) == { len (l )} );
54+
55+ int main() {{
56+ return 0;
57+ }}
58+ """ )
59+
60+
61+ @settings (deadline = 10000 )
62+ @given (list_trees (small_ints ), st .integers ())
63+ def test_get_by_index (compile , l , i ):
64+ assume (len (l ) > 0 )
65+ t = as_tuple_tree (l )
66+ i = i % len (l )
67+
68+ expected_v = as_tuple_tree (l [i ])
69+
70+ assert compile (f"""
71+ #include <stdx/tuple.hpp>
72+
73+ using namespace stdx::literals;
74+
75+ constexpr auto t = { t } ;
76+ constexpr auto expected = { expected_v } ;
77+
78+ static_assert(stdx::get<{ i } >(t) == expected);
79+ static_assert(get<{ i } >(t) == expected);
80+
81+ static_assert(t[{ i } _idx] == expected);
82+ static_assert(t[stdx::index<{ i } >] == expected);
83+
84+ // TODO: enable once #148 is fixed
85+ //static_assert(t.get(stdx::index<{ i } >) == expected);
86+ //static_assert(t.get({ i } _idx) == expected);
87+
88+ int main() {{
89+ return 0;
90+ }}
91+ """ )
92+
93+
94+ @settings (deadline = 10000 )
95+ @given (st .lists (list_trees (small_ints )))
96+ def test_tuple_cat (compile , ls ):
97+ ts = [as_tuple_tree (l ) for l in ls ]
98+
99+ flattened_ls = [i for subl in ls for i in subl ]
100+ expected = as_tuple_tree (flattened_ls )
101+
102+ assert compile (f"""
103+ #include <stdx/tuple.hpp>
104+ #include <stdx/tuple_algorithms.hpp>
105+
106+ static_assert(stdx::tuple_cat({ unpack (ts )} ) == { expected } );
107+
108+ int main() {{
109+ return 0;
110+ }}
111+ """ )
112+
113+
114+ @settings (deadline = 10000 )
115+ @given (list_trees (small_ints ), st .one_of (list_trees (small_ints ), small_ints ))
116+ def test_push (compile , l , elem ):
117+ expected_back = as_tuple_tree (l + [elem ])
118+ expected_front = as_tuple_tree ([elem ] + l )
119+
120+ if isinstance (elem , list ):
121+ elem = as_tuple_tree (elem )
122+ else :
123+ elem = str (elem )
124+
125+ t = as_tuple_tree (l )
126+
127+ assert compile (f"""
128+ #include <stdx/tuple.hpp>
129+ #include <stdx/tuple_algorithms.hpp>
130+
131+ constexpr auto t = { t } ;
132+ constexpr auto elem = { elem } ;
133+
134+ constexpr auto expected_back = { expected_back } ;
135+ static_assert(stdx::tuple_push_back(t, elem) == expected_back);
136+ static_assert(stdx::tuple_snoc(t, elem) == expected_back);
137+
138+ constexpr auto expected_front = { expected_front } ;
139+ static_assert(stdx::tuple_push_front(elem, t) == expected_front);
140+ static_assert(stdx::tuple_cons(elem, t) == expected_front);
141+
142+ int main() {{
143+ return 0;
144+ }}
145+ """ )
146+
147+ from itertools import product
148+
149+ @settings (deadline = 20000 )
150+ @given (st .lists (list_trees (small_ints ), max_size = 3 ))
151+ def test_cartesian_product (compile , ls ):
152+ expected = as_tuple_tree ([list (p ) for p in product (* ls )])
153+
154+ ts = [as_tuple_tree (l ) for l in ls ]
155+
156+ assert compile (f"""
157+ #include <stdx/tuple.hpp>
158+ #include <stdx/tuple_algorithms.hpp>
159+
160+ static_assert(stdx::cartesian_product_copy({ unpack (ts )} ) == { expected } );
161+
162+ int main() {{
163+ return 0;
164+ }}
165+ """ )
166+
167+ from functools import reduce
168+
169+ @settings (deadline = 20000 )
170+ @given (st .lists (small_ints ))
171+ def test_star_of (compile , l ):
172+ expected_any_of = any ([i > 50 for i in l ])
173+ expected_all_of = all ([i > 50 for i in l ])
174+ expected_none_of = not expected_any_of
175+
176+ t = as_tuple_tree (l )
177+
178+ assert compile (f"""
179+ #include <stdx/tuple.hpp>
180+ #include <stdx/tuple_algorithms.hpp>
181+
182+ constexpr auto f = [](int i) {{ return i > 50; }};
183+
184+ static_assert(stdx::any_of(f, { t } ) == { str (expected_any_of ).lower ()} );
185+ static_assert(stdx::all_of(f, { t } ) == { str (expected_all_of ).lower ()} );
186+ static_assert(stdx::none_of(f, { t } ) == { str (expected_none_of ).lower ()} );
187+
188+ int main() {{
189+ return 0;
190+ }}
191+ """ )
0 commit comments