Blaze 3.9
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>
54
55
56namespace blaze {
57
58//=================================================================================================
59//
60// AUXILIARY VARIABLE TEMPLATE DEFINITIONS
61//
62//=================================================================================================
63
64//*************************************************************************************************
69template< typename To, typename From >
70constexpr bool IsCriticalIntIntConversion_v =
71 ( IsIntegral_v<To> && IsIntegral_v<From> && !IsSame_v<To,From> );
73//*************************************************************************************************
74
75
76//*************************************************************************************************
81template< typename To, typename From >
82constexpr bool IsCriticalFloatIntConversion_v =
83 ( IsIntegral_v<To> && IsFloatingPoint_v<From> );
85//*************************************************************************************************
86
87
88//*************************************************************************************************
93template< typename To, typename From >
94constexpr bool IsCriticalFloatFloatConversion_v =
95 ( IsFloatingPoint_v<To> && IsFloatingPoint_v<From> && ( sizeof(To) < sizeof(From) ) );
97//*************************************************************************************************
98
99
100//*************************************************************************************************
105template< typename To, typename From >
106constexpr bool IsUncriticalConversion_v =
107 ( !IsCriticalIntIntConversion_v<To,From> &&
108 !IsCriticalFloatIntConversion_v<To,From> &&
109 !IsCriticalFloatFloatConversion_v<To,From> );
111//*************************************************************************************************
112
113
114
115
116//=================================================================================================
117//
118// NUMERIC CAST OPERATORS
119//
120//=================================================================================================
121
122//*************************************************************************************************
125template< typename To, typename From > inline To numeric_cast( From from );
127//*************************************************************************************************
128
129
130//*************************************************************************************************
138template< typename To, typename From >
139inline EnableIf_t< IsUncriticalConversion_v<To,From>, To >
140 numeric_cast_backend( From from ) noexcept
141{
142 return from;
143}
145//*************************************************************************************************
146
147
148//*************************************************************************************************
158template< typename To, typename From >
159inline EnableIf_t< IsCriticalIntIntConversion_v<To,From>, To >
160 numeric_cast_backend( From from )
161{
162 if( ( sizeof(To) < sizeof(From) || ( IsSigned_v<To> && IsUnsigned_v<From> ) ) &&
163 ( from > From( std::numeric_limits<To>::max() ) ) ) {
164 BLAZE_THROW_OVERFLOW_ERROR( "Invalid numeric cast (overflow)" );
165 }
166
167 if( IsSigned_v<From> &&
168 ( from < From( std::numeric_limits<To>::min() ) ) ) {
169 BLAZE_THROW_UNDERFLOW_ERROR( "Invalid numeric cast (underflow)" );
170 }
171
172 BLAZE_INTERNAL_ASSERT( from == From( To( from ) ), "Numeric cast failed" );
173
174 return from;
175}
177//*************************************************************************************************
178
179
180//*************************************************************************************************
190template< typename To, typename From >
191inline 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
200 if( from < From( std::numeric_limits<To>::min() ) ) {
201 BLAZE_THROW_UNDERFLOW_ERROR( "Invalid numeric cast (underflow)" );
202 }
203
204 BLAZE_INTERNAL_ASSERT( trunc( from ) == From( To( from ) ), "Numeric cast failed" );
205
206 return from;
207}
209//*************************************************************************************************
210
211
212//*************************************************************************************************
222template< typename To, typename From >
223inline EnableIf_t< IsCriticalFloatFloatConversion_v<To,From>, To >
224 numeric_cast_backend( From from )
225{
226 if( from > From( std::numeric_limits<To>::max() ) ) {
227 BLAZE_THROW_OVERFLOW_ERROR( "Invalid numeric cast (overflow)" );
228 }
229
230 if( from < From( std::numeric_limits<To>::min() ) ) {
231 BLAZE_THROW_UNDERFLOW_ERROR( "Invalid numeric cast (underflow)" );
232 }
233
234 BLAZE_INTERNAL_ASSERT( from == From( To( from ) ), "Numeric cast failed" );
235
236 return from;
237}
239//*************************************************************************************************
240
241
242//*************************************************************************************************
273template< typename To // The target type
274 , typename From > // The source type
275inline To numeric_cast( From from )
276{
279
280 return numeric_cast_backend<To>( from );
281}
282//*************************************************************************************************
283
284} // namespace blaze
285
286#endif
Header file for run time assertion macros.
Header file for the EnableIf class template.
Header file for the IntegralConstant class template.
Header file for the IsFloatingPoint type trait.
Header file for the IsIntegral type trait.
Header file for the IsSame and IsStrictlySame type traits.
Header file for the IsSigned type trait.
Header file for the IsUnsigned type trait.
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_NUMERIC_TYPE(T)
Constraint on the data type.
Definition: Numeric.h:61
decltype(auto) trunc(const DenseMatrix< MT, SO > &dm)
Applies the trunc() function to each single element of the dense matrix dm.
Definition: DMatMapExpr.h:1408
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:1339
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:1375
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
To numeric_cast(From from)
Checked conversion of values of numeric type.
Definition: NumericCast.h:275
#define BLAZE_THROW_UNDERFLOW_ERROR(MESSAGE)
Macro for the emission of a std::underflow_error exception.
Definition: Exception.h:475
#define BLAZE_THROW_OVERFLOW_ERROR(MESSAGE)
Macro for the emission of a std::overflow_error exception.
Definition: Exception.h:427
Header file for exception macros.