Skip to content

Commit 90c3e72

Browse files
committed
Add a few compile-time unit tests.
1 parent 92fdd0a commit 90c3e72

File tree

1 file changed

+324
-0
lines changed

1 file changed

+324
-0
lines changed

test/gray.cpp

+324
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2016 Morwenn
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
#include <cstdint>
25+
#include <limits>
26+
#include <type_traits>
27+
#include <cpp-gray/gray.h>
28+
29+
// Trick function used in tests with stateful functions
30+
constexpr auto check(bool condition, int pos)
31+
-> std::uint64_t
32+
{
33+
std::uint64_t res = condition;
34+
return res << pos;
35+
}
36+
37+
constexpr auto assignment()
38+
-> std::uint64_t
39+
{
40+
using namespace cppgray;
41+
42+
std::uint64_t res = 0u;
43+
std::size_t pos = 0u;
44+
45+
////////////////////////////////////////////////////////////
46+
// Assignment operator
47+
48+
// From another Gray code
49+
{
50+
gray_code<unsigned> gr1, gr2;
51+
gr1 = gray(58u);
52+
gr2 = gray(22u);
53+
54+
res |= check(gr1 == gray(58u), pos++);
55+
res |= check(gr2 == gray(22u), pos++);
56+
res |= check(gr1 == 58u, pos++);
57+
res |= check(22u == gr2, pos++);
58+
}
59+
60+
// From an unsigned integer
61+
{
62+
gray_code<unsigned> gr1, gr2;
63+
gr1 = 73u;
64+
gr2 = 194u;
65+
66+
res |= check(gr1 == gray(73u), pos++);
67+
res |= check(gr2 == gray(194u), pos++);
68+
res |= check(gr1 == 73u, pos++);
69+
res |= check(194u == gr2, pos++);
70+
}
71+
72+
////////////////////////////////////////////////////////////
73+
// Swap function
74+
75+
{
76+
auto gr1 = gray(52u);
77+
auto gr2 = gray(48u);
78+
79+
swap(gr1, gr2);
80+
res |= check(gr1 == 48u, pos++);
81+
res |= check(gr2 == 52u, pos++);
82+
}
83+
84+
////////////////////////////////////////////////////////////
85+
// Bitwise assignment operators
86+
87+
{
88+
unsigned a = 0b0110u;
89+
unsigned b = 0b1001u;
90+
unsigned c = 0b1101u;
91+
92+
a |= gray(0u);
93+
res |= check(a == 0b0110u, pos++);
94+
a &= gray(4u);
95+
res |= check(a == 0b0110u, pos++);
96+
97+
b |= gray(9u);
98+
res |= check(b == 0b1101u, pos++);
99+
100+
c ^= gray(5u);
101+
res |= check(c == 0b1010u, pos++);
102+
}
103+
104+
return res;
105+
}
106+
107+
constexpr auto increment()
108+
-> std::uint64_t
109+
{
110+
using namespace cppgray;
111+
112+
std::uint64_t res = 0b011011u;
113+
std::size_t pos = 0u;
114+
////////////////////////////////////////////////////////////
115+
// Incrementation
116+
117+
// Simple case
118+
{
119+
unsigned i = 0u;
120+
for (auto val = gray(0u) ; val != gray(10u) ; ++val, ++i)
121+
{
122+
res &= ~!check(val == i, pos);
123+
}
124+
++pos;
125+
126+
i = 0u;
127+
for (auto val = gray(0u) ; val != gray(10u) ; val++, i++)
128+
{
129+
res &= ~!check(val == i, pos);
130+
}
131+
++pos;
132+
}
133+
134+
// Circular behaviour on overflow
135+
{
136+
auto max_uint = std::numeric_limits<unsigned>::max();
137+
auto gr = gray(max_uint);
138+
139+
++gr;
140+
res |= check(gr.value == 0u, pos++);
141+
}
142+
143+
////////////////////////////////////////////////////////////
144+
// Decrementation
145+
146+
// Simple case
147+
{
148+
unsigned i = 35u;
149+
for (auto val = gray(35u) ; val != gray(23u) ; --val, --i)
150+
{
151+
res &= ~!(val == i, pos);
152+
}
153+
++pos;
154+
155+
i = 35u;
156+
for (auto val = gray(35u) ; val != gray(23u) ; val--, i--)
157+
{
158+
res &= ~!check(val == i, pos);
159+
}
160+
++pos;
161+
}
162+
163+
// Circular behaviour on overflow
164+
{
165+
auto max_uint = std::numeric_limits<unsigned>::max();
166+
auto gr = gray(0u);
167+
168+
--gr;
169+
res |= check(gr == gray(max_uint), pos++);
170+
}
171+
172+
return res;
173+
}
174+
175+
int main()
176+
{
177+
using namespace cppgray;
178+
179+
////////////////////////////////////////////////////////////
180+
// Conversions between two's complement integers and
181+
// Gray codes
182+
183+
// Convert to and from zero
184+
{
185+
constexpr auto zero = gray(0u);
186+
static_assert(zero == 0u, "");
187+
static_assert(zero.value == 0b0000u, "");
188+
189+
constexpr unsigned zero_u(zero);
190+
static_assert(zero_u == 0u, "");
191+
}
192+
193+
// Convert to and from unsigned integer
194+
{
195+
constexpr auto gr = gray(5u);
196+
static_assert(gr == 5u, "");
197+
static_assert(gr.value == 0b0111u, "");
198+
199+
constexpr unsigned five(gr);
200+
static_assert(five == 5u, "");
201+
}
202+
203+
// Convert to and from std::numeric_limits::max
204+
{
205+
constexpr auto max_uint = std::numeric_limits<unsigned>::max();
206+
constexpr auto max_gr = gray(max_uint);
207+
static_assert(max_gr == max_uint, "");
208+
}
209+
210+
////////////////////////////////////////////////////////////
211+
// Construction
212+
213+
{
214+
constexpr gray_code<unsigned> gr1{};
215+
static_assert(gr1.value == 0u, "");
216+
217+
constexpr gray_code<unsigned long long> gr2{};
218+
static_assert(gr2.value == 0ull, "");
219+
}
220+
221+
////////////////////////////////////////////////////////////
222+
// Comparison operators
223+
224+
{
225+
constexpr auto gr = gray(52u);
226+
227+
static_assert(gr == gray(52u), "");
228+
static_assert(gr == 52u, "");
229+
static_assert(52u == gr, "");
230+
static_assert(gr != 56u, "");
231+
static_assert(54u != gr, "");
232+
static_assert(gr != gray(89u), "");
233+
}
234+
235+
////////////////////////////////////////////////////////////
236+
// Bitwise operations
237+
238+
{
239+
constexpr auto gr1 = gray(42u);
240+
constexpr auto gr2 = gray(28u);
241+
242+
static_assert((gr1 & gr2).value == (gr1.value & gr2.value), "");
243+
static_assert((gr1 | gr2).value == (gr1.value | gr2.value), "");
244+
static_assert((gr1 ^ gr2).value == (gr1.value ^ gr2.value), "");
245+
static_assert((~gr1).value == ~(gr1.value), "");
246+
static_assert((gr1 << 3u).value == (gr1.value << 3u), "");
247+
static_assert((gr1 >> 2u).value == (gr1.value >> 2u), "");
248+
}
249+
250+
////////////////////////////////////////////////////////////
251+
// gray() function type inference
252+
253+
{
254+
constexpr auto llgr = gray(8ull);
255+
using value_type = decltype(llgr)::value_type;
256+
257+
static_assert(std::is_same<value_type, unsigned long long>::value, "");
258+
}
259+
260+
////////////////////////////////////////////////////////////
261+
// Mathematical operations
262+
263+
// is_even
264+
{
265+
static_assert(not is_even(gray(5u)), "");
266+
static_assert(is_even(gray(4u)), "");
267+
static_assert(is_even(gray(0u)), "");
268+
static_assert(not is_even(gray(12357u)), "");
269+
static_assert(is_even(gray(15328u)), "");
270+
}
271+
272+
// is_odd
273+
{
274+
static_assert(not is_odd(gray(8u)), "");
275+
static_assert(not is_odd(gray(0u)), "");
276+
static_assert(is_odd(gray(5u)), "");
277+
}
278+
279+
////////////////////////////////////////////////////////////
280+
// Test assignment and swap functions
281+
282+
{
283+
constexpr auto res = assignment();
284+
285+
// Assignment from another Gray code
286+
static_assert(res >> 0 & 1, "");
287+
static_assert(res >> 1 & 1, "");
288+
static_assert(res >> 2 & 1, "");
289+
static_assert(res >> 3 & 1, "");
290+
291+
// Assignment from an unsigned integer
292+
static_assert(res >> 4 & 1, "");
293+
static_assert(res >> 5 & 1, "");
294+
static_assert(res >> 6 & 1, "");
295+
static_assert(res >> 7 & 1, "");
296+
297+
// Swap function
298+
static_assert(res >> 8 & 1, "");
299+
static_assert(res >> 9 & 1, "");
300+
301+
// Bitwise assignment operators
302+
static_assert(res >> 10 & 1, "");
303+
static_assert(res >> 11 & 1, "");
304+
static_assert(res >> 12 & 1, "");
305+
static_assert(res >> 13 & 1, "");
306+
}
307+
308+
////////////////////////////////////////////////////////////
309+
// Test increment functions
310+
311+
{
312+
constexpr auto res = increment();
313+
314+
// Incrementation
315+
static_assert(res >> 0 & 1, "");
316+
static_assert(res >> 1 & 1, "");
317+
static_assert(res >> 2 & 1, "");
318+
319+
// Decrementation
320+
static_assert(res >> 3 & 1, "");
321+
static_assert(res >> 4 & 1, "");
322+
static_assert(res >> 5 & 1, "");
323+
}
324+
}

0 commit comments

Comments
 (0)