Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_as.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef TEUCHOS_AS_HPP
11 #define TEUCHOS_AS_HPP
12 
38 
39 #include "Teuchos_ConfigDefs.hpp"
40 #include "Teuchos_Assert.hpp"
41 #include <limits>
42 #include <cstdlib>
43 #include <cerrno>
44 #include <climits>
45 
46 #ifdef HAVE_TEUCHOS_COMPLEX
47 #include <complex>
48 #endif // HAVE_TEUCHOS_COMPLEX
49 
50 #ifdef HAVE_TEUCHOS_QD
51 #include <qd/qd_real.h>
52 #include <qd/dd_real.h>
53 #endif // HAVE_TEUCHOS_QD
54 
55 namespace Teuchos {
56 
57 
146 template<class TypeTo, class TypeFrom>
148 public:
150  static TypeTo convert (const TypeFrom t) {
151  // This default implementation is just an implicit conversion and
152  // may generate compiler warnings on dangerous conversions.
153  return t;
154  }
155 
157  static TypeTo safeConvert (const TypeFrom t) {
158  // This default implementation is just an implicit conversion and
159  // may generate compiler warnings on dangerous conversions. No
160  // runtime checking (e.g., for overflow) can be done by default;
161  // only specializations can define meaningful and portable
162  // run-time checks of conversions.
163  return t;
164  }
165 };
166 
254 template<class TypeTo, class TypeFrom>
255 inline TypeTo as( const TypeFrom& t );
256 
257 
323 template<class TypeTo, class TypeFrom>
324 inline TypeTo asSafe( const TypeFrom& t );
325 
326 
339 template <class TypeTo>
340 class asFunc {
341 public:
342  asFunc() {}
343 
344  template <class TypeFrom>
345  inline TypeTo operator()(const TypeFrom &t) {
346  return as<TypeTo>(t);
347  }
348 };
349 
350 
351 
352 namespace { // anonymous
353 
371  template<class IntType>
372  IntType
373  intToString (const std::string& t,
374  IntType (*rawConvert) (const char*, char**, int),
375  const char* intTypeName)
376  {
377  // We call the "raw" conversion function instead of using
378  // std::istringstream, because we want more detailed information
379  // in case of failure to convert. I have no idea what
380  // operator>>(std::istream&, unsigned long long&) does if it
381  // encounters an integer too long to fit in IntType, for example.
382  //
383  // mfh 13 Nov 2012: It's fair to assume that if you have "long
384  // long", then your implementation of the C standard library
385  // includes strtoul(). Ditto for "unsigned long long" and
386  // strtoull(). If this is not the case, we could include a
387  // configure-time test for these functions(), with a fall-back to
388  // an std::istringstream operator>> implementation.
389  char* endptr = NULL;
390  // Keep the pointer, because std::string doesn't necessarily
391  // guarantee that this is the same across calls to c_str(), does
392  // it? Or perhaps it does...
393  const char* t_ptr = t.c_str ();
394  // We preset errno to 0, to distinguish success or failure after
395  // calling strtoull. Most implementations of the C standard
396  // library written with threads in mind have errno be a macro that
397  // expands to thread-local storage. Thanks to the Linux
398  // documentation for strtol ("man 3 strtol", Red Hat Enterprise
399  // Linux 5) for advice with the following checks.
400  errno = 0;
401  const IntType val = rawConvert (t_ptr, &endptr, 10);
402 
403  const IntType minVal = std::numeric_limits<IntType>::min ();
404  const IntType maxVal = std::numeric_limits<IntType>::max ();
406  errno == ERANGE && (val == minVal || val == maxVal),
407  std::range_error,
408  "Teuchos::ValueTypeConversionTraits<" << intTypeName << ", std::string>::convert: "
409  "The integer value in the given string \"" << t << "\" overflows " << intTypeName << ".");
411  errno != 0 && val == 0,
412  std::invalid_argument,
413  "Teuchos::ValueTypeConversionTraits<" << intTypeName << ", std::string>::convert: "
414  "The conversion function was unable to convert the given string \"" << t << "\" to " << intTypeName << ".");
416  endptr == t_ptr, // See above discussion of c_str().
417  std::invalid_argument,
418  "Teuchos::ValueTypeConversionTraits<" << intTypeName << ", std::string>::convert: "
419  "The conversion function was unable to read any integer digits from the given string "
420  "\"" << t << "\".");
421  return val;
422  }
423 
435  template<class OutputRealType, class InputRealType>
436  OutputRealType
437  realToReal (const InputRealType& x, const bool doBoundsChecking)
438  {
440 
441  if (doBoundsChecking) {
442  // For floating-point types T, std::numeric_limits<T>::min()
443  // returns the smallest positive value. IEEE 754 types have a
444  // sign bit, so the largest-magnitude negative value is the
445  // negative of the largest-magnitude positive value.
446  const OutputRealType minVal = -std::numeric_limits<OutputRealType>::max ();
447  const OutputRealType maxVal = std::numeric_limits<OutputRealType>::max ();
448 
449  // NaN is neither less than nor greater than anything. We just
450  // let it pass through, per the rules for propagation of silent
451  // NaN. (Signaling NaN will signal, but that's OK.)
453  x < as<InputRealType>(minVal) || x > as<InputRealType>(maxVal),
454  std::range_error,
455  "realToReal<" << TypeNameTraits<OutputRealType>::name () << ", "
456  << TypeNameTraits<InputRealType>::name () << ">: "
457  "Input value x = " << x << " is out of the valid range [" << minVal
458  << ", " << maxVal << "] for conversion to the output type.");
459  }
460 
461  // Call as() and not static_cast, because there might not
462  // necessarily be a conversion defined between the two types,
463  // other than via as(). Definitely don't call asSafe(), because
464  // that could cause infinite recursion.
465  return as<OutputRealType> (x);
466  }
467 
468 
493  template<class RealType>
494  RealType
495  stringToReal (const std::string& t,
496  RealType (*rawConvert) (const char*, char**),
497  const char* realTypeName)
498  {
499  if (rawConvert == NULL) {
500  std::istringstream in (t);
501  RealType out;
502  in >> out;
503  return out;
504  }
505  else {
506  char* endptr = NULL;
507  // Keep the pointer, because std::string doesn't necessarily
508  // guarantee that this is the same across calls to c_str(), does
509  // it? Or perhaps it does...
510  const char* t_ptr = t.c_str ();
511  // We preset errno to 0, to distinguish success or failure after
512  // calling strtoull. Most implementations of the C standard
513  // library written with threads in mind have errno be a macro that
514  // expands to thread-local storage. Thanks to the Linux
515  // documentation for strtod ("man 3 strtod", Red Hat Enterprise
516  // Linux 5) for advice with the following checks.
517  errno = 0;
518  const RealType val = rawConvert (t_ptr, &endptr);
519 
521  errno == ERANGE && (val != 0),
522  std::range_error,
523  "Teuchos::ValueTypeConversionTraits<" << realTypeName
524  << ", std::string>::convert: "
525  "The value in the given string \"" << t << "\" overflows "
526  << realTypeName << ".");
527  //
528  // mfh 20 Nov 2012: Should we treat underflow as an error?
529  //
531  errno == ERANGE && val == 0,
532  std::invalid_argument,
533  "Teuchos::ValueTypeConversionTraits<" << realTypeName
534  << ", std::string>::convert: "
535  "The value in the given string \"" << t << "\" underflows "
536  << realTypeName << ".");
538  endptr == t_ptr, // See above discussion of c_str().
539  std::invalid_argument,
540  "Teuchos::ValueTypeConversionTraits<" << realTypeName
541  << ", std::string>::convert: "
542  "The conversion function was unable to read any floating-point data "
543  "from the given string \"" << t << "\".");
544  return val;
545  }
546  }
547 
548 } // namespace (anonymous)
549 
550 
551 //
552 // Standard specializations of ValueTypeConversionTraits
553 //
554 
555 //
556 // * Partial specialization for conversion from std::string to any type T.
557 // There are full specializations for specific types T below.
558 //
559 
572 template<class OutType>
573 class ValueTypeConversionTraits<OutType, std::string> {
574 public:
575  static OutType safeConvert (const std::string& t) {
576  return convert (t);
577  }
578 
579  static OutType convert (const std::string& t) {
580  std::istringstream in (t);
581  OutType out;
582  in >> out;
583  return out;
584  }
585 };
586 
587 //
588 // * Specializations for conversions from std::string to build-in
589 // real-valued floating-point types.
590 //
591 
593 template<>
594 class ValueTypeConversionTraits<double, std::string> {
595 public:
596  static double convert (const std::string& t) {
597  return stringToReal<double> (t, &strtod, "double");
598  }
599 
600  static double safeConvert (const std::string& t) {
601  return stringToReal<double> (t, &strtod, "double");
602  }
603 };
604 
606 template<>
607 class ValueTypeConversionTraits<float, std::string> {
608 public:
609  static float convert (const std::string& t) {
610 #ifdef _ISOC99_SOURCE
611  return stringToReal<float> (t, &strtof, "float");
612 #else
613  // strtof is new in C99. If you don't have it, just use strtod
614  // and convert the resulting double to float.
615  const double d = stringToReal<double> (t, &strtod, "double");
616  return realToReal<float, double> (d, false);
617 #endif // _ISOC99_SOURCE
618  }
619 
620  static float safeConvert (const std::string& t) {
621 #ifdef _ISOC99_SOURCE
622  return stringToReal<float> (t, &strtof, "float");
623 #else
624  // strtof is new in C99. If you don't have it, just use strtod
625  // and convert the resulting double to float.
626  const double d = stringToReal<double> (t, &strtod, "double");
627  return realToReal<float, double> (d, true);
628 #endif // _ISOC99_SOURCE
629  }
630 };
631 
633 template<>
634 class ValueTypeConversionTraits<long double, std::string> {
635 public:
636  static long double convert (const std::string& t) {
637 #ifdef _ISOC99_SOURCE
638  return stringToReal<long double> (t, &strtold, "long double");
639 #else
640  // strtof is new in C99. If you don't have it, just use
641  // operator>>(std::istream&, long double&).
642  return stringToReal<long double> (t, NULL, "long double");
643 #endif // _ISOC99_SOURCE
644  }
645 
646  static long double safeConvert (const std::string& t) {
647  return convert (t);
648  }
649 };
650 
651 
652 //
653 // * Specializations for conversions from std::string to build-in integer types.
654 //
655 
659 template<>
660 class ValueTypeConversionTraits<long long, std::string> {
661 public:
667  static long long safeConvert (const std::string& t) {
668 #if defined(_MSC_VER)
669  // Windows does not implement strtoull, so we resort to a
670  // fallback. Thanks to Ross Bartlett for pointing out _strtoi64.
671  // See the MSDN reference [last accessed 21 Mar 2013]:
672  //
673  // http://msdn.microsoft.com/en-us/library/h80404d3%28v=vs.80%29.aspx
674  return intToString<long long> (t, &_strtoi64, "long long");
675 #else
676  return intToString<long long> (t, &strtoll, "long long");
677 #endif // defined(_MSC_VER)
678  }
679 
681  static long long convert (const std::string& t) {
682  return safeConvert (t);
683  }
684 };
685 
686 
690 template<>
691 class ValueTypeConversionTraits<unsigned long long, std::string> {
692 public:
698  static unsigned long long safeConvert (const std::string& t) {
699 #if defined(_MSC_VER)
700  // Windows does not implement strtoull, so we resort to a
701  // fallback. The fallback does not know how to check for under-
702  // or overflow. Alas, Windows does not seem to have an equivalent
703  // of _strtoi64 for unsigned long long.
704  const char intTypeName[] = "unsigned long long";
705  std::istringstream istr (t);
706  unsigned long long i = 0;
707  istr >> i;
709  ! istr, std::invalid_argument,
710  "Teuchos::ValueTypeConversionTraits<" << intTypeName << ", std::string>::"
711  "convert: Unable to convert the given string \"" << t << "\" to " <<
712  intTypeName << ". Windows lacks strtoull(), so we had to resort to a "
713  "fall-back conversion. The fall-back method does not know how to test "
714  "for overflow.");
715  return i;
716 #else
717  return intToString<unsigned long long> (t, &strtoull, "unsigned long long");
718 #endif // defined(_MSC_VER)
719  }
720 
722  static unsigned long long convert (const std::string& t) {
723  return safeConvert (t);
724  }
725 };
726 
727 
731 template<>
732 class ValueTypeConversionTraits<long, std::string> {
733 public:
739  static long safeConvert (const std::string& t) {
740  return intToString<long> (t, &strtol, "long");
741  }
742 
744  static long convert (const std::string& t) {
745  return safeConvert (t);
746  }
747 };
748 
749 
753 template<>
754 class ValueTypeConversionTraits<unsigned long, std::string> {
755 public:
761  static unsigned long safeConvert (const std::string& t) {
762  return intToString<unsigned long> (t, &strtoul, "unsigned long");
763  }
764 
766  static unsigned long convert (const std::string& t) {
767  return safeConvert (t);
768  }
769 };
770 
771 
772 // Windows size_t is not unsigned long(32 bit), but unsigned long long(64 bit)
773 #ifdef HAVE_TEUCHOS___INT64
774 template<>
778 class ValueTypeConversionTraits<unsigned __int64, std::string> {
779 public:
785  static unsigned __int64 safeConvert(const std::string& t) {
786  unsigned __int64 output;
787  std::istringstream stream(t);
788  stream >> output;
789  return output;
790  }
791 
793  static unsigned __int64 convert(const std::string& t) {
794  unsigned __int64 output;
795  std::istringstream stream(t);
796  stream >> output;
797  return output;
798  }
799 };
800 #endif // HAVE_TEUCHOS___INT64
801 
802 
806 template<>
807 class ValueTypeConversionTraits<int, std::string> {
808 private:
810  static long safeConvertToLong (const std::string& t) {
811  long val = 0;
812  try {
814  } catch (std::range_error&) {
816  true,
817  std::range_error,
818  "Teuchos::ValueTypeConversionTraits<int, std::string>::convert: "
819  "The given std::string \"" << t << "\" is too big to fit into long, so there is no way it could fit into int.");
820  } catch (std::invalid_argument& e) {
822  true,
823  std::invalid_argument,
824  "Teuchos::ValueTypeConversionTraits<int, std::string>::convert: "
825  "Intermediate conversion from std::string to long failed, with the following error message: "
826  << e.what ());
827  }
828  return val;
829  }
830 
831 public:
837  static int safeConvert (const std::string& t) {
838  return asSafe<int> (safeConvertToLong (t));
839  }
840 
842  static int convert (const std::string& t) {
843  return as<int> (safeConvertToLong (t));
844  }
845 };
846 
847 
851 template<>
852 class ValueTypeConversionTraits<unsigned int, std::string> {
853 private:
855  static unsigned long safeConvertToUnsignedLong (const std::string& t) {
856  unsigned long val = 0;
857  try {
858  val = as<unsigned long> (t);
859  } catch (std::range_error&) {
861  true,
862  std::range_error,
863  "Teuchos::ValueTypeConversionTraits<unsigned int, std::string>::convert: "
864  "The given std::string \"" << t << "\" is too big to fit into unsigned long, so there is no way it could fit into unsigned int.");
865  } catch (std::invalid_argument& e) {
867  true,
868  std::invalid_argument,
869  "Teuchos::ValueTypeConversionTraits<unsigned int, std::string>::convert: "
870  "Intermediate conversion from std::string to unsigned long failed, with the following error message: "
871  << e.what ());
872  }
873  return val;
874  }
875 
876 public:
882  static unsigned int safeConvert (const std::string& t) {
883  return asSafe<unsigned int> (safeConvertToUnsignedLong (t));
884  }
885 
887  static unsigned int convert (const std::string& t) {
888  return as<unsigned int> (safeConvertToUnsignedLong (t));
889  }
890 };
891 
892 
896 template<>
897 class ValueTypeConversionTraits<short, std::string> {
898 private:
900  static long safeConvertToLong (const std::string& t) {
901  long val = 0;
902  try {
904  } catch (std::range_error&) {
906  true,
907  std::range_error,
908  "Teuchos::ValueTypeConversionTraits<short, std::string>::convert: "
909  "The given std::string \"" << t << "\" is too big to fit into long, so there is no way it could fit into short.");
910  } catch (std::invalid_argument& e) {
912  true,
913  std::invalid_argument,
914  "Teuchos::ValueTypeConversionTraits<short, std::string>::convert: "
915  "Intermediate conversion from std::string to long failed, with the following error message: "
916  << e.what ());
917  }
918  return val;
919  }
920 
921 public:
927  static short safeConvert (const std::string& t) {
928  return asSafe<short> (safeConvertToLong (t));
929  }
930 
932  static short convert (const std::string& t) {
933  return as<short> (safeConvertToLong (t));
934  }
935 };
936 
937 
941 template<>
942 class ValueTypeConversionTraits<unsigned short, std::string> {
943 private:
945  static unsigned long safeConvertToUnsignedLong (const std::string& t) {
946  unsigned long val = 0;
947  try {
948  val = as<unsigned long> (t);
949  } catch (std::range_error&) {
951  true,
952  std::range_error,
953  "Teuchos::ValueTypeConversionTraits<unsigned short, std::string>::convert: "
954  "The given std::string \"" << t << "\" is too big to fit into unsigned long, so there is no way it could fit into unsigned short.");
955  } catch (std::invalid_argument& e) {
957  true,
958  std::invalid_argument,
959  "Teuchos::ValueTypeConversionTraits<unsigned short, std::string>::convert: "
960  "Intermediate conversion from std::string to unsigned long failed, with the following error message: "
961  << e.what ());
962  }
963  return val;
964  }
965 
966 public:
972  static unsigned short safeConvert (const std::string& t) {
973  return asSafe<unsigned short> (safeConvertToUnsignedLong (t));
974  }
975 
977  static unsigned short convert (const std::string& t) {
978  return as<unsigned short> (safeConvertToUnsignedLong (t));
979  }
980 };
981 
982 //
983 // * Specializations for conversions between built-in real-valued
984 // floating-point types (like float and double).
985 //
986 
988 template<>
989 class ValueTypeConversionTraits<float, double> {
990 public:
991  static float safeConvert (const double t) {
992  // mfh 25 Nov 2012: Disabling bounds checking, in favor of IEEE
993  // 754 overflow semantics. Users who want bounds checking should
994  // set the appropriate trap.
995 #if 0
996  // For floating-point types T, std::numeric_limits<T>::min()
997  // returns the smallest positive value. IEEE 754 types have a
998  // sign bit, so the largest-magnitude negative value is the
999  // negative of the largest-magnitude positive value.
1000  const float minVal = -std::numeric_limits<float>::max ();
1001  const float maxVal = std::numeric_limits<float>::max ();
1002 
1003  // NaN is neither less than nor greater than anything. We just
1004  // let it pass through, per the rules for propagation of silent
1005  // NaN. (Signaling NaN will signal, but that's OK.)
1007  t < minVal || t > maxVal,
1008  std::range_error,
1009  "Teuchos::ValueTypeConversionTraits<float, double>::safeConvert: "
1010  "Input double t = " << t << " is out of the valid range [" << minVal
1011  << ", " << maxVal << "] for conversion to float.");
1012 #endif // 0
1013 
1014  return static_cast<float> (t);
1015  }
1016 
1017  static float convert (const double t) {
1018  return static_cast<float> (t);
1019  }
1020 };
1021 
1022 
1024 template<>
1025 class ValueTypeConversionTraits<float, long double> {
1026 public:
1027  static float safeConvert (const long double t) {
1028  // mfh 25 Nov 2012: Disabling bounds checking, in favor of IEEE
1029  // 754 overflow semantics. Users who want bounds checking should
1030  // set the appropriate trap.
1031 #if 0
1032  // For floating-point types T, std::numeric_limits<T>::min()
1033  // returns the smallest positive value. IEEE 754 types have a
1034  // sign bit, so the largest-magnitude negative value is the
1035  // negative of the largest-magnitude positive value.
1036  const float minVal = -std::numeric_limits<float>::max ();
1037  const float maxVal = std::numeric_limits<float>::max ();
1038 
1039  // NaN is neither less than nor greater than anything. We just
1040  // let it pass through, per the rules for propagation of silent
1041  // NaN. (Signaling NaN will signal, but that's OK.)
1043  t < minVal || t > maxVal,
1044  std::range_error,
1045  "Teuchos::ValueTypeConversionTraits<float, long double>::safeConvert: "
1046  "Input long double t = " << t << " is out of the valid range [" << minVal
1047  << ", " << maxVal << "] for conversion to float.");
1048 #endif // 0
1049 
1050  return static_cast<float> (t);
1051  }
1052 
1053  static float convert (const long double t) {
1054  return static_cast<float> (t);
1055  }
1056 };
1057 
1058 
1060 template<>
1061 class ValueTypeConversionTraits<double, long double> {
1062 public:
1063  static double safeConvert (const long double t) {
1064  // mfh 25 Nov 2012: Disabling bounds checking, in favor of IEEE
1065  // 754 overflow semantics. Users who want bounds checking should
1066  // set the appropriate trap.
1067 #if 0
1068  // For floating-point types T, std::numeric_limits<T>::min()
1069  // returns the smallest positive value. IEEE 754 types have a
1070  // sign bit, so the largest-magnitude negative value is the
1071  // negative of the largest-magnitude positive value.
1072  const double minVal = -std::numeric_limits<double>::max ();
1073  const double maxVal = std::numeric_limits<double>::max ();
1074 
1075  // NaN is neither less than nor greater than anything. We just
1076  // let it pass through, per the rules for propagation of silent
1077  // NaN. (Signaling NaN will signal, but that's OK.)
1079  t < minVal || t > maxVal,
1080  std::range_error,
1081  "Teuchos::ValueTypeConversionTraits<double, long double>::safeConvert: "
1082  "Input long double t = " << t << " is out of the valid range [" << minVal
1083  << ", " << maxVal << "] for conversion to double.");
1084 #endif // 0
1085 
1086  return static_cast<double> (t);
1087  }
1088 
1089  static double convert (const long double t) {
1090  return static_cast<double> (t);
1091  }
1092 };
1093 
1094 
1095 //
1096 // * Specializations for conversions from built-in real-valued
1097 // floating-point types (float and double) to build-in integer
1098 // types.
1099 //
1100 
1102 template<>
1103 class ValueTypeConversionTraits<short, double> {
1104 public:
1110  static short convert (const double t) {
1111  // Implicit conversion may cause compiler warnings, but
1112  // static_cast does not.
1113  return static_cast<short> (t);
1114  }
1115 
1117  static short safeConvert (const double t) {
1118  const short minVal = std::numeric_limits<short>::min ();
1119  const short maxVal = std::numeric_limits<short>::max ();
1120 
1121  // Cases:
1122  // 1. sizeof(short) < sizeof(double) == 8
1123  // 2. sizeof(short) == sizeof(double) == 8
1124  // 3. sizeof(short) > sizeof(double) == 8
1125  //
1126  // Overflow when converting from double to short is possible only
1127  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1128  // 2 and 3, but safeConvert() only cares about overflow, not
1129  // rounding. In Case 3, casting minVal or maxVal to double in
1130  // this case could result in overflow. Thus, we only do the test
1131  // for Case 1.
1132  //
1133  // All three cases are legal according to both C++03 and C99.
1134  // However, I (mfh 15 Nov 2012) have never encountered Cases 2 and
1135  // 3.
1136  if (sizeof (short) < sizeof (double)) {
1138  t < minVal || t > maxVal,
1139  std::range_error,
1140  "Teuchos::ValueTypeConversionTraits<short, double>::safeConvert: "
1141  "Input double t = " << t << " is out of the valid range [" << minVal
1142  << ", " << maxVal << "] for conversion to short.");
1143  }
1144  return static_cast<short> (t);
1145  }
1146 };
1147 
1148 
1150 template<>
1151 class ValueTypeConversionTraits<unsigned short, double> {
1152 public:
1154  static unsigned short convert (const double t) {
1155  // Implicit conversion may cause compiler warnings, but
1156  // static_cast does not.
1157  return static_cast<unsigned short> (t);
1158  }
1159 
1161  static unsigned short safeConvert (const double t) {
1162  const unsigned short minVal = 0;
1163  const unsigned short maxVal = std::numeric_limits<unsigned short>::max ();
1164 
1166  t < minVal || t > maxVal,
1167  std::range_error,
1168  "Teuchos::ValueTypeConversionTraits<unsigned short, double>::safeConvert: "
1169  "Input double t = " << t << " is out of the valid range [" << minVal
1170  << ", " << maxVal << "] for conversion to unsigned short.");
1171 
1172  return static_cast<unsigned short> (t);
1173  }
1174 };
1175 
1176 
1178 template<>
1179 class ValueTypeConversionTraits<int, double> {
1180 public:
1186  static int convert (const double t) {
1187  // Implicit conversion from double to int causes compiler
1188  // warnings, but static_cast does not.
1189  return static_cast<int> (t);
1190  }
1191 
1193  static int safeConvert (const double t) {
1194  const int minVal = std::numeric_limits<int>::min ();
1195  const int maxVal = std::numeric_limits<int>::max ();
1196 
1197  // Cases:
1198  // 1. sizeof(int) < sizeof(double) == 8
1199  // 2. sizeof(int) == sizeof(double) == 8
1200  // 3. sizeof(int) > sizeof(double) == 8
1201  //
1202  // Overflow when converting from double to int is possible only
1203  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1204  // 2 and 3, but safeConvert() only cares about overflow, not
1205  // rounding. Case 3 is quite rare, but casting minVal or maxVal
1206  // to double in this case could result in overflow. Thus, we only
1207  // do the cast for Case 1.
1208  if (sizeof (int) < sizeof (double)) {
1210  t < minVal || t > maxVal,
1211  std::range_error,
1212  "Teuchos::ValueTypeConversionTraits<int, double>::safeConvert: "
1213  "Input double t = " << t << " is out of the valid range [" << minVal
1214  << ", " << maxVal << "] for conversion to int.");
1215  }
1216  return static_cast<int> (t);
1217  }
1218 };
1219 
1220 
1222 template<>
1223 class ValueTypeConversionTraits<unsigned int, double> {
1224 public:
1226  static unsigned int convert (const double t) {
1227  // Implicit conversion may cause compiler warnings, but
1228  // static_cast does not.
1229  return static_cast<unsigned int> (t);
1230  }
1231 
1233  static unsigned int safeConvert (const double t) {
1234  const unsigned int minVal = 0;
1235  const unsigned int maxVal = std::numeric_limits<unsigned int>::max ();
1236 
1238  t < minVal || t > maxVal,
1239  std::range_error,
1240  "Teuchos::ValueTypeConversionTraits<unsigned int, double>::safeConvert: "
1241  "Input double t = " << t << " is out of the valid range [" << minVal
1242  << ", " << maxVal << "] for conversion to unsigned int.");
1243 
1244  return static_cast<unsigned int> (t);
1245  }
1246 };
1247 
1248 
1250 template<>
1251 class ValueTypeConversionTraits<long, double> {
1252 public:
1254  static long convert (const double t) {
1255  // Implicit conversion may cause compiler warnings, but
1256  // static_cast does not.
1257  return static_cast<long> (t);
1258  }
1259 
1261  static long safeConvert (const double t) {
1262  const long minVal = std::numeric_limits<long>::min ();
1263  const long maxVal = std::numeric_limits<long>::max ();
1264 
1265  // Cases:
1266  // 1. sizeof(long) < sizeof(double) == 8
1267  // 2. sizeof(long) == sizeof(double) == 8
1268  // 3. sizeof(long) > sizeof(double) == 8
1269  //
1270  // Overflow when converting from double to long is possible only
1271  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1272  // 2 and 3, but safeConvert() only cares about overflow, not
1273  // rounding. In Case 3, casting minVal or maxVal to double could
1274  // result in overflow. Thus, we only test for Case 1.
1275  //
1276  // Case 1 is entirely possible, for example on Win64 (an
1277  // implementation of the LLP64 integer model, on which
1278  // sizeof(long) == 4, and sizeof(long long) == sizeof(void*) ==
1279  // 8).
1280  if (sizeof (long) < sizeof (double)) {
1282  t < minVal || t > maxVal,
1283  std::range_error,
1284  "Teuchos::ValueTypeConversionTraits<long, double>::safeConvert: "
1285  "Input double t = " << t << " is out of the valid range [" << minVal
1286  << ", " << maxVal << "] for conversion to long.");
1287  }
1288  return static_cast<long> (t);
1289  }
1290 };
1291 
1292 
1294 template<>
1295 class ValueTypeConversionTraits<unsigned long, double> {
1296 public:
1298  static unsigned long convert (const double t) {
1299  // Implicit conversion may cause compiler warnings, but
1300  // static_cast does not.
1301  return static_cast<unsigned long> (t);
1302  }
1303 
1305  static unsigned long safeConvert (const double t) {
1306  const unsigned long minVal = 0;
1307  const unsigned long maxVal = std::numeric_limits<unsigned long>::max ();
1308 
1310  t < minVal || t > static_cast<double>(maxVal),
1311  std::range_error,
1312  "Teuchos::ValueTypeConversionTraits<unsigned long, double>::safeConvert: "
1313  "Input double t = " << t << " is out of the valid range [" << minVal
1314  << ", " << maxVal << "] for conversion to unsigned long.");
1315 
1316  return static_cast<unsigned long> (t);
1317  }
1318 };
1319 
1321 template<>
1322 class ValueTypeConversionTraits<long long, double> {
1323 public:
1325  static long long convert (const double t) {
1326  // Implicit conversion may cause compiler warnings, but
1327  // static_cast does not.
1328  return static_cast<long long> (t);
1329  }
1330 
1332  static long long safeConvert (const double t) {
1333  // Cases:
1334  // 1. sizeof(long long) < sizeof(double) == 8
1335  // 2. sizeof(long long) == sizeof(double) == 8
1336  // 3. sizeof(long long) > sizeof(double) == 8
1337  //
1338  // C99 (which defines long long) prohibits Case 1. Case 2 could
1339  // result in loss of accuracy (rounding), but safeConvert() only
1340  // cares about overflow, not rounding. In Case 3, casting minVal
1341  // or maxVal to double could result in overflow. Thus, we don't
1342  // need to check anything here.
1343  return static_cast<long long> (t);
1344  }
1345 };
1346 
1347 
1349 template<>
1350 class ValueTypeConversionTraits<unsigned long long, double> {
1351 public:
1353  static unsigned long long convert (const double t) {
1354  // Implicit conversion may cause compiler warnings, but
1355  // static_cast does not.
1356  return static_cast<unsigned long long> (t);
1357  }
1358 
1360  static unsigned long long safeConvert (const double t) {
1361  const unsigned long long minVal = 0; // unsigned, so min value is 0.
1362  const unsigned long long maxVal = std::numeric_limits<unsigned long long>::max ();
1363 
1365  t < minVal || t > static_cast<double>(maxVal),
1366  std::range_error,
1367  "Teuchos::ValueTypeConversionTraits<unsigned long long, double>::safeConvert: "
1368  "Input double t = " << t << " is out of the valid range [" << minVal
1369  << ", " << maxVal << "] for conversion to unsigned long long.");
1370 
1371  return static_cast<unsigned long long> (t);
1372  }
1373 };
1374 
1375 
1377 template<>
1378 class ValueTypeConversionTraits<short, float> {
1379 public:
1385  static short convert (const float t) {
1386  // Implicit conversion may cause compiler warnings, but
1387  // static_cast does not.
1388  return static_cast<short> (t);
1389  }
1390 
1392  static short safeConvert (const float t) {
1393  const short minVal = std::numeric_limits<short>::min ();
1394  const short maxVal = std::numeric_limits<short>::max ();
1395 
1396  // Cases:
1397  // 1. sizeof(short) < sizeof(float) == 4
1398  // 2. sizeof(short) == sizeof(float) == 4
1399  // 3. sizeof(short) > sizeof(float) == 4
1400  //
1401  // Overflow when converting from float to short is possible only
1402  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1403  // 2 and 3, but safeConvert() only cares about overflow, not
1404  // rounding. In Case 3, casting minVal or maxVal to float in this
1405  // case could result in overflow. Thus, we only do the test for
1406  // Case 1.
1407  //
1408  // All three cases are legal according to both C++03 and C99. I
1409  // (mfh 15 Nov 2012) think Case 1 is the most common, but Case 2
1410  // is certainly reasonable. (For example, some hardware prefers
1411  // to work only with 32-bit words, so _every_ built-in type has
1412  // size a multiple of 4 bytes.)
1413  if (sizeof (short) < sizeof (float)) {
1415  t < minVal || t > maxVal,
1416  std::range_error,
1417  "Teuchos::ValueTypeConversionTraits<short, float>::safeConvert: "
1418  "Input float t = " << t << " is out of the valid range [" << minVal
1419  << ", " << maxVal << "] for conversion to short.");
1420  }
1421 
1422  return static_cast<short> (t);
1423  }
1424 };
1425 
1426 
1428 template<>
1429 class ValueTypeConversionTraits<unsigned short, float> {
1430 public:
1432  static unsigned short convert (const float t) {
1433  // Implicit conversion may cause compiler warnings, but
1434  // static_cast does not.
1435  return static_cast<unsigned short> (t);
1436  }
1437 
1439  static unsigned short safeConvert (const float t) {
1440  const unsigned short minVal = 0;
1441  const unsigned short maxVal = std::numeric_limits<unsigned short>::max ();
1442 
1444  t < minVal || t > maxVal,
1445  std::range_error,
1446  "Teuchos::ValueTypeConversionTraits<unsigned short, float>::safeConvert: "
1447  "Input float t = " << t << " is out of the valid range [" << minVal
1448  << ", " << maxVal << "] for conversion to unsigned short.");
1449 
1450  return static_cast<unsigned short> (t);
1451  }
1452 };
1453 
1454 
1456 template<>
1457 class ValueTypeConversionTraits<int, float> {
1458 public:
1460  static int convert (const float t) {
1461  // Implicit conversion from float to int may cause compiler
1462  // warnings, but static_cast does not. Overflow here would mean
1463  // that sizeof(int) < sizeof(float), which is legal, but unlikely
1464  // on platforms of interest.
1465  return static_cast<int> (t);
1466  }
1467 
1469  static int safeConvert (const float t) {
1470  const int minVal = std::numeric_limits<int>::min ();
1471  const int maxVal = std::numeric_limits<int>::max ();
1472 
1473  // Cases:
1474  // 1. sizeof(int) < sizeof(float) == 4
1475  // 2. sizeof(int) == sizeof(float) == 4
1476  // 3. sizeof(int) > sizeof(float) == 4
1477  //
1478  // Overflow when converting from float to int is possible only for
1479  // Case 1. Loss of accuracy (rounding) is possible for Cases 2
1480  // and 3, but safeConvert() only cares about overflow, not
1481  // rounding. Case 3 is rare, but casting minVal or maxVal to
1482  // float in this case could result in loss of accuracy
1483  // (sizeof(int) == 8 or 16) or overflow (sizeof(int) > 16). Thus,
1484  // we only do the test for Case 1.
1485  if (sizeof (int) < sizeof (float)) {
1487  t < minVal || t > maxVal,
1488  std::range_error,
1489  "Teuchos::ValueTypeConversionTraits<int, float>::safeConvert: "
1490  "Input float t = " << t << " is out of the valid range ["
1491  << minVal << ", " << maxVal << "] for conversion to int.");
1492  }
1493  return static_cast<int> (t);
1494  }
1495 };
1496 
1497 
1499 template<>
1500 class ValueTypeConversionTraits<unsigned int, float> {
1501 public:
1503  static unsigned int convert (const float t) {
1504  // Implicit conversion from float to unsigned int may cause
1505  // compiler warnings, but static_cast does not.
1506  return static_cast<unsigned int> (t);
1507  }
1508 
1510  static unsigned int safeConvert (const float t) {
1511  const unsigned int minVal = 0; // Had better be, since it's unsigned.
1512  const unsigned int maxVal = std::numeric_limits<unsigned int>::max ();
1513 
1515  t < minVal || t > static_cast<float>(maxVal),
1516  std::range_error,
1517  "Teuchos::ValueTypeConversionTraits<unsigned int, float>::safeConvert: "
1518  "Input double t = " << t << " is out of the valid range [" << minVal
1519  << ", " << maxVal << "] for conversion to unsigned int.");
1520 
1521  return static_cast<unsigned int> (t);
1522  }
1523 };
1524 
1525 
1527 template<>
1528 class ValueTypeConversionTraits<long, float> {
1529 public:
1531  static long convert (const float t) {
1532  // Implicit conversion from float to long may cause compiler
1533  // warnings, but static_cast does not. Overflow here would mean
1534  // that sizeof(long) < sizeof(float), which is legal, but unlikely
1535  // on platforms of longerest.
1536  return static_cast<long> (t);
1537  }
1538 
1540  static long safeConvert (const float t) {
1541  const long minVal = std::numeric_limits<long>::min ();
1542  const long maxVal = std::numeric_limits<long>::max ();
1543 
1544  // Cases:
1545  // 1. sizeof(long) < sizeof(float) == 4
1546  // 2. sizeof(long) == sizeof(float) == 4
1547  // 3. sizeof(long) > sizeof(float) == 4
1548  //
1549  // Overflow when converting from float to long is possible only
1550  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1551  // 2 and 3, but safeConvert() only cares about overflow, not
1552  // rounding. Casting minVal or maxVal to double in Case 3 could
1553  // result in overflow. Thus, we only do the cast for Case 1.
1554  //
1555  // I've never encountered a Case 1 platform (mfh 14 Nov 2012).
1556  // C99 actually forbids it, though I don't think a valid C++
1557  // compiler (for version C++03 of the language standard) needs to
1558  // implement C99 (mfh 14 Nov 2012). Case 2 occurs in Win64
1559  // (64-bit Windows) and other implementations of (I32L32)LLP64.
1560  // Case 3 is common (e.g., in the (I32)LP64 integer model of
1561  // GNU/Linux and other operating systems).
1562  if (sizeof (long) < sizeof (float)) {
1564  t < minVal || t > static_cast<float>(maxVal),
1565  std::range_error,
1566  "Teuchos::ValueTypeConversionTraits<long, float>::safeConvert: "
1567  "Input float t = " << t << " is out of the valid range ["
1568  << minVal << ", " << maxVal << "] for conversion to long.");
1569  }
1570  return static_cast<long> (t);
1571  }
1572 };
1573 
1574 
1576 template<>
1577 class ValueTypeConversionTraits<unsigned long, float> {
1578 public:
1580  static unsigned long convert (const float t) {
1581  // Implicit conversion from float to unsigned long may cause
1582  // compiler warnings, but static_cast does not.
1583  return static_cast<unsigned long> (t);
1584  }
1585 
1587  static unsigned long safeConvert (const float t) {
1588  const unsigned long minVal = 0; // Had better be, since it's unsigned.
1589  const unsigned long maxVal = std::numeric_limits<unsigned long>::max ();
1590 
1592  t < minVal || t > static_cast<float>(maxVal),
1593  std::range_error,
1594  "Teuchos::ValueTypeConversionTraits<unsigned long, float>::safeConvert: "
1595  << "Input float t = " << t << " is out of the valid range [" << minVal
1596  << ", " << maxVal << "] for conversion to unsigned long.");
1597 
1598  return static_cast<unsigned long> (t);
1599  }
1600 };
1601 
1603 template<>
1604 class ValueTypeConversionTraits<long long, float> {
1605 public:
1607  static long long convert (const float t) {
1608  return static_cast<long long> (t);
1609  }
1610 
1612  static long long safeConvert (const float t) {
1613  // The C99 standard (Section 5.2.4.2.1) actually requires
1614  // sizeof(long long) >= 64, so overflow is impossible.
1615  return static_cast<long long> (t);
1616  }
1617 };
1618 
1619 
1621 template<>
1622 class ValueTypeConversionTraits<unsigned long long, float> {
1623 public:
1625  static unsigned long long convert (const float t) {
1626  return static_cast<unsigned long long> (t);
1627  }
1628 
1630  static unsigned long long safeConvert (const float t) {
1631  const unsigned long long minVal = 0; // unsigned, so min value is 0.
1632  const unsigned long long maxVal = std::numeric_limits<unsigned long long>::max ();
1633 
1635  t < minVal || t > static_cast<float>(maxVal),
1636  std::range_error,
1637  "Teuchos::ValueTypeConversionTraits<unsigned long long, float>::safeConvert: "
1638  "Input float t = " << t << " is out of the valid range [" << minVal
1639  << ", " << maxVal << "] for conversion to unsigned long long.");
1640 
1641  return static_cast<unsigned long long> (t);
1642  }
1643 };
1644 
1645 //
1646 // * Specializations for conversions between a unsigned built-in
1647 // integer type and the signed version of the same type (either
1648 // direction).
1649 //
1650 
1651 namespace {
1652 // Implementation of conversion from an unsigned built-in integer
1653 // type, to an signed built-in integer type with the same number of
1654 // bits.
1655 template<class SignedIntType, class UnsignedIntType>
1656 class UnsignedToSignedValueTypeConversionTraits {
1657 public:
1665  static SignedIntType convert (const UnsignedIntType t) {
1666  // Implicit conversion may cause compiler warnings, but
1667  // static_cast does not.
1668  return static_cast<SignedIntType> (t);
1669  }
1670 
1672  static SignedIntType safeConvert (const UnsignedIntType t) {
1674  const SignedIntType maxSigned = std::numeric_limits<SignedIntType>::max ();
1675 
1676  // SignedIntType and UnsignedIntType have the same number of bits,
1677  // so it suffices (via two's complement arithmetic) to check
1678  // whether the cast turned a positive number negative.
1679  const SignedIntType signedVal = static_cast<SignedIntType> (t);
1681  signedVal < 0,
1682  std::range_error,
1683  "Teuchos::ValueTypeConversionTraits<" << TypeNameTraits<SignedIntType>::name ()
1684  << ", " << TypeNameTraits<UnsignedIntType>::name () << ">::safeConvert: "
1685  "Input " << TypeNameTraits<UnsignedIntType>::name () << " t = " << t
1686  << " is out of the valid range [0, " << ", " << maxSigned
1687  << "] for conversion to " << TypeNameTraits<SignedIntType>::name () << ".");
1688  return signedVal;
1689  }
1690 };
1691 
1692 
1693 // Implementation of conversion from a signed built-in integer type,
1694 // to an unsigned built-in integer type with the same number of bits.
1695 template<class UnsignedIntType, class SignedIntType>
1696 class SignedToUnsignedValueTypeConversionTraits {
1697 public:
1699  static UnsignedIntType convert (const SignedIntType t) {
1700  // Implicit conversion may cause compiler warnings, but
1701  // static_cast does not.
1702  return static_cast<UnsignedIntType> (t);
1703  }
1704 
1706  static UnsignedIntType safeConvert (const SignedIntType t) {
1708 
1709  // SignedIntType and UnsignedIntType have the same number of bits,
1710  // so it suffices (via two's complement arithmetic) to check
1711  // whether the input is negative.
1713  t < static_cast<SignedIntType> (0),
1714  std::range_error,
1715  "Teuchos::ValueTypeConversionTraits<" << TypeNameTraits<UnsignedIntType>::name ()
1716  << ", " << TypeNameTraits<SignedIntType>::name () << ">::safeConvert: "
1717  "Input " << TypeNameTraits<SignedIntType>::name () << " t = " << t
1718  << " is negative, so it cannot be correctly converted to the unsigned type "
1719  << TypeNameTraits<UnsignedIntType>::name () << ".");
1720 
1721  return static_cast<UnsignedIntType> (t);
1722  }
1723 };
1724 
1725 } // namespace (anonymous)
1726 
1727 
1729 template<>
1730 class ValueTypeConversionTraits<short, unsigned short> {
1731 public:
1732  static short convert (const unsigned short t) {
1733  return UnsignedToSignedValueTypeConversionTraits<short, unsigned short>::convert (t);
1734  }
1735 
1736  static short safeConvert (const unsigned short t) {
1737  return UnsignedToSignedValueTypeConversionTraits<short, unsigned short>::safeConvert (t);
1738  }
1739 };
1740 
1741 
1743 template<>
1744 class ValueTypeConversionTraits<unsigned short, short> {
1745 public:
1746  static unsigned short convert (const short t) {
1747  return SignedToUnsignedValueTypeConversionTraits<unsigned short, short>::convert (t);
1748  }
1749 
1750  static unsigned short safeConvert (const short t) {
1751  return SignedToUnsignedValueTypeConversionTraits<unsigned short, short>::safeConvert (t);
1752  }
1753 };
1754 
1755 
1757 template<>
1758 class ValueTypeConversionTraits<int, unsigned int> {
1759 public:
1760  static int convert (const unsigned int t) {
1761  return UnsignedToSignedValueTypeConversionTraits<int, unsigned int>::convert (t);
1762  }
1763 
1764  static int safeConvert (const unsigned int t) {
1765  return UnsignedToSignedValueTypeConversionTraits<int, unsigned int>::safeConvert (t);
1766  }
1767 };
1768 
1769 
1771 template<>
1772 class ValueTypeConversionTraits<unsigned int, int> {
1773 public:
1774  static unsigned int convert (const int t) {
1775  return SignedToUnsignedValueTypeConversionTraits<unsigned int, int>::convert (t);
1776  }
1777 
1778  static unsigned int safeConvert (const int t) {
1779  return SignedToUnsignedValueTypeConversionTraits<unsigned int, int>::safeConvert (t);
1780  }
1781 };
1782 
1783 
1785 template<>
1786 class ValueTypeConversionTraits<long, unsigned long> {
1787 public:
1788  static long convert (const unsigned long t) {
1789  return UnsignedToSignedValueTypeConversionTraits<long, unsigned long>::convert (t);
1790  }
1791 
1792  static long safeConvert (const unsigned long t) {
1793  return UnsignedToSignedValueTypeConversionTraits<long, unsigned long>::safeConvert (t);
1794  }
1795 };
1796 
1797 
1799 template<>
1800 class ValueTypeConversionTraits<unsigned long, long> {
1801 public:
1802  static unsigned long convert (const long t) {
1803  return SignedToUnsignedValueTypeConversionTraits<unsigned long, long>::convert (t);
1804  }
1805 
1806  static unsigned long safeConvert (const long t) {
1807  return SignedToUnsignedValueTypeConversionTraits<unsigned long, long>::safeConvert (t);
1808  }
1809 };
1810 
1811 
1813 template<>
1814 class ValueTypeConversionTraits<long long, unsigned long long> {
1815 public:
1816  static long long convert (const unsigned long long t) {
1817  return UnsignedToSignedValueTypeConversionTraits<long long, unsigned long long>::convert (t);
1818  }
1819 
1820  static long long safeConvert (const unsigned long long t) {
1821  return UnsignedToSignedValueTypeConversionTraits<long long, unsigned long long>::safeConvert (t);
1822  }
1823 };
1824 
1825 
1827 template<>
1828 class ValueTypeConversionTraits<unsigned long long, long long> {
1829 public:
1830  static unsigned long long convert (const long long t) {
1831  return SignedToUnsignedValueTypeConversionTraits<unsigned long long, long long>::convert (t);
1832  }
1833 
1834  static unsigned long long safeConvert (const long long t) {
1835  return SignedToUnsignedValueTypeConversionTraits<unsigned long long, long long>::safeConvert (t);
1836  }
1837 };
1838 
1839 //
1840 // * Specializations for conversions between different built-in
1841 // integer types.
1842 //
1843 
1845 template<>
1846 class ValueTypeConversionTraits<short, int> {
1847 public:
1853  static short convert (const int t) {
1854  // Implicit conversion may cause compiler warnings, but
1855  // static_cast does not.
1856  return static_cast<short> (t);
1857  }
1858 
1860  static short safeConvert (const int t) {
1861  const short minShort = std::numeric_limits<short>::min ();
1862  const short maxShort = std::numeric_limits<short>::max ();
1863 
1864  // Casting from short to int never overflows, since the C++
1865  // standard guarantees that sizeof (short) <= sizeof (int).
1867  t < static_cast<int> (minShort) ||
1868  t > static_cast<int> (maxShort),
1869  std::range_error,
1870  "Teuchos::ValueTypeConversionTraits<short, int>::safeConvert: "
1871  "Input int t = " << t << " is out of the valid range [" << minShort
1872  << ", " << maxShort << "] for conversion to short.");
1873 
1874  return static_cast<short> (t);
1875  }
1876 };
1877 
1878 
1880 template<>
1881 class ValueTypeConversionTraits<short, long> {
1882 public:
1888  static short convert (const long t) {
1889  // Implicit conversion may cause compiler warnings, but
1890  // static_cast does not.
1891  return static_cast<short> (t);
1892  }
1893 
1895  static short safeConvert (const long t) {
1896  const short minShort = std::numeric_limits<short>::min ();
1897  const short maxShort = std::numeric_limits<short>::max ();
1898 
1899  // Casting from short to long never overflows, since the C++
1900  // standard guarantees that sizeof (short) <= sizeof (long).
1902  t < static_cast<long> (minShort) ||
1903  t > static_cast<long> (maxShort),
1904  std::range_error,
1905  "Teuchos::ValueTypeConversionTraits<short, long>::safeConvert: "
1906  "Input long t = " << t << " is out of the valid range [" << minShort
1907  << ", " << maxShort << "] for conversion to short.");
1908 
1909  return static_cast<short> (t);
1910  }
1911 };
1912 
1913 
1915 template<>
1916 class ValueTypeConversionTraits<int, long> {
1917 public:
1923  static int convert (const long t) {
1924  // Implicit conversion from long to int may cause compiler
1925  // warnings, but static_cast does not.
1926  return static_cast<int> (t);
1927  }
1928 
1930  static int safeConvert (const long t) {
1931  const int minInt = std::numeric_limits<int>::min ();
1932  const int maxInt = std::numeric_limits<int>::max ();
1933 
1934  // Casting from int to long never overflows, since the C++
1935  // standard guarantees that sizeof (int) <= sizeof (long).
1937  t < static_cast<long> (minInt) ||
1938  t > static_cast<long> (maxInt),
1939  std::range_error,
1940  "Teuchos::ValueTypeConversionTraits<int, long>::safeConvert: "
1941  "Input long t = " << t << " is out of the valid range [" << minInt
1942  << ", " << maxInt << "] for conversion to int.");
1943 
1944  // Implicit conversion from long to int may cause compiler
1945  // warnings, but static_cast does not.
1946  return static_cast<int> (t);
1947  }
1948 };
1949 
1950 
1952 template<>
1953 class ValueTypeConversionTraits<int, unsigned long> {
1954 public:
1961  static int convert (const unsigned long t) {
1962  // Implicit conversion may cause compiler warnings, but
1963  // static_cast does not.
1964  return static_cast<int> (t);
1965  }
1966 
1968  static int safeConvert (const unsigned long t) {
1969  const int minInt = std::numeric_limits<int>::min ();
1970  const int maxInt = std::numeric_limits<int>::max ();
1971 
1972  // On some platforms, sizeof(int) == sizeof(long). (This is the
1973  // "LLP64" model of Win64, which aims for backwards compatibility
1974  // with 32-bit code by making sizeof(int) == sizeof(long) == 4.)
1975  // If this is the case, then we can't safely cast unsigned long to
1976  // int, or unsigned int to long, because values with the most
1977  // significant bit set will overflow to negative values.
1978 
1979  // The C++ standard promises that sizeof (int) <= sizeof (unsigned
1980  // long). We use #if with INT_MAX and LONG_MAX to test for this,
1981  // rather than if statements, in order to avoid a compiler
1982  // warning. Thanks to Jeremie Gaidamour (13 Nov 2012) for letting
1983  // me know about the warning.
1984 #if INT_MAX == LONG_MAX
1985  // The two types have the same number of bits. Thus,
1986  // two's-complement arithmetic means that if casting from unsigned
1987  // long to int results in a negative number, it overflowed.
1988  // Otherwise, it didn't overflow (same number of bits).
1990  static_cast<int> (t) < static_cast<int> (0),
1991  std::range_error,
1992  "Teuchos::ValueTypeConversionTraits<int, unsigned long>::safeConvert: "
1993  "Input unsigned long t = " << t << " is out of the valid range ["
1994  << minInt << ", " << maxInt << "] for conversion to int.");
1995 #else // INT_MAX < LONG_MAX
1996  // t is unsigned, so it is >= 0 by definition.
1997  // Casting from int to unsigned long won't overflow in this case.
1999  t > static_cast<unsigned long> (maxInt),
2000  std::range_error,
2001  "Teuchos::ValueTypeConversionTraits<int, unsigned long>::safeConvert: "
2002  "Input unsigned long t = " << t << " is out of the valid range ["
2003  << minInt << ", " << maxInt << "] for conversion to int. An unchecked "
2004  "cast would have resulted in " << static_cast<int> (t) << ".");
2005 #endif // INT_MAX == LONG_MAX
2006 
2007  // Implicit conversion from unsigned long to int may cause
2008  // compiler warnings, but static_cast does not.
2009  return static_cast<int> (t);
2010  }
2011 };
2012 
2013 
2015 template<>
2016 class ValueTypeConversionTraits<long, unsigned int> {
2017 public:
2025  static long convert (const unsigned int t) {
2026  // Implicit conversion may cause compiler warnings, but
2027  // static_cast does not.
2028  return static_cast<long> (t);
2029  }
2030 
2032  static long safeConvert (const unsigned int t) {
2033  // On some platforms, sizeof(int) == sizeof(long). (This is the
2034  // "LLP64" model of Win64, which aims for backwards compatibility
2035  // with 32-bit code by making sizeof(int) == sizeof(long) == 4.)
2036  // If this is the case, then we can't safely cast unsigned long to
2037  // int, or unsigned int to long, because values with the most
2038  // significant bit set will overflow to negative values.
2039 
2040  // The C++ standard promises that sizeof (unsigned int) <= sizeof
2041  // (long). If strictly less, then the conversion won't overflow.
2042  // We protect the test with an #ifdef ... #endif to avoid compiler
2043  // warnings like the following: "warning: comparison is always
2044  // false due to limited range of data type".
2045 #if UINT_MAX == LONG_MAX
2046  const long minLong = std::numeric_limits<long>::min ();
2047  const long maxLong = std::numeric_limits<long>::max ();
2048 
2049  // The two types have the same number of bits. Thus,
2050  // two's-complement arithmetic means that if casting from
2051  // unsigned int to long results in a negative number, it
2052  // overflowed. Otherwise, it didn't overflow (same number of
2053  // bits).
2055  static_cast<long> (t) < static_cast<long> (0),
2056  std::range_error,
2057  "Teuchos::ValueTypeConversionTraits<long, unsigned int>::safeConvert: "
2058  "Input unsigned int t = " << t << " is out of the valid range ["
2059  << minLong << ", " << maxLong << "] for conversion to long.");
2060 #endif // UINT_MAX == LONG_MAX
2061 
2062  return static_cast<long> (t);
2063  }
2064 };
2065 
2066 
2068 template<>
2069 class ValueTypeConversionTraits<unsigned int, long> {
2070 public:
2077  static unsigned int convert (const long t) {
2078  // Implicit conversion from long to unsigned int may cause
2079  // compiler warnings, but static_cast does not.
2080  return static_cast<unsigned int> (t);
2081  }
2082 
2084  static unsigned int safeConvert (const long t) {
2085  // On some platforms, sizeof(int) == sizeof(long). (This is the
2086  // "LLP64" model of Win64, which aims for backwards compatibility
2087  // with 32-bit code by making sizeof(int) == sizeof(long) == 4.)
2088  // In this case, conversion from long to unsigned int can't
2089  // overflow.
2090 
2091  // The C++ standard promises that sizeof (unsigned int) <= sizeof (long).
2092  if (sizeof (unsigned int) < sizeof (long)) {
2093  const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
2094 
2096  t < static_cast<long> (0) || t > static_cast<long> (maxInt),
2097  std::range_error,
2098  "Teuchos::ValueTypeConversionTraits<unsigned int, long>::safeConvert: "
2099  "Input long t = " << t << " is out of the valid range [0, "
2100  << maxInt << "] for conversion to unsigned int.");
2101  }
2102  // Implicit conversion from long to unsigned int may cause
2103  // compiler warnings, but static_cast does not.
2104  return static_cast<unsigned int> (t);
2105  }
2106 };
2107 
2108 
2110 template<>
2111 class ValueTypeConversionTraits<unsigned int, unsigned long> {
2112 public:
2119  static unsigned int convert (const unsigned long t) {
2120  // Implicit conversion from unsigned long to unsigned int may cause
2121  // compiler warnings, but static_cast does not.
2122  return static_cast<unsigned int> (t);
2123  }
2124 
2126  static unsigned int safeConvert (const unsigned long t) {
2127  const unsigned int minInt = 0; // Had better be, since it's unsigned.
2128  const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
2129 
2130  // t >= 0 by definition, because it is unsigned.
2132  t > static_cast<unsigned long> (maxInt),
2133  std::range_error,
2134  "Teuchos::ValueTypeConversionTraits<unsigned int, unsigned long>::safeConvert: "
2135  "Input unsigned long t = " << t << " is out of the valid range [" << minInt
2136  << ", " << maxInt << "] for conversion to unsigned int.");
2137 
2138  // Implicit conversion from unsigned long to unsigned int may
2139  // cause compiler warnings, but static_cast does not.
2140  return static_cast<unsigned int> (t);
2141  }
2142 };
2143 
2145 template<>
2146 class ValueTypeConversionTraits<unsigned short, unsigned long> {
2147 public:
2154  static unsigned short convert (const unsigned long t) {
2155  // Implicit conversion from unsigned long to unsigned short may cause
2156  // compiler warnings, but static_cast does not.
2157  return static_cast<unsigned short> (t);
2158  }
2159 
2161  static unsigned short safeConvert (const unsigned long t) {
2162  const unsigned short minShort = 0; // Had better be, since it's unsigned.
2163  const unsigned short maxShort = std::numeric_limits<unsigned short>::max ();
2164 
2165  // t >= 0 by definition, because it is unsigned.
2167  t > static_cast<unsigned long> (maxShort),
2168  std::range_error,
2169  "Teuchos::ValueTypeConversionTraits<unsigned short, unsigned long>::safeConvert: "
2170  "Input unsigned long t = " << t << " is out of the valid range [" << minShort
2171  << ", " << maxShort << "] for conversion to unsigned short.");
2172 
2173  // Implicit conversion from unsigned long to unsigned short may
2174  // cause compiler warnings, but static_cast does not.
2175  return static_cast<unsigned short> (t);
2176  }
2177 };
2178 
2180 template<>
2181 class ValueTypeConversionTraits<int, long long> {
2182 public:
2188  static int convert (const long long t) {
2189  // Implicit conversion from long long to int may cause compiler
2190  // warnings, but static_cast does not.
2191  return static_cast<int> (t);
2192  }
2193 
2195  static int safeConvert (const long long t) {
2196  const int minInt = std::numeric_limits<int>::min ();
2197  const int maxInt = std::numeric_limits<int>::max ();
2198 
2200  t < static_cast<long long> (minInt) ||
2201  t > static_cast<long long> (maxInt),
2202  std::range_error,
2203  "Teuchos::ValueTypeConversionTraits<int, long long>::safeConvert: "
2204  "Input long long t = " << t << " is out of the valid range [" << minInt
2205  << ", " << maxInt << "] for conversion to int.");
2206 
2207  // Implicit conversion from long long to int may cause compiler
2208  // warnings, but static_cast does not.
2209  return static_cast<int> (t);
2210  }
2211 };
2212 
2213 
2215 template<>
2216 class ValueTypeConversionTraits<unsigned int, long long> {
2217 public:
2224  static unsigned int convert (const long long t) {
2225  // Implicit conversion from long long to unsigned int may cause
2226  // compiler warnings, but static_cast does not.
2227  return static_cast<unsigned int> (t);
2228  }
2229 
2231  static unsigned int safeConvert (const long long t) {
2232  const unsigned int minInt = 0; // Had better be, because it's unsigned.
2233  const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
2234 
2236  t < static_cast<long long> (minInt) || t > static_cast<long long> (maxInt),
2237  std::range_error,
2238  "Teuchos::ValueTypeConversionTraits<unsigned int, long long>::safeConvert: "
2239  "Input long long t = " << t << " is out of the valid range [" << minInt
2240  << ", " << maxInt << "] for conversion to unsigned int.");
2241 
2242  // Implicit conversion from long long to unsigned int may cause
2243  // compiler warnings, but static_cast does not.
2244  return static_cast<unsigned int> (t);
2245  }
2246 };
2247 
2248 
2250 template<>
2251 class ValueTypeConversionTraits<int, unsigned long long> {
2252 public:
2258  static int convert (const unsigned long long t) {
2259  // Implicit conversion from unsigned long long to int may cause
2260  // compiler warnings, but static_cast does not.
2261  return static_cast<int> (t);
2262  }
2263 
2265  static int safeConvert (const unsigned long long t) {
2266  const int minInt = std::numeric_limits<int>::min ();
2267  const int maxInt = std::numeric_limits<int>::max ();
2268 
2269  // t >= 0 by definition, because it is unsigned.
2271  t > static_cast<unsigned long long> (maxInt),
2272  std::invalid_argument,
2273  "Teuchos::ValueTypeConversionTraits<int, unsigned long long>::safeConvert: "
2274  "Input unsigned long long t = " << t << " is out of the valid range [" << minInt
2275  << ", " << maxInt << "] for conversion to int.");
2276 
2277  // Implicit conversion from unsigned long long to int may cause
2278  // compiler warnings, but static_cast does not.
2279  return static_cast<int> (t);
2280  }
2281 };
2282 
2283 
2285 template<>
2286 class ValueTypeConversionTraits<unsigned int, unsigned long long> {
2287 public:
2294  static unsigned int convert (const unsigned long long t) {
2295  // Implicit conversion from unsigned long long to unsigned int may
2296  // cause compiler warnings, but static_cast does not.
2297  return static_cast<unsigned int> (t);
2298  }
2299 
2301  static unsigned int safeConvert (const unsigned long long t) {
2302  const unsigned int minInt = 0; // Had better be, since it's unsigned.
2303  const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
2304 
2305  // t >= 0 by definition, because it is unsigned.
2307  t > static_cast<unsigned long long> (maxInt),
2308  std::invalid_argument,
2309  "Teuchos::ValueTypeConversionTraits<unsigned int, unsigned long long>::safeConvert: "
2310  "Input unsigned long long t = " << t << " is out of the valid range [" << minInt
2311  << ", " << maxInt << "] for conversion to unsigned int.");
2312 
2313  // Implicit conversion from unsigned long long to unsigned int may
2314  // cause compiler warnings, but static_cast does not.
2315  return static_cast<unsigned int> (t);
2316  }
2317 };
2318 
2319 //
2320 // * Conversions from built-in integer types to built-in real-valued
2321 // floating-point types.
2322 //
2323 
2325 template<>
2326 class ValueTypeConversionTraits<float, long long> {
2327 public:
2333  static float convert (const long long t) {
2334  // Implicit conversion from long long to float may cause compiler
2335  // warnings, but static_cast does not.
2336  return static_cast<float> (t);
2337  }
2338 
2340  static float safeConvert (const long long t) {
2341  // std::numeric_limits<float>::min() gives the minimum _positive_
2342  // normalized value of type float. IEEE 754 floating-point values
2343  // can change sign just by flipping the sign bit, so the "most
2344  // negative" finite float is just the negative of the "most
2345  // positive" finite float.
2346  const float minFloat = -std::numeric_limits<float>::max ();
2347  const float maxFloat = std::numeric_limits<float>::max ();
2348 
2349  // mfh 16 Nov 2012: On my platform (gcc 4.7.2, Red Hat Linux 5,
2350  // Intel x86_64), first casting [minFloat,maxFloat] to long long
2351  // (so that the comparison only compares long long values)
2352  // gives different results in the comparison below than just
2353  // comparing t (as a long long) with minFloat and maxFloat. It
2354  // doesn't matter whether you use static_cast<long long> (...) or
2355  // (long long) (...) to do the cast: the original float interval
2356  // of [-3.40282e+38, 3.40282e+38] becomes [-9223372036854775808,
2357  // -9223372036854775808], which is obviously wrong.
2359  t < minFloat || t > maxFloat,
2360  std::range_error,
2361  "Teuchos::ValueTypeConversionTraits<float, long long>::safeConvert: "
2362  "Input long long t = " << t << " is out of the valid range [" << minFloat
2363  << ", " << maxFloat << "] for conversion to float.");
2364 
2365  // Implicit conversion from long long to float may cause compiler
2366  // warnings, but static_cast does not.
2367  return static_cast<float> (t);
2368  }
2369 };
2370 
2371 
2373 template<>
2374 class ValueTypeConversionTraits<float, unsigned long long> {
2375 public:
2381  static float convert (const unsigned long long t) {
2382  // Implicit conversion from unsigned long long to float may cause
2383  // compiler warnings, but static_cast does not.
2384  return static_cast<float> (t);
2385  }
2386 
2388  static float safeConvert (const unsigned long long t) {
2389  // std::numeric_limits<float>::min() gives the minimum _positive_
2390  // normalized value of type float. IEEE 754 floating-point values
2391  // can change sign just by flipping the sign bit, so the "most
2392  // negative" finite float is just the negative of the "most
2393  // positive" finite float.
2394  const float minFloat = -std::numeric_limits<float>::max ();
2395  const float maxFloat = std::numeric_limits<float>::max ();
2396 
2397  // t >= 0 by definition, because it is unsigned.
2398  //
2399  // mfh 16 Nov 2012: See my note above on the <float, long long>
2400  // specialization that explains why I don't cast maxFloat to
2401  // unsigned long long here.
2403  t > maxFloat,
2404  std::invalid_argument,
2405  "Teuchos::ValueTypeConversionTraits<float, unsigned long long>::safeConvert: "
2406  "Input unsigned long long t = " << t << " is out of the valid range [" << minFloat
2407  << ", " << maxFloat << "] for conversion to float.");
2408 
2409  // Implicit conversion from unsigned long long to float may cause
2410  // compiler warnings, but static_cast does not.
2411  return static_cast<float> (t);
2412  }
2413 };
2414 
2415 //
2416 // * Other conversions
2417 //
2418 
2420 template<int N>
2421 class ValueTypeConversionTraits<std::string, char[N]> {
2422 public:
2423  static std::string convert( const char t[] )
2424  { return std::string(t); }
2425  static std::string safeConvert( const char t[] )
2426  { return std::string(t); }
2427 };
2428 
2429 //
2430 // * Conversions from built-in integer types to std::complex<T>.
2431 //
2432 
2433 #ifdef HAVE_TEUCHOS_COMPLEX
2434 
2436 template<class RealType>
2437 class ValueTypeConversionTraits<std::complex<RealType>, short> {
2438 public:
2439  inline static std::complex<RealType> convert (const short t) {
2440  // Let RealType handle the conversion of the zero imaginary part.
2441  return std::complex<RealType> (t, as<RealType> (0));
2442  }
2443  static std::complex<RealType> safeConvert (const short t) {
2444  // Let RealType handle the conversion of the zero imaginary part.
2445  return std::complex<RealType> (t, asSafe<RealType> (0));
2446  }
2447 };
2448 
2450 template<class RealType>
2451 class ValueTypeConversionTraits<std::complex<RealType>, unsigned short> {
2452 public:
2453  inline static std::complex<RealType> convert (const unsigned short t) {
2454  // Let RealType handle the conversion of the zero imaginary part.
2455  return std::complex<RealType> (t, as<RealType> (0));
2456  }
2457  static std::complex<RealType> safeConvert (const unsigned short t) {
2458  // Let RealType handle the conversion of the zero imaginary part.
2459  return std::complex<RealType> (t, asSafe<RealType> (0));
2460  }
2461 };
2462 
2464 template<class RealType>
2465 class ValueTypeConversionTraits<std::complex<RealType>, int> {
2466 public:
2467  inline static std::complex<RealType> convert (const int t) {
2468  // Let RealType handle the conversion of the zero imaginary part.
2469  return std::complex<RealType> (t, as<RealType> (0));
2470  }
2471  static std::complex<RealType> safeConvert (const int t) {
2472  // Let RealType handle the conversion of the zero imaginary part.
2473  return std::complex<RealType> (t, asSafe<RealType> (0));
2474  }
2475 };
2476 
2478 template<class RealType>
2479 class ValueTypeConversionTraits<std::complex<RealType>, unsigned int> {
2480 public:
2481  inline static std::complex<RealType> convert (const unsigned int t) {
2482  // Let RealType handle the conversion of the zero imaginary part.
2483  return std::complex<RealType> (t, as<RealType> (0));
2484  }
2485  static std::complex<RealType> safeConvert (const unsigned int t) {
2486  // Let RealType handle the conversion of the zero imaginary part.
2487  return std::complex<RealType> (t, asSafe<RealType> (0));
2488  }
2489 };
2490 
2492 template<class RealType>
2493 class ValueTypeConversionTraits<std::complex<RealType>, long> {
2494 public:
2495  inline static std::complex<RealType> convert (const long t) {
2496  // Let RealType handle the conversion of the zero imaginary part.
2497  return std::complex<RealType> (t, as<RealType> (0));
2498  }
2499  static std::complex<RealType> safeConvert (const long t) {
2500  // Let RealType handle the conversion of the zero imaginary part.
2501  return std::complex<RealType> (t, asSafe<RealType> (0));
2502  }
2503 };
2504 
2506 template<class RealType>
2507 class ValueTypeConversionTraits<std::complex<RealType>, unsigned long> {
2508 public:
2509  inline static std::complex<RealType> convert (const unsigned long t) {
2510  // Let RealType handle the conversion of the zero imaginary part.
2511  return std::complex<RealType> (t, as<RealType> (0));
2512  }
2513  static std::complex<RealType> safeConvert (const unsigned long t) {
2514  // Let RealType handle the conversion of the zero imaginary part.
2515  return std::complex<RealType> (t, asSafe<RealType> (0));
2516  }
2517 };
2518 
2520 template<class RealType>
2521 class ValueTypeConversionTraits<std::complex<RealType>, long long> {
2522 public:
2523  inline static std::complex<RealType> convert (const long long t) {
2524  // Let RealType handle the conversion of the zero imaginary part.
2525  return std::complex<RealType> (t, as<RealType> (0));
2526  }
2527  static std::complex<RealType> safeConvert (const long long t) {
2528  // Let RealType handle the conversion of the zero imaginary part.
2529  return std::complex<RealType> (t, asSafe<RealType> (0));
2530  }
2531 };
2532 
2534 template<class RealType>
2535 class ValueTypeConversionTraits<std::complex<RealType>, unsigned long long> {
2536 public:
2537  inline static std::complex<RealType> convert (const unsigned long long t) {
2538  // Let RealType handle the conversion of the zero imaginary part.
2539  return std::complex<RealType> (t, as<RealType> (0));
2540  }
2541  static std::complex<RealType> safeConvert (const unsigned long long t) {
2542  // Let RealType handle the conversion of the zero imaginary part.
2543  return std::complex<RealType> (t, asSafe<RealType> (0));
2544  }
2545 };
2546 
2547 
2549 template<>
2550 class ValueTypeConversionTraits<std::complex<float>, std::complex<double> > {
2551 public:
2552  inline static std::complex<float> convert (const std::complex<double> t) {
2553  // Let double->float conversion handle real and imaginary part.
2554  return std::complex<float> (as<float> (t.real ()), as<float> (t.imag ()));
2555  }
2556  static std::complex<float> safeConvert (const std::complex<double> t) {
2557  // Let double->float conversion handle real and imaginary part.
2558  return std::complex<float> (asSafe<float> (t.real ()), asSafe<float> (t.imag ()));
2559  }
2560 };
2561 
2562 #endif // HAVE_TEUCHOS_COMPLEX
2563 
2564 //
2565 // * Conversions for dd_real and qd_real
2566 //
2567 
2568 #ifdef HAVE_TEUCHOS_QD
2569 
2571 template <>
2572 class ValueTypeConversionTraits<double, qd_real> {
2573 public:
2574  inline static double convert (const qd_real t) {
2575  return to_double (t);
2576  }
2577  static double safeConvert (const qd_real t) {
2578  // std::numeric_limits<double>::min() gives the minimum _positive_
2579  // normalized value of type double. IEEE 754 floating-point
2580  // values can change sign just by flipping the sign bit, so the
2581  // "most negative" finite double is just the negative of the "most
2582  // positive" finite double.
2583  const qd_real minVal = -std::numeric_limits<double>::max ();
2584  const qd_real maxVal = std::numeric_limits<double>::max ();
2585 
2587  t < minVal || t > maxVal,
2588  std::range_error,
2589  "Teuchos::ValueTypeConversionTraits<double, qd_real>::safeConvert: "
2590  "Input qd_real t = " << t << " is out of the valid range [" << minVal
2591  << ", " << maxVal << "] for conversion to double.");
2592 
2593  return to_double (t);
2594  }
2595 };
2596 
2598 template <>
2599 class ValueTypeConversionTraits<float, qd_real> {
2600 public:
2601  inline static float convert (const qd_real t) {
2602  // In a debug build, this should also test the double->float
2603  // conversion for overflow.
2604  return as<float> (to_double (t));
2605  }
2606 
2607  static float safeConvert (const qd_real t) {
2608  // std::numeric_limits<float>::min() gives the minimum _positive_
2609  // normalized value of type float. IEEE 754 floating-point
2610  // values can change sign just by flipping the sign bit, so the
2611  // "most negative" finite float is just the negative of the "most
2612  // positive" finite float.
2613  //
2614  // qd_real has a constructor for double, but not for float,
2615  // so we cast to double first.
2616  const qd_real minVal = static_cast<double> (-std::numeric_limits<float>::max ());
2617  const qd_real maxVal = static_cast<double> (std::numeric_limits<float>::max ());
2618 
2620  t < minVal || t > maxVal,
2621  std::range_error,
2622  "Teuchos::ValueTypeConversionTraits<float, qd_real>::safeConvert: "
2623  "Input qd_real t = " << t << " is out of the valid range [" << minVal
2624  << ", " << maxVal << "] for conversion to float.");
2625 
2626  // This should also test the double->float conversion for overflow.
2627  return asSafe<float> (to_double (t));
2628  }
2629 };
2630 
2632 template <>
2633 class ValueTypeConversionTraits<int, qd_real> {
2634 public:
2635  inline static int convert (const qd_real t) {
2636  return to_int (t);
2637  }
2638  static int safeConvert (const qd_real t) {
2639  // qd_real has a constructor for int.
2640  const qd_real minVal = std::numeric_limits<int>::min ();
2641  const qd_real maxVal = std::numeric_limits<int>::max ();
2642 
2644  t < minVal || t > maxVal,
2645  std::range_error,
2646  "Teuchos::ValueTypeConversionTraits<int, qd_real>::safeConvert: "
2647  "Input qd_real t = " << t << " is out of the valid range [" << minVal
2648  << ", " << maxVal << "] for conversion to int.");
2649  return to_int (t);
2650  }
2651 };
2652 
2654 template <>
2655 class ValueTypeConversionTraits<dd_real, qd_real> {
2656 public:
2657  inline static dd_real convert (const qd_real t) {
2658  return to_dd_real(t);
2659  }
2660  static dd_real safeConvert (const qd_real t) {
2661  // std::numeric_limits<dd_real>::min() gives the minimum
2662  // _positive_ (normalized? not sure what this means for dd_real --
2663  // mfh 14 Nov 2012) value of type dd_real. dd_real values are
2664  // built from two IEEE 754 doubles. This means they can change
2665  // sign just by flipping the sign bit, so the "most negative"
2666  // finite dd_real is just the negative of the "most positive"
2667  // finite dd_real.
2668  //
2669  // qd_real has a constructor for dd_real.
2670  const qd_real minVal = -std::numeric_limits<dd_real>::max ();
2671  const qd_real maxVal = std::numeric_limits<dd_real>::max ();
2672 
2674  t < minVal || t > maxVal,
2675  std::range_error,
2676  "Teuchos::ValueTypeConversionTraits<dd_real, qd_real>::safeConvert: "
2677  "Input qd_real t = " << t << " is out of the valid range [" << minVal
2678  << ", " << maxVal << "] for conversion to dd_real.");
2679 
2680  return to_dd_real (t);
2681  }
2682 };
2683 
2685 template <>
2686 class ValueTypeConversionTraits<double, dd_real> {
2687 public:
2688  inline static double convert (const dd_real t) {
2689  return to_double (t);
2690  }
2691  static double safeConvert (const dd_real t) {
2692  // std::numeric_limits<double>::min() gives the minimum _positive_
2693  // normalized value of type double. IEEE 754 floating-point
2694  // values can change sign just by flipping the sign bit, so the
2695  // "most negative" finite double is just the negative of the "most
2696  // positive" finite double.
2697  //
2698  // qd_real has a constructor for double.
2699  const dd_real minVal = -std::numeric_limits<double>::max ();
2700  const dd_real maxVal = std::numeric_limits<double>::max ();
2701 
2703  t < minVal || t > maxVal,
2704  std::range_error,
2705  "Teuchos::ValueTypeConversionTraits<double, dd_real>::safeConvert: "
2706  "Input dd_real t = " << t << " is out of the valid range [" << minVal
2707  << ", " << maxVal << "] for conversion to double.");
2708 
2709  return to_double (t);
2710  }
2711 };
2712 
2714 template <>
2715 class ValueTypeConversionTraits<float, dd_real> {
2716 public:
2717  inline static float convert (const dd_real t) {
2718  // This also checks for double->float overflow in a debug build.
2719  return as<float> (to_double (t));
2720  }
2721  static float safeConvert (const dd_real t) {
2722  // std::numeric_limits<float>::min() gives the minimum _positive_
2723  // normalized value of type float. IEEE 754 floating-point
2724  // values can change sign just by flipping the sign bit, so the
2725  // "most negative" finite float is just the negative of the "most
2726  // positive" finite float.
2727  //
2728  // dd_real has a constructor for double but not for float,
2729  // so we cast to double first.
2730  const dd_real minVal = static_cast<double> (-std::numeric_limits<float>::max ());
2731  const dd_real maxVal = static_cast<double> (std::numeric_limits<float>::max ());
2732 
2734  t < minVal || t > maxVal,
2735  std::range_error,
2736  "Teuchos::ValueTypeConversionTraits<float, dd_real>::safeConvert: "
2737  "Input dd_real t = " << t << " is out of the valid range [" << minVal
2738  << ", " << maxVal << "] for conversion to float.");
2739 
2740  // This also checks for double->float overflow.
2741  return as<float> (to_double (t));
2742  }
2743 };
2744 
2746 template <>
2747 class ValueTypeConversionTraits<int, dd_real> {
2748 public:
2749  inline static int convert (const dd_real t) {
2750  return to_int (t);
2751  }
2752  static int safeConvert (const dd_real t) {
2753  // dd_real has a constructor for int.
2754  const dd_real minVal = std::numeric_limits<int>::min ();
2755  const dd_real maxVal = std::numeric_limits<int>::max ();
2756 
2758  t < minVal || t > maxVal,
2759  std::range_error,
2760  "Teuchos::ValueTypeConversionTraits<int, dd_real>::safeConvert: "
2761  "Input dd_real t = " << t << " is out of the valid range [" << minVal
2762  << ", " << maxVal << "] for conversion to int.");
2763  return to_int (t);
2764  }
2765 };
2766 
2768 template <>
2769 class ValueTypeConversionTraits<qd_real, long unsigned int> {
2770 public:
2771  inline static qd_real convert( const long unsigned int t ) {
2772  // FIXME (mfh 14 Nov 2012): qd_real unfortunately lacks a
2773  // constructor or conversion function for conversions from
2774  // built-in integer types other than int. However, it does allow
2775  // reading in values from a string. We could use this to convert
2776  // from any type to qd_real, by first writing the value to an
2777  // std::ostringstream, then creating a qd_real from the resulting
2778  // string.
2779  return ValueTypeConversionTraits<qd_real,int>::convert(ValueTypeConversionTraits<int,long unsigned int>::convert(t));
2780  }
2781  inline static qd_real safeConvert( const long unsigned int t )
2782  { return ValueTypeConversionTraits<qd_real,int>::safeConvert(ValueTypeConversionTraits<int,long unsigned int>::safeConvert(t)); }
2783 };
2784 
2786 template <>
2787 class ValueTypeConversionTraits<dd_real, long unsigned int> {
2788 public:
2789  inline static dd_real convert( const long unsigned int t ) {
2790  // FIXME (mfh 14 Nov 2012): dd_real unfortunately lacks a
2791  // constructor or conversion function for conversions from
2792  // built-in integer types other than int. However, it does allow
2793  // reading in values from a string. We could use this to convert
2794  // from any type to dd_real, by first writing the value to an
2795  // std::ostringstream, then creating a dd_real from the resulting
2796  // string.
2797  return ValueTypeConversionTraits<dd_real,int>::convert(ValueTypeConversionTraits<int,long unsigned int>::convert(t));
2798  }
2799  inline static dd_real safeConvert( const long unsigned int t )
2800  { return ValueTypeConversionTraits<dd_real,int>::safeConvert(ValueTypeConversionTraits<int,long unsigned int>::safeConvert(t)); }
2801 };
2802 
2803 #endif // HAVE_TEUCHOS_QD
2804 
2805 // ToDo: Add more specializations as needed!
2806 
2807 template<class TypeTo, class TypeFrom>
2808 inline TypeTo as( const TypeFrom& t )
2809 {
2810 #ifdef HAVE_TEUCHOS_DEBUG
2812 #else
2814 #endif // HAVE_TEUCHOS_DEBUG
2815 }
2816 
2817 template<class TypeTo, class TypeFrom>
2818 inline TypeTo asSafe( const TypeFrom& t )
2819 {
2821 }
2822 
2823 } // end namespace Teuchos
2824 
2825 
2826 #endif // TEUCHOS_AS_HPP
static short convert(const int t)
Convert the given int to a short.
static unsigned int convert(const double t)
Convert the given double to an unsigned int.
static int safeConvert(const unsigned long t)
Convert from unsigned long to int, checking for overflow first.
static unsigned int convert(const float t)
Convert the given float to an unsigned int.
static unsigned long safeConvert(const float t)
Convert the given float to an unsigned long, checking first or under- or overflow.
static unsigned int convert(const unsigned long long t)
Convert the given unsigned long long to an unsigned int.
static unsigned long long convert(const long long t)
TypeTo operator()(const TypeFrom &t)
Definition: Teuchos_as.hpp:345
static long long safeConvert(const std::string &t)
Convert the given std::string to a long long, with checks.
Definition: Teuchos_as.hpp:667
static short safeConvert(const long t)
Convert from long to short, checking for overflow first.
static short safeConvert(const double t)
Convert the given double to a short, checking for overflow first.
static long long safeConvert(const unsigned long long t)
static OutType safeConvert(const std::string &t)
Definition: Teuchos_as.hpp:575
static float safeConvert(const long long t)
Convert from long long to float, checking for overflow first.
static short safeConvert(const float t)
Convert the given float to a short, checking for overflow first.
static int safeConvert(const std::string &t)
Convert the given std::string to an int, with checks.
Definition: Teuchos_as.hpp:837
static long safeConvert(const std::string &t)
Convert the given std::string to a long, with checks.
Definition: Teuchos_as.hpp:739
static long convert(const float t)
Convert the given float to an long.
static int convert(const long long t)
Convert the given long long to an int.
static unsigned short convert(const float t)
Convert the given float to an unsigned short.
TypeTo asSafe(const TypeFrom &t)
Convert from one value type to another, with validity checks if appropriate.
static unsigned int safeConvert(const std::string &t)
Convert the given std::string to an unsigned int, with checks.
Definition: Teuchos_as.hpp:882
static short convert(const std::string &t)
Convert the given std::string to a short.
Definition: Teuchos_as.hpp:932
static TypeTo safeConvert(const TypeFrom t)
Convert t from a TypeFrom object to a TypeTo object, with checks for validity.
Definition: Teuchos_as.hpp:157
static long double convert(const std::string &t)
Definition: Teuchos_as.hpp:636
static float safeConvert(const std::string &t)
Definition: Teuchos_as.hpp:620
static int safeConvert(const unsigned long long t)
Convert from unsigned long long to int, checking for overflow first.
static unsigned long safeConvert(const std::string &t)
Convert the given std::string to an unsigned long, with checks.
Definition: Teuchos_as.hpp:761
static unsigned long safeConvertToUnsignedLong(const std::string &t)
Convert the given std::string to an intermediate unsigned long, with checks.
Definition: Teuchos_as.hpp:855
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
static TypeTo convert(const TypeFrom t)
Convert t from a TypeFrom object to a TypeTo object.
Definition: Teuchos_as.hpp:150
static unsigned int convert(const long long t)
Convert the given long long to an unsigned int.
Teuchos header file which uses auto-configuration information to include necessary C++ headers...
static int convert(const std::string &t)
Convert the given std::string to an int.
Definition: Teuchos_as.hpp:842
static int convert(const float t)
Convert the given float to an int.
static long convert(const std::string &t)
Convert the given std::string to a long.
Definition: Teuchos_as.hpp:744
static long convert(const double t)
Convert the given double to long.
static unsigned long convert(const std::string &t)
Convert the given std::string to an unsigned long.
Definition: Teuchos_as.hpp:766
static int convert(const long t)
Convert the given long to an int.
static float safeConvert(const unsigned long long t)
Convert from unsigned long long to float, checking for overflow first.
static unsigned int convert(const unsigned long t)
Convert the given unsigned long to an unsigned int.
static int convert(const unsigned long long t)
Convert the given unsigned long long to an int.
static unsigned long long safeConvert(const std::string &t)
Convert the given std::string to an unsigned long long, with checks.
Definition: Teuchos_as.hpp:698
static long safeConvert(const double t)
Convert the given double to long, checking for overflow first.
static int safeConvert(const double t)
Convert the given double to an int, checking for overflow first.
static unsigned int safeConvert(const long long t)
Convert from long long to unsigned int, checking for overflow first.
static unsigned short safeConvert(const double t)
Convert the given double to an unsigned short, checking for overflow first.
static unsigned short safeConvert(const float t)
Convert the given float to an unsigned short, checking for overflow first.
static unsigned short convert(const unsigned long t)
Convert the given unsigned long to an unsigned short.
static unsigned short safeConvert(const unsigned long t)
Convert from unsigned long to unsigned short, checking for overflow first.
static short convert(const double t)
Convert the given double to a short.
static long safeConvert(const unsigned int t)
Convert from unsigned int to long, checking for overflow first.
static int safeConvert(const float t)
Convert the given float to an int.
static unsigned int safeConvert(const float t)
Convert the given float to an unsigned int, checking first or under- or overflow. ...
static short convert(const float t)
Convert the given float to a short.
static unsigned int safeConvert(const double t)
Convert the given double to an unsigned int, checking for overflow first.
static unsigned short convert(const std::string &t)
Convert the given std::string to an unsigned short.
Definition: Teuchos_as.hpp:977
static long safeConvertToLong(const std::string &t)
Convert the given std::string to an intermediate long, with checks.
Definition: Teuchos_as.hpp:810
static long safeConvert(const float t)
Convert the given float to an long, checking first for overflow.
Function object wrapper for as().
Definition: Teuchos_as.hpp:340
static unsigned int safeConvert(const long t)
Convert from long to unsigned int, checking for underflow or overflow first.
static int convert(const double t)
Convert the given double to an int.
static unsigned long long convert(const double t)
Convert the given double to unsigned long long.
static long long safeConvert(const float t)
Convert the given float to a long long, checking first for overflow.
static unsigned long long convert(const std::string &t)
Convert the given std::string to an unsigned long long.
Definition: Teuchos_as.hpp:722
static unsigned long safeConvertToUnsignedLong(const std::string &t)
Convert the given std::string to an intermediate unsigned long, with checks.
Definition: Teuchos_as.hpp:945
static long long convert(const unsigned long long t)
static long long convert(const std::string &t)
Convert the given std::string to a long long.
Definition: Teuchos_as.hpp:681
static long double safeConvert(const std::string &t)
Definition: Teuchos_as.hpp:646
static long long convert(const double t)
Convert the given double to long long.
Default traits class for all conversions between value types.
Definition: Teuchos_as.hpp:147
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
static unsigned int convert(const std::string &t)
Convert the given std::string to an unsigned int.
Definition: Teuchos_as.hpp:887
static long safeConvertToLong(const std::string &t)
Convert the given std::string to an intermediate long, with checks.
Definition: Teuchos_as.hpp:900
static short convert(const long t)
Convert the given long to a short.
static unsigned short safeConvert(const std::string &t)
Convert the given std::string to an unsigned short, with checks.
Definition: Teuchos_as.hpp:972
static float convert(const long long t)
Convert the given long long to a float.
static double safeConvert(const std::string &t)
Definition: Teuchos_as.hpp:600
static unsigned int safeConvert(const unsigned long t)
Convert from unsigned long to unsigned int, checking for overflow first.
Default traits class that just returns typeid(T).name().
static float convert(const unsigned long long t)
Convert the given unsigned long long to a float.
static int safeConvert(const long long t)
Convert from long long to int, checking for overflow first.
static int convert(const unsigned long t)
Convert the given unsigned long to an int.
static int safeConvert(const long t)
Convert from long to int, checking for overflow first.
static unsigned int safeConvert(const unsigned long long t)
Convert from unsigned long long to unsigned int, checking for overflow first.
static unsigned long convert(const double t)
Convert the given double to an unsigned long.
static long convert(const unsigned int t)
Convert the given unsigned int to a long.
static long long convert(const float t)
Convert the given float to a long long.
static unsigned long long safeConvert(const long long t)
static unsigned long safeConvert(const double t)
Convert the given double to an unsigned long, checking for overflow first.
static unsigned long long convert(const float t)
Convert the given float to an unsigned long long.
static short safeConvert(const int t)
Convert from int to short, checking for overflow first.
static long long safeConvert(const double t)
Convert the given double to long long, checking for overflow first.
static unsigned short convert(const double t)
Convert the given double to an unsigned short.
static short safeConvert(const std::string &t)
Convert the given std::string to a short, with checks.
Definition: Teuchos_as.hpp:927
static unsigned long convert(const float t)
Convert the given float to an unsigned long.
static unsigned long long safeConvert(const double t)
Convert the given double to unsigned long long, checking for overflow first.
static unsigned long long safeConvert(const float t)
Convert the given float to an unsigned long long, checking first for overflow.
static unsigned int convert(const long t)
Convert the given long to an unsigned int.