]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (c) 2006 Johan Rade |
2 | // Copyright (c) 2011 Paul A. Bristow To incorporate into Boost.Math | |
3 | ||
4 | // Distributed under the Boost Software License, Version 1.0. | |
5 | // (See accompanying file LICENSE_1_0.txt | |
6 | // or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | // test_nonfinite_trap.cpp | |
9 | ||
10 | #ifdef _MSC_VER | |
11 | # pragma warning(disable : 4702) | |
12 | #endif | |
13 | ||
14 | #define BOOST_TEST_MAIN | |
15 | ||
92f5a8d4 | 16 | #include <boost/test/unit_test.hpp> |
7c673cae FG |
17 | #include "almost_equal.ipp" // Similar to BOOST_CLOSE_FRACTION. |
18 | #include "s_.ipp" // To create test strings like std::basic_string<CharType> s = S_("0 -0"); | |
19 | #include <boost/math/special_functions/nonfinite_num_facets.hpp> | |
20 | ||
21 | #include <locale> | |
22 | #include <sstream> | |
23 | ||
24 | namespace { | |
25 | ||
26 | // Using an anonymous namespace resolves ambiguities on platforms | |
27 | // with fpclassify etc functions at global scope. | |
28 | ||
29 | using namespace boost::math; | |
30 | using boost::math::signbit; | |
31 | using boost::math::changesign; | |
32 | using boost::math::isnan; | |
33 | ||
34 | //------------------------------------------------------------------------------ | |
35 | ||
36 | void trap_test_finite(); | |
37 | void trap_test_inf(); | |
38 | void trap_test_nan(); | |
39 | ||
40 | BOOST_AUTO_TEST_CASE(trap_test) | |
41 | { | |
42 | trap_test_finite(); | |
43 | trap_test_inf(); | |
44 | trap_test_nan(); | |
45 | } | |
46 | ||
47 | //------------------------------------------------------------------------------ | |
48 | ||
49 | template<class CharType, class ValType> void trap_test_finite_impl(); | |
50 | ||
51 | void trap_test_finite() | |
52 | { | |
53 | trap_test_finite_impl<char, float>(); | |
54 | trap_test_finite_impl<char, double>(); | |
55 | trap_test_finite_impl<char, long double>(); | |
56 | trap_test_finite_impl<wchar_t, float>(); | |
57 | trap_test_finite_impl<wchar_t, double>(); | |
58 | trap_test_finite_impl<wchar_t, long double>(); | |
59 | } | |
60 | ||
61 | template<class CharType, class ValType> void trap_test_finite_impl() | |
62 | { | |
63 | std::locale old_locale; | |
64 | std::locale tmp_locale(old_locale, | |
65 | new nonfinite_num_put<CharType>(trap_infinity | trap_nan)); | |
66 | std::locale new_locale(tmp_locale, | |
67 | new nonfinite_num_get<CharType>(trap_infinity | trap_nan)); | |
68 | ||
69 | std::basic_stringstream<CharType> ss; | |
70 | ss.imbue(new_locale); | |
71 | ||
72 | ValType a1 = (ValType)1.2; | |
73 | ValType a2 = (ValType)-3.5; | |
74 | ValType a3 = (std::numeric_limits<ValType>::max)(); | |
75 | ValType a4 = -(std::numeric_limits<ValType>::max)(); | |
76 | ss << a1 << ' ' << a2 << ' ' << a3 << ' ' << a4; | |
77 | ||
78 | ValType b1, b2, b3, b4; | |
79 | ss >> b1 >> b2 >> b3 >> b4; | |
80 | ||
81 | BOOST_CHECK(almost_equal(b1, a1)); | |
82 | BOOST_CHECK(almost_equal(b2, a2)); | |
83 | BOOST_CHECK(almost_equal(b3, a3)); | |
84 | BOOST_CHECK(almost_equal(b4, a4)); | |
85 | BOOST_CHECK(b3 != std::numeric_limits<ValType>::infinity()); | |
86 | BOOST_CHECK(b4 != -std::numeric_limits<ValType>::infinity()); | |
87 | BOOST_CHECK(ss.rdstate() == std::ios_base::eofbit); | |
88 | ||
89 | ss.clear(); | |
90 | ss.str(S_("")); | |
91 | ||
92 | ss << "++5"; | |
93 | ValType b5; | |
94 | ss >> b5; | |
95 | BOOST_CHECK(ss.rdstate() == std::ios_base::failbit); | |
96 | } | |
97 | ||
98 | //------------------------------------------------------------------------------ | |
99 | ||
100 | template<class CharType, class ValType> void trap_test_inf_impl(); | |
101 | template<class CharType, class ValType> void trap_test_put_inf_impl(); | |
102 | template<class CharType, class ValType> void trap_test_get_inf_impl(); | |
103 | ||
104 | void trap_test_inf() | |
105 | { | |
106 | trap_test_inf_impl<char, float>(); | |
107 | trap_test_inf_impl<char, double>(); | |
108 | trap_test_inf_impl<char, long double>(); | |
109 | trap_test_inf_impl<wchar_t, float>(); | |
110 | trap_test_inf_impl<wchar_t, double>(); | |
111 | trap_test_inf_impl<wchar_t, long double>(); | |
112 | } | |
113 | ||
114 | template<class CharType, class ValType> void trap_test_inf_impl() | |
115 | { | |
116 | trap_test_put_inf_impl<CharType, ValType>(); | |
117 | trap_test_get_inf_impl<CharType, ValType>(); | |
118 | } | |
119 | ||
120 | template<class CharType, class ValType> void trap_test_put_inf_impl() | |
121 | { | |
122 | std::locale old_locale; | |
123 | std::locale new_locale(old_locale, | |
124 | new nonfinite_num_put<CharType>(trap_infinity)); | |
125 | ||
126 | std::basic_stringstream<CharType> ss; | |
127 | ss.imbue(new_locale); | |
128 | ||
129 | ValType a1 = std::numeric_limits<ValType>::infinity(); | |
130 | ss << a1; | |
131 | BOOST_CHECK(ss.rdstate() == std::ios_base::failbit | |
132 | || ss.rdstate() == std::ios_base::badbit); | |
133 | ss.clear(); | |
134 | ||
135 | ValType a2 = -std::numeric_limits<ValType>::infinity(); | |
136 | ss << a2; | |
137 | BOOST_CHECK(ss.rdstate() == std::ios_base::failbit | |
138 | || ss.rdstate() == std::ios_base::badbit); | |
139 | } | |
140 | ||
141 | template<class CharType, class ValType> void trap_test_get_inf_impl() | |
142 | { | |
143 | std::locale old_locale; | |
144 | std::locale tmp_locale(old_locale, new nonfinite_num_put<CharType>); | |
145 | std::locale new_locale(tmp_locale, | |
146 | new nonfinite_num_get<CharType>(trap_infinity)); | |
147 | ||
148 | std::basic_stringstream<CharType> ss; | |
149 | ss.imbue(new_locale); | |
150 | ||
151 | ValType a1 = std::numeric_limits<ValType>::infinity(); | |
152 | ss << a1; | |
153 | ValType b1; | |
154 | ss >> b1; | |
155 | BOOST_CHECK(ss.rdstate() == std::ios_base::failbit); | |
156 | ||
157 | ss.clear(); | |
158 | ss.str(S_("")); | |
159 | ||
160 | ValType a2 = -std::numeric_limits<ValType>::infinity(); | |
161 | ss << a2; | |
162 | ValType b2; | |
163 | ss >> b2; | |
164 | BOOST_CHECK(ss.rdstate() == std::ios_base::failbit); | |
165 | } | |
166 | ||
167 | //------------------------------------------------------------------------------ | |
168 | ||
169 | template<class CharType, class ValType> void trap_test_nan_impl(); | |
170 | template<class CharType, class ValType> void trap_test_put_nan_impl(); | |
171 | template<class CharType, class ValType> void trap_test_get_nan_impl(); | |
172 | ||
173 | void trap_test_nan() | |
174 | { | |
175 | trap_test_nan_impl<char, float>(); | |
176 | trap_test_nan_impl<char, double>(); | |
177 | trap_test_nan_impl<char, long double>(); | |
178 | trap_test_nan_impl<wchar_t, float>(); | |
179 | trap_test_nan_impl<wchar_t, double>(); | |
180 | trap_test_nan_impl<wchar_t, long double>(); | |
181 | } | |
182 | ||
183 | template<class CharType, class ValType> void trap_test_nan_impl() | |
184 | { | |
185 | trap_test_put_nan_impl<CharType, ValType>(); | |
186 | trap_test_get_nan_impl<CharType, ValType>(); | |
187 | } | |
188 | ||
189 | template<class CharType, class ValType> void trap_test_put_nan_impl() | |
190 | { | |
191 | std::locale old_locale; | |
192 | std::locale new_locale(old_locale, | |
193 | new nonfinite_num_put<CharType>(trap_nan)); | |
194 | ||
195 | std::basic_stringstream<CharType> ss; | |
196 | ss.imbue(new_locale); | |
197 | ||
198 | ValType a1 = std::numeric_limits<ValType>::quiet_NaN(); | |
199 | ss << a1; | |
200 | BOOST_CHECK(ss.rdstate() == std::ios_base::failbit | |
201 | || ss.rdstate() == std::ios_base::badbit); | |
202 | ss.clear(); | |
203 | ||
204 | ValType a2 = std::numeric_limits<ValType>::signaling_NaN(); | |
205 | ss << a2; | |
206 | BOOST_CHECK(ss.rdstate() == std::ios_base::failbit | |
207 | || ss.rdstate() == std::ios_base::badbit); | |
208 | } | |
209 | ||
210 | template<class CharType, class ValType> void trap_test_get_nan_impl() | |
211 | { | |
212 | std::locale old_locale; | |
213 | std::locale tmp_locale(old_locale, new nonfinite_num_put<CharType>); | |
214 | std::locale new_locale(tmp_locale, | |
215 | new nonfinite_num_get<CharType>(trap_nan)); | |
216 | ||
217 | std::basic_stringstream<CharType> ss; | |
218 | ss.imbue(new_locale); | |
219 | ||
220 | ValType a1 = std::numeric_limits<ValType>::quiet_NaN(); | |
221 | ss << a1; | |
222 | ValType b1; | |
223 | ss >> b1; | |
224 | BOOST_CHECK(ss.rdstate() == std::ios_base::failbit); | |
225 | ||
226 | ss.clear(); | |
227 | ss.str(S_("")); | |
228 | ||
229 | ValType a2 = std::numeric_limits<ValType>::signaling_NaN(); | |
230 | ss << a2; | |
231 | ValType b2; | |
232 | ss >> b2; | |
233 | BOOST_CHECK(ss.rdstate() == std::ios_base::failbit); | |
234 | } | |
235 | ||
236 | //------------------------------------------------------------------------------ | |
237 | ||
238 | } // anonymous namespace | |
239 |