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//
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
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
87namespace Teuchos {
88
89
178template<class TypeTo, class TypeFrom>
180public:
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
286template<class TypeTo, class TypeFrom>
287inline TypeTo as( const TypeFrom& t );
288
289
355template<class TypeTo, class TypeFrom>
356inline TypeTo asSafe( const TypeFrom& t );
357
358
371template <class TypeTo>
372class asFunc {
373public:
374 asFunc() {}
375
376 template <class TypeFrom>
377 inline TypeTo operator()(const TypeFrom &t) {
378 return as<TypeTo>(t);
379 }
380};
381
382
383
384namespace { // 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 () << ", "
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
604template<class OutType>
605class ValueTypeConversionTraits<OutType, std::string> {
606public:
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
625template<>
626class ValueTypeConversionTraits<double, std::string> {
627public:
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
638template<>
639class ValueTypeConversionTraits<float, std::string> {
640public:
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
665template<>
666class ValueTypeConversionTraits<long double, std::string> {
667public:
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
691template<>
692class ValueTypeConversionTraits<long long, std::string> {
693public:
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
722template<>
723class ValueTypeConversionTraits<unsigned long long, std::string> {
724public:
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
763template<>
764class ValueTypeConversionTraits<long, std::string> {
765public:
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
785template<>
786class ValueTypeConversionTraits<unsigned long, std::string> {
787public:
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
809template<>
810class ValueTypeConversionTraits<unsigned __int64, std::string> {
811public:
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
838template<>
839class ValueTypeConversionTraits<int, std::string> {
840private:
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
863public:
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
883template<>
884class ValueTypeConversionTraits<unsigned int, std::string> {
885private:
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
908public:
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
928template<>
929class ValueTypeConversionTraits<short, std::string> {
930private:
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
953public:
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
973template<>
974class ValueTypeConversionTraits<unsigned short, std::string> {
975private:
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
998public:
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
1020template<>
1021class ValueTypeConversionTraits<float, double> {
1022public:
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
1056template<>
1057class ValueTypeConversionTraits<float, long double> {
1058public:
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
1092template<>
1093class ValueTypeConversionTraits<double, long double> {
1094public:
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
1134template<>
1135class ValueTypeConversionTraits<short, double> {
1136public:
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
1182template<>
1183class ValueTypeConversionTraits<unsigned short, double> {
1184public:
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
1210template<>
1211class ValueTypeConversionTraits<int, double> {
1212public:
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
1254template<>
1255class ValueTypeConversionTraits<unsigned int, double> {
1256public:
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
1282template<>
1283class ValueTypeConversionTraits<long, double> {
1284public:
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
1326template<>
1327class ValueTypeConversionTraits<unsigned long, double> {
1328public:
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
1353template<>
1354class ValueTypeConversionTraits<long long, double> {
1355public:
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
1381template<>
1382class ValueTypeConversionTraits<unsigned long long, double> {
1383public:
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
1409template<>
1410class ValueTypeConversionTraits<short, float> {
1411public:
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
1460template<>
1461class ValueTypeConversionTraits<unsigned short, float> {
1462public:
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
1488template<>
1489class ValueTypeConversionTraits<int, float> {
1490public:
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
1531template<>
1532class ValueTypeConversionTraits<unsigned int, float> {
1533public:
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
1559template<>
1560class ValueTypeConversionTraits<long, float> {
1561public:
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
1608template<>
1609class ValueTypeConversionTraits<unsigned long, float> {
1610public:
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
1635template<>
1636class ValueTypeConversionTraits<long long, float> {
1637public:
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
1653template<>
1654class ValueTypeConversionTraits<unsigned long long, float> {
1655public:
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
1683namespace {
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.
1687template<class SignedIntType, class UnsignedIntType>
1688class UnsignedToSignedValueTypeConversionTraits {
1689public:
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.
1727template<class UnsignedIntType, class SignedIntType>
1728class SignedToUnsignedValueTypeConversionTraits {
1729public:
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 "
1752
1753 return static_cast<UnsignedIntType> (t);
1754 }
1755};
1756
1757} // namespace (anonymous)
1758
1759
1761template<>
1762class ValueTypeConversionTraits<short, unsigned short> {
1763public:
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
1775template<>
1776class ValueTypeConversionTraits<unsigned short, short> {
1777public:
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
1789template<>
1790class ValueTypeConversionTraits<int, unsigned int> {
1791public:
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
1803template<>
1804class ValueTypeConversionTraits<unsigned int, int> {
1805public:
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
1817template<>
1818class ValueTypeConversionTraits<long, unsigned long> {
1819public:
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
1831template<>
1832class ValueTypeConversionTraits<unsigned long, long> {
1833public:
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
1845template<>
1846class ValueTypeConversionTraits<long long, unsigned long long> {
1847public:
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
1859template<>
1860class ValueTypeConversionTraits<unsigned long long, long long> {
1861public:
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
1877template<>
1878class ValueTypeConversionTraits<short, int> {
1879public:
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
1912template<>
1913class ValueTypeConversionTraits<short, long> {
1914public:
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
1947template<>
1949public:
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
1984template<>
1985class ValueTypeConversionTraits<int, unsigned long> {
1986public:
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
2047template<>
2048class ValueTypeConversionTraits<long, unsigned int> {
2049public:
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
2100template<>
2101class ValueTypeConversionTraits<unsigned int, long> {
2102public:
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
2142template<>
2143class ValueTypeConversionTraits<unsigned int, unsigned long> {
2144public:
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
2177template<>
2178class ValueTypeConversionTraits<unsigned short, unsigned long> {
2179public:
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
2212template<>
2213class ValueTypeConversionTraits<int, long long> {
2214public:
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
2247template<>
2248class ValueTypeConversionTraits<unsigned int, long long> {
2249public:
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
2282template<>
2283class ValueTypeConversionTraits<int, unsigned long long> {
2284public:
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
2317template<>
2318class ValueTypeConversionTraits<unsigned int, unsigned long long> {
2319public:
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
2357template<>
2358class ValueTypeConversionTraits<float, long long> {
2359public:
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
2405template<>
2406class ValueTypeConversionTraits<float, unsigned long long> {
2407public:
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
2452template<int N>
2453class ValueTypeConversionTraits<std::string, char[N]> {
2454public:
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
2468template<class RealType>
2469class ValueTypeConversionTraits<std::complex<RealType>, short> {
2470public:
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
2482template<class RealType>
2483class ValueTypeConversionTraits<std::complex<RealType>, unsigned short> {
2484public:
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
2496template<class RealType>
2497class ValueTypeConversionTraits<std::complex<RealType>, int> {
2498public:
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
2510template<class RealType>
2511class ValueTypeConversionTraits<std::complex<RealType>, unsigned int> {
2512public:
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
2524template<class RealType>
2525class ValueTypeConversionTraits<std::complex<RealType>, long> {
2526public:
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
2538template<class RealType>
2539class ValueTypeConversionTraits<std::complex<RealType>, unsigned long> {
2540public:
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
2552template<class RealType>
2553class ValueTypeConversionTraits<std::complex<RealType>, long long> {
2554public:
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
2566template<class RealType>
2567class ValueTypeConversionTraits<std::complex<RealType>, unsigned long long> {
2568public:
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
2581template<>
2582class ValueTypeConversionTraits<std::complex<float>, std::complex<double> > {
2583public:
2584 inline static std::complex<float> convert (const std::complex<double> t) {
2585 // Let double->float conversion handle real and imaginary part.
2586 return std::complex<float> (as<float> (t.real ()), as<float> (t.imag ()));
2587 }
2588 static std::complex<float> safeConvert (const std::complex<double> t) {
2589 // Let double->float conversion handle real and imaginary part.
2590 return std::complex<float> (asSafe<float> (t.real ()), asSafe<float> (t.imag ()));
2591 }
2592};
2593
2594#endif // HAVE_TEUCHOS_COMPLEX
2595
2596//
2597// * Conversions for dd_real and qd_real
2598//
2599
2600#ifdef HAVE_TEUCHOS_QD
2601
2603template <>
2604class ValueTypeConversionTraits<double, qd_real> {
2605public:
2606 inline static double convert (const qd_real t) {
2607 return to_double (t);
2608 }
2609 static double safeConvert (const qd_real t) {
2610 // std::numeric_limits<double>::min() gives the minimum _positive_
2611 // normalized value of type double. IEEE 754 floating-point
2612 // values can change sign just by flipping the sign bit, so the
2613 // "most negative" finite double is just the negative of the "most
2614 // positive" finite double.
2615 const qd_real minVal = -std::numeric_limits<double>::max ();
2616 const qd_real maxVal = std::numeric_limits<double>::max ();
2617
2619 t < minVal || t > maxVal,
2620 std::range_error,
2621 "Teuchos::ValueTypeConversionTraits<double, qd_real>::safeConvert: "
2622 "Input qd_real t = " << t << " is out of the valid range [" << minVal
2623 << ", " << maxVal << "] for conversion to double.");
2624
2625 return to_double (t);
2626 }
2627};
2628
2630template <>
2631class ValueTypeConversionTraits<float, qd_real> {
2632public:
2633 inline static float convert (const qd_real t) {
2634 // In a debug build, this should also test the double->float
2635 // conversion for overflow.
2636 return as<float> (to_double (t));
2637 }
2638
2639 static float safeConvert (const qd_real t) {
2640 // std::numeric_limits<float>::min() gives the minimum _positive_
2641 // normalized value of type float. IEEE 754 floating-point
2642 // values can change sign just by flipping the sign bit, so the
2643 // "most negative" finite float is just the negative of the "most
2644 // positive" finite float.
2645 //
2646 // qd_real has a constructor for double, but not for float,
2647 // so we cast to double first.
2648 const qd_real minVal = static_cast<double> (-std::numeric_limits<float>::max ());
2649 const qd_real maxVal = static_cast<double> (std::numeric_limits<float>::max ());
2650
2652 t < minVal || t > maxVal,
2653 std::range_error,
2654 "Teuchos::ValueTypeConversionTraits<float, qd_real>::safeConvert: "
2655 "Input qd_real t = " << t << " is out of the valid range [" << minVal
2656 << ", " << maxVal << "] for conversion to float.");
2657
2658 // This should also test the double->float conversion for overflow.
2659 return asSafe<float> (to_double (t));
2660 }
2661};
2662
2664template <>
2665class ValueTypeConversionTraits<int, qd_real> {
2666public:
2667 inline static int convert (const qd_real t) {
2668 return to_int (t);
2669 }
2670 static int safeConvert (const qd_real t) {
2671 // qd_real has a constructor for int.
2672 const qd_real minVal = std::numeric_limits<int>::min ();
2673 const qd_real maxVal = std::numeric_limits<int>::max ();
2674
2676 t < minVal || t > maxVal,
2677 std::range_error,
2678 "Teuchos::ValueTypeConversionTraits<int, qd_real>::safeConvert: "
2679 "Input qd_real t = " << t << " is out of the valid range [" << minVal
2680 << ", " << maxVal << "] for conversion to int.");
2681 return to_int (t);
2682 }
2683};
2684
2686template <>
2687class ValueTypeConversionTraits<dd_real, qd_real> {
2688public:
2689 inline static dd_real convert (const qd_real t) {
2690 return to_dd_real(t);
2691 }
2692 static dd_real safeConvert (const qd_real t) {
2693 // std::numeric_limits<dd_real>::min() gives the minimum
2694 // _positive_ (normalized? not sure what this means for dd_real --
2695 // mfh 14 Nov 2012) value of type dd_real. dd_real values are
2696 // built from two IEEE 754 doubles. This means they can change
2697 // sign just by flipping the sign bit, so the "most negative"
2698 // finite dd_real is just the negative of the "most positive"
2699 // finite dd_real.
2700 //
2701 // qd_real has a constructor for dd_real.
2702 const qd_real minVal = -std::numeric_limits<dd_real>::max ();
2703 const qd_real maxVal = std::numeric_limits<dd_real>::max ();
2704
2706 t < minVal || t > maxVal,
2707 std::range_error,
2708 "Teuchos::ValueTypeConversionTraits<dd_real, qd_real>::safeConvert: "
2709 "Input qd_real t = " << t << " is out of the valid range [" << minVal
2710 << ", " << maxVal << "] for conversion to dd_real.");
2711
2712 return to_dd_real (t);
2713 }
2714};
2715
2717template <>
2718class ValueTypeConversionTraits<double, dd_real> {
2719public:
2720 inline static double convert (const dd_real t) {
2721 return to_double (t);
2722 }
2723 static double safeConvert (const dd_real t) {
2724 // std::numeric_limits<double>::min() gives the minimum _positive_
2725 // normalized value of type double. IEEE 754 floating-point
2726 // values can change sign just by flipping the sign bit, so the
2727 // "most negative" finite double is just the negative of the "most
2728 // positive" finite double.
2729 //
2730 // qd_real has a constructor for double.
2731 const dd_real minVal = -std::numeric_limits<double>::max ();
2732 const dd_real maxVal = std::numeric_limits<double>::max ();
2733
2735 t < minVal || t > maxVal,
2736 std::range_error,
2737 "Teuchos::ValueTypeConversionTraits<double, dd_real>::safeConvert: "
2738 "Input dd_real t = " << t << " is out of the valid range [" << minVal
2739 << ", " << maxVal << "] for conversion to double.");
2740
2741 return to_double (t);
2742 }
2743};
2744
2746template <>
2747class ValueTypeConversionTraits<float, dd_real> {
2748public:
2749 inline static float convert (const dd_real t) {
2750 // This also checks for double->float overflow in a debug build.
2751 return as<float> (to_double (t));
2752 }
2753 static float safeConvert (const dd_real t) {
2754 // std::numeric_limits<float>::min() gives the minimum _positive_
2755 // normalized value of type float. IEEE 754 floating-point
2756 // values can change sign just by flipping the sign bit, so the
2757 // "most negative" finite float is just the negative of the "most
2758 // positive" finite float.
2759 //
2760 // dd_real has a constructor for double but not for float,
2761 // so we cast to double first.
2762 const dd_real minVal = static_cast<double> (-std::numeric_limits<float>::max ());
2763 const dd_real maxVal = static_cast<double> (std::numeric_limits<float>::max ());
2764
2766 t < minVal || t > maxVal,
2767 std::range_error,
2768 "Teuchos::ValueTypeConversionTraits<float, dd_real>::safeConvert: "
2769 "Input dd_real t = " << t << " is out of the valid range [" << minVal
2770 << ", " << maxVal << "] for conversion to float.");
2771
2772 // This also checks for double->float overflow.
2773 return as<float> (to_double (t));
2774 }
2775};
2776
2778template <>
2779class ValueTypeConversionTraits<int, dd_real> {
2780public:
2781 inline static int convert (const dd_real t) {
2782 return to_int (t);
2783 }
2784 static int safeConvert (const dd_real t) {
2785 // dd_real has a constructor for int.
2786 const dd_real minVal = std::numeric_limits<int>::min ();
2787 const dd_real maxVal = std::numeric_limits<int>::max ();
2788
2790 t < minVal || t > maxVal,
2791 std::range_error,
2792 "Teuchos::ValueTypeConversionTraits<int, dd_real>::safeConvert: "
2793 "Input dd_real t = " << t << " is out of the valid range [" << minVal
2794 << ", " << maxVal << "] for conversion to int.");
2795 return to_int (t);
2796 }
2797};
2798
2800template <>
2801class ValueTypeConversionTraits<qd_real, long unsigned int> {
2802public:
2803 inline static qd_real convert( const long unsigned int t ) {
2804 // FIXME (mfh 14 Nov 2012): qd_real unfortunately lacks a
2805 // constructor or conversion function for conversions from
2806 // built-in integer types other than int. However, it does allow
2807 // reading in values from a string. We could use this to convert
2808 // from any type to qd_real, by first writing the value to an
2809 // std::ostringstream, then creating a qd_real from the resulting
2810 // string.
2812 }
2813 inline static qd_real safeConvert( const long unsigned int t )
2815};
2816
2818template <>
2819class ValueTypeConversionTraits<dd_real, long unsigned int> {
2820public:
2821 inline static dd_real convert( const long unsigned int t ) {
2822 // FIXME (mfh 14 Nov 2012): dd_real unfortunately lacks a
2823 // constructor or conversion function for conversions from
2824 // built-in integer types other than int. However, it does allow
2825 // reading in values from a string. We could use this to convert
2826 // from any type to dd_real, by first writing the value to an
2827 // std::ostringstream, then creating a dd_real from the resulting
2828 // string.
2830 }
2831 inline static dd_real safeConvert( const long unsigned int t )
2833};
2834
2835#endif // HAVE_TEUCHOS_QD
2836
2837// ToDo: Add more specializations as needed!
2838
2839template<class TypeTo, class TypeFrom>
2840inline TypeTo as( const TypeFrom& t )
2841{
2842#ifdef HAVE_TEUCHOS_DEBUG
2844#else
2846#endif // HAVE_TEUCHOS_DEBUG
2847}
2848
2849template<class TypeTo, class TypeFrom>
2850inline TypeTo asSafe( const TypeFrom& t )
2851{
2853}
2854
2855} // end namespace Teuchos
2856
2857
2858#endif // TEUCHOS_AS_HPP
Teuchos header file which uses auto-configuration information to include necessary C++ headers.
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.
Definition: Teuchos_as.hpp:869
static int convert(const std::string &t)
Convert the given std::string to an int.
Definition: Teuchos_as.hpp:874
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.
Definition: Teuchos_as.hpp:776
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 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.
Definition: Teuchos_as.hpp:699
static long long convert(const std::string &t)
Convert the given std::string to a long long.
Definition: Teuchos_as.hpp:713
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.
Definition: Teuchos_as.hpp:959
static short convert(const std::string &t)
Convert the given std::string to a short.
Definition: Teuchos_as.hpp:964
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.
Definition: Teuchos_as.hpp:919
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 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.
Definition: Teuchos_as.hpp:798
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 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.
Definition: Teuchos_as.hpp:754
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 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.
Definition: Teuchos_as.hpp:179
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 TypeTo convert(const TypeFrom t)
Convert t from a TypeFrom object to a TypeTo object.
Definition: Teuchos_as.hpp:182
Function object wrapper for as().
Definition: Teuchos_as.hpp:372
#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,...