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