1 | // Copyright 2019 Peter Dimov |
2 | // |
3 | // Distributed under the Boost Software License, Version 1.0. |
4 | // http://www.boost.org/LICENSE_1_0.txt |
5 | |
6 | #include <boost/endian/arithmetic.hpp> |
7 | #include <boost/core/lightweight_test.hpp> |
8 | #include <boost/config.hpp> |
9 | #include <boost/cstdint.hpp> |
10 | #include <cstddef> |
11 | |
12 | template<boost::endian::order Order, boost::endian::align Align, class T> void test_arithmetic_( T const& x ) |
13 | { |
14 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y( x ); |
15 | |
16 | BOOST_TEST_EQ( +x, +y ); |
17 | |
18 | BOOST_TEST_EQ( x + x, y + y ); |
19 | BOOST_TEST_EQ( x - x, y - y ); |
20 | |
21 | BOOST_TEST_EQ( x * x, y * y ); |
22 | BOOST_TEST_EQ( x / x, y / y ); |
23 | |
24 | { |
25 | T x2( x ); |
26 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
27 | |
28 | BOOST_TEST_EQ( x2 += x, y2 += y ); |
29 | } |
30 | |
31 | { |
32 | T x2( x ); |
33 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
34 | |
35 | BOOST_TEST_EQ( x2 -= x, y2 -= y ); |
36 | } |
37 | |
38 | { |
39 | T x2( x ); |
40 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
41 | |
42 | BOOST_TEST_EQ( x2 *= x, y2 *= y ); |
43 | } |
44 | |
45 | { |
46 | T x2( x ); |
47 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
48 | |
49 | BOOST_TEST_EQ( x2 /= x, y2 /= y ); |
50 | } |
51 | |
52 | { |
53 | T x2( x ); |
54 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
55 | |
56 | BOOST_TEST_EQ( ++x2, ++y2 ); |
57 | } |
58 | |
59 | { |
60 | T x2( x ); |
61 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
62 | |
63 | BOOST_TEST_EQ( --x2, --y2 ); |
64 | } |
65 | |
66 | { |
67 | T x2( x ); |
68 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
69 | |
70 | BOOST_TEST_EQ( x2++, y2++ ); |
71 | } |
72 | |
73 | { |
74 | T x2( x ); |
75 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
76 | |
77 | BOOST_TEST_EQ( x2--, y2-- ); |
78 | } |
79 | } |
80 | |
81 | template<boost::endian::order Order, boost::endian::align Align, class T> void test_integral_( T const& x ) |
82 | { |
83 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y( x ); |
84 | |
85 | BOOST_TEST_EQ( x % x, y % y ); |
86 | |
87 | BOOST_TEST_EQ( x & x, y & y ); |
88 | BOOST_TEST_EQ( x | x, y | y ); |
89 | BOOST_TEST_EQ( x ^ x, y ^ y ); |
90 | |
91 | BOOST_TEST_EQ( x << 1, y << 1 ); |
92 | BOOST_TEST_EQ( x >> 1, y >> 1 ); |
93 | |
94 | { |
95 | T x2( x ); |
96 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
97 | |
98 | BOOST_TEST_EQ( x2 %= x, y2 %= y ); |
99 | } |
100 | |
101 | { |
102 | T x2( x ); |
103 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
104 | |
105 | BOOST_TEST_EQ( x2 &= x, y2 &= y ); |
106 | } |
107 | |
108 | { |
109 | T x2( x ); |
110 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
111 | |
112 | BOOST_TEST_EQ( x2 |= x, y2 |= y ); |
113 | } |
114 | |
115 | { |
116 | T x2( x ); |
117 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
118 | |
119 | BOOST_TEST_EQ( x2 ^= x, y2 ^= y ); |
120 | } |
121 | |
122 | { |
123 | T x2( x ); |
124 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
125 | |
126 | BOOST_TEST_EQ( x2 <<= 1, y2 <<= 1 ); |
127 | } |
128 | |
129 | { |
130 | T x2( x ); |
131 | boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y ); |
132 | |
133 | BOOST_TEST_EQ( x2 >>= 1, y2 >>= 1 ); |
134 | } |
135 | } |
136 | |
137 | template<class T> void test_arithmetic( T const& x ) |
138 | { |
139 | test_arithmetic_<boost::endian::order::little, boost::endian::align::no>( x ); |
140 | test_arithmetic_<boost::endian::order::little, boost::endian::align::yes>( x ); |
141 | test_arithmetic_<boost::endian::order::big, boost::endian::align::no>( x ); |
142 | test_arithmetic_<boost::endian::order::big, boost::endian::align::yes>( x ); |
143 | } |
144 | |
145 | template<class T> void test_integral( T const& x ) |
146 | { |
147 | test_arithmetic( x ); |
148 | |
149 | test_integral_<boost::endian::order::little, boost::endian::align::no>( x ); |
150 | test_integral_<boost::endian::order::little, boost::endian::align::yes>( x ); |
151 | test_integral_<boost::endian::order::big, boost::endian::align::no>( x ); |
152 | test_integral_<boost::endian::order::big, boost::endian::align::yes>( x ); |
153 | } |
154 | |
155 | int main() |
156 | { |
157 | test_integral( x: 0x7EF2 ); |
158 | test_integral( x: 0x01020304u ); |
159 | |
160 | test_arithmetic( x: 3.1416f ); |
161 | test_arithmetic( x: 3.14159 ); |
162 | |
163 | return boost::report_errors(); |
164 | } |
165 | |