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 //
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.
65 namespace {
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 //
72 typedef unsigned short unsigned_short_type;
73 typedef unsigned int unsigned_int_type;
74 typedef unsigned long unsigned_long_type;
75 
76 typedef long long long_long_type;
77 typedef unsigned long long unsigned_long_long_type;
78 
79 
80 template <class T>
81 std::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 //
95 TEUCHOS_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 //
285 TEUCHOS_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 //
513 TEUCHOS_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 //
539 TEUCHOS_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 
635 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, short )
636 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, int )
637 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, long )
638 
639 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, long_long_type )
640 
641 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, unsigned_short_type )
642 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, double, unsigned_int_type )
643 // mfh 16,19 Nov 2012: See note above on formerly disabled tests.
644 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, double, unsigned_long_type )
645 
646 TEUCHOS_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 
653 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, short )
654 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, int )
655 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, long )
656 
657 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, long_long_type )
658 
659 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, unsigned_short_type )
660 // mfh 16,19 Nov 2012: See note above on formerly disabled tests.
661 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, float, unsigned_int_type )
662 // mfh 16,19 Nov 2012: See note above on formerly disabled tests.
663 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, float, unsigned_long_type )
664 
665 TEUCHOS_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().
689 TEUCHOS_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.
720 TEUCHOS_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().
754 TEUCHOS_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 //
796 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, short )
797 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, unsigned_short_type )
798 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, unsigned_short_type )
799 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, short )
800 
801 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, int )
802 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, unsigned_int_type )
803 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, unsigned_int_type )
804 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, int )
805 
806 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, long )
807 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, unsigned_long_type )
808 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, unsigned_long_type )
809 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, long )
810 
811 //
812 // 2. Tests for types of possibly different sizes.
813 //
814 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, int )
815 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, unsigned_int_type )
816 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, long )
817 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, unsigned_long_type )
818 
819 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, unsigned_short_type )
820 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, short )
821 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, long )
822 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, long )
823 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, unsigned_long_type )
824 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, unsigned_long_type )
825 
826 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, unsigned_short_type )
827 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, short )
828 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, int )
829 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, int )
830 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, unsigned_int_type )
831 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, unsigned_int_type )
832 
833 //
834 // 3. "long long", "unsigned long long" tests
835 //
836 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, long_long_type )
837 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, unsigned_long_long_type )
838 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, unsigned_long_long_type )
839 TEUCHOS_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 //
845 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, long_long_type )
846 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, unsigned_long_long_type )
847 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, unsigned_long_long_type )
848 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, long_long_type )
849 
850 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, long )
851 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, unsigned_long_type )
852 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, unsigned_long_type )
853 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, long )
854 
855 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, long_long_type )
856 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, unsigned_long_long_type )
857 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, unsigned_long_long_type )
858 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, long_long_type )
859 
860 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, int )
861 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, unsigned_int_type )
862 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, unsigned_int_type )
863 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, int )
864 
865 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, long_long_type )
866 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, unsigned_long_long_type )
867 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, unsigned_long_long_type )
868 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, long_long_type )
869 
870 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, short )
871 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, unsigned_short_type )
872 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, unsigned_short_type )
873 TEUCHOS_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 
881 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, negativeSignedIntToUnsignedInt, short, unsigned_short_type )
882 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, negativeSignedIntToUnsignedInt, int, unsigned_int_type )
883 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, negativeSignedIntToUnsignedInt, long, unsigned_long_type )
884 
885 TEUCHOS_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 
893 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, short, short )
894 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, short, int )
895 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, short, long )
896 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, int, short )
897 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, int, int )
898 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, int, long )
899 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long, short )
900 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long, int )
901 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long, long )
902 
903 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, short, long_long_type )
904 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, int, long_long_type )
905 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long, long_long_type )
906 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long_long_type, short )
907 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long_long_type, int )
908 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long_long_type, long )
909 TEUCHOS_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.
917 TEUCHOS_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.
953 TEUCHOS_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).
989 TEUCHOS_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).
1001 TEUCHOS_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).
1013 TEUCHOS_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 )
1047 UNIT_TEST_GROUP_ANY_INTEGER( unsigned_short_type )
1048 //UNIT_TEST_GROUP_ANY_INTEGER( unsigned int )
1049 UNIT_TEST_GROUP_ANY_INTEGER( unsigned_int_type )
1050 //UNIT_TEST_GROUP_ANY_INTEGER( unsigned long )
1051 UNIT_TEST_GROUP_ANY_INTEGER( unsigned_long_type )
1052 
1053 //UNIT_TEST_GROUP_ANY_INTEGER( long long )
1054 UNIT_TEST_GROUP_ANY_INTEGER( long_long_type )
1055 //UNIT_TEST_GROUP_SIGNED_INTEGER( long long )
1056 UNIT_TEST_GROUP_SIGNED_INTEGER( long_long_type )
1057 //UNIT_TEST_GROUP_ANY_INTEGER( unsigned long long )
1058 UNIT_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 //
1068 TEUCHOS_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 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)