1 #include "d_range.h"
2 #include "d_zip.h"
3 #include <array>
4 #include <vector>
5 
6 #define BOOST_TEST_DYN_LINK
7 #define BOOST_TEST_MODULE Rebirth zip
8 #include <boost/test/unit_test.hpp>
9 
10 /* Test that a zipped range is empty when the component range is empty.
11  */
BOOST_AUTO_TEST_CASE(zip_empty)12 BOOST_AUTO_TEST_CASE(zip_empty)
13 {
14 	bool empty = true;
15 	std::array<int, 0> a;
16 	for (auto &&v : zip(a))
17 	{
18 		(void)v;
19 		empty = false;
20 	}
21 	BOOST_TEST(empty);
22 }
23 
24 /* Test that a zipped range is the length of the first sequence.
25  *
26  * Note that there is no test for when the first sequence is longer than
27  * the later ones, since such a test would increment some iterators past
28  * their end.
29  */
BOOST_AUTO_TEST_CASE(zip_length)30 BOOST_AUTO_TEST_CASE(zip_length)
31 {
32 	unsigned count = 0;
33 	std::array<int, 2> a;
34 	short b[4];
35 	for (auto &&v : zip(a, b))
36 	{
37 		(void)v;
38 		++ count;
39 	}
40 	BOOST_TEST(count == a.size());
41 }
42 
43 /* Test that a zipped value references the underlying storage.
44  */
BOOST_AUTO_TEST_CASE(zip_passthrough_modifications)45 BOOST_AUTO_TEST_CASE(zip_passthrough_modifications)
46 {
47 	std::array<int, 1> a{{1}};
48 	short b[1]{2};
49 	for (auto &&v : zip(a, b))
50 	{
51 		++ std::get<0>(v);
52 		++ std::get<1>(v);
53 	}
54 	BOOST_TEST(a[0] == 2);
55 	BOOST_TEST(b[0] == 3);
56 }
57 
58 /* Test that a zipped range can zip an xrange, and produce the correct
59  * underlying value.
60  */
BOOST_AUTO_TEST_CASE(zip_xrange)61 BOOST_AUTO_TEST_CASE(zip_xrange)
62 {
63 	for (auto &&v : zip(xrange(1u)))
64 	{
65 		BOOST_TEST(std::get<0>(v) == 0);
66 	}
67 }
68 
69 /* Type system tests can be done at compile-time.  Applying them as
70  * static_assert can produce a better error message than letting it fail
71  * at runtime.
72  */
73 template <typename Expected, typename zip_type, typename index_type = typename zip_type::index_type>
74 struct assert_index_type : std::true_type
75 {
76 	static_assert(std::is_same<Expected, index_type>::value);
77 };
78 
79 static_assert(assert_index_type<void, decltype(zip(std::declval<std::array<int, 1>>(), std::declval<std::array<float, 1>>()))>::value);
80 
81 template <typename T>
82 struct custom_index_type : std::array<int, 1>
83 {
84 	using index_type = T;
85 	void operator[](typename std::remove_reference<T>::type);
86 };
87 enum class e1 : unsigned char;
88 enum class e2 : unsigned char;
89 
90 static_assert(assert_index_type<e1, decltype(zip(std::declval<custom_index_type<e1>&>(), std::declval<custom_index_type<e1>&>()))>::value);
91 static_assert(assert_index_type<void, decltype(zip(std::declval<custom_index_type<e1>&>(), std::declval<custom_index_type<e2>&>()))>::value);
92