Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
Teuchos_as.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef TEUCHOS_AS_HPP
43 #define TEUCHOS_AS_HPP
44 
70 
71 #include "Teuchos_ConfigDefs.hpp"
72 #include "Teuchos_Assert.hpp"
73 #include <limits>
74 #include <cstdlib>
75 #include <cerrno>
76 #include <climits>
77 
78 #ifdef HAVE_TEUCHOS_COMPLEX
79 #include <complex>
80 #endif // HAVE_TEUCHOS_COMPLEX
81 
82 #ifdef HAVE_TEUCHOS_QD
83 #include <qd/qd_real.h>
84 #include <qd/dd_real.h>
85 #endif // HAVE_TEUCHOS_QD
86 
87 namespace Teuchos {
88 
89 
178 template<class TypeTo, class TypeFrom>
180 public:
182  static TypeTo convert (const TypeFrom t) {
183  // This default implementation is just an implicit conversion and
184  // may generate compiler warnings on dangerous conversions.
185  return t;
186  }
187 
189  static TypeTo safeConvert (const TypeFrom t) {
190  // This default implementation is just an implicit conversion and
191  // may generate compiler warnings on dangerous conversions. No
192  // runtime checking (e.g., for overflow) can be done by default;
193  // only specializations can define meaningful and portable
194  // run-time checks of conversions.
195  return t;
196  }
197 };
198 
286 template<class TypeTo, class TypeFrom>
287 inline TypeTo as( const TypeFrom& t );
288 
289 
355 template<class TypeTo, class TypeFrom>
356 inline TypeTo asSafe( const TypeFrom& t );
357 
358 
371 template <class TypeTo>
372 class asFunc {
373 public:
374  asFunc() {}
375 
376  template <class TypeFrom>
377  inline TypeTo operator()(const TypeFrom &t) {
378  return as<TypeTo>(t);
379  }
380 };
381 
382 
383 
384 namespace { // anonymous
385 
403  template<class IntType>
404  IntType
405  intToString (const std::string& t,
406  IntType (*rawConvert) (const char*, char**, int),
407  const char* intTypeName)
408  {
409  // We call the "raw" conversion function instead of using
410  // std::istringstream, because we want more detailed information
411  // in case of failure to convert. I have no idea what
412  // operator>>(std::istream&, unsigned long long&) does if it
413  // encounters an integer too long to fit in IntType, for example.
414  //
415  // mfh 13 Nov 2012: It's fair to assume that if you have "long
416  // long", then your implementation of the C standard library
417  // includes strtoul(). Ditto for "unsigned long long" and
418  // strtoull(). If this is not the case, we could include a
419  // configure-time test for these functions(), with a fall-back to
420  // an std::istringstream operator>> implementation.
421  char* endptr = NULL;
422  // Keep the pointer, because std::string doesn't necessarily
423  // guarantee that this is the same across calls to c_str(), does
424  // it? Or perhaps it does...
425  const char* t_ptr = t.c_str ();
426  // We preset errno to 0, to distinguish success or failure after
427  // calling strtoull. Most implementations of the C standard
428  // library written with threads in mind have errno be a macro that
429  // expands to thread-local storage. Thanks to the Linux
430  // documentation for strtol ("man 3 strtol", Red Hat Enterprise
431  // Linux 5) for advice with the following checks.
432  errno = 0;
433  const IntType val = rawConvert (t_ptr, &endptr, 10);
434 
435  const IntType minVal = std::numeric_limits<IntType>::min ();
436  const IntType maxVal = std::numeric_limits<IntType>::max ();
438  errno == ERANGE && (val == minVal || val == maxVal),
439  std::range_error,
440  "Teuchos::ValueTypeConversionTraits<" << intTypeName << ", std::string>::convert: "
441  "The integer value in the given string \"" << t << "\" overflows " << intTypeName << ".");
443  errno != 0 && val == 0,
444  std::invalid_argument,
445  "Teuchos::ValueTypeConversionTraits<" << intTypeName << ", std::string>::convert: "
446  "The conversion function was unable to convert the given string \"" << t << "\" to " << intTypeName << ".");
448  endptr == t_ptr, // See above discussion of c_str().
449  std::invalid_argument,
450  "Teuchos::ValueTypeConversionTraits<" << intTypeName << ", std::string>::convert: "
451  "The conversion function was unable to read any integer digits from the given string "
452  "\"" << t << "\".");
453  return val;
454  }
455 
467  template<class OutputRealType, class InputRealType>
468  OutputRealType
469  realToReal (const InputRealType& x, const bool doBoundsChecking)
470  {
472 
473  if (doBoundsChecking) {
474  // For floating-point types T, std::numeric_limits<T>::min()
475  // returns the smallest positive value. IEEE 754 types have a
476  // sign bit, so the largest-magnitude negative value is the
477  // negative of the largest-magnitude positive value.
478  const OutputRealType minVal = -std::numeric_limits<OutputRealType>::max ();
479  const OutputRealType maxVal = std::numeric_limits<OutputRealType>::max ();
480 
481  // NaN is neither less than nor greater than anything. We just
482  // let it pass through, per the rules for propagation of silent
483  // NaN. (Signaling NaN will signal, but that's OK.)
485  x < minVal || x > maxVal,
486  std::range_error,
487  "realToReal<" << TypeNameTraits<OutputRealType>::name () << ", "
489  "Input value x = " << x << " is out of the valid range [" << minVal
490  << ", " << maxVal << "] for conversion to the output type.");
491  }
492 
493  // Call as() and not static_cast, because there might not
494  // necessarily be a conversion defined between the two types,
495  // other than via as(). Definitely don't call asSafe(), because
496  // that could cause infinite recursion.
497  return as<OutputRealType> (x);
498  }
499 
500 
525  template<class RealType>
526  RealType
527  stringToReal (const std::string& t,
528  RealType (*rawConvert) (const char*, char**),
529  const char* realTypeName)
530  {
531  if (rawConvert == NULL) {
532  std::istringstream in (t);
533  RealType out;
534  in >> out;
535  return out;
536  }
537  else {
538  char* endptr = NULL;
539  // Keep the pointer, because std::string doesn't necessarily
540  // guarantee that this is the same across calls to c_str(), does
541  // it? Or perhaps it does...
542  const char* t_ptr = t.c_str ();
543  // We preset errno to 0, to distinguish success or failure after
544  // calling strtoull. Most implementations of the C standard
545  // library written with threads in mind have errno be a macro that
546  // expands to thread-local storage. Thanks to the Linux
547  // documentation for strtod ("man 3 strtod", Red Hat Enterprise
548  // Linux 5) for advice with the following checks.
549  errno = 0;
550  const RealType val = rawConvert (t_ptr, &endptr);
551 
553  errno == ERANGE && (val != 0),
554  std::range_error,
555  "Teuchos::ValueTypeConversionTraits<" << realTypeName
556  << ", std::string>::convert: "
557  "The value in the given string \"" << t << "\" overflows "
558  << realTypeName << ".");
559  //
560  // mfh 20 Nov 2012: Should we treat underflow as an error?
561  //
563  errno == ERANGE && val == 0,
564  std::invalid_argument,
565  "Teuchos::ValueTypeConversionTraits<" << realTypeName
566  << ", std::string>::convert: "
567  "The value in the given string \"" << t << "\" underflows "
568  << realTypeName << ".");
570  endptr == t_ptr, // See above discussion of c_str().
571  std::invalid_argument,
572  "Teuchos::ValueTypeConversionTraits<" << realTypeName
573  << ", std::string>::convert: "
574  "The conversion function was unable to read any floating-point data "
575  "from the given string \"" << t << "\".");
576  return val;
577  }
578  }
579 
580 } // namespace (anonymous)
581 
582 
583 //
584 // Standard specializations of ValueTypeConversionTraits
585 //
586 
587 //
588 // * Partial specialization for conversion from std::string to any type T.
589 // There are full specializations for specific types T below.
590 //
591 
604 template<class OutType>
605 class ValueTypeConversionTraits<OutType, std::string> {
606 public:
607  static OutType safeConvert (const std::string& t) {
608  return convert (t);
609  }
610 
611  static OutType convert (const std::string& t) {
612  std::istringstream in (t);
613  OutType out;
614  in >> out;
615  return out;
616  }
617 };
618 
619 //
620 // * Specializations for conversions from std::string to build-in
621 // real-valued floating-point types.
622 //
623 
625 template<>
626 class ValueTypeConversionTraits<double, std::string> {
627 public:
628  static double convert (const std::string& t) {
629  return stringToReal<double> (t, &strtod, "double");
630  }
631 
632  static double safeConvert (const std::string& t) {
633  return stringToReal<double> (t, &strtod, "double");
634  }
635 };
636 
638 template<>
639 class ValueTypeConversionTraits<float, std::string> {
640 public:
641  static float convert (const std::string& t) {
642 #ifdef _ISOC99_SOURCE
643  return stringToReal<float> (t, &strtof, "float");
644 #else
645  // strtof is new in C99. If you don't have it, just use strtod
646  // and convert the resulting double to float.
647  const double d = stringToReal<double> (t, &strtod, "double");
648  return realToReal<float, double> (d, false);
649 #endif // _ISOC99_SOURCE
650  }
651 
652  static float safeConvert (const std::string& t) {
653 #ifdef _ISOC99_SOURCE
654  return stringToReal<float> (t, &strtof, "float");
655 #else
656  // strtof is new in C99. If you don't have it, just use strtod
657  // and convert the resulting double to float.
658  const double d = stringToReal<double> (t, &strtod, "double");
659  return realToReal<float, double> (d, true);
660 #endif // _ISOC99_SOURCE
661  }
662 };
663 
665 template<>
666 class ValueTypeConversionTraits<long double, std::string> {
667 public:
668  static long double convert (const std::string& t) {
669 #ifdef _ISOC99_SOURCE
670  return stringToReal<long double> (t, &strtold, "long double");
671 #else
672  // strtof is new in C99. If you don't have it, just use
673  // operator>>(std::istream&, long double&).
674  return stringToReal<long double> (t, NULL, "long double");
675 #endif // _ISOC99_SOURCE
676  }
677 
678  static long double safeConvert (const std::string& t) {
679  return convert (t);
680  }
681 };
682 
683 
684 //
685 // * Specializations for conversions from std::string to build-in integer types.
686 //
687 
688 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
689 
693 template<>
694 class ValueTypeConversionTraits<long long, std::string> {
695 public:
701  static long long safeConvert (const std::string& t) {
702 #if defined(_MSC_VER)
703  // Windows does not implement strtoull, so we resort to a
704  // fallback. Thanks to Ross Bartlett for pointing out _strtoi64.
705  // See the MSDN reference [last accessed 21 Mar 2013]:
706  //
707  // http://msdn.microsoft.com/en-us/library/h80404d3%28v=vs.80%29.aspx
708  return intToString<long long> (t, &_strtoi64, "long long");
709 #else
710  return intToString<long long> (t, &strtoll, "long long");
711 #endif // defined(_MSC_VER)
712  }
713 
715  static long long convert (const std::string& t) {
716  return safeConvert (t);
717  }
718 };
719 
720 
724 template<>
725 class ValueTypeConversionTraits<unsigned long long, std::string> {
726 public:
732  static unsigned long long safeConvert (const std::string& t) {
733 #if defined(_MSC_VER)
734  // Windows does not implement strtoull, so we resort to a
735  // fallback. The fallback does not know how to check for under-
736  // or overflow. Alas, Windows does not seem to have an equivalent
737  // of _strtoi64 for unsigned long long.
738  const char intTypeName[] = "unsigned long long";
739  std::istringstream istr (t);
740  unsigned long long i = 0;
741  istr >> i;
743  ! istr, std::invalid_argument,
744  "Teuchos::ValueTypeConversionTraits<" << intTypeName << ", std::string>::"
745  "convert: Unable to convert the given string \"" << t << "\" to " <<
746  intTypeName << ". Windows lacks strtoull(), so we had to resort to a "
747  "fall-back conversion. The fall-back method does not know how to test "
748  "for overflow.");
749  return i;
750 #else
751  return intToString<unsigned long long> (t, &strtoull, "unsigned long long");
752 #endif // defined(_MSC_VER)
753  }
754 
756  static unsigned long long convert (const std::string& t) {
757  return safeConvert (t);
758  }
759 };
760 
761 #endif // HAVE_TEUCHOS_LONG_LONG_INT
762 
763 
767 template<>
768 class ValueTypeConversionTraits<long, std::string> {
769 public:
775  static long safeConvert (const std::string& t) {
776  return intToString<long> (t, &strtol, "long");
777  }
778 
780  static long convert (const std::string& t) {
781  return safeConvert (t);
782  }
783 };
784 
785 
789 template<>
790 class ValueTypeConversionTraits<unsigned long, std::string> {
791 public:
797  static unsigned long safeConvert (const std::string& t) {
798  return intToString<unsigned long> (t, &strtoul, "unsigned long");
799  }
800 
802  static unsigned long convert (const std::string& t) {
803  return safeConvert (t);
804  }
805 };
806 
807 
808 // Windows size_t is not unsigned long(32 bit), but unsigned long long(64 bit)
809 #ifdef HAVE_TEUCHOS___INT64
810 template<>
814 class ValueTypeConversionTraits<unsigned __int64, std::string> {
815 public:
821  static unsigned __int64 safeConvert(const std::string& t) {
822  unsigned __int64 output;
823  std::istringstream stream(t);
824  stream >> output;
825  return output;
826  }
827 
829  static unsigned __int64 convert(const std::string& t) {
830  unsigned __int64 output;
831  std::istringstream stream(t);
832  stream >> output;
833  return output;
834  }
835 };
836 #endif // HAVE_TEUCHOS___INT64
837 
838 
842 template<>
843 class ValueTypeConversionTraits<int, std::string> {
844 private:
846  static long safeConvertToLong (const std::string& t) {
847  long val = 0;
848  try {
850  } catch (std::range_error&) {
852  true,
853  std::range_error,
854  "Teuchos::ValueTypeConversionTraits<int, std::string>::convert: "
855  "The given std::string \"" << t << "\" is too big to fit into long, so there is no way it could fit into int.");
856  } catch (std::invalid_argument& e) {
858  true,
859  std::invalid_argument,
860  "Teuchos::ValueTypeConversionTraits<int, std::string>::convert: "
861  "Intermediate conversion from std::string to long failed, with the following error message: "
862  << e.what ());
863  }
864  return val;
865  }
866 
867 public:
873  static int safeConvert (const std::string& t) {
874  return asSafe<int> (safeConvertToLong (t));
875  }
876 
878  static int convert (const std::string& t) {
879  return as<int> (safeConvertToLong (t));
880  }
881 };
882 
883 
887 template<>
888 class ValueTypeConversionTraits<unsigned int, std::string> {
889 private:
891  static unsigned long safeConvertToUnsignedLong (const std::string& t) {
892  unsigned long val = 0;
893  try {
894  val = as<unsigned long> (t);
895  } catch (std::range_error&) {
897  true,
898  std::range_error,
899  "Teuchos::ValueTypeConversionTraits<unsigned int, std::string>::convert: "
900  "The given std::string \"" << t << "\" is too big to fit into unsigned long, so there is no way it could fit into unsigned int.");
901  } catch (std::invalid_argument& e) {
903  true,
904  std::invalid_argument,
905  "Teuchos::ValueTypeConversionTraits<unsigned int, std::string>::convert: "
906  "Intermediate conversion from std::string to unsigned long failed, with the following error message: "
907  << e.what ());
908  }
909  return val;
910  }
911 
912 public:
918  static unsigned int safeConvert (const std::string& t) {
919  return asSafe<unsigned int> (safeConvertToUnsignedLong (t));
920  }
921 
923  static unsigned int convert (const std::string& t) {
924  return as<unsigned int> (safeConvertToUnsignedLong (t));
925  }
926 };
927 
928 
932 template<>
933 class ValueTypeConversionTraits<short, std::string> {
934 private:
936  static long safeConvertToLong (const std::string& t) {
937  long val = 0;
938  try {
940  } catch (std::range_error&) {
942  true,
943  std::range_error,
944  "Teuchos::ValueTypeConversionTraits<short, std::string>::convert: "
945  "The given std::string \"" << t << "\" is too big to fit into long, so there is no way it could fit into short.");
946  } catch (std::invalid_argument& e) {
948  true,
949  std::invalid_argument,
950  "Teuchos::ValueTypeConversionTraits<short, std::string>::convert: "
951  "Intermediate conversion from std::string to long failed, with the following error message: "
952  << e.what ());
953  }
954  return val;
955  }
956 
957 public:
963  static short safeConvert (const std::string& t) {
964  return asSafe<short> (safeConvertToLong (t));
965  }
966 
968  static short convert (const std::string& t) {
969  return as<short> (safeConvertToLong (t));
970  }
971 };
972 
973 
977 template<>
978 class ValueTypeConversionTraits<unsigned short, std::string> {
979 private:
981  static unsigned long safeConvertToUnsignedLong (const std::string& t) {
982  unsigned long val = 0;
983  try {
984  val = as<unsigned long> (t);
985  } catch (std::range_error&) {
987  true,
988  std::range_error,
989  "Teuchos::ValueTypeConversionTraits<unsigned short, std::string>::convert: "
990  "The given std::string \"" << t << "\" is too big to fit into unsigned long, so there is no way it could fit into unsigned short.");
991  } catch (std::invalid_argument& e) {
993  true,
994  std::invalid_argument,
995  "Teuchos::ValueTypeConversionTraits<unsigned short, std::string>::convert: "
996  "Intermediate conversion from std::string to unsigned long failed, with the following error message: "
997  << e.what ());
998  }
999  return val;
1000  }
1001 
1002 public:
1008  static unsigned short safeConvert (const std::string& t) {
1009  return asSafe<unsigned short> (safeConvertToUnsignedLong (t));
1010  }
1011 
1013  static unsigned short convert (const std::string& t) {
1014  return as<unsigned short> (safeConvertToUnsignedLong (t));
1015  }
1016 };
1017 
1018 //
1019 // * Specializations for conversions between built-in real-valued
1020 // floating-point types (like float and double).
1021 //
1022 
1024 template<>
1025 class ValueTypeConversionTraits<float, double> {
1026 public:
1027  static float safeConvert (const 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, double>::safeConvert: "
1046  "Input 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 double t) {
1054  return static_cast<float> (t);
1055  }
1056 };
1057 
1058 
1060 template<>
1061 class ValueTypeConversionTraits<float, long double> {
1062 public:
1063  static float 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 float minVal = -std::numeric_limits<float>::max ();
1073  const float maxVal = std::numeric_limits<float>::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<float, long double>::safeConvert: "
1082  "Input long double t = " << t << " is out of the valid range [" << minVal
1083  << ", " << maxVal << "] for conversion to float.");
1084 #endif // 0
1085 
1086  return static_cast<float> (t);
1087  }
1088 
1089  static float convert (const long double t) {
1090  return static_cast<float> (t);
1091  }
1092 };
1093 
1094 
1096 template<>
1097 class ValueTypeConversionTraits<double, long double> {
1098 public:
1099  static double safeConvert (const long double t) {
1100  // mfh 25 Nov 2012: Disabling bounds checking, in favor of IEEE
1101  // 754 overflow semantics. Users who want bounds checking should
1102  // set the appropriate trap.
1103 #if 0
1104  // For floating-point types T, std::numeric_limits<T>::min()
1105  // returns the smallest positive value. IEEE 754 types have a
1106  // sign bit, so the largest-magnitude negative value is the
1107  // negative of the largest-magnitude positive value.
1108  const double minVal = -std::numeric_limits<double>::max ();
1109  const double maxVal = std::numeric_limits<double>::max ();
1110 
1111  // NaN is neither less than nor greater than anything. We just
1112  // let it pass through, per the rules for propagation of silent
1113  // NaN. (Signaling NaN will signal, but that's OK.)
1115  t < minVal || t > maxVal,
1116  std::range_error,
1117  "Teuchos::ValueTypeConversionTraits<double, long double>::safeConvert: "
1118  "Input long double t = " << t << " is out of the valid range [" << minVal
1119  << ", " << maxVal << "] for conversion to double.");
1120 #endif // 0
1121 
1122  return static_cast<double> (t);
1123  }
1124 
1125  static double convert (const long double t) {
1126  return static_cast<double> (t);
1127  }
1128 };
1129 
1130 
1131 //
1132 // * Specializations for conversions from built-in real-valued
1133 // floating-point types (float and double) to build-in integer
1134 // types.
1135 //
1136 
1138 template<>
1139 class ValueTypeConversionTraits<short, double> {
1140 public:
1146  static short convert (const double t) {
1147  // Implicit conversion may cause compiler warnings, but
1148  // static_cast does not.
1149  return static_cast<short> (t);
1150  }
1151 
1153  static short safeConvert (const double t) {
1154  const short minVal = std::numeric_limits<short>::min ();
1155  const short maxVal = std::numeric_limits<short>::max ();
1156 
1157  // Cases:
1158  // 1. sizeof(short) < sizeof(double) == 8
1159  // 2. sizeof(short) == sizeof(double) == 8
1160  // 3. sizeof(short) > sizeof(double) == 8
1161  //
1162  // Overflow when converting from double to short is possible only
1163  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1164  // 2 and 3, but safeConvert() only cares about overflow, not
1165  // rounding. In Case 3, casting minVal or maxVal to double in
1166  // this case could result in overflow. Thus, we only do the test
1167  // for Case 1.
1168  //
1169  // All three cases are legal according to both C++03 and C99.
1170  // However, I (mfh 15 Nov 2012) have never encountered Cases 2 and
1171  // 3.
1172  if (sizeof (short) < sizeof (double)) {
1174  t < minVal || t > maxVal,
1175  std::range_error,
1176  "Teuchos::ValueTypeConversionTraits<short, double>::safeConvert: "
1177  "Input double t = " << t << " is out of the valid range [" << minVal
1178  << ", " << maxVal << "] for conversion to short.");
1179  }
1180  return static_cast<short> (t);
1181  }
1182 };
1183 
1184 
1186 template<>
1187 class ValueTypeConversionTraits<unsigned short, double> {
1188 public:
1190  static unsigned short convert (const double t) {
1191  // Implicit conversion may cause compiler warnings, but
1192  // static_cast does not.
1193  return static_cast<unsigned short> (t);
1194  }
1195 
1197  static unsigned short safeConvert (const double t) {
1198  const unsigned short minVal = 0;
1199  const unsigned short maxVal = std::numeric_limits<unsigned short>::max ();
1200 
1202  t < minVal || t > maxVal,
1203  std::range_error,
1204  "Teuchos::ValueTypeConversionTraits<unsigned short, double>::safeConvert: "
1205  "Input double t = " << t << " is out of the valid range [" << minVal
1206  << ", " << maxVal << "] for conversion to unsigned short.");
1207 
1208  return static_cast<unsigned short> (t);
1209  }
1210 };
1211 
1212 
1214 template<>
1215 class ValueTypeConversionTraits<int, double> {
1216 public:
1222  static int convert (const double t) {
1223  // Implicit conversion from double to int causes compiler
1224  // warnings, but static_cast does not.
1225  return static_cast<int> (t);
1226  }
1227 
1229  static int safeConvert (const double t) {
1230  const int minVal = std::numeric_limits<int>::min ();
1231  const int maxVal = std::numeric_limits<int>::max ();
1232 
1233  // Cases:
1234  // 1. sizeof(int) < sizeof(double) == 8
1235  // 2. sizeof(int) == sizeof(double) == 8
1236  // 3. sizeof(int) > sizeof(double) == 8
1237  //
1238  // Overflow when converting from double to int is possible only
1239  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1240  // 2 and 3, but safeConvert() only cares about overflow, not
1241  // rounding. Case 3 is quite rare, but casting minVal or maxVal
1242  // to double in this case could result in overflow. Thus, we only
1243  // do the cast for Case 1.
1244  if (sizeof (int) < sizeof (double)) {
1246  t < minVal || t > maxVal,
1247  std::range_error,
1248  "Teuchos::ValueTypeConversionTraits<int, double>::safeConvert: "
1249  "Input double t = " << t << " is out of the valid range [" << minVal
1250  << ", " << maxVal << "] for conversion to int.");
1251  }
1252  return static_cast<int> (t);
1253  }
1254 };
1255 
1256 
1258 template<>
1259 class ValueTypeConversionTraits<unsigned int, double> {
1260 public:
1262  static unsigned int convert (const double t) {
1263  // Implicit conversion may cause compiler warnings, but
1264  // static_cast does not.
1265  return static_cast<unsigned int> (t);
1266  }
1267 
1269  static unsigned int safeConvert (const double t) {
1270  const unsigned int minVal = 0;
1271  const unsigned int maxVal = std::numeric_limits<unsigned int>::max ();
1272 
1274  t < minVal || t > maxVal,
1275  std::range_error,
1276  "Teuchos::ValueTypeConversionTraits<unsigned int, double>::safeConvert: "
1277  "Input double t = " << t << " is out of the valid range [" << minVal
1278  << ", " << maxVal << "] for conversion to unsigned int.");
1279 
1280  return static_cast<unsigned int> (t);
1281  }
1282 };
1283 
1284 
1286 template<>
1287 class ValueTypeConversionTraits<long, double> {
1288 public:
1290  static long convert (const double t) {
1291  // Implicit conversion may cause compiler warnings, but
1292  // static_cast does not.
1293  return static_cast<long> (t);
1294  }
1295 
1297  static long safeConvert (const double t) {
1298  const long minVal = std::numeric_limits<long>::min ();
1299  const long maxVal = std::numeric_limits<long>::max ();
1300 
1301  // Cases:
1302  // 1. sizeof(long) < sizeof(double) == 8
1303  // 2. sizeof(long) == sizeof(double) == 8
1304  // 3. sizeof(long) > sizeof(double) == 8
1305  //
1306  // Overflow when converting from double to long is possible only
1307  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1308  // 2 and 3, but safeConvert() only cares about overflow, not
1309  // rounding. In Case 3, casting minVal or maxVal to double could
1310  // result in overflow. Thus, we only test for Case 1.
1311  //
1312  // Case 1 is entirely possible, for example on Win64 (an
1313  // implementation of the LLP64 integer model, on which
1314  // sizeof(long) == 4, and sizeof(long long) == sizeof(void*) ==
1315  // 8).
1316  if (sizeof (long) < sizeof (double)) {
1318  t < minVal || t > maxVal,
1319  std::range_error,
1320  "Teuchos::ValueTypeConversionTraits<long, double>::safeConvert: "
1321  "Input double t = " << t << " is out of the valid range [" << minVal
1322  << ", " << maxVal << "] for conversion to long.");
1323  }
1324  return static_cast<long> (t);
1325  }
1326 };
1327 
1328 
1330 template<>
1331 class ValueTypeConversionTraits<unsigned long, double> {
1332 public:
1334  static unsigned long convert (const double t) {
1335  // Implicit conversion may cause compiler warnings, but
1336  // static_cast does not.
1337  return static_cast<unsigned long> (t);
1338  }
1339 
1341  static unsigned long safeConvert (const double t) {
1342  const unsigned long minVal = 0;
1343  const unsigned long maxVal = std::numeric_limits<unsigned long>::max ();
1344 
1346  t < minVal || t > maxVal,
1347  std::range_error,
1348  "Teuchos::ValueTypeConversionTraits<unsigned long, double>::safeConvert: "
1349  "Input double t = " << t << " is out of the valid range [" << minVal
1350  << ", " << maxVal << "] for conversion to unsigned long.");
1351 
1352  return static_cast<unsigned long> (t);
1353  }
1354 };
1355 
1356 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
1357 
1359 template<>
1360 class ValueTypeConversionTraits<long long, double> {
1361 public:
1363  static long long convert (const double t) {
1364  // Implicit conversion may cause compiler warnings, but
1365  // static_cast does not.
1366  return static_cast<long long> (t);
1367  }
1368 
1370  static long long safeConvert (const double t) {
1371  // Cases:
1372  // 1. sizeof(long long) < sizeof(double) == 8
1373  // 2. sizeof(long long) == sizeof(double) == 8
1374  // 3. sizeof(long long) > sizeof(double) == 8
1375  //
1376  // C99 (which defines long long) prohibits Case 1. Case 2 could
1377  // result in loss of accuracy (rounding), but safeConvert() only
1378  // cares about overflow, not rounding. In Case 3, casting minVal
1379  // or maxVal to double could result in overflow. Thus, we don't
1380  // need to check anything here.
1381  return static_cast<long long> (t);
1382  }
1383 };
1384 
1385 
1387 template<>
1388 class ValueTypeConversionTraits<unsigned long long, double> {
1389 public:
1391  static unsigned long long convert (const double t) {
1392  // Implicit conversion may cause compiler warnings, but
1393  // static_cast does not.
1394  return static_cast<unsigned long long> (t);
1395  }
1396 
1398  static unsigned long long safeConvert (const double t) {
1399  const unsigned long long minVal = 0; // unsigned, so min value is 0.
1400  const unsigned long long maxVal = std::numeric_limits<unsigned long long>::max ();
1401 
1403  t < minVal || t > maxVal,
1404  std::range_error,
1405  "Teuchos::ValueTypeConversionTraits<unsigned long long, double>::safeConvert: "
1406  "Input double t = " << t << " is out of the valid range [" << minVal
1407  << ", " << maxVal << "] for conversion to unsigned long long.");
1408 
1409  return static_cast<unsigned long long> (t);
1410  }
1411 };
1412 
1413 #endif // HAVE_TEUCHOS_LONG_LONG_INT
1414 
1415 
1417 template<>
1418 class ValueTypeConversionTraits<short, float> {
1419 public:
1425  static short convert (const float t) {
1426  // Implicit conversion may cause compiler warnings, but
1427  // static_cast does not.
1428  return static_cast<short> (t);
1429  }
1430 
1432  static short safeConvert (const float t) {
1433  const short minVal = std::numeric_limits<short>::min ();
1434  const short maxVal = std::numeric_limits<short>::max ();
1435 
1436  // Cases:
1437  // 1. sizeof(short) < sizeof(float) == 4
1438  // 2. sizeof(short) == sizeof(float) == 4
1439  // 3. sizeof(short) > sizeof(float) == 4
1440  //
1441  // Overflow when converting from float to short is possible only
1442  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1443  // 2 and 3, but safeConvert() only cares about overflow, not
1444  // rounding. In Case 3, casting minVal or maxVal to float in this
1445  // case could result in overflow. Thus, we only do the test for
1446  // Case 1.
1447  //
1448  // All three cases are legal according to both C++03 and C99. I
1449  // (mfh 15 Nov 2012) think Case 1 is the most common, but Case 2
1450  // is certainly reasonable. (For example, some hardware prefers
1451  // to work only with 32-bit words, so _every_ built-in type has
1452  // size a multiple of 4 bytes.)
1453  if (sizeof (short) < sizeof (float)) {
1455  t < minVal || t > maxVal,
1456  std::range_error,
1457  "Teuchos::ValueTypeConversionTraits<short, float>::safeConvert: "
1458  "Input float t = " << t << " is out of the valid range [" << minVal
1459  << ", " << maxVal << "] for conversion to short.");
1460  }
1461 
1462  return static_cast<short> (t);
1463  }
1464 };
1465 
1466 
1468 template<>
1469 class ValueTypeConversionTraits<unsigned short, float> {
1470 public:
1472  static unsigned short convert (const float t) {
1473  // Implicit conversion may cause compiler warnings, but
1474  // static_cast does not.
1475  return static_cast<unsigned short> (t);
1476  }
1477 
1479  static unsigned short safeConvert (const float t) {
1480  const unsigned short minVal = 0;
1481  const unsigned short maxVal = std::numeric_limits<unsigned short>::max ();
1482 
1484  t < minVal || t > maxVal,
1485  std::range_error,
1486  "Teuchos::ValueTypeConversionTraits<unsigned short, float>::safeConvert: "
1487  "Input float t = " << t << " is out of the valid range [" << minVal
1488  << ", " << maxVal << "] for conversion to unsigned short.");
1489 
1490  return static_cast<unsigned short> (t);
1491  }
1492 };
1493 
1494 
1496 template<>
1497 class ValueTypeConversionTraits<int, float> {
1498 public:
1500  static int convert (const float t) {
1501  // Implicit conversion from float to int may cause compiler
1502  // warnings, but static_cast does not. Overflow here would mean
1503  // that sizeof(int) < sizeof(float), which is legal, but unlikely
1504  // on platforms of interest.
1505  return static_cast<int> (t);
1506  }
1507 
1509  static int safeConvert (const float t) {
1510  const int minVal = std::numeric_limits<int>::min ();
1511  const int maxVal = std::numeric_limits<int>::max ();
1512 
1513  // Cases:
1514  // 1. sizeof(int) < sizeof(float) == 4
1515  // 2. sizeof(int) == sizeof(float) == 4
1516  // 3. sizeof(int) > sizeof(float) == 4
1517  //
1518  // Overflow when converting from float to int is possible only for
1519  // Case 1. Loss of accuracy (rounding) is possible for Cases 2
1520  // and 3, but safeConvert() only cares about overflow, not
1521  // rounding. Case 3 is rare, but casting minVal or maxVal to
1522  // float in this case could result in loss of accuracy
1523  // (sizeof(int) == 8 or 16) or overflow (sizeof(int) > 16). Thus,
1524  // we only do the test for Case 1.
1525  if (sizeof (int) < sizeof (float)) {
1527  t < minVal || t > maxVal,
1528  std::range_error,
1529  "Teuchos::ValueTypeConversionTraits<int, float>::safeConvert: "
1530  "Input float t = " << t << " is out of the valid range ["
1531  << minVal << ", " << maxVal << "] for conversion to int.");
1532  }
1533  return static_cast<int> (t);
1534  }
1535 };
1536 
1537 
1539 template<>
1540 class ValueTypeConversionTraits<unsigned int, float> {
1541 public:
1543  static unsigned int convert (const float t) {
1544  // Implicit conversion from float to unsigned int may cause
1545  // compiler warnings, but static_cast does not.
1546  return static_cast<unsigned int> (t);
1547  }
1548 
1550  static unsigned int safeConvert (const float t) {
1551  const unsigned int minVal = 0; // Had better be, since it's unsigned.
1552  const unsigned int maxVal = std::numeric_limits<unsigned int>::max ();
1553 
1555  t < minVal || t > maxVal,
1556  std::range_error,
1557  "Teuchos::ValueTypeConversionTraits<unsigned int, float>::safeConvert: "
1558  "Input double t = " << t << " is out of the valid range [" << minVal
1559  << ", " << maxVal << "] for conversion to unsigned int.");
1560 
1561  return static_cast<unsigned int> (t);
1562  }
1563 };
1564 
1565 
1567 template<>
1568 class ValueTypeConversionTraits<long, float> {
1569 public:
1571  static long convert (const float t) {
1572  // Implicit conversion from float to long may cause compiler
1573  // warnings, but static_cast does not. Overflow here would mean
1574  // that sizeof(long) < sizeof(float), which is legal, but unlikely
1575  // on platforms of longerest.
1576  return static_cast<long> (t);
1577  }
1578 
1580  static long safeConvert (const float t) {
1581  const long minVal = std::numeric_limits<long>::min ();
1582  const long maxVal = std::numeric_limits<long>::max ();
1583 
1584  // Cases:
1585  // 1. sizeof(long) < sizeof(float) == 4
1586  // 2. sizeof(long) == sizeof(float) == 4
1587  // 3. sizeof(long) > sizeof(float) == 4
1588  //
1589  // Overflow when converting from float to long is possible only
1590  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1591  // 2 and 3, but safeConvert() only cares about overflow, not
1592  // rounding. Casting minVal or maxVal to double in Case 3 could
1593  // result in overflow. Thus, we only do the cast for Case 1.
1594  //
1595  // I've never encountered a Case 1 platform (mfh 14 Nov 2012).
1596  // C99 actually forbids it, though I don't think a valid C++
1597  // compiler (for version C++03 of the language standard) needs to
1598  // implement C99 (mfh 14 Nov 2012). Case 2 occurs in Win64
1599  // (64-bit Windows) and other implementations of (I32L32)LLP64.
1600  // Case 3 is common (e.g., in the (I32)LP64 integer model of
1601  // GNU/Linux and other operating systems).
1602  if (sizeof (long) < sizeof (float)) {
1604  t < minVal || t > maxVal,
1605  std::range_error,
1606  "Teuchos::ValueTypeConversionTraits<long, float>::safeConvert: "
1607  "Input float t = " << t << " is out of the valid range ["
1608  << minVal << ", " << maxVal << "] for conversion to long.");
1609  }
1610  return static_cast<long> (t);
1611  }
1612 };
1613 
1614 
1616 template<>
1617 class ValueTypeConversionTraits<unsigned long, float> {
1618 public:
1620  static unsigned long convert (const float t) {
1621  // Implicit conversion from float to unsigned long may cause
1622  // compiler warnings, but static_cast does not.
1623  return static_cast<unsigned long> (t);
1624  }
1625 
1627  static unsigned long safeConvert (const float t) {
1628  const unsigned long minVal = 0; // Had better be, since it's unsigned.
1629  const unsigned long maxVal = std::numeric_limits<unsigned long>::max ();
1630 
1632  t < minVal || t > maxVal,
1633  std::range_error,
1634  "Teuchos::ValueTypeConversionTraits<unsigned long, float>::safeConvert: "
1635  << "Input float t = " << t << " is out of the valid range [" << minVal
1636  << ", " << maxVal << "] for conversion to unsigned long.");
1637 
1638  return static_cast<unsigned long> (t);
1639  }
1640 };
1641 
1642 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
1643 
1645 template<>
1646 class ValueTypeConversionTraits<long long, float> {
1647 public:
1649  static long long convert (const float t) {
1650  return static_cast<long long> (t);
1651  }
1652 
1654  static long long safeConvert (const float t) {
1655  // The C99 standard (Section 5.2.4.2.1) actually requires
1656  // sizeof(long long) >= 64, so overflow is impossible.
1657  return static_cast<long long> (t);
1658  }
1659 };
1660 
1661 
1663 template<>
1664 class ValueTypeConversionTraits<unsigned long long, float> {
1665 public:
1667  static unsigned long long convert (const float t) {
1668  return static_cast<unsigned long long> (t);
1669  }
1670 
1672  static unsigned long long safeConvert (const float t) {
1673  const unsigned long long minVal = 0; // unsigned, so min value is 0.
1674  const unsigned long long maxVal = std::numeric_limits<unsigned long long>::max ();
1675 
1677  t < minVal || t > maxVal,
1678  std::range_error,
1679  "Teuchos::ValueTypeConversionTraits<unsigned long long, float>::safeConvert: "
1680  "Input float t = " << t << " is out of the valid range [" << minVal
1681  << ", " << maxVal << "] for conversion to unsigned long long.");
1682 
1683  return static_cast<unsigned long long> (t);
1684  }
1685 };
1686 
1687 #endif // HAVE_TEUCHOS_LONG_LONG_INT
1688 
1689 //
1690 // * Specializations for conversions between a unsigned built-in
1691 // integer type and the signed version of the same type (either
1692 // direction).
1693 //
1694 
1695 namespace {
1696 // Implementation of conversion from an unsigned built-in integer
1697 // type, to an signed built-in integer type with the same number of
1698 // bits.
1699 template<class SignedIntType, class UnsignedIntType>
1700 class UnsignedToSignedValueTypeConversionTraits {
1701 public:
1709  static SignedIntType convert (const UnsignedIntType t) {
1710  // Implicit conversion may cause compiler warnings, but
1711  // static_cast does not.
1712  return static_cast<SignedIntType> (t);
1713  }
1714 
1716  static SignedIntType safeConvert (const UnsignedIntType t) {
1718  const SignedIntType maxSigned = std::numeric_limits<SignedIntType>::max ();
1719 
1720  // SignedIntType and UnsignedIntType have the same number of bits,
1721  // so it suffices (via two's complement arithmetic) to check
1722  // whether the cast turned a positive number negative.
1723  const SignedIntType signedVal = static_cast<SignedIntType> (t);
1725  signedVal < 0,
1726  std::range_error,
1727  "Teuchos::ValueTypeConversionTraits<" << TypeNameTraits<SignedIntType>::name ()
1728  << ", " << TypeNameTraits<UnsignedIntType>::name () << ">::safeConvert: "
1729  "Input " << TypeNameTraits<UnsignedIntType>::name () << " t = " << t
1730  << " is out of the valid range [0, " << ", " << maxSigned
1731  << "] for conversion to " << TypeNameTraits<SignedIntType>::name () << ".");
1732  return signedVal;
1733  }
1734 };
1735 
1736 
1737 // Implementation of conversion from a signed built-in integer type,
1738 // to an unsigned built-in integer type with the same number of bits.
1739 template<class UnsignedIntType, class SignedIntType>
1740 class SignedToUnsignedValueTypeConversionTraits {
1741 public:
1743  static UnsignedIntType convert (const SignedIntType t) {
1744  // Implicit conversion may cause compiler warnings, but
1745  // static_cast does not.
1746  return static_cast<UnsignedIntType> (t);
1747  }
1748 
1750  static UnsignedIntType safeConvert (const SignedIntType t) {
1752 
1753  // SignedIntType and UnsignedIntType have the same number of bits,
1754  // so it suffices (via two's complement arithmetic) to check
1755  // whether the input is negative.
1757  t < static_cast<SignedIntType> (0),
1758  std::range_error,
1759  "Teuchos::ValueTypeConversionTraits<" << TypeNameTraits<UnsignedIntType>::name ()
1760  << ", " << TypeNameTraits<SignedIntType>::name () << ">::safeConvert: "
1761  "Input " << TypeNameTraits<SignedIntType>::name () << " t = " << t
1762  << " is negative, so it cannot be correctly converted to the unsigned type "
1764 
1765  return static_cast<UnsignedIntType> (t);
1766  }
1767 };
1768 
1769 } // namespace (anonymous)
1770 
1771 
1773 template<>
1774 class ValueTypeConversionTraits<short, unsigned short> {
1775 public:
1776  static short convert (const unsigned short t) {
1777  return UnsignedToSignedValueTypeConversionTraits<short, unsigned short>::convert (t);
1778  }
1779 
1780  static short safeConvert (const unsigned short t) {
1781  return UnsignedToSignedValueTypeConversionTraits<short, unsigned short>::safeConvert (t);
1782  }
1783 };
1784 
1785 
1787 template<>
1788 class ValueTypeConversionTraits<unsigned short, short> {
1789 public:
1790  static unsigned short convert (const short t) {
1791  return SignedToUnsignedValueTypeConversionTraits<unsigned short, short>::convert (t);
1792  }
1793 
1794  static unsigned short safeConvert (const short t) {
1795  return SignedToUnsignedValueTypeConversionTraits<unsigned short, short>::safeConvert (t);
1796  }
1797 };
1798 
1799 
1801 template<>
1802 class ValueTypeConversionTraits<int, unsigned int> {
1803 public:
1804  static int convert (const unsigned int t) {
1805  return UnsignedToSignedValueTypeConversionTraits<int, unsigned int>::convert (t);
1806  }
1807 
1808  static int safeConvert (const unsigned int t) {
1809  return UnsignedToSignedValueTypeConversionTraits<int, unsigned int>::safeConvert (t);
1810  }
1811 };
1812 
1813 
1815 template<>
1816 class ValueTypeConversionTraits<unsigned int, int> {
1817 public:
1818  static unsigned int convert (const int t) {
1819  return SignedToUnsignedValueTypeConversionTraits<unsigned int, int>::convert (t);
1820  }
1821 
1822  static unsigned int safeConvert (const int t) {
1823  return SignedToUnsignedValueTypeConversionTraits<unsigned int, int>::safeConvert (t);
1824  }
1825 };
1826 
1827 
1829 template<>
1830 class ValueTypeConversionTraits<long, unsigned long> {
1831 public:
1832  static long convert (const unsigned long t) {
1833  return UnsignedToSignedValueTypeConversionTraits<long, unsigned long>::convert (t);
1834  }
1835 
1836  static long safeConvert (const unsigned long t) {
1837  return UnsignedToSignedValueTypeConversionTraits<long, unsigned long>::safeConvert (t);
1838  }
1839 };
1840 
1841 
1843 template<>
1844 class ValueTypeConversionTraits<unsigned long, long> {
1845 public:
1846  static unsigned long convert (const long t) {
1847  return SignedToUnsignedValueTypeConversionTraits<unsigned long, long>::convert (t);
1848  }
1849 
1850  static unsigned long safeConvert (const long t) {
1851  return SignedToUnsignedValueTypeConversionTraits<unsigned long, long>::safeConvert (t);
1852  }
1853 };
1854 
1855 
1856 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
1857 
1859 template<>
1860 class ValueTypeConversionTraits<long long, unsigned long long> {
1861 public:
1862  static long long convert (const unsigned long long t) {
1863  return UnsignedToSignedValueTypeConversionTraits<long long, unsigned long long>::convert (t);
1864  }
1865 
1866  static long long safeConvert (const unsigned long long t) {
1867  return UnsignedToSignedValueTypeConversionTraits<long long, unsigned long long>::safeConvert (t);
1868  }
1869 };
1870 
1871 
1873 template<>
1874 class ValueTypeConversionTraits<unsigned long long, long long> {
1875 public:
1876  static unsigned long long convert (const long long t) {
1877  return SignedToUnsignedValueTypeConversionTraits<unsigned long long, long long>::convert (t);
1878  }
1879 
1880  static unsigned long long safeConvert (const long long t) {
1881  return SignedToUnsignedValueTypeConversionTraits<unsigned long long, long long>::safeConvert (t);
1882  }
1883 };
1884 
1885 #endif // HAVE_TEUCHOS_LONG_LONG_INT
1886 
1887 //
1888 // * Specializations for conversions between different built-in
1889 // integer types.
1890 //
1891 
1893 template<>
1894 class ValueTypeConversionTraits<short, int> {
1895 public:
1901  static short convert (const int t) {
1902  // Implicit conversion may cause compiler warnings, but
1903  // static_cast does not.
1904  return static_cast<short> (t);
1905  }
1906 
1908  static short safeConvert (const int t) {
1909  const short minShort = std::numeric_limits<short>::min ();
1910  const short maxShort = std::numeric_limits<short>::max ();
1911 
1912  // Casting from short to int never overflows, since the C++
1913  // standard guarantees that sizeof (short) <= sizeof (int).
1915  t < static_cast<int> (minShort) ||
1916  t > static_cast<int> (maxShort),
1917  std::range_error,
1918  "Teuchos::ValueTypeConversionTraits<short, int>::safeConvert: "
1919  "Input int t = " << t << " is out of the valid range [" << minShort
1920  << ", " << maxShort << "] for conversion to short.");
1921 
1922  return static_cast<short> (t);
1923  }
1924 };
1925 
1926 
1928 template<>
1929 class ValueTypeConversionTraits<short, long> {
1930 public:
1936  static short convert (const long t) {
1937  // Implicit conversion may cause compiler warnings, but
1938  // static_cast does not.
1939  return static_cast<short> (t);
1940  }
1941 
1943  static short safeConvert (const long t) {
1944  const short minShort = std::numeric_limits<short>::min ();
1945  const short maxShort = std::numeric_limits<short>::max ();
1946 
1947  // Casting from short to long never overflows, since the C++
1948  // standard guarantees that sizeof (short) <= sizeof (long).
1950  t < static_cast<long> (minShort) ||
1951  t > static_cast<long> (maxShort),
1952  std::range_error,
1953  "Teuchos::ValueTypeConversionTraits<short, long>::safeConvert: "
1954  "Input long t = " << t << " is out of the valid range [" << minShort
1955  << ", " << maxShort << "] for conversion to short.");
1956 
1957  return static_cast<short> (t);
1958  }
1959 };
1960 
1961 
1963 template<>
1964 class ValueTypeConversionTraits<int, long> {
1965 public:
1971  static int convert (const long t) {
1972  // Implicit conversion from long to int may cause compiler
1973  // warnings, but static_cast does not.
1974  return static_cast<int> (t);
1975  }
1976 
1978  static int safeConvert (const long t) {
1979  const int minInt = std::numeric_limits<int>::min ();
1980  const int maxInt = std::numeric_limits<int>::max ();
1981 
1982  // Casting from int to long never overflows, since the C++
1983  // standard guarantees that sizeof (int) <= sizeof (long).
1985  t < static_cast<long> (minInt) ||
1986  t > static_cast<long> (maxInt),
1987  std::range_error,
1988  "Teuchos::ValueTypeConversionTraits<int, long>::safeConvert: "
1989  "Input long t = " << t << " is out of the valid range [" << minInt
1990  << ", " << maxInt << "] for conversion to int.");
1991 
1992  // Implicit conversion from long to int may cause compiler
1993  // warnings, but static_cast does not.
1994  return static_cast<int> (t);
1995  }
1996 };
1997 
1998 
2000 template<>
2001 class ValueTypeConversionTraits<int, unsigned long> {
2002 public:
2009  static int convert (const unsigned long t) {
2010  // Implicit conversion may cause compiler warnings, but
2011  // static_cast does not.
2012  return static_cast<int> (t);
2013  }
2014 
2016  static int safeConvert (const unsigned long t) {
2017  const int minInt = std::numeric_limits<int>::min ();
2018  const int maxInt = std::numeric_limits<int>::max ();
2019 
2020  // On some platforms, sizeof(int) == sizeof(long). (This is the
2021  // "LLP64" model of Win64, which aims for backwards compatibility
2022  // with 32-bit code by making sizeof(int) == sizeof(long) == 4.)
2023  // If this is the case, then we can't safely cast unsigned long to
2024  // int, or unsigned int to long, because values with the most
2025  // significant bit set will overflow to negative values.
2026 
2027  // The C++ standard promises that sizeof (int) <= sizeof (unsigned
2028  // long). We use #if with INT_MAX and LONG_MAX to test for this,
2029  // rather than if statements, in order to avoid a compiler
2030  // warning. Thanks to Jeremie Gaidamour (13 Nov 2012) for letting
2031  // me know about the warning.
2032 #if INT_MAX == LONG_MAX
2033  // The two types have the same number of bits. Thus,
2034  // two's-complement arithmetic means that if casting from unsigned
2035  // long to int results in a negative number, it overflowed.
2036  // Otherwise, it didn't overflow (same number of bits).
2038  static_cast<int> (t) < static_cast<int> (0),
2039  std::range_error,
2040  "Teuchos::ValueTypeConversionTraits<int, unsigned long>::safeConvert: "
2041  "Input unsigned long t = " << t << " is out of the valid range ["
2042  << minInt << ", " << maxInt << "] for conversion to int.");
2043 #else // INT_MAX < LONG_MAX
2044  // t is unsigned, so it is >= 0 by definition.
2045  // Casting from int to unsigned long won't overflow in this case.
2047  t > static_cast<unsigned long> (maxInt),
2048  std::range_error,
2049  "Teuchos::ValueTypeConversionTraits<int, unsigned long>::safeConvert: "
2050  "Input unsigned long t = " << t << " is out of the valid range ["
2051  << minInt << ", " << maxInt << "] for conversion to int. An unchecked "
2052  "cast would have resulted in " << static_cast<int> (t) << ".");
2053 #endif // INT_MAX == LONG_MAX
2054 
2055  // Implicit conversion from unsigned long to int may cause
2056  // compiler warnings, but static_cast does not.
2057  return static_cast<int> (t);
2058  }
2059 };
2060 
2061 
2063 template<>
2064 class ValueTypeConversionTraits<long, unsigned int> {
2065 public:
2073  static long convert (const unsigned int t) {
2074  // Implicit conversion may cause compiler warnings, but
2075  // static_cast does not.
2076  return static_cast<long> (t);
2077  }
2078 
2080  static long safeConvert (const unsigned int t) {
2081  // On some platforms, sizeof(int) == sizeof(long). (This is the
2082  // "LLP64" model of Win64, which aims for backwards compatibility
2083  // with 32-bit code by making sizeof(int) == sizeof(long) == 4.)
2084  // If this is the case, then we can't safely cast unsigned long to
2085  // int, or unsigned int to long, because values with the most
2086  // significant bit set will overflow to negative values.
2087 
2088  // The C++ standard promises that sizeof (unsigned int) <= sizeof
2089  // (long). If strictly less, then the conversion won't overflow.
2090  // We protect the test with an #ifdef ... #endif to avoid compiler
2091  // warnings like the following: "warning: comparison is always
2092  // false due to limited range of data type".
2093 #if UINT_MAX == LONG_MAX
2094  const long minLong = std::numeric_limits<long>::min ();
2095  const long maxLong = std::numeric_limits<long>::max ();
2096 
2097  // The two types have the same number of bits. Thus,
2098  // two's-complement arithmetic means that if casting from
2099  // unsigned int to long results in a negative number, it
2100  // overflowed. Otherwise, it didn't overflow (same number of
2101  // bits).
2103  static_cast<long> (t) < static_cast<long> (0),
2104  std::range_error,
2105  "Teuchos::ValueTypeConversionTraits<long, unsigned int>::safeConvert: "
2106  "Input unsigned int t = " << t << " is out of the valid range ["
2107  << minLong << ", " << maxLong << "] for conversion to long.");
2108 #endif // UINT_MAX == LONG_MAX
2109 
2110  return static_cast<long> (t);
2111  }
2112 };
2113 
2114 
2116 template<>
2117 class ValueTypeConversionTraits<unsigned int, long> {
2118 public:
2125  static unsigned int convert (const long t) {
2126  // Implicit conversion from long to unsigned int may cause
2127  // compiler warnings, but static_cast does not.
2128  return static_cast<unsigned int> (t);
2129  }
2130 
2132  static unsigned int safeConvert (const long t) {
2133  // On some platforms, sizeof(int) == sizeof(long). (This is the
2134  // "LLP64" model of Win64, which aims for backwards compatibility
2135  // with 32-bit code by making sizeof(int) == sizeof(long) == 4.)
2136  // In this case, conversion from long to unsigned int can't
2137  // overflow.
2138 
2139  // The C++ standard promises that sizeof (unsigned int) <= sizeof (long).
2140  if (sizeof (unsigned int) < sizeof (long)) {
2141  const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
2142 
2144  t < static_cast<long> (0) || t > static_cast<long> (maxInt),
2145  std::range_error,
2146  "Teuchos::ValueTypeConversionTraits<unsigned int, long>::safeConvert: "
2147  "Input long t = " << t << " is out of the valid range [0, "
2148  << maxInt << "] for conversion to unsigned int.");
2149  }
2150  // Implicit conversion from long to unsigned int may cause
2151  // compiler warnings, but static_cast does not.
2152  return static_cast<unsigned int> (t);
2153  }
2154 };
2155 
2156 
2158 template<>
2159 class ValueTypeConversionTraits<unsigned int, unsigned long> {
2160 public:
2167  static unsigned int convert (const unsigned long t) {
2168  // Implicit conversion from unsigned long to unsigned int may cause
2169  // compiler warnings, but static_cast does not.
2170  return static_cast<unsigned int> (t);
2171  }
2172 
2174  static unsigned int safeConvert (const unsigned long t) {
2175  const unsigned int minInt = 0; // Had better be, since it's unsigned.
2176  const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
2177 
2178  // t >= 0 by definition, because it is unsigned.
2180  t > static_cast<unsigned long> (maxInt),
2181  std::range_error,
2182  "Teuchos::ValueTypeConversionTraits<unsigned int, unsigned long>::safeConvert: "
2183  "Input unsigned long t = " << t << " is out of the valid range [" << minInt
2184  << ", " << maxInt << "] for conversion to unsigned int.");
2185 
2186  // Implicit conversion from unsigned long to unsigned int may
2187  // cause compiler warnings, but static_cast does not.
2188  return static_cast<unsigned int> (t);
2189  }
2190 };
2191 
2193 template<>
2194 class ValueTypeConversionTraits<unsigned short, unsigned long> {
2195 public:
2202  static unsigned short convert (const unsigned long t) {
2203  // Implicit conversion from unsigned long to unsigned short may cause
2204  // compiler warnings, but static_cast does not.
2205  return static_cast<unsigned short> (t);
2206  }
2207 
2209  static unsigned short safeConvert (const unsigned long t) {
2210  const unsigned short minShort = 0; // Had better be, since it's unsigned.
2211  const unsigned short maxShort = std::numeric_limits<unsigned short>::max ();
2212 
2213  // t >= 0 by definition, because it is unsigned.
2215  t > static_cast<unsigned long> (maxShort),
2216  std::range_error,
2217  "Teuchos::ValueTypeConversionTraits<unsigned short, unsigned long>::safeConvert: "
2218  "Input unsigned long t = " << t << " is out of the valid range [" << minShort
2219  << ", " << maxShort << "] for conversion to unsigned short.");
2220 
2221  // Implicit conversion from unsigned long to unsigned short may
2222  // cause compiler warnings, but static_cast does not.
2223  return static_cast<unsigned short> (t);
2224  }
2225 };
2226 
2227 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
2228 
2230 template<>
2231 class ValueTypeConversionTraits<int, long long> {
2232 public:
2238  static int convert (const long long t) {
2239  // Implicit conversion from long long to int may cause compiler
2240  // warnings, but static_cast does not.
2241  return static_cast<int> (t);
2242  }
2243 
2245  static int safeConvert (const long long t) {
2246  const int minInt = std::numeric_limits<int>::min ();
2247  const int maxInt = std::numeric_limits<int>::max ();
2248 
2250  t < static_cast<long long> (minInt) ||
2251  t > static_cast<long long> (maxInt),
2252  std::range_error,
2253  "Teuchos::ValueTypeConversionTraits<int, long long>::safeConvert: "
2254  "Input long long t = " << t << " is out of the valid range [" << minInt
2255  << ", " << maxInt << "] for conversion to int.");
2256 
2257  // Implicit conversion from long long to int may cause compiler
2258  // warnings, but static_cast does not.
2259  return static_cast<int> (t);
2260  }
2261 };
2262 
2263 
2265 template<>
2266 class ValueTypeConversionTraits<unsigned int, long long> {
2267 public:
2274  static unsigned int convert (const long long t) {
2275  // Implicit conversion from long long to unsigned int may cause
2276  // compiler warnings, but static_cast does not.
2277  return static_cast<unsigned int> (t);
2278  }
2279 
2281  static unsigned int safeConvert (const long long t) {
2282  const unsigned int minInt = 0; // Had better be, because it's unsigned.
2283  const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
2284 
2286  t < static_cast<long long> (minInt) || t > static_cast<long long> (maxInt),
2287  std::range_error,
2288  "Teuchos::ValueTypeConversionTraits<unsigned int, long long>::safeConvert: "
2289  "Input long long t = " << t << " is out of the valid range [" << minInt
2290  << ", " << maxInt << "] for conversion to unsigned int.");
2291 
2292  // Implicit conversion from long long to unsigned int may cause
2293  // compiler warnings, but static_cast does not.
2294  return static_cast<unsigned int> (t);
2295  }
2296 };
2297 
2298 
2300 template<>
2301 class ValueTypeConversionTraits<int, unsigned long long> {
2302 public:
2308  static int convert (const unsigned long long t) {
2309  // Implicit conversion from unsigned long long to int may cause
2310  // compiler warnings, but static_cast does not.
2311  return static_cast<int> (t);
2312  }
2313 
2315  static int safeConvert (const unsigned long long t) {
2316  const int minInt = std::numeric_limits<int>::min ();
2317  const int maxInt = std::numeric_limits<int>::max ();
2318 
2319  // t >= 0 by definition, because it is unsigned.
2321  t > static_cast<unsigned long long> (maxInt),
2322  std::invalid_argument,
2323  "Teuchos::ValueTypeConversionTraits<int, unsigned long long>::safeConvert: "
2324  "Input unsigned long long t = " << t << " is out of the valid range [" << minInt
2325  << ", " << maxInt << "] for conversion to int.");
2326 
2327  // Implicit conversion from unsigned long long to int may cause
2328  // compiler warnings, but static_cast does not.
2329  return static_cast<int> (t);
2330  }
2331 };
2332 
2333 
2335 template<>
2336 class ValueTypeConversionTraits<unsigned int, unsigned long long> {
2337 public:
2344  static unsigned int convert (const unsigned long long t) {
2345  // Implicit conversion from unsigned long long to unsigned int may
2346  // cause compiler warnings, but static_cast does not.
2347  return static_cast<unsigned int> (t);
2348  }
2349 
2351  static unsigned int safeConvert (const unsigned long long t) {
2352  const unsigned int minInt = 0; // Had better be, since it's unsigned.
2353  const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
2354 
2355  // t >= 0 by definition, because it is unsigned.
2357  t > static_cast<unsigned long long> (maxInt),
2358  std::invalid_argument,
2359  "Teuchos::ValueTypeConversionTraits<unsigned int, unsigned long long>::safeConvert: "
2360  "Input unsigned long long t = " << t << " is out of the valid range [" << minInt
2361  << ", " << maxInt << "] for conversion to unsigned int.");
2362 
2363  // Implicit conversion from unsigned long long to unsigned int may
2364  // cause compiler warnings, but static_cast does not.
2365  return static_cast<unsigned int> (t);
2366  }
2367 };
2368 
2369 #endif // HAVE_TEUCHOS_LONG_LONG_INT
2370 
2371 //
2372 // * Conversions from built-in integer types to built-in real-valued
2373 // floating-point types.
2374 //
2375 
2376 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
2377 
2379 template<>
2380 class ValueTypeConversionTraits<float, long long> {
2381 public:
2387  static float convert (const long long t) {
2388  // Implicit conversion from long long to float may cause compiler
2389  // warnings, but static_cast does not.
2390  return static_cast<float> (t);
2391  }
2392 
2394  static float safeConvert (const long long t) {
2395  // std::numeric_limits<float>::min() gives the minimum _positive_
2396  // normalized value of type float. IEEE 754 floating-point values
2397  // can change sign just by flipping the sign bit, so the "most
2398  // negative" finite float is just the negative of the "most
2399  // positive" finite float.
2400  const float minFloat = -std::numeric_limits<float>::max ();
2401  const float maxFloat = std::numeric_limits<float>::max ();
2402 
2403  // mfh 16 Nov 2012: On my platform (gcc 4.7.2, Red Hat Linux 5,
2404  // Intel x86_64), first casting [minFloat,maxFloat] to long long
2405  // (so that the comparison only compares long long values)
2406  // gives different results in the comparison below than just
2407  // comparing t (as a long long) with minFloat and maxFloat. It
2408  // doesn't matter whether you use static_cast<long long> (...) or
2409  // (long long) (...) to do the cast: the original float interval
2410  // of [-3.40282e+38, 3.40282e+38] becomes [-9223372036854775808,
2411  // -9223372036854775808], which is obviously wrong.
2413  t < minFloat || t > maxFloat,
2414  std::range_error,
2415  "Teuchos::ValueTypeConversionTraits<float, long long>::safeConvert: "
2416  "Input long long t = " << t << " is out of the valid range [" << minFloat
2417  << ", " << maxFloat << "] for conversion to float.");
2418 
2419  // Implicit conversion from long long to float may cause compiler
2420  // warnings, but static_cast does not.
2421  return static_cast<float> (t);
2422  }
2423 };
2424 
2425 
2427 template<>
2428 class ValueTypeConversionTraits<float, unsigned long long> {
2429 public:
2435  static float convert (const unsigned long long t) {
2436  // Implicit conversion from unsigned long long to float may cause
2437  // compiler warnings, but static_cast does not.
2438  return static_cast<float> (t);
2439  }
2440 
2442  static float safeConvert (const unsigned long long t) {
2443  // std::numeric_limits<float>::min() gives the minimum _positive_
2444  // normalized value of type float. IEEE 754 floating-point values
2445  // can change sign just by flipping the sign bit, so the "most
2446  // negative" finite float is just the negative of the "most
2447  // positive" finite float.
2448  const float minFloat = -std::numeric_limits<float>::max ();
2449  const float maxFloat = std::numeric_limits<float>::max ();
2450 
2451  // t >= 0 by definition, because it is unsigned.
2452  //
2453  // mfh 16 Nov 2012: See my note above on the <float, long long>
2454  // specialization that explains why I don't cast maxFloat to
2455  // unsigned long long here.
2457  t > maxFloat,
2458  std::invalid_argument,
2459  "Teuchos::ValueTypeConversionTraits<float, unsigned long long>::safeConvert: "
2460  "Input unsigned long long t = " << t << " is out of the valid range [" << minFloat
2461  << ", " << maxFloat << "] for conversion to float.");
2462 
2463  // Implicit conversion from unsigned long long to float may cause
2464  // compiler warnings, but static_cast does not.
2465  return static_cast<float> (t);
2466  }
2467 };
2468 
2469 #endif // HAVE_TEUCHOS_LONG_LONG_INT
2470 
2471 //
2472 // * Other conversions
2473 //
2474 
2476 template<int N>
2477 class ValueTypeConversionTraits<std::string, char[N]> {
2478 public:
2479  static std::string convert( const char t[] )
2480  { return std::string(t); }
2481  static std::string safeConvert( const char t[] )
2482  { return std::string(t); }
2483 };
2484 
2485 //
2486 // * Conversions from built-in integer types to std::complex<T>.
2487 //
2488 
2489 #ifdef HAVE_TEUCHOS_COMPLEX
2490 
2492 template<class RealType>
2493 class ValueTypeConversionTraits<std::complex<RealType>, short> {
2494 public:
2495  inline static std::complex<RealType> convert (const short 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 short 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 short> {
2508 public:
2509  inline static std::complex<RealType> convert (const unsigned short 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 short 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>, int> {
2522 public:
2523  inline static std::complex<RealType> convert (const int 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 int 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 int> {
2536 public:
2537  inline static std::complex<RealType> convert (const unsigned int 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 int t) {
2542  // Let RealType handle the conversion of the zero imaginary part.
2543  return std::complex<RealType> (t, asSafe<RealType> (0));
2544  }
2545 };
2546 
2548 template<class RealType>
2549 class ValueTypeConversionTraits<std::complex<RealType>, long> {
2550 public:
2551  inline static std::complex<RealType> convert (const long t) {
2552  // Let RealType handle the conversion of the zero imaginary part.
2553  return std::complex<RealType> (t, as<RealType> (0));
2554  }
2555  static std::complex<RealType> safeConvert (const long t) {
2556  // Let RealType handle the conversion of the zero imaginary part.
2557  return std::complex<RealType> (t, asSafe<RealType> (0));
2558  }
2559 };
2560 
2562 template<class RealType>
2563 class ValueTypeConversionTraits<std::complex<RealType>, unsigned long> {
2564 public:
2565  inline static std::complex<RealType> convert (const unsigned long t) {
2566  // Let RealType handle the conversion of the zero imaginary part.
2567  return std::complex<RealType> (t, as<RealType> (0));
2568  }
2569  static std::complex<RealType> safeConvert (const unsigned long t) {
2570  // Let RealType handle the conversion of the zero imaginary part.
2571  return std::complex<RealType> (t, asSafe<RealType> (0));
2572  }
2573 };
2574 
2575 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
2576 
2578 template<class RealType>
2579 class ValueTypeConversionTraits<std::complex<RealType>, long long> {
2580 public:
2581  inline static std::complex<RealType> convert (const long long t) {
2582  // Let RealType handle the conversion of the zero imaginary part.
2583  return std::complex<RealType> (t, as<RealType> (0));
2584  }
2585  static std::complex<RealType> safeConvert (const long long t) {
2586  // Let RealType handle the conversion of the zero imaginary part.
2587  return std::complex<RealType> (t, asSafe<RealType> (0));
2588  }
2589 };
2590 
2592 template<class RealType>
2593 class ValueTypeConversionTraits<std::complex<RealType>, unsigned long long> {
2594 public:
2595  inline static std::complex<RealType> convert (const unsigned long long t) {
2596  // Let RealType handle the conversion of the zero imaginary part.
2597  return std::complex<RealType> (t, as<RealType> (0));
2598  }
2599  static std::complex<RealType> safeConvert (const unsigned long long t) {
2600  // Let RealType handle the conversion of the zero imaginary part.
2601  return std::complex<RealType> (t, asSafe<RealType> (0));
2602  }
2603 };
2604 
2605 #endif // HAVE_TEUCHOS_LONG_LONG_INT
2606 #endif // HAVE_TEUCHOS_COMPLEX
2607 
2608 //
2609 // * Conversions for dd_real and qd_real
2610 //
2611 
2612 #ifdef HAVE_TEUCHOS_QD
2613 
2615 template <>
2616 class ValueTypeConversionTraits<double, qd_real> {
2617 public:
2618  inline static double convert (const qd_real t) {
2619  return to_double (t);
2620  }
2621  static double safeConvert (const qd_real t) {
2622  // std::numeric_limits<double>::min() gives the minimum _positive_
2623  // normalized value of type double. IEEE 754 floating-point
2624  // values can change sign just by flipping the sign bit, so the
2625  // "most negative" finite double is just the negative of the "most
2626  // positive" finite double.
2627  const qd_real minVal = -std::numeric_limits<double>::max ();
2628  const qd_real maxVal = std::numeric_limits<double>::max ();
2629 
2631  t < minVal || t > maxVal,
2632  std::range_error,
2633  "Teuchos::ValueTypeConversionTraits<double, qd_real>::safeConvert: "
2634  "Input qd_real t = " << t << " is out of the valid range [" << minVal
2635  << ", " << maxVal << "] for conversion to double.");
2636 
2637  return to_double (t);
2638  }
2639 };
2640 
2642 template <>
2643 class ValueTypeConversionTraits<float, qd_real> {
2644 public:
2645  inline static float convert (const qd_real t) {
2646  // In a debug build, this should also test the double->float
2647  // conversion for overflow.
2648  return as<float> (to_double (t));
2649  }
2650 
2651  static float safeConvert (const qd_real t) {
2652  // std::numeric_limits<float>::min() gives the minimum _positive_
2653  // normalized value of type float. IEEE 754 floating-point
2654  // values can change sign just by flipping the sign bit, so the
2655  // "most negative" finite float is just the negative of the "most
2656  // positive" finite float.
2657  //
2658  // qd_real has a constructor for double, but not for float,
2659  // so we cast to double first.
2660  const qd_real minVal = static_cast<double> (-std::numeric_limits<float>::max ());
2661  const qd_real maxVal = static_cast<double> (std::numeric_limits<float>::max ());
2662 
2664  t < minVal || t > maxVal,
2665  std::range_error,
2666  "Teuchos::ValueTypeConversionTraits<float, qd_real>::safeConvert: "
2667  "Input qd_real t = " << t << " is out of the valid range [" << minVal
2668  << ", " << maxVal << "] for conversion to float.");
2669 
2670  // This should also test the double->float conversion for overflow.
2671  return asSafe<float> (to_double (t));
2672  }
2673 };
2674 
2676 template <>
2677 class ValueTypeConversionTraits<int, qd_real> {
2678 public:
2679  inline static int convert (const qd_real t) {
2680  return to_int (t);
2681  }
2682  static int safeConvert (const qd_real t) {
2683  // qd_real has a constructor for int.
2684  const qd_real minVal = std::numeric_limits<int>::min ();
2685  const qd_real maxVal = std::numeric_limits<int>::max ();
2686 
2688  t < minVal || t > maxVal,
2689  std::range_error,
2690  "Teuchos::ValueTypeConversionTraits<int, qd_real>::safeConvert: "
2691  "Input qd_real t = " << t << " is out of the valid range [" << minVal
2692  << ", " << maxVal << "] for conversion to int.");
2693  return to_int (t);
2694  }
2695 };
2696 
2698 template <>
2699 class ValueTypeConversionTraits<dd_real, qd_real> {
2700 public:
2701  inline static dd_real convert (const qd_real t) {
2702  return to_dd_real(t);
2703  }
2704  static dd_real safeConvert (const qd_real t) {
2705  // std::numeric_limits<dd_real>::min() gives the minimum
2706  // _positive_ (normalized? not sure what this means for dd_real --
2707  // mfh 14 Nov 2012) value of type dd_real. dd_real values are
2708  // built from two IEEE 754 doubles. This means they can change
2709  // sign just by flipping the sign bit, so the "most negative"
2710  // finite dd_real is just the negative of the "most positive"
2711  // finite dd_real.
2712  //
2713  // qd_real has a constructor for dd_real.
2714  const qd_real minVal = -std::numeric_limits<dd_real>::max ();
2715  const qd_real maxVal = std::numeric_limits<dd_real>::max ();
2716 
2718  t < minVal || t > maxVal,
2719  std::range_error,
2720  "Teuchos::ValueTypeConversionTraits<dd_real, qd_real>::safeConvert: "
2721  "Input qd_real t = " << t << " is out of the valid range [" << minVal
2722  << ", " << maxVal << "] for conversion to dd_real.");
2723 
2724  return to_dd_real (t);
2725  }
2726 };
2727 
2729 template <>
2730 class ValueTypeConversionTraits<double, dd_real> {
2731 public:
2732  inline static double convert (const dd_real t) {
2733  return to_double (t);
2734  }
2735  static double safeConvert (const dd_real t) {
2736  // std::numeric_limits<double>::min() gives the minimum _positive_
2737  // normalized value of type double. IEEE 754 floating-point
2738  // values can change sign just by flipping the sign bit, so the
2739  // "most negative" finite double is just the negative of the "most
2740  // positive" finite double.
2741  //
2742  // qd_real has a constructor for double.
2743  const dd_real minVal = -std::numeric_limits<double>::max ();
2744  const dd_real maxVal = std::numeric_limits<double>::max ();
2745 
2747  t < minVal || t > maxVal,
2748  std::range_error,
2749  "Teuchos::ValueTypeConversionTraits<double, dd_real>::safeConvert: "
2750  "Input dd_real t = " << t << " is out of the valid range [" << minVal
2751  << ", " << maxVal << "] for conversion to double.");
2752 
2753  return to_double (t);
2754  }
2755 };
2756 
2758 template <>
2759 class ValueTypeConversionTraits<float, dd_real> {
2760 public:
2761  inline static float convert (const dd_real t) {
2762  // This also checks for double->float overflow in a debug build.
2763  return as<float> (to_double (t));
2764  }
2765  static float safeConvert (const dd_real t) {
2766  // std::numeric_limits<float>::min() gives the minimum _positive_
2767  // normalized value of type float. IEEE 754 floating-point
2768  // values can change sign just by flipping the sign bit, so the
2769  // "most negative" finite float is just the negative of the "most
2770  // positive" finite float.
2771  //
2772  // dd_real has a constructor for double but not for float,
2773  // so we cast to double first.
2774  const dd_real minVal = static_cast<double> (-std::numeric_limits<float>::max ());
2775  const dd_real maxVal = static_cast<double> (std::numeric_limits<float>::max ());
2776 
2778  t < minVal || t > maxVal,
2779  std::range_error,
2780  "Teuchos::ValueTypeConversionTraits<float, dd_real>::safeConvert: "
2781  "Input dd_real t = " << t << " is out of the valid range [" << minVal
2782  << ", " << maxVal << "] for conversion to float.");
2783 
2784  // This also checks for double->float overflow.
2785  return as<float> (to_double (t));
2786  }
2787 };
2788 
2790 template <>
2791 class ValueTypeConversionTraits<int, dd_real> {
2792 public:
2793  inline static int convert (const dd_real t) {
2794  return to_int (t);
2795  }
2796  static int safeConvert (const dd_real t) {
2797  // dd_real has a constructor for int.
2798  const dd_real minVal = std::numeric_limits<int>::min ();
2799  const dd_real maxVal = std::numeric_limits<int>::max ();
2800 
2802  t < minVal || t > maxVal,
2803  std::range_error,
2804  "Teuchos::ValueTypeConversionTraits<int, dd_real>::safeConvert: "
2805  "Input dd_real t = " << t << " is out of the valid range [" << minVal
2806  << ", " << maxVal << "] for conversion to int.");
2807  return to_int (t);
2808  }
2809 };
2810 
2812 template <>
2813 class ValueTypeConversionTraits<qd_real, long unsigned int> {
2814 public:
2815  inline static qd_real convert( const long unsigned int t ) {
2816  // FIXME (mfh 14 Nov 2012): qd_real unfortunately lacks a
2817  // constructor or conversion function for conversions from
2818  // built-in integer types other than int. However, it does allow
2819  // reading in values from a string. We could use this to convert
2820  // from any type to qd_real, by first writing the value to an
2821  // std::ostringstream, then creating a qd_real from the resulting
2822  // string.
2824  }
2825  inline static qd_real safeConvert( const long unsigned int t )
2827 };
2828 
2830 template <>
2831 class ValueTypeConversionTraits<dd_real, long unsigned int> {
2832 public:
2833  inline static dd_real convert( const long unsigned int t ) {
2834  // FIXME (mfh 14 Nov 2012): dd_real unfortunately lacks a
2835  // constructor or conversion function for conversions from
2836  // built-in integer types other than int. However, it does allow
2837  // reading in values from a string. We could use this to convert
2838  // from any type to dd_real, by first writing the value to an
2839  // std::ostringstream, then creating a dd_real from the resulting
2840  // string.
2842  }
2843  inline static dd_real safeConvert( const long unsigned int t )
2845 };
2846 
2847 #endif // HAVE_TEUCHOS_QD
2848 
2849 // ToDo: Add more specializations as needed!
2850 
2851 template<class TypeTo, class TypeFrom>
2852 inline TypeTo as( const TypeFrom& t )
2853 {
2854 #ifdef HAVE_TEUCHOS_DEBUG
2856 #else
2858 #endif // HAVE_TEUCHOS_DEBUG
2859 }
2860 
2861 template<class TypeTo, class TypeFrom>
2862 inline TypeTo asSafe( const TypeFrom& t )
2863 {
2865 }
2866 
2867 } // end namespace Teuchos
2868 
2869 
2870 #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.
TypeTo operator()(const TypeFrom &t)
Definition: Teuchos_as.hpp:377
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 OutType safeConvert(const std::string &t)
Definition: Teuchos_as.hpp:607
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:873
static long safeConvert(const std::string &t)
Convert the given std::string to a long, with checks.
Definition: Teuchos_as.hpp:775
static long convert(const float t)
Convert the given float to an long.
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:918
static short convert(const std::string &t)
Convert the given std::string to a short.
Definition: Teuchos_as.hpp:968
static TypeTo safeConvert(const TypeFrom t)
Convert t from a TypeFrom object to a TypeTo object, with checks for validity.
Definition: Teuchos_as.hpp:189
static long double convert(const std::string &t)
Definition: Teuchos_as.hpp:668
static float safeConvert(const std::string &t)
Definition: Teuchos_as.hpp:652
static unsigned long safeConvert(const std::string &t)
Convert the given std::string to an unsigned long, with checks.
Definition: Teuchos_as.hpp:797
static unsigned long safeConvertToUnsignedLong(const std::string &t)
Convert the given std::string to an intermediate unsigned long, with checks.
Definition: Teuchos_as.hpp:891
#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:182
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:878
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:780
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:802
static int convert(const long t)
Convert the given long to an int.
static unsigned int convert(const unsigned long t)
Convert the given unsigned long to an unsigned int.
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 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.
static long safeConvertToLong(const std::string &t)
Convert the given std::string to an intermediate long, with checks.
Definition: Teuchos_as.hpp:846
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:372
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 safeConvertToUnsignedLong(const std::string &t)
Convert the given std::string to an intermediate unsigned long, with checks.
Definition: Teuchos_as.hpp:981
static long double safeConvert(const std::string &t)
Definition: Teuchos_as.hpp:678
Default traits class for all conversions between value types.
Definition: Teuchos_as.hpp:179
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:923
static long safeConvertToLong(const std::string &t)
Convert the given std::string to an intermediate long, with checks.
Definition: Teuchos_as.hpp:936
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.
static double safeConvert(const std::string &t)
Definition: Teuchos_as.hpp:632
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 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 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 unsigned long safeConvert(const double t)
Convert the given double to an unsigned long, checking for overflow first.
static short safeConvert(const int t)
Convert from int to short, 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:963
static unsigned long convert(const float t)
Convert the given float to an unsigned long.
static unsigned int convert(const long t)
Convert the given long to an unsigned int.