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 //
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 < as<InputRealType>(minVal) || x > as<InputRealType>(maxVal),
486  std::range_error,
487  "realToReal<" << TypeNameTraits<OutputRealType>::name () << ", "
488  << TypeNameTraits<InputRealType>::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 
691 template<>
692 class ValueTypeConversionTraits<long long, std::string> {
693 public:
699  static long long safeConvert (const std::string& t) {
700 #if defined(_MSC_VER)
701  // Windows does not implement strtoull, so we resort to a
702  // fallback. Thanks to Ross Bartlett for pointing out _strtoi64.
703  // See the MSDN reference [last accessed 21 Mar 2013]:
704  //
705  // http://msdn.microsoft.com/en-us/library/h80404d3%28v=vs.80%29.aspx
706  return intToString<long long> (t, &_strtoi64, "long long");
707 #else
708  return intToString<long long> (t, &strtoll, "long long");
709 #endif // defined(_MSC_VER)
710  }
711 
713  static long long convert (const std::string& t) {
714  return safeConvert (t);
715  }
716 };
717 
718 
722 template<>
723 class ValueTypeConversionTraits<unsigned long long, std::string> {
724 public:
730  static unsigned long long safeConvert (const std::string& t) {
731 #if defined(_MSC_VER)
732  // Windows does not implement strtoull, so we resort to a
733  // fallback. The fallback does not know how to check for under-
734  // or overflow. Alas, Windows does not seem to have an equivalent
735  // of _strtoi64 for unsigned long long.
736  const char intTypeName[] = "unsigned long long";
737  std::istringstream istr (t);
738  unsigned long long i = 0;
739  istr >> i;
741  ! istr, std::invalid_argument,
742  "Teuchos::ValueTypeConversionTraits<" << intTypeName << ", std::string>::"
743  "convert: Unable to convert the given string \"" << t << "\" to " <<
744  intTypeName << ". Windows lacks strtoull(), so we had to resort to a "
745  "fall-back conversion. The fall-back method does not know how to test "
746  "for overflow.");
747  return i;
748 #else
749  return intToString<unsigned long long> (t, &strtoull, "unsigned long long");
750 #endif // defined(_MSC_VER)
751  }
752 
754  static unsigned long long convert (const std::string& t) {
755  return safeConvert (t);
756  }
757 };
758 
759 
763 template<>
764 class ValueTypeConversionTraits<long, std::string> {
765 public:
771  static long safeConvert (const std::string& t) {
772  return intToString<long> (t, &strtol, "long");
773  }
774 
776  static long convert (const std::string& t) {
777  return safeConvert (t);
778  }
779 };
780 
781 
785 template<>
786 class ValueTypeConversionTraits<unsigned long, std::string> {
787 public:
793  static unsigned long safeConvert (const std::string& t) {
794  return intToString<unsigned long> (t, &strtoul, "unsigned long");
795  }
796 
798  static unsigned long convert (const std::string& t) {
799  return safeConvert (t);
800  }
801 };
802 
803 
804 // Windows size_t is not unsigned long(32 bit), but unsigned long long(64 bit)
805 #ifdef HAVE_TEUCHOS___INT64
806 template<>
810 class ValueTypeConversionTraits<unsigned __int64, std::string> {
811 public:
817  static unsigned __int64 safeConvert(const std::string& t) {
818  unsigned __int64 output;
819  std::istringstream stream(t);
820  stream >> output;
821  return output;
822  }
823 
825  static unsigned __int64 convert(const std::string& t) {
826  unsigned __int64 output;
827  std::istringstream stream(t);
828  stream >> output;
829  return output;
830  }
831 };
832 #endif // HAVE_TEUCHOS___INT64
833 
834 
838 template<>
839 class ValueTypeConversionTraits<int, std::string> {
840 private:
842  static long safeConvertToLong (const std::string& t) {
843  long val = 0;
844  try {
846  } catch (std::range_error&) {
848  true,
849  std::range_error,
850  "Teuchos::ValueTypeConversionTraits<int, std::string>::convert: "
851  "The given std::string \"" << t << "\" is too big to fit into long, so there is no way it could fit into int.");
852  } catch (std::invalid_argument& e) {
854  true,
855  std::invalid_argument,
856  "Teuchos::ValueTypeConversionTraits<int, std::string>::convert: "
857  "Intermediate conversion from std::string to long failed, with the following error message: "
858  << e.what ());
859  }
860  return val;
861  }
862 
863 public:
869  static int safeConvert (const std::string& t) {
870  return asSafe<int> (safeConvertToLong (t));
871  }
872 
874  static int convert (const std::string& t) {
875  return as<int> (safeConvertToLong (t));
876  }
877 };
878 
879 
883 template<>
884 class ValueTypeConversionTraits<unsigned int, std::string> {
885 private:
887  static unsigned long safeConvertToUnsignedLong (const std::string& t) {
888  unsigned long val = 0;
889  try {
890  val = as<unsigned long> (t);
891  } catch (std::range_error&) {
893  true,
894  std::range_error,
895  "Teuchos::ValueTypeConversionTraits<unsigned int, std::string>::convert: "
896  "The given std::string \"" << t << "\" is too big to fit into unsigned long, so there is no way it could fit into unsigned int.");
897  } catch (std::invalid_argument& e) {
899  true,
900  std::invalid_argument,
901  "Teuchos::ValueTypeConversionTraits<unsigned int, std::string>::convert: "
902  "Intermediate conversion from std::string to unsigned long failed, with the following error message: "
903  << e.what ());
904  }
905  return val;
906  }
907 
908 public:
914  static unsigned int safeConvert (const std::string& t) {
915  return asSafe<unsigned int> (safeConvertToUnsignedLong (t));
916  }
917 
919  static unsigned int convert (const std::string& t) {
920  return as<unsigned int> (safeConvertToUnsignedLong (t));
921  }
922 };
923 
924 
928 template<>
929 class ValueTypeConversionTraits<short, std::string> {
930 private:
932  static long safeConvertToLong (const std::string& t) {
933  long val = 0;
934  try {
936  } catch (std::range_error&) {
938  true,
939  std::range_error,
940  "Teuchos::ValueTypeConversionTraits<short, std::string>::convert: "
941  "The given std::string \"" << t << "\" is too big to fit into long, so there is no way it could fit into short.");
942  } catch (std::invalid_argument& e) {
944  true,
945  std::invalid_argument,
946  "Teuchos::ValueTypeConversionTraits<short, std::string>::convert: "
947  "Intermediate conversion from std::string to long failed, with the following error message: "
948  << e.what ());
949  }
950  return val;
951  }
952 
953 public:
959  static short safeConvert (const std::string& t) {
960  return asSafe<short> (safeConvertToLong (t));
961  }
962 
964  static short convert (const std::string& t) {
965  return as<short> (safeConvertToLong (t));
966  }
967 };
968 
969 
973 template<>
974 class ValueTypeConversionTraits<unsigned short, std::string> {
975 private:
977  static unsigned long safeConvertToUnsignedLong (const std::string& t) {
978  unsigned long val = 0;
979  try {
980  val = as<unsigned long> (t);
981  } catch (std::range_error&) {
983  true,
984  std::range_error,
985  "Teuchos::ValueTypeConversionTraits<unsigned short, std::string>::convert: "
986  "The given std::string \"" << t << "\" is too big to fit into unsigned long, so there is no way it could fit into unsigned short.");
987  } catch (std::invalid_argument& e) {
989  true,
990  std::invalid_argument,
991  "Teuchos::ValueTypeConversionTraits<unsigned short, std::string>::convert: "
992  "Intermediate conversion from std::string to unsigned long failed, with the following error message: "
993  << e.what ());
994  }
995  return val;
996  }
997 
998 public:
1004  static unsigned short safeConvert (const std::string& t) {
1005  return asSafe<unsigned short> (safeConvertToUnsignedLong (t));
1006  }
1007 
1009  static unsigned short convert (const std::string& t) {
1010  return as<unsigned short> (safeConvertToUnsignedLong (t));
1011  }
1012 };
1013 
1014 //
1015 // * Specializations for conversions between built-in real-valued
1016 // floating-point types (like float and double).
1017 //
1018 
1020 template<>
1021 class ValueTypeConversionTraits<float, double> {
1022 public:
1023  static float safeConvert (const double t) {
1024  // mfh 25 Nov 2012: Disabling bounds checking, in favor of IEEE
1025  // 754 overflow semantics. Users who want bounds checking should
1026  // set the appropriate trap.
1027 #if 0
1028  // For floating-point types T, std::numeric_limits<T>::min()
1029  // returns the smallest positive value. IEEE 754 types have a
1030  // sign bit, so the largest-magnitude negative value is the
1031  // negative of the largest-magnitude positive value.
1032  const float minVal = -std::numeric_limits<float>::max ();
1033  const float maxVal = std::numeric_limits<float>::max ();
1034 
1035  // NaN is neither less than nor greater than anything. We just
1036  // let it pass through, per the rules for propagation of silent
1037  // NaN. (Signaling NaN will signal, but that's OK.)
1039  t < minVal || t > maxVal,
1040  std::range_error,
1041  "Teuchos::ValueTypeConversionTraits<float, double>::safeConvert: "
1042  "Input double t = " << t << " is out of the valid range [" << minVal
1043  << ", " << maxVal << "] for conversion to float.");
1044 #endif // 0
1045 
1046  return static_cast<float> (t);
1047  }
1048 
1049  static float convert (const double t) {
1050  return static_cast<float> (t);
1051  }
1052 };
1053 
1054 
1056 template<>
1057 class ValueTypeConversionTraits<float, long double> {
1058 public:
1059  static float safeConvert (const long double t) {
1060  // mfh 25 Nov 2012: Disabling bounds checking, in favor of IEEE
1061  // 754 overflow semantics. Users who want bounds checking should
1062  // set the appropriate trap.
1063 #if 0
1064  // For floating-point types T, std::numeric_limits<T>::min()
1065  // returns the smallest positive value. IEEE 754 types have a
1066  // sign bit, so the largest-magnitude negative value is the
1067  // negative of the largest-magnitude positive value.
1068  const float minVal = -std::numeric_limits<float>::max ();
1069  const float maxVal = std::numeric_limits<float>::max ();
1070 
1071  // NaN is neither less than nor greater than anything. We just
1072  // let it pass through, per the rules for propagation of silent
1073  // NaN. (Signaling NaN will signal, but that's OK.)
1075  t < minVal || t > maxVal,
1076  std::range_error,
1077  "Teuchos::ValueTypeConversionTraits<float, long double>::safeConvert: "
1078  "Input long double t = " << t << " is out of the valid range [" << minVal
1079  << ", " << maxVal << "] for conversion to float.");
1080 #endif // 0
1081 
1082  return static_cast<float> (t);
1083  }
1084 
1085  static float convert (const long double t) {
1086  return static_cast<float> (t);
1087  }
1088 };
1089 
1090 
1092 template<>
1093 class ValueTypeConversionTraits<double, long double> {
1094 public:
1095  static double safeConvert (const long double t) {
1096  // mfh 25 Nov 2012: Disabling bounds checking, in favor of IEEE
1097  // 754 overflow semantics. Users who want bounds checking should
1098  // set the appropriate trap.
1099 #if 0
1100  // For floating-point types T, std::numeric_limits<T>::min()
1101  // returns the smallest positive value. IEEE 754 types have a
1102  // sign bit, so the largest-magnitude negative value is the
1103  // negative of the largest-magnitude positive value.
1104  const double minVal = -std::numeric_limits<double>::max ();
1105  const double maxVal = std::numeric_limits<double>::max ();
1106 
1107  // NaN is neither less than nor greater than anything. We just
1108  // let it pass through, per the rules for propagation of silent
1109  // NaN. (Signaling NaN will signal, but that's OK.)
1111  t < minVal || t > maxVal,
1112  std::range_error,
1113  "Teuchos::ValueTypeConversionTraits<double, long double>::safeConvert: "
1114  "Input long double t = " << t << " is out of the valid range [" << minVal
1115  << ", " << maxVal << "] for conversion to double.");
1116 #endif // 0
1117 
1118  return static_cast<double> (t);
1119  }
1120 
1121  static double convert (const long double t) {
1122  return static_cast<double> (t);
1123  }
1124 };
1125 
1126 
1127 //
1128 // * Specializations for conversions from built-in real-valued
1129 // floating-point types (float and double) to build-in integer
1130 // types.
1131 //
1132 
1134 template<>
1135 class ValueTypeConversionTraits<short, double> {
1136 public:
1142  static short convert (const double t) {
1143  // Implicit conversion may cause compiler warnings, but
1144  // static_cast does not.
1145  return static_cast<short> (t);
1146  }
1147 
1149  static short safeConvert (const double t) {
1150  const short minVal = std::numeric_limits<short>::min ();
1151  const short maxVal = std::numeric_limits<short>::max ();
1152 
1153  // Cases:
1154  // 1. sizeof(short) < sizeof(double) == 8
1155  // 2. sizeof(short) == sizeof(double) == 8
1156  // 3. sizeof(short) > sizeof(double) == 8
1157  //
1158  // Overflow when converting from double to short is possible only
1159  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1160  // 2 and 3, but safeConvert() only cares about overflow, not
1161  // rounding. In Case 3, casting minVal or maxVal to double in
1162  // this case could result in overflow. Thus, we only do the test
1163  // for Case 1.
1164  //
1165  // All three cases are legal according to both C++03 and C99.
1166  // However, I (mfh 15 Nov 2012) have never encountered Cases 2 and
1167  // 3.
1168  if (sizeof (short) < sizeof (double)) {
1170  t < minVal || t > maxVal,
1171  std::range_error,
1172  "Teuchos::ValueTypeConversionTraits<short, double>::safeConvert: "
1173  "Input double t = " << t << " is out of the valid range [" << minVal
1174  << ", " << maxVal << "] for conversion to short.");
1175  }
1176  return static_cast<short> (t);
1177  }
1178 };
1179 
1180 
1182 template<>
1183 class ValueTypeConversionTraits<unsigned short, double> {
1184 public:
1186  static unsigned short convert (const double t) {
1187  // Implicit conversion may cause compiler warnings, but
1188  // static_cast does not.
1189  return static_cast<unsigned short> (t);
1190  }
1191 
1193  static unsigned short safeConvert (const double t) {
1194  const unsigned short minVal = 0;
1195  const unsigned short maxVal = std::numeric_limits<unsigned short>::max ();
1196 
1198  t < minVal || t > maxVal,
1199  std::range_error,
1200  "Teuchos::ValueTypeConversionTraits<unsigned short, double>::safeConvert: "
1201  "Input double t = " << t << " is out of the valid range [" << minVal
1202  << ", " << maxVal << "] for conversion to unsigned short.");
1203 
1204  return static_cast<unsigned short> (t);
1205  }
1206 };
1207 
1208 
1210 template<>
1211 class ValueTypeConversionTraits<int, double> {
1212 public:
1218  static int convert (const double t) {
1219  // Implicit conversion from double to int causes compiler
1220  // warnings, but static_cast does not.
1221  return static_cast<int> (t);
1222  }
1223 
1225  static int safeConvert (const double t) {
1226  const int minVal = std::numeric_limits<int>::min ();
1227  const int maxVal = std::numeric_limits<int>::max ();
1228 
1229  // Cases:
1230  // 1. sizeof(int) < sizeof(double) == 8
1231  // 2. sizeof(int) == sizeof(double) == 8
1232  // 3. sizeof(int) > sizeof(double) == 8
1233  //
1234  // Overflow when converting from double to int is possible only
1235  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1236  // 2 and 3, but safeConvert() only cares about overflow, not
1237  // rounding. Case 3 is quite rare, but casting minVal or maxVal
1238  // to double in this case could result in overflow. Thus, we only
1239  // do the cast for Case 1.
1240  if (sizeof (int) < sizeof (double)) {
1242  t < minVal || t > maxVal,
1243  std::range_error,
1244  "Teuchos::ValueTypeConversionTraits<int, double>::safeConvert: "
1245  "Input double t = " << t << " is out of the valid range [" << minVal
1246  << ", " << maxVal << "] for conversion to int.");
1247  }
1248  return static_cast<int> (t);
1249  }
1250 };
1251 
1252 
1254 template<>
1255 class ValueTypeConversionTraits<unsigned int, double> {
1256 public:
1258  static unsigned int convert (const double t) {
1259  // Implicit conversion may cause compiler warnings, but
1260  // static_cast does not.
1261  return static_cast<unsigned int> (t);
1262  }
1263 
1265  static unsigned int safeConvert (const double t) {
1266  const unsigned int minVal = 0;
1267  const unsigned int maxVal = std::numeric_limits<unsigned int>::max ();
1268 
1270  t < minVal || t > maxVal,
1271  std::range_error,
1272  "Teuchos::ValueTypeConversionTraits<unsigned int, double>::safeConvert: "
1273  "Input double t = " << t << " is out of the valid range [" << minVal
1274  << ", " << maxVal << "] for conversion to unsigned int.");
1275 
1276  return static_cast<unsigned int> (t);
1277  }
1278 };
1279 
1280 
1282 template<>
1283 class ValueTypeConversionTraits<long, double> {
1284 public:
1286  static long convert (const double t) {
1287  // Implicit conversion may cause compiler warnings, but
1288  // static_cast does not.
1289  return static_cast<long> (t);
1290  }
1291 
1293  static long safeConvert (const double t) {
1294  const long minVal = std::numeric_limits<long>::min ();
1295  const long maxVal = std::numeric_limits<long>::max ();
1296 
1297  // Cases:
1298  // 1. sizeof(long) < sizeof(double) == 8
1299  // 2. sizeof(long) == sizeof(double) == 8
1300  // 3. sizeof(long) > sizeof(double) == 8
1301  //
1302  // Overflow when converting from double to long is possible only
1303  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1304  // 2 and 3, but safeConvert() only cares about overflow, not
1305  // rounding. In Case 3, casting minVal or maxVal to double could
1306  // result in overflow. Thus, we only test for Case 1.
1307  //
1308  // Case 1 is entirely possible, for example on Win64 (an
1309  // implementation of the LLP64 integer model, on which
1310  // sizeof(long) == 4, and sizeof(long long) == sizeof(void*) ==
1311  // 8).
1312  if (sizeof (long) < sizeof (double)) {
1314  t < minVal || t > maxVal,
1315  std::range_error,
1316  "Teuchos::ValueTypeConversionTraits<long, double>::safeConvert: "
1317  "Input double t = " << t << " is out of the valid range [" << minVal
1318  << ", " << maxVal << "] for conversion to long.");
1319  }
1320  return static_cast<long> (t);
1321  }
1322 };
1323 
1324 
1326 template<>
1327 class ValueTypeConversionTraits<unsigned long, double> {
1328 public:
1330  static unsigned long convert (const double t) {
1331  // Implicit conversion may cause compiler warnings, but
1332  // static_cast does not.
1333  return static_cast<unsigned long> (t);
1334  }
1335 
1337  static unsigned long safeConvert (const double t) {
1338  const unsigned long minVal = 0;
1339  const unsigned long maxVal = std::numeric_limits<unsigned long>::max ();
1340 
1342  t < minVal || t > static_cast<double>(maxVal),
1343  std::range_error,
1344  "Teuchos::ValueTypeConversionTraits<unsigned long, double>::safeConvert: "
1345  "Input double t = " << t << " is out of the valid range [" << minVal
1346  << ", " << maxVal << "] for conversion to unsigned long.");
1347 
1348  return static_cast<unsigned long> (t);
1349  }
1350 };
1351 
1353 template<>
1354 class ValueTypeConversionTraits<long long, double> {
1355 public:
1357  static long long convert (const double t) {
1358  // Implicit conversion may cause compiler warnings, but
1359  // static_cast does not.
1360  return static_cast<long long> (t);
1361  }
1362 
1364  static long long safeConvert (const double t) {
1365  // Cases:
1366  // 1. sizeof(long long) < sizeof(double) == 8
1367  // 2. sizeof(long long) == sizeof(double) == 8
1368  // 3. sizeof(long long) > sizeof(double) == 8
1369  //
1370  // C99 (which defines long long) prohibits Case 1. Case 2 could
1371  // result in loss of accuracy (rounding), but safeConvert() only
1372  // cares about overflow, not rounding. In Case 3, casting minVal
1373  // or maxVal to double could result in overflow. Thus, we don't
1374  // need to check anything here.
1375  return static_cast<long long> (t);
1376  }
1377 };
1378 
1379 
1381 template<>
1382 class ValueTypeConversionTraits<unsigned long long, double> {
1383 public:
1385  static unsigned long long convert (const double t) {
1386  // Implicit conversion may cause compiler warnings, but
1387  // static_cast does not.
1388  return static_cast<unsigned long long> (t);
1389  }
1390 
1392  static unsigned long long safeConvert (const double t) {
1393  const unsigned long long minVal = 0; // unsigned, so min value is 0.
1394  const unsigned long long maxVal = std::numeric_limits<unsigned long long>::max ();
1395 
1397  t < minVal || t > static_cast<double>(maxVal),
1398  std::range_error,
1399  "Teuchos::ValueTypeConversionTraits<unsigned long long, double>::safeConvert: "
1400  "Input double t = " << t << " is out of the valid range [" << minVal
1401  << ", " << maxVal << "] for conversion to unsigned long long.");
1402 
1403  return static_cast<unsigned long long> (t);
1404  }
1405 };
1406 
1407 
1409 template<>
1410 class ValueTypeConversionTraits<short, float> {
1411 public:
1417  static short convert (const float t) {
1418  // Implicit conversion may cause compiler warnings, but
1419  // static_cast does not.
1420  return static_cast<short> (t);
1421  }
1422 
1424  static short safeConvert (const float t) {
1425  const short minVal = std::numeric_limits<short>::min ();
1426  const short maxVal = std::numeric_limits<short>::max ();
1427 
1428  // Cases:
1429  // 1. sizeof(short) < sizeof(float) == 4
1430  // 2. sizeof(short) == sizeof(float) == 4
1431  // 3. sizeof(short) > sizeof(float) == 4
1432  //
1433  // Overflow when converting from float to short is possible only
1434  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1435  // 2 and 3, but safeConvert() only cares about overflow, not
1436  // rounding. In Case 3, casting minVal or maxVal to float in this
1437  // case could result in overflow. Thus, we only do the test for
1438  // Case 1.
1439  //
1440  // All three cases are legal according to both C++03 and C99. I
1441  // (mfh 15 Nov 2012) think Case 1 is the most common, but Case 2
1442  // is certainly reasonable. (For example, some hardware prefers
1443  // to work only with 32-bit words, so _every_ built-in type has
1444  // size a multiple of 4 bytes.)
1445  if (sizeof (short) < sizeof (float)) {
1447  t < minVal || t > maxVal,
1448  std::range_error,
1449  "Teuchos::ValueTypeConversionTraits<short, float>::safeConvert: "
1450  "Input float t = " << t << " is out of the valid range [" << minVal
1451  << ", " << maxVal << "] for conversion to short.");
1452  }
1453 
1454  return static_cast<short> (t);
1455  }
1456 };
1457 
1458 
1460 template<>
1461 class ValueTypeConversionTraits<unsigned short, float> {
1462 public:
1464  static unsigned short convert (const float t) {
1465  // Implicit conversion may cause compiler warnings, but
1466  // static_cast does not.
1467  return static_cast<unsigned short> (t);
1468  }
1469 
1471  static unsigned short safeConvert (const float t) {
1472  const unsigned short minVal = 0;
1473  const unsigned short maxVal = std::numeric_limits<unsigned short>::max ();
1474 
1476  t < minVal || t > maxVal,
1477  std::range_error,
1478  "Teuchos::ValueTypeConversionTraits<unsigned short, float>::safeConvert: "
1479  "Input float t = " << t << " is out of the valid range [" << minVal
1480  << ", " << maxVal << "] for conversion to unsigned short.");
1481 
1482  return static_cast<unsigned short> (t);
1483  }
1484 };
1485 
1486 
1488 template<>
1489 class ValueTypeConversionTraits<int, float> {
1490 public:
1492  static int convert (const float t) {
1493  // Implicit conversion from float to int may cause compiler
1494  // warnings, but static_cast does not. Overflow here would mean
1495  // that sizeof(int) < sizeof(float), which is legal, but unlikely
1496  // on platforms of interest.
1497  return static_cast<int> (t);
1498  }
1499 
1501  static int safeConvert (const float t) {
1502  const int minVal = std::numeric_limits<int>::min ();
1503  const int maxVal = std::numeric_limits<int>::max ();
1504 
1505  // Cases:
1506  // 1. sizeof(int) < sizeof(float) == 4
1507  // 2. sizeof(int) == sizeof(float) == 4
1508  // 3. sizeof(int) > sizeof(float) == 4
1509  //
1510  // Overflow when converting from float to int is possible only for
1511  // Case 1. Loss of accuracy (rounding) is possible for Cases 2
1512  // and 3, but safeConvert() only cares about overflow, not
1513  // rounding. Case 3 is rare, but casting minVal or maxVal to
1514  // float in this case could result in loss of accuracy
1515  // (sizeof(int) == 8 or 16) or overflow (sizeof(int) > 16). Thus,
1516  // we only do the test for Case 1.
1517  if (sizeof (int) < sizeof (float)) {
1519  t < minVal || t > maxVal,
1520  std::range_error,
1521  "Teuchos::ValueTypeConversionTraits<int, float>::safeConvert: "
1522  "Input float t = " << t << " is out of the valid range ["
1523  << minVal << ", " << maxVal << "] for conversion to int.");
1524  }
1525  return static_cast<int> (t);
1526  }
1527 };
1528 
1529 
1531 template<>
1532 class ValueTypeConversionTraits<unsigned int, float> {
1533 public:
1535  static unsigned int convert (const float t) {
1536  // Implicit conversion from float to unsigned int may cause
1537  // compiler warnings, but static_cast does not.
1538  return static_cast<unsigned int> (t);
1539  }
1540 
1542  static unsigned int safeConvert (const float t) {
1543  const unsigned int minVal = 0; // Had better be, since it's unsigned.
1544  const unsigned int maxVal = std::numeric_limits<unsigned int>::max ();
1545 
1547  t < minVal || t > static_cast<float>(maxVal),
1548  std::range_error,
1549  "Teuchos::ValueTypeConversionTraits<unsigned int, float>::safeConvert: "
1550  "Input double t = " << t << " is out of the valid range [" << minVal
1551  << ", " << maxVal << "] for conversion to unsigned int.");
1552 
1553  return static_cast<unsigned int> (t);
1554  }
1555 };
1556 
1557 
1559 template<>
1560 class ValueTypeConversionTraits<long, float> {
1561 public:
1563  static long convert (const float t) {
1564  // Implicit conversion from float to long may cause compiler
1565  // warnings, but static_cast does not. Overflow here would mean
1566  // that sizeof(long) < sizeof(float), which is legal, but unlikely
1567  // on platforms of longerest.
1568  return static_cast<long> (t);
1569  }
1570 
1572  static long safeConvert (const float t) {
1573  const long minVal = std::numeric_limits<long>::min ();
1574  const long maxVal = std::numeric_limits<long>::max ();
1575 
1576  // Cases:
1577  // 1. sizeof(long) < sizeof(float) == 4
1578  // 2. sizeof(long) == sizeof(float) == 4
1579  // 3. sizeof(long) > sizeof(float) == 4
1580  //
1581  // Overflow when converting from float to long is possible only
1582  // for Case 1. Loss of accuracy (rounding) is possible for Cases
1583  // 2 and 3, but safeConvert() only cares about overflow, not
1584  // rounding. Casting minVal or maxVal to double in Case 3 could
1585  // result in overflow. Thus, we only do the cast for Case 1.
1586  //
1587  // I've never encountered a Case 1 platform (mfh 14 Nov 2012).
1588  // C99 actually forbids it, though I don't think a valid C++
1589  // compiler (for version C++03 of the language standard) needs to
1590  // implement C99 (mfh 14 Nov 2012). Case 2 occurs in Win64
1591  // (64-bit Windows) and other implementations of (I32L32)LLP64.
1592  // Case 3 is common (e.g., in the (I32)LP64 integer model of
1593  // GNU/Linux and other operating systems).
1594  if (sizeof (long) < sizeof (float)) {
1596  t < minVal || t > static_cast<float>(maxVal),
1597  std::range_error,
1598  "Teuchos::ValueTypeConversionTraits<long, float>::safeConvert: "
1599  "Input float t = " << t << " is out of the valid range ["
1600  << minVal << ", " << maxVal << "] for conversion to long.");
1601  }
1602  return static_cast<long> (t);
1603  }
1604 };
1605 
1606 
1608 template<>
1609 class ValueTypeConversionTraits<unsigned long, float> {
1610 public:
1612  static unsigned long convert (const float t) {
1613  // Implicit conversion from float to unsigned long may cause
1614  // compiler warnings, but static_cast does not.
1615  return static_cast<unsigned long> (t);
1616  }
1617 
1619  static unsigned long safeConvert (const float t) {
1620  const unsigned long minVal = 0; // Had better be, since it's unsigned.
1621  const unsigned long maxVal = std::numeric_limits<unsigned long>::max ();
1622 
1624  t < minVal || t > static_cast<float>(maxVal),
1625  std::range_error,
1626  "Teuchos::ValueTypeConversionTraits<unsigned long, float>::safeConvert: "
1627  << "Input float t = " << t << " is out of the valid range [" << minVal
1628  << ", " << maxVal << "] for conversion to unsigned long.");
1629 
1630  return static_cast<unsigned long> (t);
1631  }
1632 };
1633 
1635 template<>
1636 class ValueTypeConversionTraits<long long, float> {
1637 public:
1639  static long long convert (const float t) {
1640  return static_cast<long long> (t);
1641  }
1642 
1644  static long long safeConvert (const float t) {
1645  // The C99 standard (Section 5.2.4.2.1) actually requires
1646  // sizeof(long long) >= 64, so overflow is impossible.
1647  return static_cast<long long> (t);
1648  }
1649 };
1650 
1651 
1653 template<>
1654 class ValueTypeConversionTraits<unsigned long long, float> {
1655 public:
1657  static unsigned long long convert (const float t) {
1658  return static_cast<unsigned long long> (t);
1659  }
1660 
1662  static unsigned long long safeConvert (const float t) {
1663  const unsigned long long minVal = 0; // unsigned, so min value is 0.
1664  const unsigned long long maxVal = std::numeric_limits<unsigned long long>::max ();
1665 
1667  t < minVal || t > static_cast<float>(maxVal),
1668  std::range_error,
1669  "Teuchos::ValueTypeConversionTraits<unsigned long long, float>::safeConvert: "
1670  "Input float t = " << t << " is out of the valid range [" << minVal
1671  << ", " << maxVal << "] for conversion to unsigned long long.");
1672 
1673  return static_cast<unsigned long long> (t);
1674  }
1675 };
1676 
1677 //
1678 // * Specializations for conversions between a unsigned built-in
1679 // integer type and the signed version of the same type (either
1680 // direction).
1681 //
1682 
1683 namespace {
1684 // Implementation of conversion from an unsigned built-in integer
1685 // type, to an signed built-in integer type with the same number of
1686 // bits.
1687 template<class SignedIntType, class UnsignedIntType>
1688 class UnsignedToSignedValueTypeConversionTraits {
1689 public:
1697  static SignedIntType convert (const UnsignedIntType t) {
1698  // Implicit conversion may cause compiler warnings, but
1699  // static_cast does not.
1700  return static_cast<SignedIntType> (t);
1701  }
1702 
1704  static SignedIntType safeConvert (const UnsignedIntType t) {
1706  const SignedIntType maxSigned = std::numeric_limits<SignedIntType>::max ();
1707 
1708  // SignedIntType and UnsignedIntType have the same number of bits,
1709  // so it suffices (via two's complement arithmetic) to check
1710  // whether the cast turned a positive number negative.
1711  const SignedIntType signedVal = static_cast<SignedIntType> (t);
1713  signedVal < 0,
1714  std::range_error,
1715  "Teuchos::ValueTypeConversionTraits<" << TypeNameTraits<SignedIntType>::name ()
1716  << ", " << TypeNameTraits<UnsignedIntType>::name () << ">::safeConvert: "
1717  "Input " << TypeNameTraits<UnsignedIntType>::name () << " t = " << t
1718  << " is out of the valid range [0, " << ", " << maxSigned
1719  << "] for conversion to " << TypeNameTraits<SignedIntType>::name () << ".");
1720  return signedVal;
1721  }
1722 };
1723 
1724 
1725 // Implementation of conversion from a signed built-in integer type,
1726 // to an unsigned built-in integer type with the same number of bits.
1727 template<class UnsignedIntType, class SignedIntType>
1728 class SignedToUnsignedValueTypeConversionTraits {
1729 public:
1731  static UnsignedIntType convert (const SignedIntType t) {
1732  // Implicit conversion may cause compiler warnings, but
1733  // static_cast does not.
1734  return static_cast<UnsignedIntType> (t);
1735  }
1736 
1738  static UnsignedIntType safeConvert (const SignedIntType t) {
1740 
1741  // SignedIntType and UnsignedIntType have the same number of bits,
1742  // so it suffices (via two's complement arithmetic) to check
1743  // whether the input is negative.
1745  t < static_cast<SignedIntType> (0),
1746  std::range_error,
1747  "Teuchos::ValueTypeConversionTraits<" << TypeNameTraits<UnsignedIntType>::name ()
1748  << ", " << TypeNameTraits<SignedIntType>::name () << ">::safeConvert: "
1749  "Input " << TypeNameTraits<SignedIntType>::name () << " t = " << t
1750  << " is negative, so it cannot be correctly converted to the unsigned type "
1751  << TypeNameTraits<UnsignedIntType>::name () << ".");
1752 
1753  return static_cast<UnsignedIntType> (t);
1754  }
1755 };
1756 
1757 } // namespace (anonymous)
1758 
1759 
1761 template<>
1762 class ValueTypeConversionTraits<short, unsigned short> {
1763 public:
1764  static short convert (const unsigned short t) {
1765  return UnsignedToSignedValueTypeConversionTraits<short, unsigned short>::convert (t);
1766  }
1767 
1768  static short safeConvert (const unsigned short t) {
1769  return UnsignedToSignedValueTypeConversionTraits<short, unsigned short>::safeConvert (t);
1770  }
1771 };
1772 
1773 
1775 template<>
1776 class ValueTypeConversionTraits<unsigned short, short> {
1777 public:
1778  static unsigned short convert (const short t) {
1779  return SignedToUnsignedValueTypeConversionTraits<unsigned short, short>::convert (t);
1780  }
1781 
1782  static unsigned short safeConvert (const short t) {
1783  return SignedToUnsignedValueTypeConversionTraits<unsigned short, short>::safeConvert (t);
1784  }
1785 };
1786 
1787 
1789 template<>
1790 class ValueTypeConversionTraits<int, unsigned int> {
1791 public:
1792  static int convert (const unsigned int t) {
1793  return UnsignedToSignedValueTypeConversionTraits<int, unsigned int>::convert (t);
1794  }
1795 
1796  static int safeConvert (const unsigned int t) {
1797  return UnsignedToSignedValueTypeConversionTraits<int, unsigned int>::safeConvert (t);
1798  }
1799 };
1800 
1801 
1803 template<>
1804 class ValueTypeConversionTraits<unsigned int, int> {
1805 public:
1806  static unsigned int convert (const int t) {
1807  return SignedToUnsignedValueTypeConversionTraits<unsigned int, int>::convert (t);
1808  }
1809 
1810  static unsigned int safeConvert (const int t) {
1811  return SignedToUnsignedValueTypeConversionTraits<unsigned int, int>::safeConvert (t);
1812  }
1813 };
1814 
1815 
1817 template<>
1818 class ValueTypeConversionTraits<long, unsigned long> {
1819 public:
1820  static long convert (const unsigned long t) {
1821  return UnsignedToSignedValueTypeConversionTraits<long, unsigned long>::convert (t);
1822  }
1823 
1824  static long safeConvert (const unsigned long t) {
1825  return UnsignedToSignedValueTypeConversionTraits<long, unsigned long>::safeConvert (t);
1826  }
1827 };
1828 
1829 
1831 template<>
1832 class ValueTypeConversionTraits<unsigned long, long> {
1833 public:
1834  static unsigned long convert (const long t) {
1835  return SignedToUnsignedValueTypeConversionTraits<unsigned long, long>::convert (t);
1836  }
1837 
1838  static unsigned long safeConvert (const long t) {
1839  return SignedToUnsignedValueTypeConversionTraits<unsigned long, long>::safeConvert (t);
1840  }
1841 };
1842 
1843 
1845 template<>
1846 class ValueTypeConversionTraits<long long, unsigned long long> {
1847 public:
1848  static long long convert (const unsigned long long t) {
1849  return UnsignedToSignedValueTypeConversionTraits<long long, unsigned long long>::convert (t);
1850  }
1851 
1852  static long long safeConvert (const unsigned long long t) {
1853  return UnsignedToSignedValueTypeConversionTraits<long long, unsigned long long>::safeConvert (t);
1854  }
1855 };
1856 
1857 
1859 template<>
1860 class ValueTypeConversionTraits<unsigned long long, long long> {
1861 public:
1862  static unsigned long long convert (const long long t) {
1863  return SignedToUnsignedValueTypeConversionTraits<unsigned long long, long long>::convert (t);
1864  }
1865 
1866  static unsigned long long safeConvert (const long long t) {
1867  return SignedToUnsignedValueTypeConversionTraits<unsigned long long, long long>::safeConvert (t);
1868  }
1869 };
1870 
1871 //
1872 // * Specializations for conversions between different built-in
1873 // integer types.
1874 //
1875 
1877 template<>
1878 class ValueTypeConversionTraits<short, int> {
1879 public:
1885  static short convert (const int t) {
1886  // Implicit conversion may cause compiler warnings, but
1887  // static_cast does not.
1888  return static_cast<short> (t);
1889  }
1890 
1892  static short safeConvert (const int t) {
1893  const short minShort = std::numeric_limits<short>::min ();
1894  const short maxShort = std::numeric_limits<short>::max ();
1895 
1896  // Casting from short to int never overflows, since the C++
1897  // standard guarantees that sizeof (short) <= sizeof (int).
1899  t < static_cast<int> (minShort) ||
1900  t > static_cast<int> (maxShort),
1901  std::range_error,
1902  "Teuchos::ValueTypeConversionTraits<short, int>::safeConvert: "
1903  "Input int t = " << t << " is out of the valid range [" << minShort
1904  << ", " << maxShort << "] for conversion to short.");
1905 
1906  return static_cast<short> (t);
1907  }
1908 };
1909 
1910 
1912 template<>
1913 class ValueTypeConversionTraits<short, long> {
1914 public:
1920  static short convert (const long t) {
1921  // Implicit conversion may cause compiler warnings, but
1922  // static_cast does not.
1923  return static_cast<short> (t);
1924  }
1925 
1927  static short safeConvert (const long t) {
1928  const short minShort = std::numeric_limits<short>::min ();
1929  const short maxShort = std::numeric_limits<short>::max ();
1930 
1931  // Casting from short to long never overflows, since the C++
1932  // standard guarantees that sizeof (short) <= sizeof (long).
1934  t < static_cast<long> (minShort) ||
1935  t > static_cast<long> (maxShort),
1936  std::range_error,
1937  "Teuchos::ValueTypeConversionTraits<short, long>::safeConvert: "
1938  "Input long t = " << t << " is out of the valid range [" << minShort
1939  << ", " << maxShort << "] for conversion to short.");
1940 
1941  return static_cast<short> (t);
1942  }
1943 };
1944 
1945 
1947 template<>
1948 class ValueTypeConversionTraits<int, long> {
1949 public:
1955  static int convert (const long t) {
1956  // Implicit conversion from long to int may cause compiler
1957  // warnings, but static_cast does not.
1958  return static_cast<int> (t);
1959  }
1960 
1962  static int safeConvert (const long t) {
1963  const int minInt = std::numeric_limits<int>::min ();
1964  const int maxInt = std::numeric_limits<int>::max ();
1965 
1966  // Casting from int to long never overflows, since the C++
1967  // standard guarantees that sizeof (int) <= sizeof (long).
1969  t < static_cast<long> (minInt) ||
1970  t > static_cast<long> (maxInt),
1971  std::range_error,
1972  "Teuchos::ValueTypeConversionTraits<int, long>::safeConvert: "
1973  "Input long t = " << t << " is out of the valid range [" << minInt
1974  << ", " << maxInt << "] for conversion to int.");
1975 
1976  // Implicit conversion from long to int may cause compiler
1977  // warnings, but static_cast does not.
1978  return static_cast<int> (t);
1979  }
1980 };
1981 
1982 
1984 template<>
1985 class ValueTypeConversionTraits<int, unsigned long> {
1986 public:
1993  static int convert (const unsigned long t) {
1994  // Implicit conversion may cause compiler warnings, but
1995  // static_cast does not.
1996  return static_cast<int> (t);
1997  }
1998 
2000  static int safeConvert (const unsigned long t) {
2001  const int minInt = std::numeric_limits<int>::min ();
2002  const int maxInt = std::numeric_limits<int>::max ();
2003 
2004  // On some platforms, sizeof(int) == sizeof(long). (This is the
2005  // "LLP64" model of Win64, which aims for backwards compatibility
2006  // with 32-bit code by making sizeof(int) == sizeof(long) == 4.)
2007  // If this is the case, then we can't safely cast unsigned long to
2008  // int, or unsigned int to long, because values with the most
2009  // significant bit set will overflow to negative values.
2010 
2011  // The C++ standard promises that sizeof (int) <= sizeof (unsigned
2012  // long). We use #if with INT_MAX and LONG_MAX to test for this,
2013  // rather than if statements, in order to avoid a compiler
2014  // warning. Thanks to Jeremie Gaidamour (13 Nov 2012) for letting
2015  // me know about the warning.
2016 #if INT_MAX == LONG_MAX
2017  // The two types have the same number of bits. Thus,
2018  // two's-complement arithmetic means that if casting from unsigned
2019  // long to int results in a negative number, it overflowed.
2020  // Otherwise, it didn't overflow (same number of bits).
2022  static_cast<int> (t) < static_cast<int> (0),
2023  std::range_error,
2024  "Teuchos::ValueTypeConversionTraits<int, unsigned long>::safeConvert: "
2025  "Input unsigned long t = " << t << " is out of the valid range ["
2026  << minInt << ", " << maxInt << "] for conversion to int.");
2027 #else // INT_MAX < LONG_MAX
2028  // t is unsigned, so it is >= 0 by definition.
2029  // Casting from int to unsigned long won't overflow in this case.
2031  t > static_cast<unsigned long> (maxInt),
2032  std::range_error,
2033  "Teuchos::ValueTypeConversionTraits<int, unsigned long>::safeConvert: "
2034  "Input unsigned long t = " << t << " is out of the valid range ["
2035  << minInt << ", " << maxInt << "] for conversion to int. An unchecked "
2036  "cast would have resulted in " << static_cast<int> (t) << ".");
2037 #endif // INT_MAX == LONG_MAX
2038 
2039  // Implicit conversion from unsigned long to int may cause
2040  // compiler warnings, but static_cast does not.
2041  return static_cast<int> (t);
2042  }
2043 };
2044 
2045 
2047 template<>
2048 class ValueTypeConversionTraits<long, unsigned int> {
2049 public:
2057  static long convert (const unsigned int t) {
2058  // Implicit conversion may cause compiler warnings, but
2059  // static_cast does not.
2060  return static_cast<long> (t);
2061  }
2062 
2064  static long safeConvert (const unsigned int t) {
2065  // On some platforms, sizeof(int) == sizeof(long). (This is the
2066  // "LLP64" model of Win64, which aims for backwards compatibility
2067  // with 32-bit code by making sizeof(int) == sizeof(long) == 4.)
2068  // If this is the case, then we can't safely cast unsigned long to
2069  // int, or unsigned int to long, because values with the most
2070  // significant bit set will overflow to negative values.
2071 
2072  // The C++ standard promises that sizeof (unsigned int) <= sizeof
2073  // (long). If strictly less, then the conversion won't overflow.
2074  // We protect the test with an #ifdef ... #endif to avoid compiler
2075  // warnings like the following: "warning: comparison is always
2076  // false due to limited range of data type".
2077 #if UINT_MAX == LONG_MAX
2078  const long minLong = std::numeric_limits<long>::min ();
2079  const long maxLong = std::numeric_limits<long>::max ();
2080 
2081  // The two types have the same number of bits. Thus,
2082  // two's-complement arithmetic means that if casting from
2083  // unsigned int to long results in a negative number, it
2084  // overflowed. Otherwise, it didn't overflow (same number of
2085  // bits).
2087  static_cast<long> (t) < static_cast<long> (0),
2088  std::range_error,
2089  "Teuchos::ValueTypeConversionTraits<long, unsigned int>::safeConvert: "
2090  "Input unsigned int t = " << t << " is out of the valid range ["
2091  << minLong << ", " << maxLong << "] for conversion to long.");
2092 #endif // UINT_MAX == LONG_MAX
2093 
2094  return static_cast<long> (t);
2095  }
2096 };
2097 
2098 
2100 template<>
2101 class ValueTypeConversionTraits<unsigned int, long> {
2102 public:
2109  static unsigned int convert (const long t) {
2110  // Implicit conversion from long to unsigned int may cause
2111  // compiler warnings, but static_cast does not.
2112  return static_cast<unsigned int> (t);
2113  }
2114 
2116  static unsigned int safeConvert (const long t) {
2117  // On some platforms, sizeof(int) == sizeof(long). (This is the
2118  // "LLP64" model of Win64, which aims for backwards compatibility
2119  // with 32-bit code by making sizeof(int) == sizeof(long) == 4.)
2120  // In this case, conversion from long to unsigned int can't
2121  // overflow.
2122 
2123  // The C++ standard promises that sizeof (unsigned int) <= sizeof (long).
2124  if (sizeof (unsigned int) < sizeof (long)) {
2125  const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
2126 
2128  t < static_cast<long> (0) || t > static_cast<long> (maxInt),
2129  std::range_error,
2130  "Teuchos::ValueTypeConversionTraits<unsigned int, long>::safeConvert: "
2131  "Input long t = " << t << " is out of the valid range [0, "
2132  << maxInt << "] for conversion to unsigned int.");
2133  }
2134  // Implicit conversion from long to unsigned int may cause
2135  // compiler warnings, but static_cast does not.
2136  return static_cast<unsigned int> (t);
2137  }
2138 };
2139 
2140 
2142 template<>
2143 class ValueTypeConversionTraits<unsigned int, unsigned long> {
2144 public:
2151  static unsigned int convert (const unsigned long t) {
2152  // Implicit conversion from unsigned long to unsigned int may cause
2153  // compiler warnings, but static_cast does not.
2154  return static_cast<unsigned int> (t);
2155  }
2156 
2158  static unsigned int safeConvert (const unsigned long t) {
2159  const unsigned int minInt = 0; // Had better be, since it's unsigned.
2160  const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
2161 
2162  // t >= 0 by definition, because it is unsigned.
2164  t > static_cast<unsigned long> (maxInt),
2165  std::range_error,
2166  "Teuchos::ValueTypeConversionTraits<unsigned int, unsigned long>::safeConvert: "
2167  "Input unsigned long t = " << t << " is out of the valid range [" << minInt
2168  << ", " << maxInt << "] for conversion to unsigned int.");
2169 
2170  // Implicit conversion from unsigned long to unsigned int may
2171  // cause compiler warnings, but static_cast does not.
2172  return static_cast<unsigned int> (t);
2173  }
2174 };
2175 
2177 template<>
2178 class ValueTypeConversionTraits<unsigned short, unsigned long> {
2179 public:
2186  static unsigned short convert (const unsigned long t) {
2187  // Implicit conversion from unsigned long to unsigned short may cause
2188  // compiler warnings, but static_cast does not.
2189  return static_cast<unsigned short> (t);
2190  }
2191 
2193  static unsigned short safeConvert (const unsigned long t) {
2194  const unsigned short minShort = 0; // Had better be, since it's unsigned.
2195  const unsigned short maxShort = std::numeric_limits<unsigned short>::max ();
2196 
2197  // t >= 0 by definition, because it is unsigned.
2199  t > static_cast<unsigned long> (maxShort),
2200  std::range_error,
2201  "Teuchos::ValueTypeConversionTraits<unsigned short, unsigned long>::safeConvert: "
2202  "Input unsigned long t = " << t << " is out of the valid range [" << minShort
2203  << ", " << maxShort << "] for conversion to unsigned short.");
2204 
2205  // Implicit conversion from unsigned long to unsigned short may
2206  // cause compiler warnings, but static_cast does not.
2207  return static_cast<unsigned short> (t);
2208  }
2209 };
2210 
2212 template<>
2213 class ValueTypeConversionTraits<int, long long> {
2214 public:
2220  static int convert (const long long t) {
2221  // Implicit conversion from long long to int may cause compiler
2222  // warnings, but static_cast does not.
2223  return static_cast<int> (t);
2224  }
2225 
2227  static int safeConvert (const long long t) {
2228  const int minInt = std::numeric_limits<int>::min ();
2229  const int maxInt = std::numeric_limits<int>::max ();
2230 
2232  t < static_cast<long long> (minInt) ||
2233  t > static_cast<long long> (maxInt),
2234  std::range_error,
2235  "Teuchos::ValueTypeConversionTraits<int, long long>::safeConvert: "
2236  "Input long long t = " << t << " is out of the valid range [" << minInt
2237  << ", " << maxInt << "] for conversion to int.");
2238 
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 };
2244 
2245 
2247 template<>
2248 class ValueTypeConversionTraits<unsigned int, long long> {
2249 public:
2256  static unsigned int convert (const long long t) {
2257  // Implicit conversion from long long to unsigned int may cause
2258  // compiler warnings, but static_cast does not.
2259  return static_cast<unsigned int> (t);
2260  }
2261 
2263  static unsigned int safeConvert (const long long t) {
2264  const unsigned int minInt = 0; // Had better be, because it's unsigned.
2265  const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
2266 
2268  t < static_cast<long long> (minInt) || t > static_cast<long long> (maxInt),
2269  std::range_error,
2270  "Teuchos::ValueTypeConversionTraits<unsigned int, long long>::safeConvert: "
2271  "Input long long t = " << t << " is out of the valid range [" << minInt
2272  << ", " << maxInt << "] for conversion to unsigned int.");
2273 
2274  // Implicit conversion from long long to unsigned int may cause
2275  // compiler warnings, but static_cast does not.
2276  return static_cast<unsigned int> (t);
2277  }
2278 };
2279 
2280 
2282 template<>
2283 class ValueTypeConversionTraits<int, unsigned long long> {
2284 public:
2290  static int convert (const unsigned long long t) {
2291  // Implicit conversion from unsigned long long to int may cause
2292  // compiler warnings, but static_cast does not.
2293  return static_cast<int> (t);
2294  }
2295 
2297  static int safeConvert (const unsigned long long t) {
2298  const int minInt = std::numeric_limits<int>::min ();
2299  const int maxInt = std::numeric_limits<int>::max ();
2300 
2301  // t >= 0 by definition, because it is unsigned.
2303  t > static_cast<unsigned long long> (maxInt),
2304  std::invalid_argument,
2305  "Teuchos::ValueTypeConversionTraits<int, unsigned long long>::safeConvert: "
2306  "Input unsigned long long t = " << t << " is out of the valid range [" << minInt
2307  << ", " << maxInt << "] for conversion to int.");
2308 
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 };
2314 
2315 
2317 template<>
2318 class ValueTypeConversionTraits<unsigned int, unsigned long long> {
2319 public:
2326  static unsigned int convert (const unsigned long long t) {
2327  // Implicit conversion from unsigned long long to unsigned int may
2328  // cause compiler warnings, but static_cast does not.
2329  return static_cast<unsigned int> (t);
2330  }
2331 
2333  static unsigned int safeConvert (const unsigned long long t) {
2334  const unsigned int minInt = 0; // Had better be, since it's unsigned.
2335  const unsigned int maxInt = std::numeric_limits<unsigned int>::max ();
2336 
2337  // t >= 0 by definition, because it is unsigned.
2339  t > static_cast<unsigned long long> (maxInt),
2340  std::invalid_argument,
2341  "Teuchos::ValueTypeConversionTraits<unsigned int, unsigned long long>::safeConvert: "
2342  "Input unsigned long long t = " << t << " is out of the valid range [" << minInt
2343  << ", " << maxInt << "] for conversion to unsigned int.");
2344 
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 };
2350 
2351 //
2352 // * Conversions from built-in integer types to built-in real-valued
2353 // floating-point types.
2354 //
2355 
2357 template<>
2358 class ValueTypeConversionTraits<float, long long> {
2359 public:
2365  static float convert (const long long t) {
2366  // Implicit conversion from long long to float may cause compiler
2367  // warnings, but static_cast does not.
2368  return static_cast<float> (t);
2369  }
2370 
2372  static float safeConvert (const long long t) {
2373  // std::numeric_limits<float>::min() gives the minimum _positive_
2374  // normalized value of type float. IEEE 754 floating-point values
2375  // can change sign just by flipping the sign bit, so the "most
2376  // negative" finite float is just the negative of the "most
2377  // positive" finite float.
2378  const float minFloat = -std::numeric_limits<float>::max ();
2379  const float maxFloat = std::numeric_limits<float>::max ();
2380 
2381  // mfh 16 Nov 2012: On my platform (gcc 4.7.2, Red Hat Linux 5,
2382  // Intel x86_64), first casting [minFloat,maxFloat] to long long
2383  // (so that the comparison only compares long long values)
2384  // gives different results in the comparison below than just
2385  // comparing t (as a long long) with minFloat and maxFloat. It
2386  // doesn't matter whether you use static_cast<long long> (...) or
2387  // (long long) (...) to do the cast: the original float interval
2388  // of [-3.40282e+38, 3.40282e+38] becomes [-9223372036854775808,
2389  // -9223372036854775808], which is obviously wrong.
2391  t < minFloat || t > maxFloat,
2392  std::range_error,
2393  "Teuchos::ValueTypeConversionTraits<float, long long>::safeConvert: "
2394  "Input long long t = " << t << " is out of the valid range [" << minFloat
2395  << ", " << maxFloat << "] for conversion to float.");
2396 
2397  // Implicit conversion from long long to float may cause compiler
2398  // warnings, but static_cast does not.
2399  return static_cast<float> (t);
2400  }
2401 };
2402 
2403 
2405 template<>
2406 class ValueTypeConversionTraits<float, unsigned long long> {
2407 public:
2413  static float convert (const unsigned long long t) {
2414  // Implicit conversion from unsigned long long to float may cause
2415  // compiler warnings, but static_cast does not.
2416  return static_cast<float> (t);
2417  }
2418 
2420  static float safeConvert (const unsigned long long t) {
2421  // std::numeric_limits<float>::min() gives the minimum _positive_
2422  // normalized value of type float. IEEE 754 floating-point values
2423  // can change sign just by flipping the sign bit, so the "most
2424  // negative" finite float is just the negative of the "most
2425  // positive" finite float.
2426  const float minFloat = -std::numeric_limits<float>::max ();
2427  const float maxFloat = std::numeric_limits<float>::max ();
2428 
2429  // t >= 0 by definition, because it is unsigned.
2430  //
2431  // mfh 16 Nov 2012: See my note above on the <float, long long>
2432  // specialization that explains why I don't cast maxFloat to
2433  // unsigned long long here.
2435  t > maxFloat,
2436  std::invalid_argument,
2437  "Teuchos::ValueTypeConversionTraits<float, unsigned long long>::safeConvert: "
2438  "Input unsigned long long t = " << t << " is out of the valid range [" << minFloat
2439  << ", " << maxFloat << "] for conversion to float.");
2440 
2441  // Implicit conversion from unsigned long long to float may cause
2442  // compiler warnings, but static_cast does not.
2443  return static_cast<float> (t);
2444  }
2445 };
2446 
2447 //
2448 // * Other conversions
2449 //
2450 
2452 template<int N>
2453 class ValueTypeConversionTraits<std::string, char[N]> {
2454 public:
2455  static std::string convert( const char t[] )
2456  { return std::string(t); }
2457  static std::string safeConvert( const char t[] )
2458  { return std::string(t); }
2459 };
2460 
2461 //
2462 // * Conversions from built-in integer types to std::complex<T>.
2463 //
2464 
2465 #ifdef HAVE_TEUCHOS_COMPLEX
2466 
2468 template<class RealType>
2469 class ValueTypeConversionTraits<std::complex<RealType>, short> {
2470 public:
2471  inline static std::complex<RealType> convert (const short t) {
2472  // Let RealType handle the conversion of the zero imaginary part.
2473  return std::complex<RealType> (t, as<RealType> (0));
2474  }
2475  static std::complex<RealType> safeConvert (const short t) {
2476  // Let RealType handle the conversion of the zero imaginary part.
2477  return std::complex<RealType> (t, asSafe<RealType> (0));
2478  }
2479 };
2480 
2482 template<class RealType>
2483 class ValueTypeConversionTraits<std::complex<RealType>, unsigned short> {
2484 public:
2485  inline static std::complex<RealType> convert (const unsigned short t) {
2486  // Let RealType handle the conversion of the zero imaginary part.
2487  return std::complex<RealType> (t, as<RealType> (0));
2488  }
2489  static std::complex<RealType> safeConvert (const unsigned short t) {
2490  // Let RealType handle the conversion of the zero imaginary part.
2491  return std::complex<RealType> (t, asSafe<RealType> (0));
2492  }
2493 };
2494 
2496 template<class RealType>
2497 class ValueTypeConversionTraits<std::complex<RealType>, int> {
2498 public:
2499  inline static std::complex<RealType> convert (const int t) {
2500  // Let RealType handle the conversion of the zero imaginary part.
2501  return std::complex<RealType> (t, as<RealType> (0));
2502  }
2503  static std::complex<RealType> safeConvert (const int t) {
2504  // Let RealType handle the conversion of the zero imaginary part.
2505  return std::complex<RealType> (t, asSafe<RealType> (0));
2506  }
2507 };
2508 
2510 template<class RealType>
2511 class ValueTypeConversionTraits<std::complex<RealType>, unsigned int> {
2512 public:
2513  inline static std::complex<RealType> convert (const unsigned int t) {
2514  // Let RealType handle the conversion of the zero imaginary part.
2515  return std::complex<RealType> (t, as<RealType> (0));
2516  }
2517  static std::complex<RealType> safeConvert (const unsigned int t) {
2518  // Let RealType handle the conversion of the zero imaginary part.
2519  return std::complex<RealType> (t, asSafe<RealType> (0));
2520  }
2521 };
2522 
2524 template<class RealType>
2525 class ValueTypeConversionTraits<std::complex<RealType>, long> {
2526 public:
2527  inline static std::complex<RealType> convert (const long t) {
2528  // Let RealType handle the conversion of the zero imaginary part.
2529  return std::complex<RealType> (t, as<RealType> (0));
2530  }
2531  static std::complex<RealType> safeConvert (const long t) {
2532  // Let RealType handle the conversion of the zero imaginary part.
2533  return std::complex<RealType> (t, asSafe<RealType> (0));
2534  }
2535 };
2536 
2538 template<class RealType>
2539 class ValueTypeConversionTraits<std::complex<RealType>, unsigned long> {
2540 public:
2541  inline static std::complex<RealType> convert (const unsigned long t) {
2542  // Let RealType handle the conversion of the zero imaginary part.
2543  return std::complex<RealType> (t, as<RealType> (0));
2544  }
2545  static std::complex<RealType> safeConvert (const unsigned long t) {
2546  // Let RealType handle the conversion of the zero imaginary part.
2547  return std::complex<RealType> (t, asSafe<RealType> (0));
2548  }
2549 };
2550 
2552 template<class RealType>
2553 class ValueTypeConversionTraits<std::complex<RealType>, long long> {
2554 public:
2555  inline static std::complex<RealType> convert (const long long t) {
2556  // Let RealType handle the conversion of the zero imaginary part.
2557  return std::complex<RealType> (t, as<RealType> (0));
2558  }
2559  static std::complex<RealType> safeConvert (const long long t) {
2560  // Let RealType handle the conversion of the zero imaginary part.
2561  return std::complex<RealType> (t, asSafe<RealType> (0));
2562  }
2563 };
2564 
2566 template<class RealType>
2567 class ValueTypeConversionTraits<std::complex<RealType>, unsigned long long> {
2568 public:
2569  inline static std::complex<RealType> convert (const unsigned long long t) {
2570  // Let RealType handle the conversion of the zero imaginary part.
2571  return std::complex<RealType> (t, as<RealType> (0));
2572  }
2573  static std::complex<RealType> safeConvert (const unsigned long long t) {
2574  // Let RealType handle the conversion of the zero imaginary part.
2575  return std::complex<RealType> (t, asSafe<RealType> (0));
2576  }
2577 };
2578 
2579 #endif // HAVE_TEUCHOS_COMPLEX
2580 
2581 //
2582 // * Conversions for dd_real and qd_real
2583 //
2584 
2585 #ifdef HAVE_TEUCHOS_QD
2586 
2588 template <>
2589 class ValueTypeConversionTraits<double, qd_real> {
2590 public:
2591  inline static double convert (const qd_real t) {
2592  return to_double (t);
2593  }
2594  static double safeConvert (const qd_real t) {
2595  // std::numeric_limits<double>::min() gives the minimum _positive_
2596  // normalized value of type double. IEEE 754 floating-point
2597  // values can change sign just by flipping the sign bit, so the
2598  // "most negative" finite double is just the negative of the "most
2599  // positive" finite double.
2600  const qd_real minVal = -std::numeric_limits<double>::max ();
2601  const qd_real maxVal = std::numeric_limits<double>::max ();
2602 
2604  t < minVal || t > maxVal,
2605  std::range_error,
2606  "Teuchos::ValueTypeConversionTraits<double, qd_real>::safeConvert: "
2607  "Input qd_real t = " << t << " is out of the valid range [" << minVal
2608  << ", " << maxVal << "] for conversion to double.");
2609 
2610  return to_double (t);
2611  }
2612 };
2613 
2615 template <>
2616 class ValueTypeConversionTraits<float, qd_real> {
2617 public:
2618  inline static float convert (const qd_real t) {
2619  // In a debug build, this should also test the double->float
2620  // conversion for overflow.
2621  return as<float> (to_double (t));
2622  }
2623 
2624  static float safeConvert (const qd_real t) {
2625  // std::numeric_limits<float>::min() gives the minimum _positive_
2626  // normalized value of type float. IEEE 754 floating-point
2627  // values can change sign just by flipping the sign bit, so the
2628  // "most negative" finite float is just the negative of the "most
2629  // positive" finite float.
2630  //
2631  // qd_real has a constructor for double, but not for float,
2632  // so we cast to double first.
2633  const qd_real minVal = static_cast<double> (-std::numeric_limits<float>::max ());
2634  const qd_real maxVal = static_cast<double> (std::numeric_limits<float>::max ());
2635 
2637  t < minVal || t > maxVal,
2638  std::range_error,
2639  "Teuchos::ValueTypeConversionTraits<float, qd_real>::safeConvert: "
2640  "Input qd_real t = " << t << " is out of the valid range [" << minVal
2641  << ", " << maxVal << "] for conversion to float.");
2642 
2643  // This should also test the double->float conversion for overflow.
2644  return asSafe<float> (to_double (t));
2645  }
2646 };
2647 
2649 template <>
2650 class ValueTypeConversionTraits<int, qd_real> {
2651 public:
2652  inline static int convert (const qd_real t) {
2653  return to_int (t);
2654  }
2655  static int safeConvert (const qd_real t) {
2656  // qd_real has a constructor for int.
2657  const qd_real minVal = std::numeric_limits<int>::min ();
2658  const qd_real maxVal = std::numeric_limits<int>::max ();
2659 
2661  t < minVal || t > maxVal,
2662  std::range_error,
2663  "Teuchos::ValueTypeConversionTraits<int, qd_real>::safeConvert: "
2664  "Input qd_real t = " << t << " is out of the valid range [" << minVal
2665  << ", " << maxVal << "] for conversion to int.");
2666  return to_int (t);
2667  }
2668 };
2669 
2671 template <>
2672 class ValueTypeConversionTraits<dd_real, qd_real> {
2673 public:
2674  inline static dd_real convert (const qd_real t) {
2675  return to_dd_real(t);
2676  }
2677  static dd_real safeConvert (const qd_real t) {
2678  // std::numeric_limits<dd_real>::min() gives the minimum
2679  // _positive_ (normalized? not sure what this means for dd_real --
2680  // mfh 14 Nov 2012) value of type dd_real. dd_real values are
2681  // built from two IEEE 754 doubles. This means they can change
2682  // sign just by flipping the sign bit, so the "most negative"
2683  // finite dd_real is just the negative of the "most positive"
2684  // finite dd_real.
2685  //
2686  // qd_real has a constructor for dd_real.
2687  const qd_real minVal = -std::numeric_limits<dd_real>::max ();
2688  const qd_real maxVal = std::numeric_limits<dd_real>::max ();
2689 
2691  t < minVal || t > maxVal,
2692  std::range_error,
2693  "Teuchos::ValueTypeConversionTraits<dd_real, qd_real>::safeConvert: "
2694  "Input qd_real t = " << t << " is out of the valid range [" << minVal
2695  << ", " << maxVal << "] for conversion to dd_real.");
2696 
2697  return to_dd_real (t);
2698  }
2699 };
2700 
2702 template <>
2703 class ValueTypeConversionTraits<double, dd_real> {
2704 public:
2705  inline static double convert (const dd_real t) {
2706  return to_double (t);
2707  }
2708  static double safeConvert (const dd_real t) {
2709  // std::numeric_limits<double>::min() gives the minimum _positive_
2710  // normalized value of type double. IEEE 754 floating-point
2711  // values can change sign just by flipping the sign bit, so the
2712  // "most negative" finite double is just the negative of the "most
2713  // positive" finite double.
2714  //
2715  // qd_real has a constructor for double.
2716  const dd_real minVal = -std::numeric_limits<double>::max ();
2717  const dd_real maxVal = std::numeric_limits<double>::max ();
2718 
2720  t < minVal || t > maxVal,
2721  std::range_error,
2722  "Teuchos::ValueTypeConversionTraits<double, dd_real>::safeConvert: "
2723  "Input dd_real t = " << t << " is out of the valid range [" << minVal
2724  << ", " << maxVal << "] for conversion to double.");
2725 
2726  return to_double (t);
2727  }
2728 };
2729 
2731 template <>
2732 class ValueTypeConversionTraits<float, dd_real> {
2733 public:
2734  inline static float convert (const dd_real t) {
2735  // This also checks for double->float overflow in a debug build.
2736  return as<float> (to_double (t));
2737  }
2738  static float safeConvert (const dd_real t) {
2739  // std::numeric_limits<float>::min() gives the minimum _positive_
2740  // normalized value of type float. IEEE 754 floating-point
2741  // values can change sign just by flipping the sign bit, so the
2742  // "most negative" finite float is just the negative of the "most
2743  // positive" finite float.
2744  //
2745  // dd_real has a constructor for double but not for float,
2746  // so we cast to double first.
2747  const dd_real minVal = static_cast<double> (-std::numeric_limits<float>::max ());
2748  const dd_real maxVal = static_cast<double> (std::numeric_limits<float>::max ());
2749 
2751  t < minVal || t > maxVal,
2752  std::range_error,
2753  "Teuchos::ValueTypeConversionTraits<float, dd_real>::safeConvert: "
2754  "Input dd_real t = " << t << " is out of the valid range [" << minVal
2755  << ", " << maxVal << "] for conversion to float.");
2756 
2757  // This also checks for double->float overflow.
2758  return as<float> (to_double (t));
2759  }
2760 };
2761 
2763 template <>
2764 class ValueTypeConversionTraits<int, dd_real> {
2765 public:
2766  inline static int convert (const dd_real t) {
2767  return to_int (t);
2768  }
2769  static int safeConvert (const dd_real t) {
2770  // dd_real has a constructor for int.
2771  const dd_real minVal = std::numeric_limits<int>::min ();
2772  const dd_real maxVal = std::numeric_limits<int>::max ();
2773 
2775  t < minVal || t > maxVal,
2776  std::range_error,
2777  "Teuchos::ValueTypeConversionTraits<int, dd_real>::safeConvert: "
2778  "Input dd_real t = " << t << " is out of the valid range [" << minVal
2779  << ", " << maxVal << "] for conversion to int.");
2780  return to_int (t);
2781  }
2782 };
2783 
2785 template <>
2786 class ValueTypeConversionTraits<qd_real, long unsigned int> {
2787 public:
2788  inline static qd_real convert( const long unsigned int t ) {
2789  // FIXME (mfh 14 Nov 2012): qd_real unfortunately lacks a
2790  // constructor or conversion function for conversions from
2791  // built-in integer types other than int. However, it does allow
2792  // reading in values from a string. We could use this to convert
2793  // from any type to qd_real, by first writing the value to an
2794  // std::ostringstream, then creating a qd_real from the resulting
2795  // string.
2796  return ValueTypeConversionTraits<qd_real,int>::convert(ValueTypeConversionTraits<int,long unsigned int>::convert(t));
2797  }
2798  inline static qd_real safeConvert( const long unsigned int t )
2799  { return ValueTypeConversionTraits<qd_real,int>::safeConvert(ValueTypeConversionTraits<int,long unsigned int>::safeConvert(t)); }
2800 };
2801 
2803 template <>
2804 class ValueTypeConversionTraits<dd_real, long unsigned int> {
2805 public:
2806  inline static dd_real convert( const long unsigned int t ) {
2807  // FIXME (mfh 14 Nov 2012): dd_real unfortunately lacks a
2808  // constructor or conversion function for conversions from
2809  // built-in integer types other than int. However, it does allow
2810  // reading in values from a string. We could use this to convert
2811  // from any type to dd_real, by first writing the value to an
2812  // std::ostringstream, then creating a dd_real from the resulting
2813  // string.
2814  return ValueTypeConversionTraits<dd_real,int>::convert(ValueTypeConversionTraits<int,long unsigned int>::convert(t));
2815  }
2816  inline static dd_real safeConvert( const long unsigned int t )
2817  { return ValueTypeConversionTraits<dd_real,int>::safeConvert(ValueTypeConversionTraits<int,long unsigned int>::safeConvert(t)); }
2818 };
2819 
2820 #endif // HAVE_TEUCHOS_QD
2821 
2822 // ToDo: Add more specializations as needed!
2823 
2824 template<class TypeTo, class TypeFrom>
2825 inline TypeTo as( const TypeFrom& t )
2826 {
2827 #ifdef HAVE_TEUCHOS_DEBUG
2829 #else
2831 #endif // HAVE_TEUCHOS_DEBUG
2832 }
2833 
2834 template<class TypeTo, class TypeFrom>
2835 inline TypeTo asSafe( const TypeFrom& t )
2836 {
2838 }
2839 
2840 } // end namespace Teuchos
2841 
2842 
2843 #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:377
static long long safeConvert(const std::string &t)
Convert the given std::string to a long long, with checks.
Definition: Teuchos_as.hpp:699
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:607
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:869
static long safeConvert(const std::string &t)
Convert the given std::string to a long, with checks.
Definition: Teuchos_as.hpp:771
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:914
static short convert(const std::string &t)
Convert the given std::string to a short.
Definition: Teuchos_as.hpp:964
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 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:793
static unsigned long safeConvertToUnsignedLong(const std::string &t)
Convert the given std::string to an intermediate unsigned long, with checks.
Definition: Teuchos_as.hpp:887
#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
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:874
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:776
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:798
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:730
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.
static long safeConvertToLong(const std::string &t)
Convert the given std::string to an intermediate long, with checks.
Definition: Teuchos_as.hpp:842
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 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:754
static unsigned long safeConvertToUnsignedLong(const std::string &t)
Convert the given std::string to an intermediate unsigned long, with checks.
Definition: Teuchos_as.hpp:977
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:713
static long double safeConvert(const std::string &t)
Definition: Teuchos_as.hpp:678
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: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:919
static long safeConvertToLong(const std::string &t)
Convert the given std::string to an intermediate long, with checks.
Definition: Teuchos_as.hpp:932
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 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: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 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:959
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.