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