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