|
Teuchos - Trilinos Tools Package
Version of the Day
|
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
1.7.6.1