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 | #if defined(_MSC_VER) |
7 | # pragma warning( disable: 4309 ) // static_cast: truncation of constant value |
8 | #endif |
9 | |
10 | #include <boost/endian/conversion.hpp> |
11 | #include <boost/core/lightweight_test.hpp> |
12 | #include <boost/config.hpp> |
13 | #include <cstddef> |
14 | |
15 | template<class T, std::size_t N = sizeof(T)> struct test_value |
16 | { |
17 | }; |
18 | |
19 | template<class T> struct test_value<T, 1> |
20 | { |
21 | static const T v1 = static_cast<T>( 0x1F ); |
22 | static const T w1 = static_cast<T>( 0x1F ); |
23 | |
24 | static const T v2 = static_cast<T>( 0xF1 ); |
25 | static const T w2 = static_cast<T>( 0xF1 ); |
26 | }; |
27 | |
28 | template<class T> T const test_value<T, 1>::v1; |
29 | template<class T> T const test_value<T, 1>::w1; |
30 | template<class T> T const test_value<T, 1>::v2; |
31 | template<class T> T const test_value<T, 1>::w2; |
32 | |
33 | template<class T> struct test_value<T, 2> |
34 | { |
35 | static const T v1 = static_cast<T>( 0x1F2E ); |
36 | static const T w1 = static_cast<T>( 0x2E1F ); |
37 | |
38 | static const T v2 = static_cast<T>( 0xF1E2 ); |
39 | static const T w2 = static_cast<T>( 0xE2F1 ); |
40 | }; |
41 | |
42 | template<class T> T const test_value<T, 2>::v1; |
43 | template<class T> T const test_value<T, 2>::w1; |
44 | template<class T> T const test_value<T, 2>::v2; |
45 | template<class T> T const test_value<T, 2>::w2; |
46 | |
47 | template<class T> struct test_value<T, 4> |
48 | { |
49 | static const T v1 = static_cast<T>( 0x1F2E3D4C ); |
50 | static const T w1 = static_cast<T>( 0x4C3D2E1F ); |
51 | |
52 | static const T v2 = static_cast<T>( 0xF1E2D3C4 ); |
53 | static const T w2 = static_cast<T>( 0xC4D3E2F1 ); |
54 | }; |
55 | |
56 | template<class T> T const test_value<T, 4>::v1; |
57 | template<class T> T const test_value<T, 4>::w1; |
58 | template<class T> T const test_value<T, 4>::v2; |
59 | template<class T> T const test_value<T, 4>::w2; |
60 | |
61 | template<class T> struct test_value<T, 8> |
62 | { |
63 | static const T v1 = static_cast<T>( 0x1F2E3D4C5B6A7988ull ); |
64 | static const T w1 = static_cast<T>( 0x88796A5B4C3D2E1Full ); |
65 | |
66 | static const T v2 = static_cast<T>( 0xF1E2D3C4B5A69788ull ); |
67 | static const T w2 = static_cast<T>( 0x8897A6B5C4D3E2F1ull ); |
68 | }; |
69 | |
70 | template<class T> T const test_value<T, 8>::v1; |
71 | template<class T> T const test_value<T, 8>::w1; |
72 | template<class T> T const test_value<T, 8>::v2; |
73 | template<class T> T const test_value<T, 8>::w2; |
74 | |
75 | #if defined(BOOST_HAS_INT128) |
76 | |
77 | template<class T> struct test_value<T, 16> |
78 | { |
79 | static const T v1 = static_cast<T>( 0x1F2E3D4C5B6A7988ull ) << 64 | static_cast<T>( 0xF1E2D3C4B5A69780ull ); |
80 | static const T w1 = static_cast<T>( 0x8097A6B5C4D3E2F1ull ) << 64 | static_cast<T>( 0x88796A5B4C3D2E1Full ); |
81 | |
82 | static const T v2 = static_cast<T>( 0xF1E2D3C4B5A69788ull ) << 64 | static_cast<T>( 0x1F2E3D4C5B6A7980ull ); |
83 | static const T w2 = static_cast<T>( 0x80796A5B4C3D2E1Full ) << 64 | static_cast<T>( 0x8897A6B5C4D3E2F1ull ); |
84 | }; |
85 | |
86 | template<class T> T const test_value<T, 16>::v1; |
87 | template<class T> T const test_value<T, 16>::w1; |
88 | template<class T> T const test_value<T, 16>::v2; |
89 | template<class T> T const test_value<T, 16>::w2; |
90 | |
91 | #endif // #if defined(BOOST_HAS_INT128) |
92 | |
93 | template<class T> void test() |
94 | { |
95 | using boost::endian::endian_reverse; |
96 | using boost::endian::endian_reverse_inplace; |
97 | |
98 | { |
99 | T t1 = test_value<T>::v1; |
100 | |
101 | T t2 = endian_reverse( t1 ); |
102 | BOOST_TEST_EQ( t2, test_value<T>::w1 ); |
103 | |
104 | T t3 = endian_reverse( t2 ); |
105 | BOOST_TEST_EQ( t3, t1 ); |
106 | |
107 | T t4 = t1; |
108 | |
109 | endian_reverse_inplace( t4 ); |
110 | BOOST_TEST_EQ( t4, test_value<T>::w1 ); |
111 | |
112 | endian_reverse_inplace( t4 ); |
113 | BOOST_TEST_EQ( t4, t1 ); |
114 | } |
115 | |
116 | { |
117 | T t1 = test_value<T>::v2; |
118 | |
119 | T t2 = endian_reverse( t1 ); |
120 | BOOST_TEST_EQ( t2, test_value<T>::w2 ); |
121 | |
122 | T t3 = endian_reverse( t2 ); |
123 | BOOST_TEST_EQ( t3, t1 ); |
124 | |
125 | T t4 = t1; |
126 | |
127 | endian_reverse_inplace( t4 ); |
128 | BOOST_TEST_EQ( t4, test_value<T>::w2 ); |
129 | |
130 | endian_reverse_inplace( t4 ); |
131 | BOOST_TEST_EQ( t4, t1 ); |
132 | } |
133 | } |
134 | |
135 | template<class T> void test_np() |
136 | { |
137 | using boost::endian::endian_reverse; |
138 | using boost::endian::endian_reverse_inplace; |
139 | |
140 | { |
141 | T t1 = test_value<T>::v1; |
142 | |
143 | T t2 = endian_reverse( t1 ); |
144 | BOOST_TEST( t2 == test_value<T>::w1 ); |
145 | |
146 | T t3 = endian_reverse( t2 ); |
147 | BOOST_TEST( t3 == t1 ); |
148 | |
149 | T t4 = t1; |
150 | |
151 | endian_reverse_inplace( t4 ); |
152 | BOOST_TEST( t4 == test_value<T>::w1 ); |
153 | |
154 | endian_reverse_inplace( t4 ); |
155 | BOOST_TEST( t4 == t1 ); |
156 | } |
157 | |
158 | { |
159 | T t1 = test_value<T>::v2; |
160 | |
161 | T t2 = endian_reverse( t1 ); |
162 | BOOST_TEST( t2 == test_value<T>::w2 ); |
163 | |
164 | T t3 = endian_reverse( t2 ); |
165 | BOOST_TEST( t3 == t1 ); |
166 | |
167 | T t4 = t1; |
168 | |
169 | endian_reverse_inplace( t4 ); |
170 | BOOST_TEST( t4 == test_value<T>::w2 ); |
171 | |
172 | endian_reverse_inplace( t4 ); |
173 | BOOST_TEST( t4 == t1 ); |
174 | } |
175 | } |
176 | |
177 | int main() |
178 | { |
179 | test<std::int8_t>(); |
180 | test<std::uint8_t>(); |
181 | |
182 | test<std::int16_t>(); |
183 | test<std::uint16_t>(); |
184 | |
185 | test<std::int32_t>(); |
186 | test<std::uint32_t>(); |
187 | |
188 | test<std::int64_t>(); |
189 | test<std::uint64_t>(); |
190 | |
191 | test<char>(); |
192 | test<unsigned char>(); |
193 | test<signed char>(); |
194 | |
195 | test<short>(); |
196 | test<unsigned short>(); |
197 | |
198 | test<int>(); |
199 | test<unsigned int>(); |
200 | |
201 | test<long>(); |
202 | test<unsigned long>(); |
203 | |
204 | test<long long>(); |
205 | test<unsigned long long>(); |
206 | |
207 | #if !defined(BOOST_NO_CXX11_CHAR16_T) |
208 | test<char16_t>(); |
209 | #endif |
210 | |
211 | #if !defined(BOOST_NO_CXX11_CHAR32_T) |
212 | test<char32_t>(); |
213 | #endif |
214 | |
215 | #if defined(BOOST_HAS_INT128) |
216 | |
217 | test_np<boost::int128_type>(); |
218 | test_np<boost::uint128_type>(); |
219 | |
220 | #endif |
221 | |
222 | return boost::report_errors(); |
223 | } |
224 | |