Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
TypeConversions_UnitTest.cpp
Go to the documentation of this file.
1// @HEADER
2// ***********************************************************************
3//
4// Teuchos: Common Tools Package
5// Copyright (2004) Sandia Corporation
6//
7// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8// license for use of this work by or on behalf of the U.S. Government.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38//
39// ***********************************************************************
40// @HEADER
41
42#include "Teuchos_as.hpp"
44#include <limits>
45
46// Like TEST_NOTHROW, but showing the exception message if the code does throw.
47// The exception must be a subclass of std::exception.
48#define TEST_NOTHROW_WITH_MESSAGE( code ) \
49 try { \
50 (out) << "Test that code {"#code";} does not throw : "; \
51 code; \
52 (out) << "passes\n"; \
53 } \
54 catch (std::exception& theException) { \
55 (success) = false; \
56 out << "failed\n"; \
57 out << "\nException message for unexpected exception:\n\n"; \
58 { \
59 Teuchos::OSTab l_tab(out); \
60 out << theException.what() << "\n\n"; \
61 } \
62 }
63
64// Putting the unit tests in an anonymous namespace avoids name collisions.
65namespace {
66
67//
68// Hack to work around Bug 5757 (unit test macros that instantiate
69// templated unit tests can't handle spaces in the name of the
70// template parameter).
71//
72typedef unsigned short unsigned_short_type;
73typedef unsigned int unsigned_int_type;
74typedef unsigned long unsigned_long_type;
75
76typedef long long long_long_type;
77typedef unsigned long long unsigned_long_long_type;
78
79
80template <class T>
81std::string valToString(const T &val)
82{
83 const int precision = std::numeric_limits<T>::digits10 + 10; // Be super safe!
84 //std::cout << "precision = " << precision << "\n";
85 std::ostringstream os;
86 os.precision(precision);
87 os << val;
88 return os.str();
89}
90
91
92//
93// Tests for conversions between built-in floating-point types.
94//
95TEUCHOS_UNIT_TEST( asSafe, realToReal ) {
96 using Teuchos::as;
97 using Teuchos::asSafe;
98
99 const float minF = -std::numeric_limits<float>::max ();
100 const float minusOneF = -1;
101 const float maxF = std::numeric_limits<float>::max ();
102
103 const double minD = -std::numeric_limits<double>::max ();
104 const double minusOneD = -1;
105 const double maxD = std::numeric_limits<double>::max ();
106
107 float valF = 0;
108 double valD = 0;
109 long double valLD = 0;
110
111 //
112 // Test float -> float conversions.
113 //
114 TEST_NOTHROW(valF = asSafe<float> (minF));
115 TEST_EQUALITY_CONST(valF, minF);
116 TEST_NOTHROW(valF = as<float> (minF));
117 TEST_EQUALITY_CONST(valF, minF);
118 TEST_NOTHROW(valF = asSafe<float> (maxF));
119 TEST_EQUALITY_CONST(valF, maxF);
120 TEST_NOTHROW(valF = as<float> (maxF));
121 TEST_EQUALITY_CONST(valF, maxF);
122 TEST_NOTHROW(valF = asSafe<float> (minusOneF));
123 TEST_EQUALITY_CONST(valF, minusOneF);
124 TEST_NOTHROW(valF = as<float> (minusOneF));
125 TEST_EQUALITY_CONST(valF, minusOneF);
126
127 //
128 // Test double -> double conversions.
129 //
130 TEST_NOTHROW(valD = asSafe<double> (minD));
131 TEST_EQUALITY_CONST(valD, minD);
132 TEST_NOTHROW(valD = as<double> (minD));
133 TEST_EQUALITY_CONST(valD, minD);
134 TEST_NOTHROW(valD = asSafe<double> (maxD));
135 TEST_EQUALITY_CONST(valD, maxD);
136 TEST_NOTHROW(valD = as<double> (maxD));
137 TEST_EQUALITY_CONST(valD, maxD);
138 TEST_NOTHROW(valD = asSafe<double> (minusOneD));
139 TEST_EQUALITY_CONST(valD, minusOneD);
140 TEST_NOTHROW(valD = as<double> (minusOneD));
141 TEST_EQUALITY_CONST(valD, minusOneD);
142
143 //
144 // Test double -> float conversions.
145 //
146 // mfh 25 Nov 2012: Disabled throwing std::range_error on overflow
147 // for conversions between build-in floating-point types, in favor
148 // of IEEE 754 overflow semantics.
149 // TEST_THROW(valF = asSafe<float> (minD), std::range_error);
150 // TEST_THROW(valF = asSafe<float> (maxD), std::range_error);
151
152 TEST_NOTHROW(valF = asSafe<float> (minusOneF));
153 TEST_EQUALITY_CONST(valF, minusOneF);
154 TEST_NOTHROW(valF = as<float> (minusOneF));
155 TEST_EQUALITY_CONST(valF, minusOneF);
156
157 TEST_NOTHROW(valF = asSafe<float> (minusOneD));
158 TEST_EQUALITY_CONST(valF, minusOneD);
159 TEST_NOTHROW(valF = as<float> (minusOneD));
160 TEST_EQUALITY_CONST(valF, minusOneD);
161
162 //
163 // Test float -> double conversions.
164 //
165 TEST_NOTHROW(valD = asSafe<double> (minF));
166 TEST_EQUALITY_CONST(valD, minF);
167 TEST_NOTHROW(valD = as<double> (minF));
168 TEST_EQUALITY_CONST(valD, minF);
169
170 TEST_NOTHROW(valD = asSafe<double> (maxF));
171 TEST_EQUALITY_CONST(valD, maxF);
172 TEST_NOTHROW(valD = as<double> (maxF));
173 TEST_EQUALITY_CONST(valD, maxF);
174
175 TEST_NOTHROW(valD = asSafe<double> (minusOneF));
176 TEST_EQUALITY_CONST(valD, minusOneF);
177 TEST_NOTHROW(valD = as<double> (minusOneF));
178 TEST_EQUALITY_CONST(valD, minusOneF);
179
180 // mfh 25 Nov 2012: C89 does not mandate that "long double"
181 // implement the extended-precision 80-bit format of IEEE 754. In
182 // fact, Microsoft Visual Studio implements long double just as
183 // double. (This goes all the way back to Bill Gates' initial
184 // discussions with the Intel x87 architects.) Relaxing the sizeof
185 // (long double) > sizeof (double) requirement will prevent test
186 // failures such as the following (on Windows):
187 //
188 // http://testing.sandia.gov/cdash/testDetails.php?test=10628321&build=801972
189
190 // // Make sure that long double is as long as the standard requires.
191 // TEUCHOS_TEST_FOR_EXCEPTION(
192 // sizeof (long double) <= sizeof (double),
193 // std::logic_error,
194 // "Your system does not have an IEEE 754 - compliant implementation of long double. "
195 // "The IEEE 754 standard requires that long double be longer than double. "
196 // "In fact, it must use at least 80 bits. "
197 // "However, sizeof (long double) = " << sizeof (long double)
198 // << " < sizeof (double) = " << sizeof (double) << ".");
199
200 const long double minLD = -std::numeric_limits<long double>::max ();
201 const long double minusOneLD = -1;
202 const long double maxLD = std::numeric_limits<long double>::max ();
203
204 //
205 // Test long double -> long double conversions.
206 //
207 TEST_NOTHROW(valLD = asSafe<long double> (minLD));
208 TEST_EQUALITY_CONST(valLD, minLD);
209 TEST_NOTHROW(valLD = as<long double> (minLD));
210 TEST_EQUALITY_CONST(valLD, minLD);
211 TEST_NOTHROW(valLD = asSafe<long double> (maxLD));
212 TEST_EQUALITY_CONST(valLD, maxLD);
213 TEST_NOTHROW(valLD = as<long double> (maxLD));
214 TEST_EQUALITY_CONST(valLD, maxLD);
215 TEST_NOTHROW(valLD = asSafe<long double> (minusOneLD));
216 TEST_EQUALITY_CONST(valLD, minusOneLD);
217 TEST_NOTHROW(valLD = as<long double> (minusOneLD));
218 TEST_EQUALITY_CONST(valLD, minusOneLD);
219
220 //
221 // Test long double -> float conversions.
222 //
223 // mfh 25 Nov 2012: Disabled throwing std::range_error on overflow
224 // for conversions between build-in floating-point types, in favor
225 // of IEEE 754 overflow semantics.
226 // TEST_THROW(valF = asSafe<float> (minLD), std::range_error);
227 // TEST_THROW(valF = asSafe<float> (maxLD), std::range_error);
228 TEST_NOTHROW(valF = asSafe<float> (minusOneLD));
229 TEST_EQUALITY_CONST(valF, minusOneLD);
230 TEST_NOTHROW(valF = as<float> (minusOneLD));
231 TEST_EQUALITY_CONST(valF, minusOneLD);
232
233 //
234 // Test long double -> double conversions.
235 //
236 // mfh 25 Nov 2012: See above note on how long double is the same as
237 // double on some systems.
238 //
239 // TEST_THROW(valD = asSafe<double> (minLD), std::range_error);
240 // TEST_THROW(valD = asSafe<double> (maxLD), std::range_error);
241 TEST_NOTHROW(valD = as<float> (minusOneLD));
242 TEST_EQUALITY_CONST(valD, minusOneLD);
243
244 //
245 // Test float -> long double conversions.
246 //
247 TEST_NOTHROW(valLD = asSafe<long double> (minF));
248 TEST_EQUALITY_CONST(valLD, minF);
249 TEST_NOTHROW(valLD = as<long double> (minF));
250 TEST_EQUALITY_CONST(valLD, minF);
251
252 TEST_NOTHROW(valLD = asSafe<long double> (maxF));
253 TEST_EQUALITY_CONST(valLD, maxF);
254 TEST_NOTHROW(valLD = as<long double> (maxF));
255 TEST_EQUALITY_CONST(valLD, maxF);
256
257 TEST_NOTHROW(valLD = asSafe<long double> (minusOneF));
258 TEST_EQUALITY_CONST(valLD, minusOneF);
259 TEST_NOTHROW(valLD = as<long double> (minusOneF));
260 TEST_EQUALITY_CONST(valLD, minusOneF);
261
262 //
263 // Test double -> long double conversions.
264 //
265 TEST_NOTHROW(valLD = asSafe<long double> (minD));
266 TEST_EQUALITY_CONST(valLD, minD);
267 TEST_NOTHROW(valLD = as<long double> (minD));
268 TEST_EQUALITY_CONST(valLD, minD);
269
270 TEST_NOTHROW(valLD = asSafe<long double> (maxD));
271 TEST_EQUALITY_CONST(valLD, maxD);
272 TEST_NOTHROW(valLD = as<long double> (maxD));
273 TEST_EQUALITY_CONST(valLD, maxD);
274
275 TEST_NOTHROW(valLD = asSafe<long double> (minusOneD));
276 TEST_EQUALITY_CONST(valLD, minusOneD);
277 TEST_NOTHROW(valLD = as<long double> (minusOneD));
278 TEST_EQUALITY_CONST(valLD, minusOneD);
279}
280
281
282//
283// Tests for conversions from std::string to built-in floating-point types.
284//
285TEUCHOS_UNIT_TEST( asSafe, stringToReal ) {
286 using Teuchos::as;
287 using Teuchos::asSafe;
288
289 const float minF = -std::numeric_limits<float>::max ();
290 const float minusOneF = -1;
291 const float maxF = std::numeric_limits<float>::max ();
292
293 out << "minF = " << minF << "\n";
294 out << "maxF = " << maxF << "\n";
295
296 const double minD = -std::numeric_limits<double>::max ();
297 const double minusOneD = -1;
298 const double maxD = std::numeric_limits<double>::max ();
299
300 out << "minD = " << minD << "\n";
301 out << "maxD = " << maxD << "\n";
302
303 // mfh 26 Nov 2012: C89 does not mandate that "long double"
304 // implement the extended-precision 80-bit format of IEEE 754. In
305 // fact, Microsoft Visual Studio implements long double just as
306 // double. (This goes all the way back to Bill Gates' initial
307 // discussions with the Intel x87 architects.) Relaxing the sizeof
308 // (long double) > sizeof (double) requirement will prevent test
309 // failures such as the following (on Windows):
310 //
311 // http://testing.sandia.gov/cdash/testDetails.php?test=10628321&build=801972
312 // http://testing.sandia.gov/cdash/testDetails.php?test=10739503&build=810247
313
314 // // Make sure that long double is as long as the standard requires.
315 // TEUCHOS_TEST_FOR_EXCEPTION(
316 // sizeof (long double) <= sizeof (double),
317 // std::logic_error,
318 // "Your system does not have an IEEE 754 - compliant implementation of long double. "
319 // "The IEEE 754 standard requires that long double be longer than double. "
320 // "In fact, it must use at least 80 bits. "
321 // "However, sizeof (long double) = " << sizeof (long double)
322 // << " < sizeof (double) = " << sizeof (double) << ".");
323
324 const long double minLD = -std::numeric_limits<long double>::max ();
325 const long double minusOneLD = -1;
326 const long double maxLD = std::numeric_limits<long double>::max ();
327
328 out << "minLD = " << minLD << "\n";
329 out << "maxLD = " << maxLD << "\n";
330
331 float valF = 0;
332 double valD = 0;
333 long double valLD = 0;
334
335 //
336 out << "Testing string -> float conversions ...\n";
337 //
338 {
339 std::ostringstream os;
340 // mfh 27 Nov 2012: Write all 17 digits that the double deserves.
341 // If you just write 9, it might round (as it does on some
342 // platforms) to a value that can't be represented in float.
343 // os.precision (9);
344 os.precision (17);
345 os << minF;
346 TEST_NOTHROW_WITH_MESSAGE(valF = asSafe<float> (os.str ()));
347 TEST_EQUALITY_CONST(valF, minF);
348 TEST_NOTHROW_WITH_MESSAGE(valF = as<float> (os.str ()));
349 TEST_EQUALITY_CONST(valF, minF);
350 }
351 {
352 std::ostringstream os;
353 os.precision (17);
354 os << maxF;
355 TEST_NOTHROW_WITH_MESSAGE(valF = asSafe<float> (os.str ()));
356 TEST_EQUALITY_CONST(valF, maxF);
357 TEST_NOTHROW_WITH_MESSAGE(valF = as<float> (os.str ()));
358 TEST_EQUALITY_CONST(valF, maxF);
359 }
360 {
361 std::ostringstream os;
362 os.precision (17);
363 os << minusOneF;
364 TEST_NOTHROW_WITH_MESSAGE(valF = asSafe<float> (os.str ()));
365 TEST_EQUALITY_CONST(valF, minusOneF);
366 TEST_NOTHROW_WITH_MESSAGE(valF = as<float> (os.str ()));
367 TEST_EQUALITY_CONST(valF, minusOneF);
368 }
369 // Write -1 as double, read as float; shouldn't throw.
370 {
371 std::ostringstream os;
372 os.precision (17);
373 os << minusOneD;
374 TEST_NOTHROW_WITH_MESSAGE(valF = asSafe<float> (os.str ()));
375 TEST_EQUALITY_CONST(valF, minusOneF);
376 TEST_NOTHROW_WITH_MESSAGE(valF = as<float> (os.str ()));
377 TEST_EQUALITY_CONST(valF, minusOneF);
378 }
379
380 //
381 out << "Testing string -> float conversions that should throw ...\n";
382 //
383 {
384 std::ostringstream os;
385 os.precision (9);
386 os << minD;
387 TEST_THROW(valF = asSafe<float> (os.str ()), std::range_error);
388 }
389 {
390 std::ostringstream os;
391 os.precision (9);
392 os << maxD;
393 TEST_THROW(valF = asSafe<float> (os.str ()), std::range_error);
394 }
395
396 //
397 out << "Testing string -> double conversions ...\n";
398 //
399 {
400 std::ostringstream os;
401 os.precision (17);
402 os << minD;
403 TEST_NOTHROW(valD = asSafe<double> (os.str ()));
404 TEST_EQUALITY_CONST(valD, minD);
405 TEST_NOTHROW(valD = as<double> (os.str ()));
406 TEST_EQUALITY_CONST(valD, minD);
407 }
408 {
409 std::ostringstream os;
410 os.precision (17);
411 os << maxD;
412 TEST_NOTHROW(valD = asSafe<double> (os.str ()));
413 TEST_EQUALITY_CONST(valD, maxD);
414 TEST_NOTHROW(valD = as<double> (os.str ()));
415 TEST_EQUALITY_CONST(valD, maxD);
416 }
417 {
418 TEST_NOTHROW(valD = asSafe<double> (valToString(minusOneD)));
419 TEST_EQUALITY_CONST(valD, minusOneD);
420 TEST_NOTHROW(valD = as<double> (valToString(minusOneD)));
421 TEST_EQUALITY_CONST(valD, minusOneD);
422 }
423
424 //
425 // Test string -> double conversions that should throw,
426 // if sizeof(long double) > sizeof(double).
427 //
428 const int sizeof_long_double = sizeof(long double);
429 const int sizeof_double = sizeof(double);
430 const int max_exponent10_long_double = std::numeric_limits<long double>::max_exponent10;
431 const int max_exponent10_double = std::numeric_limits<double>::max_exponent10;
432
433 out << "sizeof_long_double = " << sizeof_long_double << "\n";
434 out << "sizeof_double = " << sizeof_double << "\n";
435 out << "max_exponent10_long_double = " << max_exponent10_long_double << "\n";
436 out << "max_exponent10_double = " << max_exponent10_double << "\n";
437
438 if (sizeof_long_double > sizeof_double
439 && max_exponent10_long_double > max_exponent10_double)
440 {
441 out << "Testing converting from 'long double' to 'double' that does not fit ...\n";
442
443 const long double maxTooBigLD_for_D = static_cast<long double>(maxD) * 10.0;
444 const long double minTooBigLD_for_D = static_cast<long double>(minD) * 10.0;
445 out << "maxTooBigLD_for_D = " << maxTooBigLD_for_D << "\n";
446 out << "minTooBigLD_for_D = " << minTooBigLD_for_D << "\n";
447
448 {
449 TEST_THROW(valD = asSafe<double>(valToString(minTooBigLD_for_D)), std::range_error);
450 out << "valD = " << valD << "\n";
451 }
452 {
453 std::ostringstream os;
454 os.precision (36);
455 TEST_THROW(valD = asSafe<double>(valToString(maxTooBigLD_for_D)), std::range_error);
456 out << "valD = " << valD << "\n";
457 }
458
459 // NOTE: The above test avoids using std::numeric_limits<long
460 // double>::max() because with the CUDA compiler on shiller/hansen it
461 // returns 'inf'. That completely breaks the test since "inf" is a valid
462 // value to read into a 'double'.
463 //
464 // This updated test takes std::numeric_limits<double>::max() * 10.0,
465 // writes to a string and then tries to read that back in as a 'dobule'.
466 // That cathces the bad conversion and thowns an exception as it should.
467 // This will work on any system where std::numeric_limits<long
468 // double>::max_expoent10 > std::numeric_limits<double>::max_expoent10
469 // (and this test is only run in cases where that is true). See Trilinos
470 // GitHub issue #2407.
471
472 }
473
474 //
475 out << "Testing string -> long double conversions ...\n";
476 //
477 {
478 std::ostringstream os;
479 os.precision (36);
480 os << minLD;
481 TEST_NOTHROW(valLD = asSafe<long double> (os.str ()));
482 TEST_EQUALITY_CONST(valLD, minLD);
483 TEST_NOTHROW(valLD = as<long double> (os.str ()));
484 TEST_EQUALITY_CONST(valLD, minLD);
485 }
486 {
487 std::ostringstream os;
488 os.precision (36);
489 os << maxLD;
490 TEST_NOTHROW(valLD = asSafe<long double> (os.str ()));
491 TEST_EQUALITY_CONST(valLD, maxLD);
492 TEST_NOTHROW(valLD = as<long double> (os.str ()));
493 TEST_EQUALITY_CONST(valLD, maxLD);
494 }
495 {
496 std::ostringstream os;
497 os.precision (36);
498 os << minusOneLD;
499 TEST_NOTHROW(valLD = asSafe<long double> (os.str ()));
500 TEST_EQUALITY_CONST(valLD, minusOneLD);
501 TEST_NOTHROW(valLD = as<long double> (os.str ()));
502 TEST_EQUALITY_CONST(valLD, minusOneLD);
503 }
504}
505
506
507//
508// Templated test for overflow for conversion from a built-in
509// real-valued (not complex) floating-point type (float or double) to
510// a built-in signed integer type, if that should actually overflow
511// (depends on sizeof(SignedIntType)).
512//
513TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( asSafe, realToSignedIntTypeOverflow, RealType, SignedIntType )
514{
515 using Teuchos::asSafe;
516
517 // std::numeric_limits<RealType>::min() gives the minimum _positive_
518 // normalized value of type RealType. IEEE 754 floating-point
519 // values can change sign just by flipping the sign bit, so the
520 // "most negative" finite RealType is just the negative of the "most
521 // positive" finite RealType.
522 const RealType minVal = -std::numeric_limits<RealType>::max ();
523 const RealType maxVal = std::numeric_limits<RealType>::max ();
524
525 SignedIntType val = 0;
526 if (sizeof (SignedIntType) < sizeof (RealType)) {
527 TEST_THROW(val = asSafe<SignedIntType> (minVal), std::range_error);
528 TEST_THROW(val = asSafe<SignedIntType> (maxVal), std::range_error);
529 }
530 (void) val; // Silence compiler errors.
531}
532
533//
534// Templated test for overflow for conversion from a built-in
535// real-valued (not complex) floating-point type (float or double) to
536// a built-in unsigned integer type, if that should actually overflow
537// (depends on sizeof(UnsignedIntType)).
538//
539TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( asSafe, realToUnsignedIntTypeOverflow, RealType, UnsignedIntType )
540{
541 using Teuchos::asSafe;
543
544 // std::numeric_limits<RealType>::min() gives the minimum _positive_
545 // normalized value of type RealType. IEEE 754 floating-point
546 // values can change sign just by flipping the sign bit, so the
547 // "most negative" finite RealType is just the negative of the "most
548 // positive" finite RealType.
549 const RealType minVal = -std::numeric_limits<RealType>::max ();
550 const RealType maxVal = std::numeric_limits<RealType>::max ();
551 const UnsignedIntType maxUnsignedIntVal =
552 std::numeric_limits<UnsignedIntType>::max ();
553
554 // mfh 15 Nov 2012: Set val to a marker value, so we can see if the
555 // body of TEST_NOTHROW below actually did the assignment.
556 UnsignedIntType val = 42;
557 // Make sure that val starts off with a different value than what
558 // its final value should be.
560 val == static_cast<UnsignedIntType> (maxVal),
561 std::logic_error,
562 "Dear test author, please pick a different marker value. "
563 "Please report this bug to the Teuchos developers.");
564
565 // Conversion from any negative value should throw.
566 TEST_THROW(val = asSafe<UnsignedIntType> (minVal), std::range_error);
567 const RealType minusOne = -1;
568 TEST_THROW(val = asSafe<UnsignedIntType> (minusOne), std::range_error);
569
570 // Only test overflow checks if overflow can actually take place.
571 if (static_cast<RealType>(maxUnsignedIntVal) < maxVal) {
572 TEST_THROW(val = asSafe<UnsignedIntType> (maxVal), std::range_error);
573 try {
574 std::cerr << std::endl
575 << "*** RealType = " << TypeNameTraits<RealType>::name ()
576 << ", UnsignedIntType = " << TypeNameTraits<UnsignedIntType>::name ()
577 << ", maxVal = " << maxVal
578 << ", maxUnsignedIntVal = " << maxUnsignedIntVal
579 << ", asSafe (maxVal) = " << asSafe<UnsignedIntType> (maxVal)
580 << std::endl;
581 } catch (...) {
582 std::cerr << "(asSafe threw an exception)" << std::endl;
583 }
584 }
585 else { // Only conversions from negative values should throw.
586 TEST_NOTHROW(val = asSafe<UnsignedIntType> (maxVal));
587 TEST_EQUALITY_CONST(val, static_cast<UnsignedIntType> (maxVal));
588
589#if 0
591 val == 42,
592 std::logic_error,
593 "Hey, how come val == 42? It should be something completely different. "
594 << std::endl
595 << "FYI, static_cast<" << TypeNameTraits<UnsignedIntType>::name ()
596 << "> (minVal) = " << static_cast<UnsignedIntType> (minVal)
597 << " and "
598 << std::endl
599 << "static_cast<" << TypeNameTraits<UnsignedIntType>::name ()
600 << "> (maxVal) = " << static_cast<UnsignedIntType> (maxVal)
601 << ". val should be equal to the latter."
602 << std::endl
603 << "As float: minVal = " << minVal << ", maxVal = " << maxVal << ".");
604#endif // 0
605 }
606
607 (void) val; // Silence compiler errors.
608}
609
610//
611// Instantiations of templated tests for conversions from double to
612// various built-in integer types.
613//
614
615// mfh 19 Nov 2012: The tests that I disabled below in commit
616// f99c0e446f5c8dc385d00b60878314d40a7b9fe2 appear to be working now.
617// I am reenabling them tentatively.
618//
619// mfh 16 Nov 2012: The (asSafe, realToUnsignedIntTypeOverflow) test
620// keeps failing for template parameter combinations (double,
621// unsigned_long_type), (float, unsigned_int_type), and (float,
622// unsigned_long_type). It only fails on some platforms, not all, and
623// I can't figure out why. I'm disabling these tests for now until I
624// get more time to deal with this. For examples of test output, see:
625//
626// http://testing.sandia.gov/cdash/testDetails.php?test=10519753&build=793648
627// http://testing.sandia.gov/cdash/testDetails.php?test=10519852&build=793655
628// http://testing.sandia.gov/cdash/testDetails.php?test=10520495&build=793698
629// http://testing.sandia.gov/cdash/testDetails.php?test=10523690&build=793963
630// http://testing.sandia.gov/cdash/testDetails.php?test=10523763&build=793962
631// http://testing.sandia.gov/cdash/testDetails.php?test=10530499&build=794533
632// http://testing.sandia.gov/cdash/testDetails.php?test=10530585&build=794532
633// http://testing.sandia.gov/cdash/testDetails.php?test=10535648&build=794860
634
635TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, short )
636TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, int )
637TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, long )
638
639TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, long_long_type )
640
641TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, unsigned_short_type )
642TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, double, unsigned_int_type )
643// mfh 16,19 Nov 2012: See note above on formerly disabled tests.
644TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, double, unsigned_long_type )
645
646TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, double, unsigned_long_long_type )
647
648//
649// Instantiations of templated tests for conversions from float to
650// various built-in integer types.
651//
652
653TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, short )
654TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, int )
655TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, long )
656
657TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, long_long_type )
658
659TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, unsigned_short_type )
660// mfh 16,19 Nov 2012: See note above on formerly disabled tests.
661TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, float, unsigned_int_type )
662// mfh 16,19 Nov 2012: See note above on formerly disabled tests.
663TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, float, unsigned_long_type )
664
665TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, float, unsigned_long_long_type )
666
667
668//
669// Templated test for conversions between possibly different built-in
670// integer types. The C++ standard guarantees the following:
671// - <tt>sizeof (char) == 1</tt>
672// - <tt>sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long)</tt>
673//
674// C99 actually guarantees minimum sizes of the various types, and
675// that <tt>sizeof (long) <= sizeof (long long)</tt>.
676//
677// This means that any value that fits in a <tt>signed char</tt> must
678// also fit in any other built-in integer type. (The standard does
679// not promise whether <tt>char</tt> is signed or unsigned.) We've
680// chosen test values accordingly.
681//
682// We test both as() and asSafe to ensure correct behavior of both.
683//
684
685// Test for conversion between two built-in integer types FirstIntType
686// and SecondIntType. The test uses a positive number that must fit
687// in both and must not overflow. The test covers both as() and
688// asSafe().
689TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( as, positiveFirstIntToSecondInt, FirstIntType, SecondIntType )
690{
691 using Teuchos::as;
692 using Teuchos::asSafe;
693
694 std::ostringstream os;
695 const FirstIntType origVal = 42;
696 const SecondIntType origValSecond = 42;
697
698 SecondIntType asVal = 0, asSafeVal = 0;
699 TEST_NOTHROW(asVal = as<SecondIntType> (origVal));
700 TEST_NOTHROW(asSafeVal = asSafe<SecondIntType> (origVal));
701
702 TEST_EQUALITY_CONST(asVal, static_cast<SecondIntType> (origValSecond));
703 TEST_EQUALITY_CONST(asSafeVal, static_cast<SecondIntType> (origValSecond));
704 TEST_EQUALITY_CONST(asVal, asSafeVal);
705
706 FirstIntType backVal = 0, backSafeVal = 0;
707 TEST_NOTHROW(backVal = as<FirstIntType> (asVal));
708 TEST_NOTHROW(backSafeVal = asSafe<FirstIntType> (asSafeVal));
709
710 TEST_EQUALITY_CONST(backVal, origVal);
711 TEST_EQUALITY_CONST(backSafeVal, origVal);
712 TEST_EQUALITY_CONST(backVal, backSafeVal);
713}
714
715// Test for conversion between two built-in integer types
716// SignedIntType and UnsignedIntType. The two types must have the
717// same number of bits. The test starts with a negative number that
718// should trigger asSafe() to throw std::range_error. as() will only
719// throw std::range_error in a debug build, so we don't test it here.
720TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( asSafe, negativeSignedIntToUnsignedInt, SignedIntType, UnsignedIntType )
721{
722 using Teuchos::asSafe;
723
724 // Ensure that the two types have the same number of bits.
726 sizeof (SignedIntType) != sizeof (UnsignedIntType),
727 std::logic_error,
728 "Unit test Teuchos,asSafe,negativeSignedIntToUnsignedInt requires that the "
729 "two template parameters SignedIntType and UnsignedIntType have the same "
730 "number of bits.");
731
732 std::ostringstream os;
733 const SignedIntType origVal = -1;
734
735 UnsignedIntType asSafeVal = 0;
736 // Casts from negative signed values to unsigned values should
737 // throw, because they are not within range [0, maxUnsignedVal] of
738 // the target type.
739 TEST_THROW(asSafeVal = asSafe<UnsignedIntType> (origVal), std::range_error);
740 (void) asSafeVal; // Silence compiler warning.
741
742 // Casts from large unsigned values to negative signed values should
743 // throw, because they change positivity of the result.
744 UnsignedIntType negVal = static_cast<UnsignedIntType> (origVal);
745 SignedIntType backSafeVal = 0;
746 TEST_THROW(backSafeVal = asSafe<SignedIntType> (negVal), std::range_error);
747 (void) backSafeVal; // Silence compiler warning.
748}
749
750// Test for conversion between two built-in signed integer types
751// FirstSignedIntType and SecondSignedIntType. The test uses a
752// negative number that should not overflow in either case. It tests
753// both as() and asSafe().
754TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( as, negativeSignedIntToSignedInt, FirstSignedIntType, SecondSignedIntType )
755{
756 using Teuchos::as;
757 using Teuchos::asSafe;
758
759 std::ostringstream os;
760 const FirstSignedIntType origVal = -42;
761
762 // Ensure that the two types are both signed.
764 ! std::numeric_limits<FirstSignedIntType>::is_signed ||
765 ! std::numeric_limits<SecondSignedIntType>::is_signed,
766 std::logic_error,
767 "Unit test Teuchos,as,negativeSignedIntToSignedInt requires that the "
768 "two template parameters FirstSignedIntType and SecondSignedIntType "
769 "both be signed built-in integer types.");
770
771 // Test cast from FirstSignedIntType to SecondSignedIntType.
772 // The casts should not throw in either a debug or a release build.
773 SecondSignedIntType asVal = 0, asSafeVal = 0;
774 TEST_NOTHROW(asVal = as<SecondSignedIntType> (origVal));
775 TEST_NOTHROW(asSafeVal = asSafe<SecondSignedIntType> (origVal));
776 TEST_EQUALITY_CONST(asVal, static_cast<SecondSignedIntType> (origVal));
777 TEST_EQUALITY_CONST(asSafeVal, static_cast<SecondSignedIntType> (origVal));
778 TEST_EQUALITY_CONST(asVal, asSafeVal);
779
780 FirstSignedIntType backVal = 0, backSafeVal = 0;
781 TEST_NOTHROW(backVal = as<FirstSignedIntType> (origVal));
782 TEST_NOTHROW(backSafeVal = asSafe<FirstSignedIntType> (origVal));
783 TEST_EQUALITY_CONST(backVal, origVal);
784 TEST_EQUALITY_CONST(backSafeVal, origVal);
785 TEST_EQUALITY_CONST(backVal, backSafeVal);
786}
787
788//
789// Instantiations of templated tests for conversions between two
790// possibly different built-in integer types.
791//
792
793//
794// 1. Tests for types of the same size.
795//
796TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, short )
797TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, unsigned_short_type )
798TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, unsigned_short_type )
799TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, short )
800
801TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, int )
802TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, unsigned_int_type )
803TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, unsigned_int_type )
804TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, int )
805
806TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, long )
807TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, unsigned_long_type )
808TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, unsigned_long_type )
809TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, long )
810
811//
812// 2. Tests for types of possibly different sizes.
813//
814TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, int )
815TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, unsigned_int_type )
816TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, long )
817TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, unsigned_long_type )
818
819TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, unsigned_short_type )
820TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, short )
821TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, long )
822TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, long )
823TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, unsigned_long_type )
824TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, unsigned_long_type )
825
826TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, unsigned_short_type )
827TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, short )
828TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, int )
829TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, int )
830TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, unsigned_int_type )
831TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, unsigned_int_type )
832
833//
834// 3. "long long", "unsigned long long" tests
835//
836TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, long_long_type )
837TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, unsigned_long_long_type )
838TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, unsigned_long_long_type )
839TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, long_long_type )
840
841//
842// 4. Tests between "long long" or "unsigned long long", and some
843// other built-in integer type.
844//
845TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, long_long_type )
846TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, unsigned_long_long_type )
847TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, unsigned_long_long_type )
848TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, long_long_type )
849
850TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, long )
851TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, unsigned_long_type )
852TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, unsigned_long_type )
853TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, long )
854
855TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, long_long_type )
856TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, unsigned_long_long_type )
857TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, unsigned_long_long_type )
858TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, long_long_type )
859
860TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, int )
861TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, unsigned_int_type )
862TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, unsigned_int_type )
863TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, int )
864
865TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, long_long_type )
866TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, unsigned_long_long_type )
867TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, unsigned_long_long_type )
868TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, long_long_type )
869
870TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, short )
871TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, unsigned_short_type )
872TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, unsigned_short_type )
873TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, short )
874
875//
876// Instantiations of templated tests for conversions from signed to
877// unsigned built-in integer types. The two types must have the same
878// number of bits.
879//
880
881TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, negativeSignedIntToUnsignedInt, short, unsigned_short_type )
882TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, negativeSignedIntToUnsignedInt, int, unsigned_int_type )
883TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, negativeSignedIntToUnsignedInt, long, unsigned_long_type )
884
885TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, negativeSignedIntToUnsignedInt, long_long_type, unsigned_long_long_type )
886
887//
888// Instantiations of templated tests for conversions between two
889// possibly different signed integer types, for a negative value that
890// should not overflow.
891//
892
893TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, short, short )
894TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, short, int )
895TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, short, long )
896TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, int, short )
897TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, int, int )
898TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, int, long )
899TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long, short )
900TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long, int )
901TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long, long )
902
903TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, short, long_long_type )
904TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, int, long_long_type )
905TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long, long_long_type )
906TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long_long_type, short )
907TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long_long_type, int )
908TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long_long_type, long )
909TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long_long_type, long_long_type )
910
911//
912// Tests for conversions from std::string to built-in integer types.
913//
914
915// Test for overflow when converting an std::string (containing a
916// positive integer too large to fit in int) to int.
917TEUCHOS_UNIT_TEST( asSafe, stringToIntPositiveOverflow ) {
918 using Teuchos::asSafe;
919
920 std::ostringstream os;
921 const int maxInt = std::numeric_limits<int>::max ();
922
923 // Write a long int to the given string that is guaranteed to
924 // overflow int, if long is strictly bigger than int.
925 if (sizeof (int) < sizeof (long)) {
926 const long maxIntPlusOne = static_cast<long> (maxInt) + static_cast<long> (1);
927 os << maxIntPlusOne;
928
929 // Now attempt to convert the string to int. The conversion
930 // should fail, but leave the string unaffected.
931 int intVal = 0;
932 TEST_THROW(intVal = asSafe<int> (os.str ()), std::range_error);
933 (void) intVal; // Silence compiler warning.
934
935 // Since the string is unaffected, conversion to long should work
936 // just fine, and return the correct result.
937 long longVal = 0;
938 TEST_NOTHROW(longVal = asSafe<long> (os.str ()));
939 TEST_EQUALITY_CONST(longVal, maxIntPlusOne);
940 }
941 else { // C++ standard requires then that sizeof(int) == sizeof(long).
942 os << maxInt;
943 // Converting the string to int should not throw and should return
944 // the correct result.
945 int intVal = 0;
946 TEST_NOTHROW(intVal = asSafe<int> (os.str ()));
947 TEST_EQUALITY_CONST(intVal, maxInt);
948 }
949}
950
951// Test for overflow when converting an std::string (containing a
952// negative integer too negative to fit in int) to int.
953TEUCHOS_UNIT_TEST( asSafe, stringToIntNegativeOverflow ) {
954 using Teuchos::asSafe;
955
956 std::ostringstream os;
957 const int minInt = std::numeric_limits<int>::min ();
958
959 // Write a long int to the given string that is guaranteed to
960 // overflow int, if long is strictly bigger than int.
961 if (sizeof (int) < sizeof (long)) {
962 const long minIntMinusOne = static_cast<long> (minInt) - static_cast<long> (1);
963 os << minIntMinusOne;
964
965 // Now attempt to convert the string to int. The conversion
966 // should fail, but leave the string unaffected.
967 int intVal = 0;
968 TEST_THROW(intVal = asSafe<int> (os.str ()), std::range_error);
969 (void) intVal; // Silence compiler warning
970
971 // Since the string is unaffected, conversion to long should work
972 // just fine, and return the correct result.
973 long longVal = 0;
974 TEST_NOTHROW(longVal = asSafe<long> (os.str ()));
975 TEST_EQUALITY_CONST(longVal, minIntMinusOne);
976 }
977 else { // C++ standard requires then that sizeof(int) == sizeof(long).
978 os << minInt;
979 // Converting the string to int should not throw and should return
980 // the correct result.
981 int intVal = 0;
982 TEST_NOTHROW(intVal = asSafe<int> (os.str ()));
983 TEST_EQUALITY_CONST(intVal, minInt);
984 }
985}
986
987// Unit test for conversion from std::string (containing a positive
988// integer) to built-in integer types (may be signed or unsigned).
989TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( asSafe, stringToIntegerPositive, IntegerType ) {
990 using Teuchos::asSafe;
991
992 std::ostringstream os;
993 os << static_cast<IntegerType> (42);
994 IntegerType val = 0;
995 TEST_NOTHROW(val = asSafe<IntegerType> (os.str ()));
996 TEST_EQUALITY_CONST(val, static_cast<IntegerType> (42));
997}
998
999// Unit test for conversion from std::string (containing a negative
1000// integer) to built-in integer types (must be signed).
1001TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( asSafe, stringToIntegerNegative, IntegerType ) {
1002 using Teuchos::asSafe;
1003
1004 std::ostringstream os;
1005 os << static_cast<IntegerType> (-42);
1006 IntegerType val = 0;
1007 TEST_NOTHROW(val = asSafe<IntegerType> (os.str ()));
1008 TEST_EQUALITY_CONST(val, static_cast<IntegerType> (-42));
1009}
1010
1011// Unit test for conversion from std::string (NOT containing an
1012// integer) to built-in integer types (may be signed or unsigned).
1013TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( asSafe, stringToIntegerShouldThrow, IntegerType ) {
1014 using Teuchos::asSafe;
1015
1016 std::ostringstream os;
1017 os << "This string definitely does not contain an integer.";
1018 IntegerType val = 0;
1019 TEST_THROW(val = asSafe<IntegerType> (os.str ()), std::invalid_argument);
1020 (void) val; // Silence compiler warning
1021}
1022
1023// Macros to instantiate templated unit tests for conversion from
1024// std::string to built-in integer types. AnyIntegerType may be
1025// signed or unsigned; SignedIntegerType must be signed.
1026
1027#define UNIT_TEST_GROUP_ANY_INTEGER( AnyIntegerType ) \
1028 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( asSafe, stringToIntegerPositive, AnyIntegerType ) \
1029 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( asSafe, stringToIntegerShouldThrow, AnyIntegerType )
1030
1031#define UNIT_TEST_GROUP_SIGNED_INTEGER( SignedIntegerType ) \
1032 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( asSafe, stringToIntegerNegative, SignedIntegerType )
1033
1034//
1035// Instantiations of templated unit tests for conversion from
1036// std::string to built-in integer types.
1037//
1038
1045
1046//UNIT_TEST_GROUP_ANY_INTEGER( unsigned short )
1047UNIT_TEST_GROUP_ANY_INTEGER( unsigned_short_type )
1048//UNIT_TEST_GROUP_ANY_INTEGER( unsigned int )
1049UNIT_TEST_GROUP_ANY_INTEGER( unsigned_int_type )
1050//UNIT_TEST_GROUP_ANY_INTEGER( unsigned long )
1051UNIT_TEST_GROUP_ANY_INTEGER( unsigned_long_type )
1052
1053//UNIT_TEST_GROUP_ANY_INTEGER( long long )
1054UNIT_TEST_GROUP_ANY_INTEGER( long_long_type )
1055//UNIT_TEST_GROUP_SIGNED_INTEGER( long long )
1056UNIT_TEST_GROUP_SIGNED_INTEGER( long_long_type )
1057//UNIT_TEST_GROUP_ANY_INTEGER( unsigned long long )
1058UNIT_TEST_GROUP_ANY_INTEGER( unsigned_long_long_type )
1059
1060
1061#ifdef HAVE_TEUCHOS_COMPLEX
1062
1063#include <complex>
1064
1065//
1066// Tests for conversions involving complex types.
1067//
1068TEUCHOS_UNIT_TEST( asSafe, complexToComplex ) {
1069 using Teuchos::as;
1070 using Teuchos::asSafe;
1071
1072 const std::complex<float> iF = std::complex<float>(0,1);
1073 const std::complex<double> iD = std::complex<double>(0,1);
1074
1075 const std::complex<float> minF = -std::numeric_limits<float>::max ();
1076 const std::complex<float> minImagF = -iF*std::numeric_limits<float>::max ();
1077 const std::complex<float> minusOneF = -1;
1078 const std::complex<float> minusOneImagF = -iF;
1079 const std::complex<float> maxF = std::numeric_limits<float>::max ();
1080 const std::complex<float> maxImagF = iF*std::numeric_limits<float>::max ();
1081
1082 const std::complex<double> minD = -std::numeric_limits<double>::max ();
1083 const std::complex<double> minImagD = -iD*std::numeric_limits<double>::max ();
1084 const std::complex<double> minusOneD = -1;
1085 const std::complex<double> minusOneImagD = -iD;
1086 const std::complex<double> maxD = std::numeric_limits<double>::max ();
1087 const std::complex<double> maxImagD = iD*std::numeric_limits<double>::max ();
1088
1089 std::complex<float> valF = 0;
1090
1091 std::complex<double> valD = 0;
1092
1093 //
1094 // Test std::complex<float> -> std::complex<float> conversions.
1095 //
1096
1097 TEST_NOTHROW(valF = asSafe<std::complex<float> > (minF));
1098 TEST_EQUALITY_CONST(valF, minF);
1099 TEST_NOTHROW(valF = as<std::complex<float> > (minF));
1100 TEST_EQUALITY_CONST(valF, minF);
1101 TEST_NOTHROW(valF = asSafe<std::complex<float> > (minImagF));
1102 TEST_EQUALITY_CONST(valF, minImagF);
1103 TEST_NOTHROW(valF = as<std::complex<float> > (minImagF));
1104 TEST_EQUALITY_CONST(valF, minImagF);
1105 TEST_NOTHROW(valF = asSafe<std::complex<float> > (maxF));
1106 TEST_EQUALITY_CONST(valF, maxF);
1107 TEST_NOTHROW(valF = as<std::complex<float> > (maxF));
1108 TEST_EQUALITY_CONST(valF, maxF);
1109 TEST_NOTHROW(valF = asSafe<std::complex<float> > (maxImagF));
1110 TEST_EQUALITY_CONST(valF, maxImagF);
1111 TEST_NOTHROW(valF = as<std::complex<float> > (maxImagF));
1112 TEST_EQUALITY_CONST(valF, maxImagF);
1113 TEST_NOTHROW(valF = asSafe<std::complex<float> > (minusOneF));
1114 TEST_EQUALITY_CONST(valF, minusOneF);
1115 TEST_NOTHROW(valF = as<std::complex<float> > (minusOneF));
1116 TEST_EQUALITY_CONST(valF, minusOneF);
1117 TEST_NOTHROW(valF = asSafe<std::complex<float> > (minusOneImagF));
1118 TEST_EQUALITY_CONST(valF, minusOneImagF);
1119 TEST_NOTHROW(valF = as<std::complex<float> > (minusOneImagF));
1120 TEST_EQUALITY_CONST(valF, minusOneImagF);
1121
1122
1123 //
1124 // Test std::complex<double> -> std::complex<double> conversions.
1125 //
1126
1127 TEST_NOTHROW(valD = asSafe<std::complex<double> > (minD));
1128 TEST_EQUALITY_CONST(valD, minD);
1129 TEST_NOTHROW(valD = as<std::complex<double> > (minD));
1130 TEST_EQUALITY_CONST(valD, minD);
1131 TEST_NOTHROW(valD = asSafe<std::complex<double> > (minImagD));
1132 TEST_EQUALITY_CONST(valD, minImagD);
1133 TEST_NOTHROW(valD = as<std::complex<double> > (minImagD));
1134 TEST_EQUALITY_CONST(valD, minImagD);
1135 TEST_NOTHROW(valD = asSafe<std::complex<double> > (maxD));
1136 TEST_EQUALITY_CONST(valD, maxD);
1137 TEST_NOTHROW(valD = as<std::complex<double> > (maxD));
1138 TEST_EQUALITY_CONST(valD, maxD);
1139 TEST_NOTHROW(valD = asSafe<std::complex<double> > (maxImagD));
1140 TEST_EQUALITY_CONST(valD, maxImagD);
1141 TEST_NOTHROW(valD = as<std::complex<double> > (maxImagD));
1142 TEST_EQUALITY_CONST(valD, maxImagD);
1143 TEST_NOTHROW(valD = asSafe<std::complex<double> > (minusOneD));
1144 TEST_EQUALITY_CONST(valD, minusOneD);
1145 TEST_NOTHROW(valD = as<std::complex<double> > (minusOneD));
1146 TEST_EQUALITY_CONST(valD, minusOneD);
1147 TEST_NOTHROW(valD = asSafe<std::complex<double> > (minusOneImagD));
1148 TEST_EQUALITY_CONST(valD, minusOneImagD);
1149 TEST_NOTHROW(valD = as<std::complex<double> > (minusOneImagD));
1150 TEST_EQUALITY_CONST(valD, minusOneImagD);
1151
1152 //
1153 // Test std::complex<double> -> std::complex<float> conversions.
1154 //
1155
1156 TEST_NOTHROW(valF = as<std::complex<float> > (minusOneD));
1157 TEST_EQUALITY_CONST(valF, minusOneF);
1158 TEST_NOTHROW(valF = asSafe<std::complex<float> > (minusOneD));
1159 TEST_EQUALITY_CONST(valF, minusOneF);
1160 TEST_NOTHROW(valF = as<std::complex<float> > (minusOneImagD));
1161 TEST_EQUALITY_CONST(valF, minusOneImagF);
1162 TEST_NOTHROW(valF = asSafe<std::complex<float> > (minusOneImagD));
1163 TEST_EQUALITY_CONST(valF, minusOneImagF);
1164
1165}
1166
1167#endif // HAVE_TEUCHOS_COMPLEX
1168
1169} // namespace (anonymous)
1170
1171
1172
#define TEST_EQUALITY_CONST(v1, v2)
Assert the equality of v1 and constant v2.
#define TEST_NOTHROW(code)
Asserr that the statement 'code' does not thrown any excpetions.
#define TEST_THROW(code, ExceptType)
Assert that the statement 'code' throws the exception 'ExceptType' (otherwise the test fails).
Unit testing support.
#define TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL(TEST_GROUP, TEST_NAME, TYPE)
Macro for defining a templated unit test with one template parameter.
#define TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL(TEST_GROUP, TEST_NAME, TYPE1, TYPE2)
Macro for defining a templated unit test with two template parameters.
#define TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT(TEST_GROUP, TEST_NAME, TYPE1, TYPE2)
Instantiate a templated unit test with two template parameters.
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
Definition of Teuchos::as, for conversions between types.
#define TEST_NOTHROW_WITH_MESSAGE(code)
#define UNIT_TEST_GROUP_SIGNED_INTEGER(SignedIntegerType)
#define UNIT_TEST_GROUP_ANY_INTEGER(AnyIntegerType)
Default traits class that just returns typeid(T).name().
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
TypeTo asSafe(const TypeFrom &t)
Convert from one value type to another, with validity checks if appropriate.