1// Unit test for boost::lexical_cast.
2//
3// See http://www.boost.org for most recent version, including documentation.
4//
5// Copyright Antony Polukhin, 2011-2024.
6//
7// Distributed under the Boost
8// Software License, Version 1.0. (See accompanying file
9// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
10
11#include <boost/lexical_cast.hpp>
12
13#include <boost/core/cmath.hpp>
14#include <boost/type_traits/is_same.hpp>
15
16#include <boost/core/lightweight_test.hpp>
17
18#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
19#define BOOST_LCAST_NO_WCHAR_T
20#endif
21
22using namespace boost;
23
24template <class T>
25bool is_pos_inf(T value)
26{
27 return (boost::core::isinf)(value) && !(boost::core::signbit)(value);
28}
29
30template <class T>
31bool is_neg_inf(T value)
32{
33 return (boost::core::isinf)(value) && (boost::core::signbit)(value);
34}
35
36template <class T>
37bool is_pos_nan(T value)
38{
39 return (boost::core::isnan)(value) && !(boost::core::signbit)(value);
40}
41
42template <class T>
43bool is_neg_nan(T value)
44{
45 /* There is some strange behaviour on Itanium platform with -nan nuber for long double.
46 * It is a IA64 feature, or it is a boost::math feature, not a lexical_cast bug */
47#if defined(__ia64__) || defined(_M_IA64)
48 return (boost::core::isnan)(value)
49 && ( boost::is_same<T, long double >::value || (boost::core::signbit)(value) );
50#else
51 return (boost::core::isnan)(value) && (boost::core::signbit)(value);
52#endif
53}
54
55template <class T>
56void test_inf_nan_templated()
57{
58 typedef T test_t;
59
60 BOOST_TEST( is_pos_inf( lexical_cast<test_t>("inf") ) );
61 BOOST_TEST( is_pos_inf( lexical_cast<test_t>("INF") ) );
62
63 BOOST_TEST( is_neg_inf( lexical_cast<test_t>("-inf") ) );
64 BOOST_TEST( is_neg_inf( lexical_cast<test_t>("-INF") ) );
65
66 BOOST_TEST( is_pos_inf( lexical_cast<test_t>("+inf") ) );
67 BOOST_TEST( is_pos_inf( lexical_cast<test_t>("+INF") ) );
68
69 BOOST_TEST( is_pos_inf( lexical_cast<test_t>("infinity") ) );
70 BOOST_TEST( is_pos_inf( lexical_cast<test_t>("INFINITY") ) );
71
72 BOOST_TEST( is_neg_inf( lexical_cast<test_t>("-infinity") ) );
73 BOOST_TEST( is_neg_inf( lexical_cast<test_t>("-INFINITY") ) );
74
75 BOOST_TEST( is_pos_inf( lexical_cast<test_t>("+infinity") ) );
76 BOOST_TEST( is_pos_inf( lexical_cast<test_t>("+INFINITY") ) );
77
78 BOOST_TEST( is_pos_inf( lexical_cast<test_t>("iNfiNity") ) );
79 BOOST_TEST( is_pos_inf( lexical_cast<test_t>("INfinity") ) );
80
81 BOOST_TEST( is_neg_inf( lexical_cast<test_t>("-inFINITY") ) );
82 BOOST_TEST( is_neg_inf( lexical_cast<test_t>("-INFINITY") ) );
83
84 BOOST_TEST( is_pos_nan( lexical_cast<test_t>("nan") ) );
85 BOOST_TEST( is_pos_nan( lexical_cast<test_t>("NAN") ) );
86
87 BOOST_TEST( is_neg_nan( lexical_cast<test_t>("-nan") ) );
88 BOOST_TEST( is_neg_nan( lexical_cast<test_t>("-NAN") ) );
89
90 BOOST_TEST( is_pos_nan( lexical_cast<test_t>("+nan") ) );
91 BOOST_TEST( is_pos_nan( lexical_cast<test_t>("+NAN") ) );
92
93 BOOST_TEST( is_pos_nan( lexical_cast<test_t>("nAn") ) );
94 BOOST_TEST( is_pos_nan( lexical_cast<test_t>("NaN") ) );
95
96 BOOST_TEST( is_neg_nan( lexical_cast<test_t>("-nAn") ) );
97 BOOST_TEST( is_neg_nan( lexical_cast<test_t>("-NaN") ) );
98
99 BOOST_TEST( is_pos_nan( lexical_cast<test_t>("+Nan") ) );
100 BOOST_TEST( is_pos_nan( lexical_cast<test_t>("+nAN") ) );
101
102 BOOST_TEST( is_pos_nan( lexical_cast<test_t>("nan()") ) );
103 BOOST_TEST( is_pos_nan( lexical_cast<test_t>("NAN(some string)") ) );
104 BOOST_TEST_THROWS( lexical_cast<test_t>("NAN(some string"), bad_lexical_cast );
105
106 BOOST_TEST(lexical_cast<std::string>( (boost::core::copysign)(std::numeric_limits<test_t >::infinity(), static_cast<test_t>(-1.0)))
107 == "-inf" );
108 BOOST_TEST(lexical_cast<std::string>( std::numeric_limits<test_t >::infinity()) == "inf" );
109 BOOST_TEST(lexical_cast<std::string>( std::numeric_limits<test_t >::quiet_NaN()) == "nan" );
110#if !defined(__ia64__) && !defined(_M_IA64)
111 BOOST_TEST(lexical_cast<std::string>(
112 (boost::core::copysign)(std::numeric_limits<test_t >::quiet_NaN(), static_cast<test_t>(-1.0)))
113 == "-nan" );
114#endif
115
116#ifndef BOOST_LCAST_NO_WCHAR_T
117 BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"inf") ) );
118 BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"INF") ) );
119
120 BOOST_TEST( is_neg_inf( lexical_cast<test_t>(L"-inf") ) );
121 BOOST_TEST( is_neg_inf( lexical_cast<test_t>(L"-INF") ) );
122
123 BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"+inf") ) );
124 BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"+INF") ) );
125
126 BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"infinity") ) );
127 BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"INFINITY") ) );
128
129 BOOST_TEST( is_neg_inf( lexical_cast<test_t>(L"-infinity") ) );
130 BOOST_TEST( is_neg_inf( lexical_cast<test_t>(L"-INFINITY") ) );
131
132 BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"+infinity") ) );
133 BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"+INFINITY") ) );
134
135 BOOST_TEST( is_neg_inf( lexical_cast<test_t>(L"-infINIty") ) );
136 BOOST_TEST( is_neg_inf( lexical_cast<test_t>(L"-INFiniTY") ) );
137
138 BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"+inFINIty") ) );
139 BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"+INfinITY") ) );
140
141 BOOST_TEST( is_pos_nan( lexical_cast<test_t>(L"nan") ) );
142 BOOST_TEST( is_pos_nan( lexical_cast<test_t>(L"NAN") ) );
143
144 BOOST_TEST( is_neg_nan( lexical_cast<test_t>(L"-nan") ) );
145 BOOST_TEST( is_neg_nan( lexical_cast<test_t>(L"-NAN") ) );
146
147 BOOST_TEST( is_pos_nan( lexical_cast<test_t>(L"+nan") ) );
148 BOOST_TEST( is_pos_nan( lexical_cast<test_t>(L"+NAN") ) );
149
150 BOOST_TEST( is_pos_nan( lexical_cast<test_t>(L"nan()") ) );
151 BOOST_TEST( is_pos_nan( lexical_cast<test_t>(L"NAN(some string)") ) );
152 BOOST_TEST_THROWS( lexical_cast<test_t>(L"NAN(some string"), bad_lexical_cast );
153
154 BOOST_TEST(lexical_cast<std::wstring>( (boost::core::copysign)(std::numeric_limits<test_t >::infinity(), static_cast<test_t>(-1.0)))
155 == L"-inf" );
156 BOOST_TEST(lexical_cast<std::wstring>( std::numeric_limits<test_t >::infinity()) == L"inf" );
157 BOOST_TEST(lexical_cast<std::wstring>( std::numeric_limits<test_t >::quiet_NaN()) == L"nan" );
158#if !defined(__ia64__) && !defined(_M_IA64)
159 BOOST_TEST(lexical_cast<std::wstring>(
160 (boost::core::copysign)(std::numeric_limits<test_t >::quiet_NaN(), static_cast<test_t>(-1.0)))
161 == L"-nan" );
162#endif
163
164#endif
165}
166
167void test_inf_nan_float()
168{
169 test_inf_nan_templated<float >();
170
171 BOOST_TEST(is_pos_nan(lexical_cast<float>(std::numeric_limits<float>::quiet_NaN())));
172 BOOST_TEST(is_neg_nan(lexical_cast<float>(-std::numeric_limits<float>::quiet_NaN())));
173 BOOST_TEST(is_pos_inf(lexical_cast<float>(std::numeric_limits<float>::infinity())));
174 BOOST_TEST(is_neg_inf(lexical_cast<float>(-std::numeric_limits<float>::infinity())));
175
176 BOOST_TEST(is_pos_nan(lexical_cast<float>(std::numeric_limits<double>::quiet_NaN())));
177 BOOST_TEST(is_neg_nan(lexical_cast<float>(-std::numeric_limits<double>::quiet_NaN())));
178 BOOST_TEST(is_pos_inf(lexical_cast<float>(std::numeric_limits<double>::infinity())));
179 BOOST_TEST(is_neg_inf(lexical_cast<float>(-std::numeric_limits<double>::infinity())));
180}
181
182void test_inf_nan_double()
183{
184 test_inf_nan_templated<double >();
185
186 BOOST_TEST(is_pos_nan(lexical_cast<double>(std::numeric_limits<float>::quiet_NaN())));
187 BOOST_TEST(is_neg_nan(lexical_cast<double>(-std::numeric_limits<float>::quiet_NaN())));
188 BOOST_TEST(is_pos_inf(lexical_cast<double>(std::numeric_limits<float>::infinity())));
189 BOOST_TEST(is_neg_inf(lexical_cast<double>(-std::numeric_limits<float>::infinity())));
190
191 BOOST_TEST(is_pos_nan(lexical_cast<double>(std::numeric_limits<double>::quiet_NaN())));
192 BOOST_TEST(is_neg_nan(lexical_cast<double>(-std::numeric_limits<double>::quiet_NaN())));
193 BOOST_TEST(is_pos_inf(lexical_cast<double>(std::numeric_limits<double>::infinity())));
194 BOOST_TEST(is_neg_inf(lexical_cast<double>(-std::numeric_limits<double>::infinity())));
195
196 BOOST_TEST(is_pos_nan(lexical_cast<double>(std::numeric_limits<long double>::quiet_NaN())));
197 BOOST_TEST(is_neg_nan(lexical_cast<double>(-std::numeric_limits<long double>::quiet_NaN())));
198 BOOST_TEST(is_pos_inf(lexical_cast<double>(std::numeric_limits<long double>::infinity())));
199 BOOST_TEST(is_neg_inf(lexical_cast<double>(-std::numeric_limits<long double>::infinity())));
200}
201
202void test_inf_nan_long_double()
203{
204// We do not run tests on compilers with bugs
205#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
206 test_inf_nan_templated<long double >();
207#endif
208 BOOST_TEST(true);
209}
210
211int main()
212{
213 test_inf_nan_float();
214 test_inf_nan_double();
215 test_inf_nan_long_double();
216
217 return boost::report_errors();
218}
219

source code of boost/libs/lexical_cast/test/inf_nan_test.cpp