1 | // |
2 | // immer: immutable data structures for C++ |
3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente |
4 | // |
5 | // This software is distributed under the Boost Software License, Version 1.0. |
6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt |
7 | // |
8 | |
9 | #pragma once |
10 | |
11 | #include <boost/range/irange.hpp> |
12 | #include <boost/range/join.hpp> |
13 | #include <cstddef> |
14 | |
15 | namespace { |
16 | |
17 | struct identity_t |
18 | { |
19 | template <typename T> |
20 | decltype(auto) operator() (T&& x) |
21 | { |
22 | return std::forward<decltype(x)>(x); |
23 | } |
24 | }; |
25 | |
26 | template <typename Integer> |
27 | auto test_irange(Integer from, Integer to) |
28 | { |
29 | #if IMMER_SLOW_TESTS |
30 | return boost::irange(from, to); |
31 | #else |
32 | if (to - from < Integer{10}) |
33 | return boost::join( |
34 | boost::irange(Integer{}, Integer{}), |
35 | boost::join(boost::irange(from, to, 1), |
36 | boost::irange(Integer{}, Integer{}))); |
37 | else |
38 | return boost::join( |
39 | boost::irange(from, from + Integer{2}), |
40 | boost::join( |
41 | boost::irange(from + Integer{2}, |
42 | to - Integer{2}, |
43 | (to - from) / Integer{5}), |
44 | boost::irange(to - Integer{2}, to))); |
45 | #endif |
46 | } |
47 | |
48 | } // anonymous namespace |
49 | |
50 | #if IMMER_SLOW_TESTS |
51 | #define CHECK_SLOW(...) CHECK(__VA_ARGS__) |
52 | #else |
53 | #define CHECK_SLOW(...) |
54 | #endif |
55 | |
56 | #if IMMER_SLOW_TESTS |
57 | #define CHECK_VECTOR_EQUALS_RANGE_AUX(v1_, first_, last_, xf_) \ |
58 | [] (auto&& v1, auto&& first, auto&& last, auto&& xf) { \ |
59 | auto size = std::distance(first, last); \ |
60 | CHECK(static_cast<std::ptrdiff_t>(v1.size()) == size); \ |
61 | if (static_cast<std::ptrdiff_t>(v1.size()) != size) return; \ |
62 | for (auto j = 0u; j < size; ++j) \ |
63 | CHECK(xf(v1[j]) == xf(*first++)); \ |
64 | } (v1_, first_, last_, xf_) \ |
65 | // CHECK_EQUALS |
66 | #else |
67 | #define CHECK_VECTOR_EQUALS_RANGE_AUX(v1_, first_, last_, ...) \ |
68 | [] (auto&& v1, auto&& first, auto&& last, auto&& xf) { \ |
69 | auto size = std::distance(first, last); \ |
70 | CHECK(static_cast<std::ptrdiff_t>(v1.size()) == size); \ |
71 | if (static_cast<std::ptrdiff_t>(v1.size()) != size) return; \ |
72 | if (size > 0) { \ |
73 | CHECK(xf(v1[0]) == xf(*(first + (0)))); \ |
74 | CHECK(xf(v1[size - 1]) == xf(*(first + (size - 1)))); \ |
75 | CHECK(xf(v1[size / 2]) == xf(*(first + (size / 2)))); \ |
76 | CHECK(xf(v1[size / 3]) == xf(*(first + (size / 3)))); \ |
77 | CHECK(xf(v1[size / 4]) == xf(*(first + (size / 4)))); \ |
78 | CHECK(xf(v1[size - 1 - size / 2]) == xf(*(first + (size - 1 - size / 2)))); \ |
79 | CHECK(xf(v1[size - 1 - size / 3]) == xf(*(first + (size - 1 - size / 3)))); \ |
80 | CHECK(xf(v1[size - 1 - size / 4]) == xf(*(first + (size - 1 - size / 4)))); \ |
81 | } \ |
82 | if (size > 1) { \ |
83 | CHECK(xf(v1[1]) == xf(*(first + (1)))); \ |
84 | CHECK(xf(v1[size - 2]) == xf(*(first + (size - 2)))); \ |
85 | } \ |
86 | if (size > 2) { \ |
87 | CHECK(xf(v1[2]) == xf(*(first + (2)))); \ |
88 | CHECK(xf(v1[size - 3]) == xf(*(first + (size - 3)))); \ |
89 | } \ |
90 | } (v1_, first_, last_, __VA_ARGS__) \ |
91 | // CHECK_EQUALS |
92 | #endif // IMMER_SLOW_TESTS |
93 | |
94 | #define CHECK_VECTOR_EQUALS_AUX(v1_, v2_, ...) \ |
95 | [] (auto&& v1, auto&& v2, auto&& ...xs) { \ |
96 | CHECK_VECTOR_EQUALS_RANGE_AUX(v1, v2.begin(), v2.end(), xs...); \ |
97 | } (v1_, v2_, __VA_ARGS__) |
98 | |
99 | #define CHECK_VECTOR_EQUALS_RANGE(v1, b, e) \ |
100 | CHECK_VECTOR_EQUALS_RANGE_AUX((v1), (b), (e), identity_t{}) |
101 | |
102 | #define CHECK_VECTOR_EQUALS(v1, v2) \ |
103 | CHECK_VECTOR_EQUALS_AUX((v1), (v2), identity_t{}) |
104 | |