1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| // Version de g++ : 6.1.0
#include <cassert>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <typeinfo>
#include <type_traits>
/*!
* \brief Convert signed integer to another signed integer type.
* \exception std::overflow_error param is too big to be convertible to ResultT.
* \exception std::underflow_error param is too small to be convertible to ResultT.
*/
template<class ResultT, class ParamT,
typename std::enable_if<
std::is_integral<ResultT>::value &&
std::is_integral<ParamT >::value &&
std::is_signed <ResultT>::value &&
std::is_signed <ParamT >::value
>::type* = nullptr
>
ResultT checkedConvert(ParamT param)
{
#ifndef DO_NOT_CHECK_INTEGER_LIMITS_ON_CONVERSION
if(param > std::numeric_limits<ResultT>::max()) {
std::ostringstream streamMessage;
streamMessage << "Failure to convert from " << typeid(ParamT) .name()
<< " to " << typeid(ResultT).name() << ": "
<< param << " is too big (maximal allowed value: "
<< std::numeric_limits<ResultT>::max() << ").";
throw std::overflow_error(streamMessage.str());
} else if(param < std::numeric_limits<ResultT>::min()) {
std::ostringstream streamMessage;
streamMessage << "Failure to convert from " << typeid(ParamT) .name()
<< " to " << typeid(ResultT).name() << ": "
<< param << " is too small (minimal allowed value: "
<< std::numeric_limits<ResultT>::min() << ").";
throw std::underflow_error(streamMessage.str());
}
#endif
return param;
}
/*!
* \brief Convert nonnegative signed integer to unsigned integer type.
* \pre param >= 0
* \exception std::overflow_error param is too big to be convertible to ResultT.
* \exception std::domain_error (in Release mode) param < 0
*/
template<class ResultT, class ParamT,
typename std::enable_if<
std::is_integral<ResultT>::value &&
std::is_integral<ParamT >::value &&
!std::is_signed <ResultT>::value &&
std::is_signed <ParamT >::value
>::type* = nullptr
>
ResultT checkedConvert(ParamT param)
{
assert(param >= 0);
if(param < 0) {
std::ostringstream streamMessage;
streamMessage << "Failure to convert from " << typeid(ParamT) .name()
<< " to " << typeid(ResultT).name() << ": "
<< param << " is negative.";
throw std::domain_error(streamMessage.str());
}
#ifndef DO_NOT_CHECK_INTEGER_LIMITS_ON_CONVERSION
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-compare"
if(param > std::numeric_limits<ResultT>::max()) {
std::ostringstream streamMessage;
streamMessage << "Failure to convert from " << typeid(ParamT) .name()
<< " to " << typeid(ResultT).name() << ": "
<< param << " is too big (maximal allowed value:"
<< std::numeric_limits<ResultT>::max() << ").";
throw std::overflow_error(streamMessage.str());
}
#pragma GCC diagnostic pop
#endif
return param;
}
/*!
* \brief Convert unsigned integer to another integer type.
* \exception std::overflow_error param is too big to be convertible to ResultT.
*/
template<class ResultT, class ParamT,
typename std::enable_if<
std::is_integral<ResultT>::value &&
std::is_integral<ParamT >::value &&
!std::is_signed <ParamT >::value
>::type* = nullptr
>
ResultT checkedConvert(ParamT param)
{
#ifndef DO_NOT_CHECK_INTEGER_LIMITS_ON_CONVERSION
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-compare"
if(param > std::numeric_limits<ResultT>::max()) {
std::ostringstream streamMessage;
streamMessage << "Failure to convert from " << typeid(ParamT).name()
<< " to " << typeid(ResultT).name() << ": "
<< param << " is too big (maximal allowed value:"
<< std::numeric_limits<ResultT>::max() << ").";
throw std::overflow_error(streamMessage.str());
}
#pragma GCC diagnostic pop
#endif
return param;
} |
Partager