]>
Commit | Line | Data |
---|---|---|
b32b8144 | 1 | // Copyright Louis Dionne 2013-2017 |
7c673cae FG |
2 | // Distributed under the Boost Software License, Version 1.0. |
3 | // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) | |
4 | ||
5 | #ifndef BOOST_HANA_TEST_LAWS_ORDERABLE_HPP | |
6 | #define BOOST_HANA_TEST_LAWS_ORDERABLE_HPP | |
7 | ||
8 | #include <boost/hana/and.hpp> | |
9 | #include <boost/hana/assert.hpp> | |
10 | #include <boost/hana/bool.hpp> | |
11 | #include <boost/hana/concept/constant.hpp> | |
12 | #include <boost/hana/concept/orderable.hpp> | |
13 | #include <boost/hana/concept/product.hpp> | |
14 | #include <boost/hana/concept/sequence.hpp> | |
15 | #include <boost/hana/core/when.hpp> | |
16 | #include <boost/hana/first.hpp> | |
17 | #include <boost/hana/greater.hpp> | |
18 | #include <boost/hana/greater_equal.hpp> | |
19 | #include <boost/hana/lazy.hpp> | |
20 | #include <boost/hana/less.hpp> | |
21 | #include <boost/hana/less_equal.hpp> | |
22 | #include <boost/hana/not.hpp> | |
23 | #include <boost/hana/or.hpp> | |
24 | #include <boost/hana/ordering.hpp> | |
25 | #include <boost/hana/second.hpp> | |
26 | #include <boost/hana/value.hpp> | |
27 | ||
28 | #include <laws/base.hpp> | |
29 | ||
30 | ||
31 | namespace boost { namespace hana { namespace test { | |
32 | template <typename T, typename = when<true>> | |
33 | struct TestOrderable : TestOrderable<T, laws> { | |
34 | using TestOrderable<T, laws>::TestOrderable; | |
35 | }; | |
36 | ||
37 | template <typename T> | |
38 | struct TestOrderable<T, laws> { | |
39 | template <typename Xs> | |
40 | TestOrderable(Xs xs) { | |
41 | hana::for_each(xs, [](auto x) { | |
b32b8144 | 42 | static_assert(Orderable<decltype(x)>{}, ""); |
7c673cae FG |
43 | }); |
44 | ||
45 | foreach2(xs, [](auto a, auto b) { | |
46 | ||
47 | // antisymmetry | |
48 | BOOST_HANA_CHECK( | |
49 | hana::and_(hana::less_equal(a, b), hana::less_equal(b, a)) | |
50 | ^implies^ hana::equal(a, b) | |
51 | ); | |
52 | ||
53 | // totality | |
54 | BOOST_HANA_CHECK( | |
55 | hana::or_(hana::less_equal(a, b), hana::less_equal(b, a)) | |
56 | ); | |
57 | ||
58 | // other methods in terms of `less_equal` | |
59 | BOOST_HANA_CHECK( | |
60 | hana::less(a, b) ^iff^ hana::not_(hana::less_equal(b, a)) | |
61 | ); | |
62 | ||
63 | BOOST_HANA_CHECK( | |
64 | hana::greater(a, b) ^iff^ hana::less(b, a) | |
65 | ); | |
66 | ||
67 | BOOST_HANA_CHECK( | |
68 | hana::greater_equal(a, b) ^iff^ hana::not_(hana::less(a, b)) | |
69 | ); | |
70 | ||
71 | // less.than & al. | |
72 | BOOST_HANA_CHECK(hana::less.than(a)(b) ^iff^ hana::less(b, a)); | |
73 | BOOST_HANA_CHECK(hana::greater.than(a)(b) ^iff^ hana::greater(b, a)); | |
74 | BOOST_HANA_CHECK(hana::less_equal.than(a)(b) ^iff^ hana::less_equal(b, a)); | |
75 | BOOST_HANA_CHECK(hana::greater_equal.than(a)(b) ^iff^ hana::greater_equal(b, a)); | |
76 | ||
77 | // ordering | |
78 | _injection<0> f{}; // test::_injection is also monotonic | |
79 | BOOST_HANA_CHECK( | |
80 | hana::ordering(f)(a, b) ^iff^ hana::less(f(a), f(b)) | |
81 | ); | |
82 | }); | |
83 | ||
84 | // transitivity | |
85 | foreach3(xs, [](auto a, auto b, auto c) { | |
86 | BOOST_HANA_CHECK( | |
87 | hana::and_(hana::less_equal(a, b), hana::less_equal(b, c)) | |
88 | ^implies^ hana::less_equal(a, c) | |
89 | ); | |
90 | }); | |
91 | } | |
92 | }; | |
93 | ||
94 | template <typename C> | |
95 | struct TestOrderable<C, when<Constant<C>::value>> | |
96 | : TestOrderable<C, laws> | |
97 | { | |
98 | template <typename Xs> | |
99 | TestOrderable(Xs xs) : TestOrderable<C, laws>{xs} { | |
100 | foreach2(xs, [](auto a, auto b) { | |
101 | ||
102 | BOOST_HANA_CHECK( | |
103 | hana::value(hana::less(a, b)) ^iff^ | |
104 | hana::less(hana::value(a), hana::value(b)) | |
105 | ); | |
106 | ||
107 | }); | |
108 | } | |
109 | }; | |
110 | ||
111 | template <typename P> | |
112 | struct TestOrderable<P, when<Product<P>::value>> | |
113 | : TestOrderable<P, laws> | |
114 | { | |
115 | template <typename Products> | |
116 | TestOrderable(Products products) | |
117 | : TestOrderable<P, laws>{products} | |
118 | { | |
119 | foreach2(products, [](auto x, auto y) { | |
120 | BOOST_HANA_CHECK( | |
121 | hana::less(x, y) ^iff^ | |
122 | hana::or_( | |
123 | hana::less(hana::first(x), hana::first(y)), | |
124 | hana::and_( | |
125 | hana::equal(hana::first(x), hana::first(y)), | |
126 | hana::less(hana::second(x), hana::second(y)) | |
127 | ) | |
128 | ) | |
129 | ); | |
130 | }); | |
131 | } | |
132 | }; | |
133 | ||
134 | template <typename S> | |
135 | struct TestOrderable<S, when<Sequence<S>::value>> | |
136 | : TestOrderable<S, laws> | |
137 | { | |
138 | struct invalid { }; | |
139 | ||
140 | template <typename Xs> | |
141 | TestOrderable(Xs xs) : TestOrderable<S, laws>{xs} { | |
142 | constexpr auto list = make<S>; | |
143 | ||
144 | ////////////////////////////////////////////////////////////////// | |
145 | // less | |
146 | ////////////////////////////////////////////////////////////////// | |
147 | BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less( | |
148 | list(), | |
149 | list() | |
150 | ))); | |
151 | ||
152 | BOOST_HANA_CONSTANT_CHECK(hana::less( | |
153 | list(), | |
154 | list(invalid{}) | |
155 | )); | |
156 | BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less( | |
157 | list(invalid{}), | |
158 | list() | |
159 | ))); | |
160 | BOOST_HANA_CONSTANT_CHECK(hana::less( | |
161 | list(ct_ord<0>{}), | |
162 | list(ct_ord<7>{}) | |
163 | )); | |
164 | BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less( | |
165 | list(ct_ord<1>{}), | |
166 | list(ct_ord<0>{}) | |
167 | ))); | |
168 | ||
169 | BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less( | |
170 | list(ct_ord<0>{}, ct_ord<1>{}, ct_ord<8>{}), | |
171 | list(ct_ord<0>{}, ct_ord<1>{}) | |
172 | ))); | |
173 | ||
174 | BOOST_HANA_CONSTANT_CHECK(hana::less( | |
175 | list(ct_ord<0>{}, ct_ord<0>{}, ct_ord<8>{}), | |
176 | list(ct_ord<0>{}, ct_ord<1>{}) | |
177 | )); | |
178 | } | |
179 | }; | |
180 | }}} // end namespace boost::hana::test | |
181 | ||
182 | #endif // !BOOST_HANA_TEST_LAWS_ORDERABLE_HPP |