NumericCast.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_UTIL_NUMERICCAST_H_
36 #define _BLAZE_UTIL_NUMERICCAST_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <limits>
44 #include <blaze/util/Assert.h>
46 #include <blaze/util/EnableIf.h>
47 #include <blaze/util/Exception.h>
48 #include <blaze/util/FalseType.h>
50 #include <blaze/util/TrueType.h>
56 
57 
58 namespace blaze {
59 
60 //=================================================================================================
61 //
62 // AUXILIARY VARIABLE TEMPLATE DEFINITIONS
63 //
64 //=================================================================================================
65 
66 //*************************************************************************************************
71 template< typename To, typename From >
72 constexpr bool IsCriticalIntIntConversion_v =
73  ( IsIntegral_v<To> && IsIntegral_v<From> && !IsSame_v<To,From> );
75 //*************************************************************************************************
76 
77 
78 //*************************************************************************************************
83 template< typename To, typename From >
84 constexpr bool IsCriticalFloatIntConversion_v =
85  ( IsIntegral_v<To> && IsFloatingPoint_v<From> );
87 //*************************************************************************************************
88 
89 
90 //*************************************************************************************************
95 template< typename To, typename From >
96 constexpr bool IsCriticalFloatFloatConversion_v =
97  ( IsFloatingPoint_v<To> && IsFloatingPoint_v<From> && ( sizeof(To) < sizeof(From) ) );
99 //*************************************************************************************************
100 
101 
102 //*************************************************************************************************
107 template< typename To, typename From >
108 constexpr bool IsUncriticalConversion_v =
109  ( !IsCriticalIntIntConversion_v<To,From> &&
110  !IsCriticalFloatIntConversion_v<To,From> &&
111  !IsCriticalFloatFloatConversion_v<To,From> );
113 //*************************************************************************************************
114 
115 
116 
117 
118 //=================================================================================================
119 //
120 // NUMERIC CAST OPERATORS
121 //
122 //=================================================================================================
123 
124 //*************************************************************************************************
127 template< typename To, typename From > inline To numeric_cast( From from );
129 //*************************************************************************************************
130 
131 
132 //*************************************************************************************************
140 template< typename To, typename From >
141 inline EnableIf_t< IsUncriticalConversion_v<To,From>, To >
142  numeric_cast_backend( From from ) noexcept
143 {
144  return from;
145 }
147 //*************************************************************************************************
148 
149 
150 //*************************************************************************************************
160 template< typename To, typename From >
161 inline EnableIf_t< IsCriticalIntIntConversion_v<To,From>, To >
162  numeric_cast_backend( From from )
163 {
164  if( ( sizeof(To) < sizeof(From) || ( IsSigned_v<To> && IsUnsigned_v<From> ) ) &&
165  ( from > From( std::numeric_limits<To>::max() ) ) )
166  BLAZE_THROW_OVERFLOW_ERROR( "Invalid numeric cast (overflow)" );
167 
168  if( IsSigned_v<From> &&
169  ( from < From( std::numeric_limits<To>::min() ) ) )
170  BLAZE_THROW_UNDERFLOW_ERROR( "Invalid numeric cast (underflow)" );
171 
172  BLAZE_INTERNAL_ASSERT( from == From( To( from ) ), "Numeric cast failed" );
173 
174  return from;
175 }
177 //*************************************************************************************************
178 
179 
180 //*************************************************************************************************
190 template< typename To, typename From >
191 inline EnableIf_t< IsCriticalFloatIntConversion_v<To,From>, To >
192  numeric_cast_backend( From from )
193 {
194  using std::trunc;
195 
196  if( from > From( std::numeric_limits<To>::max() ) )
197  BLAZE_THROW_OVERFLOW_ERROR( "Invalid numeric cast (overflow)" );
198 
199  if( from < From( std::numeric_limits<To>::min() ) )
200  BLAZE_THROW_UNDERFLOW_ERROR( "Invalid numeric cast (underflow)" );
201 
202  BLAZE_INTERNAL_ASSERT( trunc( from ) == From( To( from ) ), "Numeric cast failed" );
203 
204  return from;
205 }
207 //*************************************************************************************************
208 
209 
210 //*************************************************************************************************
220 template< typename To, typename From >
221 inline EnableIf_t< IsCriticalFloatFloatConversion_v<To,From>, To >
222  numeric_cast_backend( From from )
223 {
224  if( from > From( std::numeric_limits<To>::max() ) )
225  BLAZE_THROW_OVERFLOW_ERROR( "Invalid numeric cast (overflow)" );
226 
227  if( from < From( std::numeric_limits<To>::min() ) )
228  BLAZE_THROW_UNDERFLOW_ERROR( "Invalid numeric cast (underflow)" );
229 
230  BLAZE_INTERNAL_ASSERT( from == From( To( from ) ), "Numeric cast failed" );
231 
232  return from;
233 }
235 //*************************************************************************************************
236 
237 
238 //*************************************************************************************************
269 template< typename To // The target type
270  , typename From > // The source type
271 inline To numeric_cast( From from )
272 {
275 
276  return numeric_cast_backend<To>( from );
277 }
278 //*************************************************************************************************
279 
280 } // namespace blaze
281 
282 #endif
Constraint on the data type.
Header file for the FalseType type/value trait base class.
Header file for the IsSame and IsStrictlySame type traits.
Header file for exception macros.
Header file for the IsIntegral type trait.
To numeric_cast(From from)
Checked conversion of values of numeric type.
Definition: NumericCast.h:271
#define BLAZE_THROW_OVERFLOW_ERROR(MESSAGE)
Macro for the emission of a std::overflow_error exception.This macro encapsulates the default way of ...
Definition: Exception.h:427
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the IsFloatingPoint type trait.
#define BLAZE_THROW_UNDERFLOW_ERROR(MESSAGE)
Macro for the emission of a std::underflow_error exception.This macro encapsulates the default way of...
Definition: Exception.h:475
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1147
decltype(auto) trunc(const DenseMatrix< MT, SO > &dm)
Applies the trunc() function to each single element of the dense matrix dm.
Definition: DMatMapExpr.h:1268
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1179
Header file for the EnableIf class template.
Header file for run time assertion macros.
#define BLAZE_CONSTRAINT_MUST_BE_NUMERIC_TYPE(T)
Constraint on the data type.In case the given data type T is not a numeric (integral or floating poin...
Definition: Numeric.h:61
Header file for the IsSigned type trait.
Header file for the IsUnsigned type trait.
Header file for the IntegralConstant class template.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the TrueType type/value trait base class.