Teuchos - Trilinos Tools Package Version of the Day
Teuchos_as.hpp
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 #ifndef TEUCHOS_AS_HPP
00043 #define TEUCHOS_AS_HPP
00044 
00045 #include "Teuchos_Assert.hpp"
00046 #include <limits>
00047 
00048 #ifdef HAVE_TEUCHOS_QD
00049 #include <qd/qd_real.h>
00050 #include <qd/dd_real.h>
00051 #endif
00052 
00053 namespace Teuchos {
00054 
00055 
00125 template<class TypeTo, class TypeFrom>
00126 class ValueTypeConversionTraits {
00127 public:
00129   static TypeTo convert (const TypeFrom t) {
00130     // This default implementation is just an implicit conversion and
00131     // may generate compiler warnings on dangerous conversions.
00132     return t;
00133   }
00134 
00136   static TypeTo safeConvert (const TypeFrom t) {
00137     // This default implementation is just an implicit conversion and
00138     // may generate compiler warnings on dangerous conversions.  No
00139     // runtime checking (e.g., for overflow) can be done by default;
00140     // only specializations can define meaningful and portable
00141     // run-time checks of conversions.
00142     return t;
00143   }
00144 };
00145 
00212 template<class TypeTo, class TypeFrom>
00213 inline TypeTo as( const TypeFrom& t )
00214 {
00215 #ifdef HAVE_TEUCHOS_DEBUG
00216   return ValueTypeConversionTraits<TypeTo,TypeFrom>::safeConvert(t);
00217 #else
00218   return ValueTypeConversionTraits<TypeTo,TypeFrom>::convert(t);
00219 #endif // HAVE_TEUCHOS_DEBUG
00220 }
00221 
00222 
00270 template<class TypeTo, class TypeFrom>
00271 inline TypeTo asSafe( const TypeFrom& t )
00272 {
00273   return ValueTypeConversionTraits<TypeTo,TypeFrom>::safeConvert(t);
00274 }
00275 
00276 
00288 template <class TypeTo>
00289 class asFunc {
00290   public:
00291   asFunc() {}
00292 
00293   template <class TypeFrom>
00294   inline TypeTo operator()(const TypeFrom &t) {
00295     return as<TypeTo>(t);
00296   }
00297 };
00298 
00299 
00300 //
00301 // Standard specializations of ValueTypeConversionTraits
00302 //
00303 
00305 template<>
00306 class ValueTypeConversionTraits<int, double> {
00307 public:
00313   static int convert (const double t) {
00314     // Implicit conversion from double to int causes compiler
00315     // warnings, but static_cast does not.
00316     return static_cast<int> (t);
00317   }
00318 
00320   static int safeConvert (const double t) {
00321     const int minInt = std::numeric_limits<int>::min ();
00322     const int maxInt = std::numeric_limits<int>::max ();
00323 
00324     TEUCHOS_TEST_FOR_EXCEPTION(
00325       t < static_cast<double> (minInt) || t > static_cast<double> (maxInt),
00326       std::range_error,
00327       "Teuchos::ValueTypeConversionTraits<int, double>::safeConvert: "
00328       "Input double t = " << t << " is out of the valid range [" << minInt
00329       << ", " << maxInt << "] for conversion to int.");
00330     return static_cast<int> (t);
00331   }
00332 };
00333 
00335 template<>
00336 class ValueTypeConversionTraits<int, float> {
00337 public:
00339   static int convert (const float t) {
00340     // Implicit conversion from float to int may cause compiler
00341     // warnings, but static_cast does not.  Note that casting from
00342     // (32-bit) float to (32-bit signed) int can never overflow.
00343     return static_cast<int> (t);
00344   }
00345 
00347   static int safeConvert (const float t) {
00348     // Implicit conversion from float to int may cause compiler
00349     // warnings, but static_cast does not.  Note that casting from
00350     // (32-bit) float to (32-bit signed) int can never overflow.
00351     return static_cast<int> (t);
00352   }
00353 };
00354 
00355 
00356 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
00357 
00359 template<>
00360 class ValueTypeConversionTraits<float, long long> {
00361 public:
00367   static float convert (const long long t) {
00368     // Implicit conversion from long long to float may cause compiler
00369     // warnings, but static_cast does not.
00370     return static_cast<float> (t);
00371   }
00372 
00374   static float safeConvert (const long long t) {
00375     const float minFloat = std::numeric_limits<float>::min ();
00376     const float maxFloat = std::numeric_limits<float>::max ();
00377 
00378     TEUCHOS_TEST_FOR_EXCEPTION(
00379       t < static_cast<long long> (minFloat) ||
00380       t > static_cast<long long> (maxFloat),
00381       std::range_error,
00382       "Teuchos::ValueTypeConversionTraits<float, long long>::safeConvert: "
00383       "Input long long t = " << t << " is out of the valid range [" << minFloat
00384       << ", " << maxFloat << "] for conversion to float.");
00385 
00386     // Implicit conversion from long long to float may cause compiler
00387     // warnings, but static_cast does not.
00388     return static_cast<float> (t);
00389   }
00390 };
00391 
00393 template<>
00394 class ValueTypeConversionTraits<float, unsigned long long> {
00395 public:
00401   static float convert (const unsigned long long t) {
00402     // Implicit conversion from unsigned long long to float may cause
00403     // compiler warnings, but static_cast does not.
00404     return static_cast<float> (t);
00405   }
00406 
00408   static float safeConvert (const unsigned long long t) {
00409     const float minFloat = std::numeric_limits<float>::min ();
00410     const float maxFloat = std::numeric_limits<float>::max ();
00411 
00412     TEUCHOS_TEST_FOR_EXCEPTION(
00413       t < static_cast<unsigned long long> (minFloat) ||
00414       t > static_cast<unsigned long long> (maxFloat),
00415       std::invalid_argument,
00416       "Teuchos::ValueTypeConversionTraits<float, unsigned long long>::safeConvert: "
00417       "Input unsigned long long t = " << t << " is out of the valid range [" << minFloat
00418       << ", " << maxFloat << "] for conversion to float.");
00419 
00420     // Implicit conversion from unsigned long long to float may cause
00421     // compiler warnings, but static_cast does not.
00422     return static_cast<float> (t);
00423   }
00424 };
00425 
00427 template<>
00428 class ValueTypeConversionTraits<int, long long> {
00429 public:
00435   static int convert (const long long t) {
00436     // Implicit conversion from long long to int may cause compiler
00437     // warnings, but static_cast does not.
00438     return static_cast<int> (t);
00439   }
00440 
00442   static int safeConvert (const long long t) {
00443     const int minInt = std::numeric_limits<int>::min ();
00444     const int maxInt = std::numeric_limits<int>::max ();
00445 
00446     TEUCHOS_TEST_FOR_EXCEPTION(
00447       t < static_cast<long long> (minInt) ||
00448       t > static_cast<long long> (maxInt),
00449       std::range_error,
00450       "Teuchos::ValueTypeConversionTraits<int, long long>::safeConvert: "
00451       "Input long long t = " << t << " is out of the valid range [" << minInt
00452       << ", " << maxInt << "] for conversion to int.");
00453 
00454     // Implicit conversion from long long to int may cause compiler
00455     // warnings, but static_cast does not.
00456     return static_cast<int> (t);
00457   }
00458 };
00459 
00460 
00462 template<>
00463 class ValueTypeConversionTraits<unsigned int, long long> {
00464 public:
00470   static unsigned int convert (const long long t) {
00471     // Implicit conversion from long long to unsigned int may cause
00472     // compiler warnings, but static_cast does not.
00473     return static_cast<unsigned int> (t);
00474   }
00475 
00477   static unsigned int safeConvert (const long long t) {
00478     const unsigned int minInt = std::numeric_limits<unsigned int>::min ();
00479     const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
00480 
00481     TEUCHOS_TEST_FOR_EXCEPTION(
00482       t < static_cast<long long> (minInt) ||
00483       t > static_cast<long long> (maxInt),
00484       std::range_error,
00485       "Teuchos::ValueTypeConversionTraits<unsigned int, long long>::safeConvert: "
00486       "Input long long t = " << t << " is out of the valid range [" << minInt
00487       << ", " << maxInt << "] for conversion to unsigned int.");
00488 
00489     // Implicit conversion from long long to unsigned int may cause
00490     // compiler warnings, but static_cast does not.
00491     return static_cast<unsigned int> (t);
00492   }
00493 };
00494 
00496 template<>
00497 class ValueTypeConversionTraits<int, unsigned long long> {
00498 public:
00504   static int convert (const unsigned long long t) {
00505     // Implicit conversion from unsigned long long to int may cause
00506     // compiler warnings, but static_cast does not.
00507     return static_cast<int> (t);
00508   }
00509 
00511   static int safeConvert (const unsigned long long t) {
00512     const int minInt = std::numeric_limits<int>::min ();
00513     const int maxInt = std::numeric_limits<int>::max ();
00514 
00515     TEUCHOS_TEST_FOR_EXCEPTION(
00516       t < static_cast<unsigned long long> (minInt) ||
00517       t > static_cast<unsigned long long> (maxInt),
00518       std::invalid_argument,
00519       "Teuchos::ValueTypeConversionTraits<int, unsigned long long>::safeConvert: "
00520       "Input unsigned long long t = " << t << " is out of the valid range [" << minInt
00521       << ", " << maxInt << "] for conversion to int.");
00522 
00523     // Implicit conversion from unsigned long long to int may cause
00524     // compiler warnings, but static_cast does not.
00525     return static_cast<int> (t);
00526   }
00527 };
00528 
00530 template<>
00531 class ValueTypeConversionTraits<unsigned int, unsigned long long> {
00532 public:
00538   static unsigned int convert (const unsigned long long t) {
00539     // Implicit conversion from unsigned long long to unsigned int may
00540     // cause compiler warnings, but static_cast does not.
00541     return static_cast<unsigned int> (t);
00542   }
00543 
00545   static unsigned int safeConvert (const unsigned long long t) {
00546     const unsigned int minInt = std::numeric_limits<unsigned int>::min ();
00547     const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
00548 
00549     TEUCHOS_TEST_FOR_EXCEPTION(
00550       t < static_cast<unsigned long long> (minInt) ||
00551       t > static_cast<unsigned long long> (maxInt),
00552       std::invalid_argument,
00553       "Teuchos::ValueTypeConversionTraits<unsigned int, unsigned long long>::safeConvert: "
00554       "Input unsigned long long t = " << t << " is out of the valid range [" << minInt
00555       << ", " << maxInt << "] for conversion to unsigned int.");
00556 
00557     // Implicit conversion from unsigned long long to unsigned int may
00558     // cause compiler warnings, but static_cast does not.
00559     return static_cast<unsigned int> (t);
00560   }
00561 };
00562 
00563 #endif // HAVE_TEUCHOS_LONG_LONG_INT
00564 
00565 
00567 template<int N>
00568 class ValueTypeConversionTraits<std::string, char[N]> {
00569 public:
00570   static std::string convert( const char t[] )
00571     { return std::string(t); }
00572   static std::string safeConvert( const char t[] )
00573     { return std::string(t); }
00574 };
00575 
00576 #ifdef HAVE_TEUCHOS_QD
00577 
00579 template <>
00580 class ValueTypeConversionTraits<double, qd_real> {
00581 public:
00582   inline static double convert( const qd_real t )
00583     { return to_double(t); }
00584   inline static double safeConvert( const qd_real t )
00585     { return to_double(t); }
00586 };
00587 
00589 template <>
00590 class ValueTypeConversionTraits<float, qd_real> {
00591 public:
00592   inline static float convert( const qd_real t )
00593     { return (float)to_double(t); }
00594   inline static float safeConvert( const qd_real t )
00595     { return (float)to_double(t); }
00596 };
00597 
00599 template <>
00600 class ValueTypeConversionTraits<int, qd_real> {
00601 public:
00602   inline static int convert( const qd_real t )
00603     { return to_int(t); }
00604   inline static int safeConvert( const qd_real t )
00605     { return to_int(t); }
00606 };
00607 
00609 template <>
00610 class ValueTypeConversionTraits<dd_real, qd_real> {
00611 public:
00612   inline static dd_real convert( const qd_real t )
00613     { return to_dd_real(t); }
00614   inline static dd_real safeConvert( const qd_real t )
00615     { return to_dd_real(t); }
00616 };
00617 
00619 template <>
00620 class ValueTypeConversionTraits<double, dd_real> {
00621 public:
00622   inline static double convert( const dd_real t )
00623     { return to_double(t); }
00624   inline static double safeConvert( const dd_real t )
00625     { return to_double(t); }
00626 };
00627 
00629 template <>
00630 class ValueTypeConversionTraits<float, dd_real> {
00631 public:
00632   inline static float convert( const dd_real t )
00633     { return (float)to_double(t); }
00634   inline static float safeConvert( const dd_real t )
00635     { return (float)to_double(t); }
00636 };
00637 
00639 template <>
00640 class ValueTypeConversionTraits<int, dd_real> {
00641 public:
00642   inline static int convert( const dd_real t )
00643     { return to_int(t); }
00644   inline static int safeConvert( const dd_real t )
00645     { return to_int(t); }
00646 };
00647 
00649 template <>
00650 class ValueTypeConversionTraits<qd_real, long unsigned int> {
00651 public:
00652   inline static qd_real convert( const long unsigned int t )
00653     { return ValueTypeConversionTraits<qd_real,int>::convert(ValueTypeConversionTraits<int,long unsigned int>::convert(t)); }
00654   inline static qd_real safeConvert( const long unsigned int t )
00655     { return ValueTypeConversionTraits<qd_real,int>::safeConvert(ValueTypeConversionTraits<int,long unsigned int>::safeConvert(t)); }
00656 };
00657 
00659 template <>
00660 class ValueTypeConversionTraits<dd_real, long unsigned int> {
00661 public:
00662   inline static dd_real convert( const long unsigned int t )
00663     { return ValueTypeConversionTraits<dd_real,int>::convert(ValueTypeConversionTraits<int,long unsigned int>::convert(t)); }
00664   inline static dd_real safeConvert( const long unsigned int t )
00665     { return ValueTypeConversionTraits<dd_real,int>::safeConvert(ValueTypeConversionTraits<int,long unsigned int>::safeConvert(t)); }
00666 };
00667 
00668 #endif // HAVE_TEUCHOS_QD
00669 
00670 // ToDo: Add more specializations as needed!
00671 
00672 
00673 } // end namespace Teuchos
00674 
00675 
00676 #endif // TEUCHOS_AS_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines