93 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// __clamp_to_integral<IntT>(RealT)10 11// Test the conversion function that truncates floating point types to the12// closest representable value for the specified integer type, or13// numeric_limits<IntT>::max()/min() if the value isn't representable.14 15#include <__cxx03/__random/clamp_to_integral.h>16#include <cassert>17#include <cmath>18#include <limits>19 20template <class IntT>21void test() {22 typedef std::numeric_limits<IntT> Lim;23 const bool MaxIsRepresentable = sizeof(IntT) < 8;24 const bool IsSigned = std::is_signed<IntT>::value;25 struct TestCase {26 double Input;27 IntT Expect;28 bool IsRepresentable;29 } TestCases[] = {30 {0, 0, true},31 {1, 1, true},32 {IsSigned ? static_cast<IntT>(-1) : 0,33 IsSigned ? static_cast<IntT>(-1) : 0, true},34 {Lim::lowest(), Lim::lowest(), true},35 {static_cast<double>(Lim::max()), Lim::max(), MaxIsRepresentable},36 {static_cast<double>(Lim::max()) + 1, Lim::max(), false},37 {static_cast<double>(Lim::max()) + 1024, Lim::max(), false},38 {nextafter(static_cast<double>(Lim::max()), INFINITY), Lim::max(), false},39 };40 for (TestCase TC : TestCases) {41 auto res = std::__clamp_to_integral<IntT>(TC.Input);42 assert(res == TC.Expect);43 if (TC.IsRepresentable) {44 auto other = static_cast<IntT>(std::trunc(TC.Input));45 assert(res == other);46 } else47 assert(res == Lim::min() || res == Lim::max());48 }49}50 51template <class IntT>52void test_float() {53 typedef std::numeric_limits<IntT> Lim;54 const bool MaxIsRepresentable = sizeof(IntT) < 4;55 ((void)MaxIsRepresentable);56 const bool IsSigned = std::is_signed<IntT>::value;57 struct TestCase {58 float Input;59 IntT Expect;60 bool IsRepresentable;61 } TestCases[] = {62 {0, 0, true},63 {1, 1, true},64 {IsSigned ? static_cast<IntT>(-1) : 0,65 IsSigned ? static_cast<IntT>(-1) : 0, true},66 {Lim::lowest(), Lim::lowest(), true},67 {static_cast<float>(Lim::max()), Lim::max(), MaxIsRepresentable },68 {nextafter(static_cast<float>(Lim::max()), INFINITY), Lim::max(), false},69 };70 for (TestCase TC : TestCases) {71 auto res = std::__clamp_to_integral<IntT>(TC.Input);72 assert(res == TC.Expect);73 if (TC.IsRepresentable) {74 auto other = static_cast<IntT>(std::trunc(TC.Input));75 assert(res == other);76 } else77 assert(res == Lim::min() || res == Lim::max());78 }79}80 81int main(int, char**) {82 test<short>();83 test<unsigned short>();84 test<int>();85 test<unsigned>();86 test<long long>();87 test<unsigned long long>();88 test_float<short>();89 test_float<int>();90 test_float<long long>();91 return 0;92}93