Teuchos Package Browser (Single Doxygen Collection) Version of the Day
TypeConversions_UnitTest.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #include "Teuchos_as.hpp"
00043 #include "Teuchos_UnitTestHarness.hpp"
00044 #include <limits>
00045 
00046 // Like TEST_NOTHROW, but showing the exception message if the code does throw.
00047 // The exception must be a subclass of std::exception.
00048 #define TEST_NOTHROW_WITH_MESSAGE( code ) \
00049   try { \
00050     (out) << "Test that code {"#code";} does not throw : "; \
00051     code; \
00052     (out) << "passes\n"; \
00053   } \
00054   catch (std::exception& theException) {      \
00055     (success) = false; \
00056     out << "failed\n"; \
00057     out << "\nException message for unexpected exception:\n\n"; \
00058     { \
00059       Teuchos::OSTab l_tab(out); \
00060       out << theException.what() << "\n\n"; \
00061     } \
00062   }
00063 
00064 // Putting the unit tests in an anonymous namespace avoids name collisions.
00065 namespace {
00066 
00067 //
00068 // Hack to work around Bug 5757 (unit test macros that instantiate
00069 // templated unit tests can't handle spaces in the name of the
00070 // template parameter).
00071 //
00072 typedef unsigned short unsigned_short_type;
00073 typedef unsigned int unsigned_int_type;
00074 typedef unsigned long unsigned_long_type;
00075 
00076 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
00077 typedef long long long_long_type;
00078 typedef unsigned long long unsigned_long_long_type;
00079 #endif // HAVE_TEUCHOS_LONG_LONG_INT
00080 
00081 //
00082 // Tests for conversions between built-in floating-point types.
00083 //
00084 TEUCHOS_UNIT_TEST( asSafe, realToReal ) {
00085   using Teuchos::as;
00086   using Teuchos::asSafe;
00087 
00088   const float minF = -std::numeric_limits<float>::max ();
00089   const float minusOneF = -1;
00090   const float maxF = std::numeric_limits<float>::max ();
00091 
00092   const double minD = -std::numeric_limits<double>::max ();
00093   const double minusOneD = -1;
00094   const double maxD = std::numeric_limits<double>::max ();
00095 
00096   float valF = 0;
00097   double valD = 0;
00098   long double valLD = 0;
00099 
00100   //
00101   // Test float -> float conversions.
00102   //
00103   TEST_NOTHROW(valF = asSafe<float> (minF));
00104   TEST_EQUALITY_CONST(valF, minF);
00105   TEST_NOTHROW(valF = as<float> (minF));
00106   TEST_EQUALITY_CONST(valF, minF);
00107   TEST_NOTHROW(valF = asSafe<float> (maxF));
00108   TEST_EQUALITY_CONST(valF, maxF);
00109   TEST_NOTHROW(valF = as<float> (maxF));
00110   TEST_EQUALITY_CONST(valF, maxF);
00111   TEST_NOTHROW(valF = asSafe<float> (minusOneF));
00112   TEST_EQUALITY_CONST(valF, minusOneF);
00113   TEST_NOTHROW(valF = as<float> (minusOneF));
00114   TEST_EQUALITY_CONST(valF, minusOneF);
00115 
00116   //
00117   // Test double -> double conversions.
00118   //
00119   TEST_NOTHROW(valD = asSafe<double> (minD));
00120   TEST_EQUALITY_CONST(valD, minD);
00121   TEST_NOTHROW(valD = as<double> (minD));
00122   TEST_EQUALITY_CONST(valD, minD);
00123   TEST_NOTHROW(valD = asSafe<double> (maxD));
00124   TEST_EQUALITY_CONST(valD, maxD);
00125   TEST_NOTHROW(valD = as<double> (maxD));
00126   TEST_EQUALITY_CONST(valD, maxD);
00127   TEST_NOTHROW(valD = asSafe<double> (minusOneD));
00128   TEST_EQUALITY_CONST(valD, minusOneD);
00129   TEST_NOTHROW(valD = as<double> (minusOneD));
00130   TEST_EQUALITY_CONST(valD, minusOneD);
00131 
00132   //
00133   // Test double -> float conversions.
00134   //
00135   // mfh 25 Nov 2012: Disabled throwing std::range_error on overflow
00136   // for conversions between build-in floating-point types, in favor
00137   // of IEEE 754 overflow semantics.
00138   // TEST_THROW(valF = asSafe<float> (minD), std::range_error);
00139   // TEST_THROW(valF = asSafe<float> (maxD), std::range_error);
00140 
00141   TEST_NOTHROW(valF = asSafe<float> (minusOneF));
00142   TEST_EQUALITY_CONST(valF, minusOneF);
00143   TEST_NOTHROW(valF = as<float> (minusOneF));
00144   TEST_EQUALITY_CONST(valF, minusOneF);
00145 
00146   TEST_NOTHROW(valF = asSafe<float> (minusOneD));
00147   TEST_EQUALITY_CONST(valF, minusOneD);
00148   TEST_NOTHROW(valF = as<float> (minusOneD));
00149   TEST_EQUALITY_CONST(valF, minusOneD);
00150 
00151   //
00152   // Test float -> double conversions.
00153   //
00154   TEST_NOTHROW(valD = asSafe<double> (minF));
00155   TEST_EQUALITY_CONST(valD, minF);
00156   TEST_NOTHROW(valD = as<double> (minF));
00157   TEST_EQUALITY_CONST(valD, minF);
00158 
00159   TEST_NOTHROW(valD = asSafe<double> (maxF));
00160   TEST_EQUALITY_CONST(valD, maxF);
00161   TEST_NOTHROW(valD = as<double> (maxF));
00162   TEST_EQUALITY_CONST(valD, maxF);
00163 
00164   TEST_NOTHROW(valD = asSafe<double> (minusOneF));
00165   TEST_EQUALITY_CONST(valD, minusOneF);
00166   TEST_NOTHROW(valD = as<double> (minusOneF));
00167   TEST_EQUALITY_CONST(valD, minusOneF);
00168 
00169   // mfh 25 Nov 2012: C89 does not mandate that "long double"
00170   // implement the extended-precision 80-bit format of IEEE 754.  In
00171   // fact, Microsoft Visual Studio implements long double just as
00172   // double.  (This goes all the way back to Bill Gates' initial
00173   // discussions with the Intel x87 architects.)  Relaxing the sizeof
00174   // (long double) > sizeof (double) requirement will prevent test
00175   // failures such as the following (on Windows):
00176   //
00177   // http://testing.sandia.gov/cdash/testDetails.php?test=10628321&build=801972
00178 
00179   // // Make sure that long double is as long as the standard requires.
00180   // TEUCHOS_TEST_FOR_EXCEPTION(
00181   //   sizeof (long double) <= sizeof (double),
00182   //   std::logic_error,
00183   //   "Your system does not have an IEEE 754 - compliant implementation of long double.  "
00184   //   "The IEEE 754 standard requires that long double be longer than double.  "
00185   //   "In fact, it must use at least 80 bits. "
00186   //   "However, sizeof (long double) = " << sizeof (long double)
00187   //   << " < sizeof (double) = " << sizeof (double) << ".");
00188 
00189   const long double minLD = -std::numeric_limits<long double>::max ();
00190   const long double minusOneLD = -1;
00191   const long double maxLD = std::numeric_limits<long double>::max ();
00192 
00193   //
00194   // Test long double -> long double conversions.
00195   //
00196   TEST_NOTHROW(valLD = asSafe<long double> (minLD));
00197   TEST_EQUALITY_CONST(valLD, minLD);
00198   TEST_NOTHROW(valLD = as<long double> (minLD));
00199   TEST_EQUALITY_CONST(valLD, minLD);
00200   TEST_NOTHROW(valLD = asSafe<long double> (maxLD));
00201   TEST_EQUALITY_CONST(valLD, maxLD);
00202   TEST_NOTHROW(valLD = as<long double> (maxLD));
00203   TEST_EQUALITY_CONST(valLD, maxLD);
00204   TEST_NOTHROW(valLD = asSafe<long double> (minusOneLD));
00205   TEST_EQUALITY_CONST(valLD, minusOneLD);
00206   TEST_NOTHROW(valLD = as<long double> (minusOneLD));
00207   TEST_EQUALITY_CONST(valLD, minusOneLD);
00208 
00209   //
00210   // Test long double -> float conversions.
00211   //
00212   // mfh 25 Nov 2012: Disabled throwing std::range_error on overflow
00213   // for conversions between build-in floating-point types, in favor
00214   // of IEEE 754 overflow semantics.
00215   // TEST_THROW(valF = asSafe<float> (minLD), std::range_error);
00216   // TEST_THROW(valF = asSafe<float> (maxLD), std::range_error);
00217   TEST_NOTHROW(valF = asSafe<float> (minusOneLD));
00218   TEST_EQUALITY_CONST(valF, minusOneLD);
00219   TEST_NOTHROW(valF = as<float> (minusOneLD));
00220   TEST_EQUALITY_CONST(valF, minusOneLD);
00221 
00222   //
00223   // Test long double -> double conversions.
00224   //
00225   // mfh 25 Nov 2012: See above note on how long double is the same as
00226   // double on some systems.
00227   //
00228   // TEST_THROW(valD = asSafe<double> (minLD), std::range_error);
00229   // TEST_THROW(valD = asSafe<double> (maxLD), std::range_error);
00230   TEST_NOTHROW(valD = as<float> (minusOneLD));
00231   TEST_EQUALITY_CONST(valD, minusOneLD);
00232 
00233   //
00234   // Test float -> long double conversions.
00235   //
00236   TEST_NOTHROW(valLD = asSafe<long double> (minF));
00237   TEST_EQUALITY_CONST(valLD, minF);
00238   TEST_NOTHROW(valLD = as<long double> (minF));
00239   TEST_EQUALITY_CONST(valLD, minF);
00240 
00241   TEST_NOTHROW(valLD = asSafe<long double> (maxF));
00242   TEST_EQUALITY_CONST(valLD, maxF);
00243   TEST_NOTHROW(valLD = as<long double> (maxF));
00244   TEST_EQUALITY_CONST(valLD, maxF);
00245 
00246   TEST_NOTHROW(valLD = asSafe<long double> (minusOneF));
00247   TEST_EQUALITY_CONST(valLD, minusOneF);
00248   TEST_NOTHROW(valLD = as<long double> (minusOneF));
00249   TEST_EQUALITY_CONST(valLD, minusOneF);
00250 
00251   //
00252   // Test double -> long double conversions.
00253   //
00254   TEST_NOTHROW(valLD = asSafe<long double> (minD));
00255   TEST_EQUALITY_CONST(valLD, minD);
00256   TEST_NOTHROW(valLD = as<long double> (minD));
00257   TEST_EQUALITY_CONST(valLD, minD);
00258 
00259   TEST_NOTHROW(valLD = asSafe<long double> (maxD));
00260   TEST_EQUALITY_CONST(valLD, maxD);
00261   TEST_NOTHROW(valLD = as<long double> (maxD));
00262   TEST_EQUALITY_CONST(valLD, maxD);
00263 
00264   TEST_NOTHROW(valLD = asSafe<long double> (minusOneD));
00265   TEST_EQUALITY_CONST(valLD, minusOneD);
00266   TEST_NOTHROW(valLD = as<long double> (minusOneD));
00267   TEST_EQUALITY_CONST(valLD, minusOneD);
00268 }
00269 
00270 
00271 //
00272 // Tests for conversions from std::string to built-in floating-point types.
00273 //
00274 TEUCHOS_UNIT_TEST( asSafe, stringToReal ) {
00275   using Teuchos::as;
00276   using Teuchos::asSafe;
00277 
00278   const float minF = -std::numeric_limits<float>::max ();
00279   const float minusOneF = -1;
00280   const float maxF = std::numeric_limits<float>::max ();
00281 
00282   const double minD = -std::numeric_limits<double>::max ();
00283   const double minusOneD = -1;
00284   const double maxD = std::numeric_limits<double>::max ();
00285 
00286   // mfh 26 Nov 2012: C89 does not mandate that "long double"
00287   // implement the extended-precision 80-bit format of IEEE 754.  In
00288   // fact, Microsoft Visual Studio implements long double just as
00289   // double.  (This goes all the way back to Bill Gates' initial
00290   // discussions with the Intel x87 architects.)  Relaxing the sizeof
00291   // (long double) > sizeof (double) requirement will prevent test
00292   // failures such as the following (on Windows):
00293   //
00294   // http://testing.sandia.gov/cdash/testDetails.php?test=10628321&build=801972
00295   // http://testing.sandia.gov/cdash/testDetails.php?test=10739503&build=810247
00296 
00297   // // Make sure that long double is as long as the standard requires.
00298   // TEUCHOS_TEST_FOR_EXCEPTION(
00299   //   sizeof (long double) <= sizeof (double),
00300   //   std::logic_error,
00301   //   "Your system does not have an IEEE 754 - compliant implementation of long double.  "
00302   //   "The IEEE 754 standard requires that long double be longer than double.  "
00303   //   "In fact, it must use at least 80 bits. "
00304   //   "However, sizeof (long double) = " << sizeof (long double)
00305   //   << " < sizeof (double) = " << sizeof (double) << ".");
00306 
00307   const long double minLD = -std::numeric_limits<long double>::max ();
00308   const long double minusOneLD = -1;
00309   const long double maxLD = std::numeric_limits<long double>::max ();
00310 
00311   float valF = 0;
00312   double valD = 0;
00313   long double valLD = 0;
00314 
00315   //
00316   // Test string -> float conversions.
00317   //
00318   {
00319     std::ostringstream os;
00320     // mfh 27 Nov 2012: Write all 17 digits that the double deserves.
00321     // If you just write 9, it might round (as it does on some
00322     // platforms) to a value that can't be represented in float.
00323     // os.precision (9);
00324     os.precision (17);
00325     os << minF;
00326     TEST_NOTHROW_WITH_MESSAGE(valF = asSafe<float> (os.str ()));
00327     TEST_EQUALITY_CONST(valF, minF);
00328     TEST_NOTHROW_WITH_MESSAGE(valF = as<float> (os.str ()));
00329     TEST_EQUALITY_CONST(valF, minF);
00330   }
00331   {
00332     std::ostringstream os;
00333     os.precision (17);
00334     os << maxF;
00335     TEST_NOTHROW_WITH_MESSAGE(valF = asSafe<float> (os.str ()));
00336     TEST_EQUALITY_CONST(valF, maxF);
00337     TEST_NOTHROW_WITH_MESSAGE(valF = as<float> (os.str ()));
00338     TEST_EQUALITY_CONST(valF, maxF);
00339   }
00340   {
00341     std::ostringstream os;
00342     os.precision (17);
00343     os << minusOneF;
00344     TEST_NOTHROW_WITH_MESSAGE(valF = asSafe<float> (os.str ()));
00345     TEST_EQUALITY_CONST(valF, minusOneF);
00346     TEST_NOTHROW_WITH_MESSAGE(valF = as<float> (os.str ()));
00347     TEST_EQUALITY_CONST(valF, minusOneF);
00348   }
00349   // Write -1 as double, read as float; shouldn't throw.
00350   {
00351     std::ostringstream os;
00352     os.precision (17);
00353     os << minusOneD;
00354     TEST_NOTHROW_WITH_MESSAGE(valF = asSafe<float> (os.str ()));
00355     TEST_EQUALITY_CONST(valF, minusOneF);
00356     TEST_NOTHROW_WITH_MESSAGE(valF = as<float> (os.str ()));
00357     TEST_EQUALITY_CONST(valF, minusOneF);
00358   }
00359 
00360   //
00361   // Test string -> float conversions that should throw.
00362   //
00363   {
00364     std::ostringstream os;
00365     os.precision (9);
00366     os << minD;
00367     TEST_THROW(valF = asSafe<float> (os.str ()), std::range_error);
00368   }
00369   {
00370     std::ostringstream os;
00371     os.precision (9);
00372     os << maxD;
00373     TEST_THROW(valF = asSafe<float> (os.str ()), std::range_error);
00374   }
00375 
00376   //
00377   // Test string -> double conversions.
00378   //
00379   {
00380     std::ostringstream os;
00381     os.precision (17);
00382     os << minD;
00383     TEST_NOTHROW(valD = asSafe<double> (os.str ()));
00384     TEST_EQUALITY_CONST(valD, minD);
00385     TEST_NOTHROW(valD = as<double> (os.str ()));
00386     TEST_EQUALITY_CONST(valD, minD);
00387   }
00388   {
00389     std::ostringstream os;
00390     os.precision (17);
00391     os << maxD;
00392     TEST_NOTHROW(valD = asSafe<double> (os.str ()));
00393     TEST_EQUALITY_CONST(valD, maxD);
00394     TEST_NOTHROW(valD = as<double> (os.str ()));
00395     TEST_EQUALITY_CONST(valD, maxD);
00396   }
00397   {
00398     std::ostringstream os;
00399     os.precision (17);
00400     os << minusOneD;
00401     TEST_NOTHROW(valD = asSafe<double> (os.str ()));
00402     TEST_EQUALITY_CONST(valD, minusOneD);
00403     TEST_NOTHROW(valD = as<double> (os.str ()));
00404     TEST_EQUALITY_CONST(valD, minusOneD);
00405   }
00406 
00407   //
00408   // Test string -> double conversions that should throw,
00409   // if sizeof(long double) > sizeof(double).
00410   //
00411   if (sizeof (long double) > sizeof (double)) {
00412     {
00413       std::ostringstream os;
00414       os.precision (36);
00415       os << minLD;
00416       TEST_THROW(valD = asSafe<double> (os.str ()), std::range_error);
00417     }
00418     {
00419       std::ostringstream os;
00420       os.precision (36);
00421       os << maxLD;
00422       TEST_THROW(valD = asSafe<double> (os.str ()), std::range_error);
00423     }
00424   }
00425 
00426   //
00427   // Test string -> long double conversions.
00428   //
00429   {
00430     std::ostringstream os;
00431     os.precision (36);
00432     os << minLD;
00433     TEST_NOTHROW(valLD = asSafe<long double> (os.str ()));
00434     TEST_EQUALITY_CONST(valLD, minLD);
00435     TEST_NOTHROW(valLD = as<long double> (os.str ()));
00436     TEST_EQUALITY_CONST(valLD, minLD);
00437   }
00438   {
00439     std::ostringstream os;
00440     os.precision (36);
00441     os << maxLD;
00442     TEST_NOTHROW(valLD = asSafe<long double> (os.str ()));
00443     TEST_EQUALITY_CONST(valLD, maxLD);
00444     TEST_NOTHROW(valLD = as<long double> (os.str ()));
00445     TEST_EQUALITY_CONST(valLD, maxLD);
00446   }
00447   {
00448     std::ostringstream os;
00449     os.precision (36);
00450     os << minusOneLD;
00451     TEST_NOTHROW(valLD = asSafe<long double> (os.str ()));
00452     TEST_EQUALITY_CONST(valLD, minusOneLD);
00453     TEST_NOTHROW(valLD = as<long double> (os.str ()));
00454     TEST_EQUALITY_CONST(valLD, minusOneLD);
00455   }
00456 }
00457 
00458 
00459 //
00460 // Templated test for overflow for conversion from a built-in
00461 // real-valued (not complex) floating-point type (float or double) to
00462 // a built-in signed integer type, if that should actually overflow
00463 // (depends on sizeof(SignedIntType)).
00464 //
00465 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( asSafe, realToSignedIntTypeOverflow, RealType, SignedIntType )
00466 {
00467   using Teuchos::asSafe;
00468 
00469   // std::numeric_limits<RealType>::min() gives the minimum _positive_
00470   // normalized value of type RealType.  IEEE 754 floating-point
00471   // values can change sign just by flipping the sign bit, so the
00472   // "most negative" finite RealType is just the negative of the "most
00473   // positive" finite RealType.
00474   const RealType minVal = -std::numeric_limits<RealType>::max ();
00475   const RealType maxVal = std::numeric_limits<RealType>::max ();
00476 
00477   SignedIntType val = 0;
00478   if (sizeof (SignedIntType) < sizeof (RealType)) {
00479     TEST_THROW(val = asSafe<SignedIntType> (minVal), std::range_error);
00480     TEST_THROW(val = asSafe<SignedIntType> (maxVal), std::range_error);
00481   }
00482   (void) val; // Silence compiler errors.
00483 }
00484 
00485 //
00486 // Templated test for overflow for conversion from a built-in
00487 // real-valued (not complex) floating-point type (float or double) to
00488 // a built-in unsigned integer type, if that should actually overflow
00489 // (depends on sizeof(UnsignedIntType)).
00490 //
00491 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( asSafe, realToUnsignedIntTypeOverflow, RealType, UnsignedIntType )
00492 {
00493   using Teuchos::asSafe;
00494   using Teuchos::TypeNameTraits;
00495 
00496   // std::numeric_limits<RealType>::min() gives the minimum _positive_
00497   // normalized value of type RealType.  IEEE 754 floating-point
00498   // values can change sign just by flipping the sign bit, so the
00499   // "most negative" finite RealType is just the negative of the "most
00500   // positive" finite RealType.
00501   const RealType minVal = -std::numeric_limits<RealType>::max ();
00502   const RealType maxVal = std::numeric_limits<RealType>::max ();
00503   const UnsignedIntType maxUnsignedIntVal =
00504     std::numeric_limits<UnsignedIntType>::max ();
00505 
00506   // mfh 15 Nov 2012: Set val to a marker value, so we can see if the
00507   // body of TEST_NOTHROW below actually did the assignment.
00508   UnsignedIntType val = 42;
00509   // Make sure that val starts off with a different value than what
00510   // its final value should be.
00511   TEUCHOS_TEST_FOR_EXCEPTION(
00512     val == static_cast<UnsignedIntType> (maxVal),
00513     std::logic_error,
00514     "Dear test author, please pick a different marker value.  "
00515     "Please report this bug to the Teuchos developers.");
00516 
00517   // Conversion from any negative value should throw.
00518   TEST_THROW(val = asSafe<UnsignedIntType> (minVal), std::range_error);
00519   const RealType minusOne = -1;
00520   TEST_THROW(val = asSafe<UnsignedIntType> (minusOne), std::range_error);
00521 
00522   // Only test overflow checks if overflow can actually take place.
00523   if (maxUnsignedIntVal < maxVal) {
00524     TEST_THROW(val = asSafe<UnsignedIntType> (maxVal), std::range_error);
00525     try {
00526       std::cerr << std::endl 
00527     << "*** RealType = " << TypeNameTraits<RealType>::name ()
00528     << ", UnsignedIntType = " << TypeNameTraits<UnsignedIntType>::name ()
00529     << ", maxVal = " << maxVal
00530                 << ", maxUnsignedIntVal = " << maxUnsignedIntVal
00531     << ", asSafe (maxVal) = " << asSafe<UnsignedIntType> (maxVal) 
00532     << std::endl;
00533     } catch (...) {
00534       std::cerr << "(asSafe threw an exception)" << std::endl;
00535     }
00536   }
00537   else { // Only conversions from negative values should throw.
00538     TEST_NOTHROW(val = asSafe<UnsignedIntType> (maxVal));
00539     TEST_EQUALITY_CONST(val, static_cast<UnsignedIntType> (maxVal));
00540 
00541 #if 0
00542     TEUCHOS_TEST_FOR_EXCEPTION(
00543       val == 42,
00544       std::logic_error,
00545       "Hey, how come val == 42?  It should be something completely different.  "
00546       << std::endl
00547       << "FYI, static_cast<" << TypeNameTraits<UnsignedIntType>::name ()
00548       << "> (minVal) = " << static_cast<UnsignedIntType> (minVal)
00549       << " and "
00550       << std::endl
00551       << "static_cast<" << TypeNameTraits<UnsignedIntType>::name ()
00552       << "> (maxVal) = " << static_cast<UnsignedIntType> (maxVal)
00553       << ".  val should be equal to the latter."
00554       << std::endl
00555       << "As float: minVal = " << minVal << ", maxVal = " << maxVal << ".");
00556 #endif // 0
00557   }
00558 
00559   (void) val; // Silence compiler errors.
00560 }
00561 
00562 //
00563 // Instantiations of templated tests for conversions from double to
00564 // various built-in integer types.
00565 //
00566 
00567 // mfh 19 Nov 2012: The tests that I disabled below in commit
00568 // f99c0e446f5c8dc385d00b60878314d40a7b9fe2 appear to be working now.
00569 // I am reenabling them tentatively.
00570 //
00571 // mfh 16 Nov 2012: The (asSafe, realToUnsignedIntTypeOverflow) test
00572 // keeps failing for template parameter combinations (double,
00573 // unsigned_long_type), (float, unsigned_int_type), and (float,
00574 // unsigned_long_type).  It only fails on some platforms, not all, and
00575 // I can't figure out why.  I'm disabling these tests for now until I
00576 // get more time to deal with this.  For examples of test output, see:
00577 //
00578 // http://testing.sandia.gov/cdash/testDetails.php?test=10519753&build=793648
00579 // http://testing.sandia.gov/cdash/testDetails.php?test=10519852&build=793655
00580 // http://testing.sandia.gov/cdash/testDetails.php?test=10520495&build=793698
00581 // http://testing.sandia.gov/cdash/testDetails.php?test=10523690&build=793963
00582 // http://testing.sandia.gov/cdash/testDetails.php?test=10523763&build=793962
00583 // http://testing.sandia.gov/cdash/testDetails.php?test=10530499&build=794533
00584 // http://testing.sandia.gov/cdash/testDetails.php?test=10530585&build=794532
00585 // http://testing.sandia.gov/cdash/testDetails.php?test=10535648&build=794860
00586 
00587 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, short )
00588 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, int )
00589 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, long )
00590 
00591 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
00592 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, long_long_type )
00593 #endif // HAVE_TEUCHOS_LONG_LONG_INT
00594 
00595 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, double, unsigned_short_type )
00596 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, double, unsigned_int_type )
00597 // mfh 16,19 Nov 2012: See note above on formerly disabled tests.
00598 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, double, unsigned_long_type )
00599 
00600 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
00601 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, double, unsigned_long_long_type )
00602 #endif // HAVE_TEUCHOS_LONG_LONG_INT
00603 
00604 //
00605 // Instantiations of templated tests for conversions from float to
00606 // various built-in integer types.
00607 //
00608 
00609 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, short )
00610 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, int )
00611 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, long )
00612 
00613 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
00614 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, long_long_type )
00615 #endif // HAVE_TEUCHOS_LONG_LONG_INT
00616 
00617 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToSignedIntTypeOverflow, float, unsigned_short_type )
00618 // mfh 16,19 Nov 2012: See note above on formerly disabled tests.
00619 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, float, unsigned_int_type )
00620 // mfh 16,19 Nov 2012: See note above on formerly disabled tests.
00621 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, float, unsigned_long_type )
00622 
00623 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
00624 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, realToUnsignedIntTypeOverflow, float, unsigned_long_long_type )
00625 #endif // HAVE_TEUCHOS_LONG_LONG_INT
00626 
00627 
00628 //
00629 // Templated test for conversions between possibly different built-in
00630 // integer types.  The C++ standard guarantees the following:
00631 // - <tt>sizeof (char) == 1</tt>
00632 // - <tt>sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long)</tt>
00633 //
00634 // C99 actually guarantees minimum sizes of the various types, and
00635 // that <tt>sizeof (long) <= sizeof (long long)</tt>.
00636 //
00637 // This means that any value that fits in a <tt>signed char</tt> must
00638 // also fit in any other built-in integer type.  (The standard does
00639 // not promise whether <tt>char</tt> is signed or unsigned.)  We've
00640 // chosen test values accordingly.
00641 //
00642 // We test both as() and asSafe to ensure correct behavior of both.
00643 //
00644 
00645 // Test for conversion between two built-in integer types FirstIntType
00646 // and SecondIntType.  The test uses a positive number that must fit
00647 // in both and must not overflow.  The test covers both as() and
00648 // asSafe().
00649 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( as, positiveFirstIntToSecondInt, FirstIntType, SecondIntType )
00650 {
00651   using Teuchos::as;
00652   using Teuchos::asSafe;
00653 
00654   std::ostringstream os;
00655   const FirstIntType origVal = 42;
00656   const SecondIntType origValSecond = 42;
00657 
00658   SecondIntType asVal = 0, asSafeVal = 0;
00659   TEST_NOTHROW(asVal = as<SecondIntType> (origVal));
00660   TEST_NOTHROW(asSafeVal = asSafe<SecondIntType> (origVal));
00661 
00662   TEST_EQUALITY_CONST(asVal, static_cast<SecondIntType> (origValSecond));
00663   TEST_EQUALITY_CONST(asSafeVal, static_cast<SecondIntType> (origValSecond));
00664   TEST_EQUALITY_CONST(asVal, asSafeVal);
00665 
00666   FirstIntType backVal = 0, backSafeVal = 0;
00667   TEST_NOTHROW(backVal = as<FirstIntType> (asVal));
00668   TEST_NOTHROW(backSafeVal = asSafe<FirstIntType> (asSafeVal));
00669 
00670   TEST_EQUALITY_CONST(backVal, origVal);
00671   TEST_EQUALITY_CONST(backSafeVal, origVal);
00672   TEST_EQUALITY_CONST(backVal, backSafeVal);
00673 }
00674 
00675 // Test for conversion between two built-in integer types
00676 // SignedIntType and UnsignedIntType.  The two types must have the
00677 // same number of bits.  The test starts with a negative number that
00678 // should trigger asSafe() to throw std::range_error.  as() will only
00679 // throw std::range_error in a debug build, so we don't test it here.
00680 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( asSafe, negativeSignedIntToUnsignedInt, SignedIntType, UnsignedIntType )
00681 {
00682   using Teuchos::asSafe;
00683 
00684   // Ensure that the two types have the same number of bits.
00685   TEUCHOS_TEST_FOR_EXCEPTION(
00686     sizeof (SignedIntType) != sizeof (UnsignedIntType),
00687     std::logic_error,
00688     "Unit test Teuchos,asSafe,negativeSignedIntToUnsignedInt requires that the "
00689     "two template parameters SignedIntType and UnsignedIntType have the same "
00690     "number of bits.");
00691 
00692   std::ostringstream os;
00693   const SignedIntType origVal = -1;
00694 
00695   UnsignedIntType asSafeVal = 0;
00696   // Casts from negative signed values to unsigned values should
00697   // throw, because they are not within range [0, maxUnsignedVal] of
00698   // the target type.
00699   TEST_THROW(asSafeVal = asSafe<UnsignedIntType> (origVal), std::range_error);
00700   (void) asSafeVal; // Silence compiler warning.
00701 
00702   // Casts from large unsigned values to negative signed values should
00703   // throw, because they change positivity of the result.
00704   UnsignedIntType negVal = static_cast<UnsignedIntType> (origVal);
00705   SignedIntType backSafeVal = 0;
00706   TEST_THROW(backSafeVal = asSafe<SignedIntType> (negVal), std::range_error);
00707   (void) backSafeVal; // Silence compiler warning.
00708 }
00709 
00710 // Test for conversion between two built-in signed integer types
00711 // FirstSignedIntType and SecondSignedIntType.  The test uses a
00712 // negative number that should not overflow in either case.  It tests
00713 // both as() and asSafe().
00714 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( as, negativeSignedIntToSignedInt, FirstSignedIntType, SecondSignedIntType )
00715 {
00716   using Teuchos::as;
00717   using Teuchos::asSafe;
00718 
00719   std::ostringstream os;
00720   const FirstSignedIntType origVal = -42;
00721 
00722   // Ensure that the two types are both signed.
00723   TEUCHOS_TEST_FOR_EXCEPTION(
00724     ! std::numeric_limits<FirstSignedIntType>::is_signed ||
00725     ! std::numeric_limits<SecondSignedIntType>::is_signed,
00726     std::logic_error,
00727     "Unit test Teuchos,as,negativeSignedIntToSignedInt requires that the "
00728     "two template parameters FirstSignedIntType and SecondSignedIntType "
00729     "both be signed built-in integer types.");
00730 
00731   // Test cast from FirstSignedIntType to SecondSignedIntType.
00732   // The casts should not throw in either a debug or a release build.
00733   SecondSignedIntType asVal = 0, asSafeVal = 0;
00734   TEST_NOTHROW(asVal = as<SecondSignedIntType> (origVal));
00735   TEST_NOTHROW(asSafeVal = asSafe<SecondSignedIntType> (origVal));
00736   TEST_EQUALITY_CONST(asVal, static_cast<SecondSignedIntType> (origVal));
00737   TEST_EQUALITY_CONST(asSafeVal, static_cast<SecondSignedIntType> (origVal));
00738   TEST_EQUALITY_CONST(asVal, asSafeVal);
00739 
00740   FirstSignedIntType backVal = 0, backSafeVal = 0;
00741   TEST_NOTHROW(backVal = as<FirstSignedIntType> (origVal));
00742   TEST_NOTHROW(backSafeVal = asSafe<FirstSignedIntType> (origVal));
00743   TEST_EQUALITY_CONST(backVal, origVal);
00744   TEST_EQUALITY_CONST(backSafeVal, origVal);
00745   TEST_EQUALITY_CONST(backVal, backSafeVal);
00746 }
00747 
00748 //
00749 // Instantiations of templated tests for conversions between two
00750 // possibly different built-in integer types.
00751 //
00752 
00753 //
00754 // 1. Tests for types of the same size.
00755 //
00756 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, short )
00757 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, unsigned_short_type )
00758 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, unsigned_short_type )
00759 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, short )
00760 
00761 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, int )
00762 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, unsigned_int_type )
00763 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, unsigned_int_type )
00764 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, int )
00765 
00766 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, long )
00767 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, unsigned_long_type )
00768 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, unsigned_long_type )
00769 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, long )
00770 
00771 //
00772 // 2. Tests for types of possibly different sizes.
00773 //
00774 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, int )
00775 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, unsigned_int_type )
00776 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, long )
00777 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, unsigned_long_type )
00778 
00779 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, unsigned_short_type )
00780 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, short )
00781 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, long )
00782 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, long )
00783 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, unsigned_long_type )
00784 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, unsigned_long_type )
00785 
00786 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, unsigned_short_type )
00787 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, short )
00788 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, int )
00789 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, int )
00790 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, unsigned_int_type )
00791 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, unsigned_int_type )
00792 
00793 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
00794 //
00795 // 3. "long long", "unsigned long long" tests
00796 //
00797 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, long_long_type )
00798 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, unsigned_long_long_type )
00799 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, unsigned_long_long_type )
00800 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, long_long_type )
00801 
00802 //
00803 // 4. Tests between "long long" or "unsigned long long", and some
00804 //    other built-in integer type.
00805 //
00806 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, long_long_type )
00807 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, unsigned_long_long_type )
00808 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long, unsigned_long_long_type )
00809 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_type, long_long_type )
00810 
00811 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, long )
00812 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, unsigned_long_type )
00813 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, unsigned_long_type )
00814 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, long )
00815 
00816 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, long_long_type )
00817 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, unsigned_long_long_type )
00818 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, int, unsigned_long_long_type )
00819 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_int_type, long_long_type )
00820 
00821 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, int )
00822 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, unsigned_int_type )
00823 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, unsigned_int_type )
00824 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, int )
00825 
00826 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, long_long_type )
00827 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, unsigned_long_long_type )
00828 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, short, unsigned_long_long_type )
00829 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_short_type, long_long_type )
00830 
00831 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, short )
00832 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, unsigned_short_type )
00833 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, long_long_type, unsigned_short_type )
00834 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, positiveFirstIntToSecondInt, unsigned_long_long_type, short )
00835 #endif // HAVE_TEUCHOS_LONG_LONG_INT
00836 
00837 //
00838 // Instantiations of templated tests for conversions from signed to
00839 // unsigned built-in integer types.  The two types must have the same
00840 // number of bits.
00841 //
00842 
00843 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, negativeSignedIntToUnsignedInt, short, unsigned_short_type )
00844 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, negativeSignedIntToUnsignedInt, int, unsigned_int_type )
00845 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, negativeSignedIntToUnsignedInt, long, unsigned_long_type )
00846 
00847 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
00848 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( asSafe, negativeSignedIntToUnsignedInt, long_long_type, unsigned_long_long_type )
00849 #endif // HAVE_TEUCHOS_LONG_LONG_INT
00850 
00851 //
00852 // Instantiations of templated tests for conversions between two
00853 // possibly different signed integer types, for a negative value that
00854 // should not overflow.
00855 //
00856 
00857 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, short, short )
00858 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, short, int )
00859 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, short, long )
00860 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, int, short )
00861 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, int, int )
00862 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, int, long )
00863 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long, short )
00864 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long, int )
00865 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long, long )
00866 
00867 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
00868 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, short, long_long_type )
00869 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, int, long_long_type )
00870 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long, long_long_type )
00871 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long_long_type, short )
00872 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long_long_type, int )
00873 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long_long_type, long )
00874 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( as, negativeSignedIntToSignedInt, long_long_type, long_long_type )
00875 #endif // HAVE_TEUCHOS_LONG_LONG_INT
00876 
00877 //
00878 // Tests for conversions from std::string to built-in integer types.
00879 //
00880 
00881 // Test for overflow when converting an std::string (containing a
00882 // positive integer too large to fit in int) to int.
00883 TEUCHOS_UNIT_TEST( asSafe, stringToIntPositiveOverflow ) {
00884   using Teuchos::asSafe;
00885 
00886   std::ostringstream os;
00887   const int maxInt = std::numeric_limits<int>::max ();
00888 
00889   // Write a long int to the given string that is guaranteed to
00890   // overflow int, if long is strictly bigger than int.
00891   if (sizeof (int) < sizeof (long)) {
00892     const long maxIntPlusOne = static_cast<long> (maxInt) + static_cast<long> (1);
00893     os << maxIntPlusOne;
00894 
00895     // Now attempt to convert the string to int.  The conversion
00896     // should fail, but leave the string unaffected.
00897     int intVal = 0;
00898     TEST_THROW(intVal = asSafe<int> (os.str ()), std::range_error);
00899     (void) intVal; // Silence compiler warning.
00900 
00901     // Since the string is unaffected, conversion to long should work
00902     // just fine, and return the correct result.
00903     long longVal = 0;
00904     TEST_NOTHROW(longVal = asSafe<long> (os.str ()));
00905     TEST_EQUALITY_CONST(longVal, maxIntPlusOne);
00906   }
00907   else { // C++ standard requires then that sizeof(int) == sizeof(long).
00908     os << maxInt;
00909     // Converting the string to int should not throw and should return
00910     // the correct result.
00911     int intVal = 0;
00912     TEST_NOTHROW(intVal = asSafe<int> (os.str ()));
00913     TEST_EQUALITY_CONST(intVal, maxInt);
00914   }
00915 }
00916 
00917 // Test for overflow when converting an std::string (containing a
00918 // negative integer too negative to fit in int) to int.
00919 TEUCHOS_UNIT_TEST( asSafe, stringToIntNegativeOverflow ) {
00920   using Teuchos::asSafe;
00921 
00922   std::ostringstream os;
00923   const int minInt = std::numeric_limits<int>::min ();
00924 
00925   // Write a long int to the given string that is guaranteed to
00926   // overflow int, if long is strictly bigger than int.
00927   if (sizeof (int) < sizeof (long)) {
00928     const long minIntMinusOne = static_cast<long> (minInt) - static_cast<long> (1);
00929     os << minIntMinusOne;
00930 
00931     // Now attempt to convert the string to int.  The conversion
00932     // should fail, but leave the string unaffected.
00933     int intVal = 0;
00934     TEST_THROW(intVal = asSafe<int> (os.str ()), std::range_error);
00935     (void) intVal; // Silence compiler warning
00936 
00937     // Since the string is unaffected, conversion to long should work
00938     // just fine, and return the correct result.
00939     long longVal = 0;
00940     TEST_NOTHROW(longVal = asSafe<long> (os.str ()));
00941     TEST_EQUALITY_CONST(longVal, minIntMinusOne);
00942   }
00943   else { // C++ standard requires then that sizeof(int) == sizeof(long).
00944     os << minInt;
00945     // Converting the string to int should not throw and should return
00946     // the correct result.
00947     int intVal = 0;
00948     TEST_NOTHROW(intVal = asSafe<int> (os.str ()));
00949     TEST_EQUALITY_CONST(intVal, minInt);
00950   }
00951 }
00952 
00953 // Unit test for conversion from std::string (containing a positive
00954 // integer) to built-in integer types (may be signed or unsigned).
00955 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( asSafe, stringToIntegerPositive, IntegerType ) {
00956   using Teuchos::asSafe;
00957 
00958   std::ostringstream os;
00959   os << static_cast<IntegerType> (42);
00960   IntegerType val = 0;
00961   TEST_NOTHROW(val = asSafe<IntegerType> (os.str ()));
00962   TEST_EQUALITY_CONST(val, static_cast<IntegerType> (42));
00963 }
00964 
00965 // Unit test for conversion from std::string (containing a negative
00966 // integer) to built-in integer types (must be signed).
00967 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( asSafe, stringToIntegerNegative, IntegerType ) {
00968   using Teuchos::asSafe;
00969 
00970   std::ostringstream os;
00971   os << static_cast<IntegerType> (-42);
00972   IntegerType val = 0;
00973   TEST_NOTHROW(val = asSafe<IntegerType> (os.str ()));
00974   TEST_EQUALITY_CONST(val, static_cast<IntegerType> (-42));
00975 }
00976 
00977 // Unit test for conversion from std::string (NOT containing an
00978 // integer) to built-in integer types (may be signed or unsigned).
00979 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( asSafe, stringToIntegerShouldThrow, IntegerType ) {
00980   using Teuchos::asSafe;
00981 
00982   std::ostringstream os;
00983   os << "This string definitely does not contain an integer.";
00984   IntegerType val = 0;
00985   TEST_THROW(val = asSafe<IntegerType> (os.str ()), std::invalid_argument);
00986   (void) val; // Silence compiler warning
00987 }
00988 
00989 // Macros to instantiate templated unit tests for conversion from
00990 // std::string to built-in integer types.  AnyIntegerType may be
00991 // signed or unsigned; SignedIntegerType must be signed.
00992 
00993 #define UNIT_TEST_GROUP_ANY_INTEGER( AnyIntegerType ) \
00994   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( asSafe, stringToIntegerPositive, AnyIntegerType ) \
00995   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( asSafe, stringToIntegerShouldThrow, AnyIntegerType )
00996 
00997 #define UNIT_TEST_GROUP_SIGNED_INTEGER( SignedIntegerType ) \
00998   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( asSafe, stringToIntegerNegative, SignedIntegerType )
00999 
01000 //
01001 // Instantiations of templated unit tests for conversion from
01002 // std::string to built-in integer types.
01003 //
01004 
01005 UNIT_TEST_GROUP_ANY_INTEGER( short )
01006 UNIT_TEST_GROUP_SIGNED_INTEGER( short )
01007 UNIT_TEST_GROUP_ANY_INTEGER( int )
01008 UNIT_TEST_GROUP_SIGNED_INTEGER( int )
01009 UNIT_TEST_GROUP_ANY_INTEGER( long )
01010 UNIT_TEST_GROUP_SIGNED_INTEGER( long )
01011 
01012 //UNIT_TEST_GROUP_ANY_INTEGER( unsigned short )
01013 UNIT_TEST_GROUP_ANY_INTEGER( unsigned_short_type )
01014 //UNIT_TEST_GROUP_ANY_INTEGER( unsigned int )
01015 UNIT_TEST_GROUP_ANY_INTEGER( unsigned_int_type )
01016 //UNIT_TEST_GROUP_ANY_INTEGER( unsigned long )
01017 UNIT_TEST_GROUP_ANY_INTEGER( unsigned_long_type )
01018 
01019 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
01020 //UNIT_TEST_GROUP_ANY_INTEGER( long long )
01021 UNIT_TEST_GROUP_ANY_INTEGER( long_long_type )
01022 //UNIT_TEST_GROUP_SIGNED_INTEGER( long long )
01023 UNIT_TEST_GROUP_SIGNED_INTEGER( long_long_type )
01024 //UNIT_TEST_GROUP_ANY_INTEGER( unsigned long long )
01025 UNIT_TEST_GROUP_ANY_INTEGER( unsigned_long_long_type )
01026 #endif // HAVE_TEUCHOS_LONG_LONG_INT
01027 
01028 } // namespace (anonymous)
01029 
01030 
01031 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines