36 forEachType<IntTypes>([]<
typename I>() {
37 forEachType<FloatTypes>([]<
typename F>() {
40 static_assert(convert<F>(std::numeric_limits<I>::max()) ==
F(std::numeric_limits<I>::max()));
41 static_assert(convert<F>(std::numeric_limits<I>::lowest()) ==
F(std::numeric_limits<I>::lowest()));
42 static_assert(convert<F>(std::numeric_limits<I>::max() - 1) ==
F(std::numeric_limits<I>::max() - 1));
43 static_assert(convert<F>(std::numeric_limits<I>::lowest() + 1) ==
F(std::numeric_limits<I>::lowest() + 1));
45 static_assert(convert<F>(I(1)) ==
F(1));
46 static_assert(convert<F>(I(0)) ==
F(0));
47 if constexpr(!ChimeraTK::isBoolean<I>) {
48 static_assert(convert<F>(I(42)) ==
F(42));
51 if constexpr(std::is_signed_v<I>) {
52 static_assert(convert<F>(I(-1)) ==
F(-1));
53 static_assert(convert<F>(I(-120)) ==
F(-120));
59 forEachType<IntTypes>([]<
typename I>() {
60 forEachType<FloatTypes>([]<
typename F>() {
61 if constexpr(!std::is_same_v<I, int64_t> && !std::is_same_v<I, uint64_t> &&
62 (std::is_same_v<F, double> || (!std::is_same_v<I, int32_t> && !std::is_same_v<I, uint32_t>))) {
64 static_assert(convert<I>(
F(std::numeric_limits<I>::max())) == std::numeric_limits<I>::max());
65 static_assert(convert<I>(
F(std::numeric_limits<I>::max() - 1)) == std::numeric_limits<I>::max() - 1);
67 static_assert(convert<I>(
F(std::numeric_limits<I>::lowest())) == std::numeric_limits<I>::lowest());
68 static_assert(convert<I>(
F(std::numeric_limits<I>::lowest() + 1)) == std::numeric_limits<I>::lowest() + 1);
71 static_assert(convert<I>(
F(std::numeric_limits<I>::max()) -
F(0.51)) == std::numeric_limits<I>::max() - 1);
72 static_assert(convert<I>(
F(std::numeric_limits<I>::max()) -
F(0.49)) == std::numeric_limits<I>::max());
75 convert<I>(
F(std::numeric_limits<I>::lowest()) +
F(0.51)) == std::numeric_limits<I>::lowest() + 1);
76 static_assert(convert<I>(
F(std::numeric_limits<I>::lowest()) +
F(0.49)) == std::numeric_limits<I>::lowest());
79 static_assert(convert<I>(
F(std::numeric_limits<I>::max()) +
F(0.49)) == std::numeric_limits<I>::max());
80 static_assert(convert<I>(
F(std::numeric_limits<I>::max()) +
F(0.51)) == std::numeric_limits<I>::max());
82 static_assert(
F(std::numeric_limits<I>::max()) +
F(1.E13) !=
F(std::numeric_limits<I>::max()));
83 static_assert(convert<I>(
F(std::numeric_limits<I>::max()) +
F(1.E13)) == std::numeric_limits<I>::max());
85 static_assert(convert<I>(
F(std::numeric_limits<I>::lowest()) -
F(0.49)) == std::numeric_limits<I>::lowest());
86 if constexpr(!ChimeraTK::isBoolean<I>) {
87 static_assert(convert<I>(
F(std::numeric_limits<I>::lowest()) -
F(0.51)) == std::numeric_limits<I>::lowest());
88 static_assert(convert<I>(
F(std::numeric_limits<I>::lowest()) -
F(100000.)) == std::numeric_limits<I>::lowest());
91 static_assert(convert<I>(-
F(0.51)) ==
true);
92 static_assert(convert<I>(-
F(100000.)) ==
true);
95 static_assert(convert<I>(
F(1)) == I(1));
96 static_assert(convert<I>(
F(0)) == I(0));
97 static_assert(convert<I>(
F(42)) == I(42));
98 if constexpr(std::is_signed_v<I>) {
99 static_assert(convert<I>(
F(-1)) == I(-1));
100 static_assert(convert<I>(
F(-120)) == I(-120));
103 if constexpr(!ChimeraTK::isBoolean<I>) {
104 static_assert(convert<I>(
F(-1)) == 0);
105 static_assert(convert<I>(
F(-120)) == 0);
108 static_assert(convert<I>(
F(-1)) ==
true);
109 static_assert(convert<I>(
F(-120)) ==
true);
114 static_assert(convert<I>(
F(0.49999)) == 0);
115 static_assert(convert<I>(
F(0.50001)) == 1);
116 static_assert(convert<I>(
F(1.49999)) == 1);
117 if constexpr(!ChimeraTK::isBoolean<I>) {
118 static_assert(convert<I>(
F(1.50001)) == 2);
120 static_assert(convert<I>(
F(-0.49999)) == 0);
121 if constexpr(std::is_signed_v<I>) {
122 static_assert(convert<I>(
F(-0.50001)) == -1);
123 static_assert(convert<I>(
F(-1.49999)) == -1);
124 static_assert(convert<I>(
F(-1.50001)) == -2);
127 if constexpr(!ChimeraTK::isBoolean<I>) {
128 static_assert(convert<I>(
F(-0.50001)) == 0);
129 static_assert(convert<I>(
F(-1.49999)) == 0);
130 static_assert(convert<I>(
F(-1.50001)) == 0);
133 static_assert(convert<I>(
F(-0.50001)) ==
true);
134 static_assert(convert<I>(
F(-1.49999)) ==
true);
135 static_assert(convert<I>(
F(-1.50001)) ==
true);
140 static_assert(convert<I>(std::numeric_limits<F>::infinity()) == std::numeric_limits<I>::max());
141 if constexpr(!ChimeraTK::isBoolean<I>) {
142 static_assert(convert<I>(-std::numeric_limits<F>::infinity()) == std::numeric_limits<I>::lowest());
145 static_assert(convert<I>(-std::numeric_limits<F>::infinity()) ==
true);
148 if constexpr(std::is_signed_v<I>) {
149 static_assert(convert<I>(std::numeric_limits<F>::quiet_NaN()) == std::numeric_limits<I>::lowest());
152 if constexpr(!ChimeraTK::isBoolean<I>) {
153 static_assert(convert<I>(std::numeric_limits<F>::quiet_NaN()) == std::numeric_limits<I>::max());
156 static_assert(convert<I>(std::numeric_limits<F>::quiet_NaN()) ==
false);
163 forEachType<IntTypes>([]<
typename I1>() {
164 forEachType<IntTypes>([]<
typename I2>() {
165 if constexpr(detail::greaterMaximum<I2, I1>()) {
167 static_assert(convert<I2>(std::numeric_limits<I1>::max()) == std::numeric_limits<I1>::max());
168 static_assert(convert<I2>(std::numeric_limits<I1>::max() - 1) == std::numeric_limits<I1>::max() - 1);
170 static_assert(convert<I1>(I2(std::numeric_limits<I1>::max()) + 1) == std::numeric_limits<I1>::max());
171 static_assert(convert<I1>(std::numeric_limits<I2>::max()) == std::numeric_limits<I1>::max());
174 static_assert(convert<I1>(I2(1)) == 1);
175 static_assert(convert<I1>(I2(0)) == 0);
177 if constexpr(std::is_signed_v<I1> && std::is_signed_v<I2>) {
179 if constexpr(std::numeric_limits<I2>::lowest() < std::numeric_limits<I1>::lowest()) {
181 static_assert(convert<I2>(std::numeric_limits<I1>::lowest()) == std::numeric_limits<I1>::lowest());
182 static_assert(convert<I2>(std::numeric_limits<I1>::lowest() + 1) == std::numeric_limits<I1>::lowest() + 1);
184 static_assert(convert<I1>(I2(std::numeric_limits<I1>::lowest()) - 1) == std::numeric_limits<I1>::lowest());
185 static_assert(convert<I1>(std::numeric_limits<I2>::lowest()) == std::numeric_limits<I1>::lowest());
189 if constexpr(std::is_signed_v<I1> && !std::is_signed_v<I2>) {
191 if constexpr(!ChimeraTK::isBoolean<I2>) {
192 static_assert(convert<I2>(std::numeric_limits<I1>::lowest()) == 0);
193 static_assert(convert<I2>(std::numeric_limits<I1>::lowest() + 1) == 0);
194 static_assert(convert<I2>(-1) == 0);
198 static_assert(convert<I2>(std::numeric_limits<I1>::lowest()) ==
true);
199 static_assert(convert<I2>(std::numeric_limits<I1>::lowest() + 1) ==
true);
200 static_assert(convert<I2>(-1) ==
true);
207 forEachType<FloatTypes>([]<
typename F1>() {
208 forEachType<FloatTypes>([]<
typename F2>() {
209 if constexpr(detail::greaterMaximum<F2, F1>()) {
211 static_assert(convert<F1>(std::numeric_limits<F2>::max()) == std::numeric_limits<F1>::max());
212 static_assert(convert<F1>(std::numeric_limits<F2>::lowest()) == std::numeric_limits<F1>::lowest());
214 static_assert(convert<F2>(std::numeric_limits<F1>::max()) == F2(std::numeric_limits<F1>::max()));
215 static_assert(convert<F2>(std::numeric_limits<F1>::lowest()) == F2(std::numeric_limits<F1>::lowest()));
218 static_assert(convert<F2>(F1(0.)) == F2(0.));
219 static_assert(convert<F2>(F1(1.)) == F2(1.));
220 static_assert(convert<F2>(F1(-1.)) == F2(-1.));
221 static_assert(convert<F2>(F1(0.12345)) == F2(F1(0.12345)));
225 BOOST_TEST(std::signbit(convert<F2>(F1(0.))) == 0);
226 constexpr F2 result = convert<F2>(F1(0.) / F1(-1.));
227 static_assert(result == 0);
228 BOOST_TEST(std::signbit(result) == 1);
230 static_assert(std::isnan(convert<F2>(std::numeric_limits<F1>::quiet_NaN())));
231 static_assert(std::isinf(convert<F2>(std::numeric_limits<F1>::infinity())));
232 static_assert(convert<F2>(std::numeric_limits<F1>::infinity()) == std::numeric_limits<F2>::infinity());
233 static_assert(convert<F2>(-std::numeric_limits<F1>::infinity()) == -std::numeric_limits<F2>::infinity());
238 forEachType<FloatTypes>([]<
typename F>() {
240 constexpr auto result1 = convert<ChimeraTK::Void>(
F(0.0));
241 static_assert(std::is_same_v<
decltype(result1),
const ChimeraTK::Void>);
242 constexpr auto result2 = convert<ChimeraTK::Void>(
F(123.456));
243 static_assert(std::is_same_v<
decltype(result2),
const ChimeraTK::Void>);
245 forEachType<IntTypes>([]<
typename I>() {
247 constexpr auto result1 = convert<ChimeraTK::Void>(I(0));
248 static_assert(std::is_same_v<
decltype(result1),
const ChimeraTK::Void>);
249 constexpr auto result2 = convert<ChimeraTK::Void>(I(123));
250 static_assert(std::is_same_v<
decltype(result2),
const ChimeraTK::Void>);