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>
49 #include <blaze/util/mpl/And.h>
50 #include <blaze/util/mpl/Bool.h>
51 #include <blaze/util/mpl/Not.h>
52 #include <blaze/util/mpl/Or.h>
53 #include <blaze/util/TrueType.h>
59 
60 
61 namespace blaze {
62 
63 //=================================================================================================
64 //
65 // AUXILIARY CLASS DEFINITIONS
66 //
67 //=================================================================================================
68 
69 //*************************************************************************************************
74 template< typename To, typename From >
75 struct IsCriticalIntIntConversion
76 {
77  public:
78  //**********************************************************************************************
79  enum : size_t { value = And< IsIntegral<To>
80  , IsIntegral<From>
81  , Not< IsSame<To,From> > >::value };
82  //**********************************************************************************************
83 };
85 //*************************************************************************************************
86 
87 
88 //*************************************************************************************************
93 template< typename To, typename From >
94 struct IsCriticalFloatIntConversion
95 {
96  public:
97  //**********************************************************************************************
98  enum : size_t { value = And< IsIntegral<To>
99  , IsFloatingPoint<From> >::value };
100  //**********************************************************************************************
101 };
103 //*************************************************************************************************
104 
105 
106 //*************************************************************************************************
111 template< typename To, typename From >
112 struct IsCriticalFloatFloatConversion
113 {
114  public:
115  //**********************************************************************************************
116  enum : size_t { value = And< IsFloatingPoint<To>
117  , IsFloatingPoint<From>
118  , Bool< ( sizeof(To) < sizeof(From) ) > >::value };
119  //**********************************************************************************************
120 };
122 //*************************************************************************************************
123 
124 
125 //*************************************************************************************************
130 template< typename To, typename From >
131 struct IsUncriticalConversion
132 {
133  public:
134  //**********************************************************************************************
135  enum : size_t { value = !IsCriticalIntIntConversion<To,From>::value &&
136  !IsCriticalFloatIntConversion<To,From>::value &&
137  !IsCriticalFloatFloatConversion<To,From>::value };
138  //**********************************************************************************************
139 };
141 //*************************************************************************************************
142 
143 
144 
145 
146 //=================================================================================================
147 //
148 // NUMERIC CAST OPERATORS
149 //
150 //=================================================================================================
151 
152 //*************************************************************************************************
155 template< typename To, typename From > inline To numeric_cast( From from );
157 //*************************************************************************************************
158 
159 
160 //*************************************************************************************************
168 template< typename To, typename From >
169 inline EnableIf_< IsUncriticalConversion<To,From>, To >
170  numeric_cast_backend( From from ) noexcept
171 {
172  return from;
173 }
175 //*************************************************************************************************
176 
177 
178 //*************************************************************************************************
188 template< typename To, typename From >
189 inline EnableIf_< IsCriticalIntIntConversion<To,From>, To >
190  numeric_cast_backend( From from )
191 {
192  if( ( sizeof(To) < sizeof(From) || ( IsSigned<To>::value && IsUnsigned<From>::value ) ) &&
193  ( from > From( std::numeric_limits<To>::max() ) ) )
194  BLAZE_THROW_OVERFLOW_ERROR( "Invalid numeric cast (overflow)" );
195 
196  if( IsSigned<From>::value &&
197  ( from < From( std::numeric_limits<To>::min() ) ) )
198  BLAZE_THROW_UNDERFLOW_ERROR( "Invalid numeric cast (underflow)" );
199 
200  BLAZE_INTERNAL_ASSERT( from == From( To( from ) ), "Numeric cast failed" );
201 
202  return from;
203 }
205 //*************************************************************************************************
206 
207 
208 //*************************************************************************************************
218 template< typename To, typename From >
219 inline EnableIf_< IsCriticalFloatIntConversion<To,From>, To >
220  numeric_cast_backend( From from )
221 {
222  using std::trunc;
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( trunc( from ) == From( To( from ) ), "Numeric cast failed" );
231 
232  return from;
233 }
235 //*************************************************************************************************
236 
237 
238 //*************************************************************************************************
248 template< typename To, typename From >
249 inline EnableIf_< IsCriticalFloatFloatConversion<To,From>, To >
250  numeric_cast_backend( From from )
251 {
252  if( from > From( std::numeric_limits<To>::max() ) )
253  BLAZE_THROW_OVERFLOW_ERROR( "Invalid numeric cast (overflow)" );
254 
255  if( from < From( std::numeric_limits<To>::min() ) )
256  BLAZE_THROW_UNDERFLOW_ERROR( "Invalid numeric cast (underflow)" );
257 
258  BLAZE_INTERNAL_ASSERT( from == From( To( from ) ), "Numeric cast failed" );
259 
260  return from;
261 }
263 //*************************************************************************************************
264 
265 
266 //*************************************************************************************************
297 template< typename To // The target type
298  , typename From > // The source type
299 inline To numeric_cast( From from )
300 {
303 
304  return numeric_cast_backend<To>( from );
305 }
306 //*************************************************************************************************
307 
308 } // namespace blaze
309 
310 #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.
Header file for the And class template.
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1903
To numeric_cast(From from)
Checked conversion of values of numeric type.
Definition: NumericCast.h:299
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1950
#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.
Header file for the Or class template.
#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) trunc(const DenseMatrix< MT, SO > &dm)
Applies the trunc() function to each single element of the dense matrix dm.
Definition: DMatMapExpr.h:1263
Header file for the Not class template.
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.
#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 Bool class template.
Header file for the TrueType type/value trait base class.