1// Copyright 2022 Christian Mazakas
2// Distributed under the Boost Software License, Version 1.0.
3// https://www.boost.org/LICENSE_1_0.txt
4
5#include <boost/unordered/detail/narrow_cast.hpp>
6
7#include <boost/core/lightweight_test.hpp>
8#include <boost/cstdint.hpp>
9
10// want to prove that for the wider type, the higher bits of the value
11// represenation don't affect the results of the narrowing, which in this case
12// is masking out the high bits when comapred to the narrow type
13
14static void signed_integral_narrowing()
15{
16 // test positive range, fits
17 // [0, 127]
18 for (boost::int32_t i = 0x00; i < 0x80; ++i) {
19 boost::int8_t k = (boost::int8_t)i;
20 BOOST_TEST_GE(k, 0);
21 BOOST_TEST_EQ(boost::unordered::detail::narrow_cast<boost::int8_t>(i), k);
22 }
23
24 // test positive range, doesn't fit
25 // [0xff00, 0xff7f]
26 for (boost::int32_t i = 0x00; i < 0x80; ++i) {
27 boost::int32_t j = i + 0xff00;
28 boost::int8_t k = (boost::int8_t)i;
29 BOOST_TEST_GE(k, 0);
30 BOOST_TEST_EQ(boost::unordered::detail::narrow_cast<boost::int8_t>(j), k);
31 }
32
33 // test negative range, fits
34 // [-128, -1]
35 for (boost::int32_t i = 0x00; i < 0x80; ++i) {
36 boost::int32_t j = i + (boost::int32_t)0xffffff80;
37 boost::int8_t k = (boost::int8_t)j;
38 BOOST_TEST_LT(j, 0);
39 BOOST_TEST_LT(k, 0);
40 BOOST_TEST_EQ(boost::unordered::detail::narrow_cast<boost::int8_t>(j), k);
41 }
42
43 // test negative range, doesn't fit
44 for (boost::int32_t i = 0x00; i < 0x80; ++i) {
45 boost::int32_t j = i + (boost::int32_t)0x80000000;
46 boost::int8_t k = (boost::int8_t)(i);
47 BOOST_TEST_LT(j, 0);
48 BOOST_TEST_EQ(boost::unordered::detail::narrow_cast<boost::int8_t>(j), k);
49 }
50
51 for (boost::int32_t i = 0x00; i < 0x100; ++i) {
52 boost::int32_t j = (boost::int32_t)0x80ff0000 + i;
53 BOOST_TEST_LT(j, 0);
54 BOOST_TEST_EQ(boost::unordered::detail::narrow_cast<boost::int8_t>(j),
55 (boost::int8_t)i);
56 }
57
58 // test special values
59 {
60 boost::int32_t x = 0xff;
61 BOOST_TEST_EQ(boost::unordered::detail::narrow_cast<boost::int8_t>(x), -1);
62 }
63
64 {
65 boost::int32_t x = (boost::int32_t)0xffffff00;
66 BOOST_TEST_EQ(boost::unordered::detail::narrow_cast<boost::int8_t>(x),
67 (boost::int8_t)0x00);
68 }
69
70 {
71 boost::int32_t x = (boost::int32_t)0xffffff7f;
72 BOOST_TEST_EQ(boost::unordered::detail::narrow_cast<boost::int8_t>(x),
73 (boost::int8_t)0x7f);
74 }
75
76 {
77 boost::int32_t x = (boost::int32_t)0xffffffff;
78 BOOST_TEST_EQ(boost::unordered::detail::narrow_cast<boost::int8_t>(x),
79 (boost::int8_t)-1);
80 }
81}
82
83static void unsigned_integral_narrowing()
84{
85 // test range: [0x00, 0xff]
86 for (boost::uint32_t i = 0x00; i < 0x100; ++i) {
87 BOOST_TEST_EQ(boost::unordered::detail::narrow_cast<boost::uint8_t>(i),
88 (boost::uint8_t)(i & 0xff));
89 }
90
91 // test range: [0xffffff00, 0xffffffff]
92 boost::uint32_t i = 0xffffff00;
93 for (; i < 0xffffffff; ++i) {
94 BOOST_TEST_EQ(boost::unordered::detail::narrow_cast<boost::uint8_t>(i),
95 (boost::uint8_t)(i & 0xff));
96 }
97 BOOST_TEST_EQ(boost::unordered::detail::narrow_cast<boost::uint8_t>(i),
98 (boost::uint8_t)(i & 0xff));
99}
100
101int main()
102{
103 signed_integral_narrowing();
104 unsigned_integral_narrowing();
105
106 return boost::report_errors();
107}
108

source code of boost/libs/unordered/test/unordered/narrow_cast_tests.cpp