00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef ACE_TRUNCATE_H
00016 #define ACE_TRUNCATE_H
00017
00018 #include "ace/pre.h"
00019
00020 #include "ace/config-all.h"
00021
00022 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00023 # pragma once
00024 #endif
00025
00026 #include "ace/Global_Macros.h"
00027 #include "ace/If_Then_Else.h"
00028 #include "ace/Numeric_Limits.h"
00029
00030 #if defined (ACE_LACKS_LONGLONG_T)
00031 # include "ace/Basic_Types.h"
00032 #endif
00033
00034 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00035
00036 namespace ACE_Utils
00037 {
00038 template<typename T> struct Sign_Check;
00039
00040
00041 template<> struct Sign_Check<unsigned char> { ACE_STATIC_CONSTANT (bool, is_signed = 0); };
00042 template<> struct Sign_Check<unsigned short> { ACE_STATIC_CONSTANT (bool, is_signed = 0); };
00043 template<> struct Sign_Check<unsigned int> { ACE_STATIC_CONSTANT (bool, is_signed = 0); };
00044 template<> struct Sign_Check<unsigned long> { ACE_STATIC_CONSTANT (bool, is_signed = 0); };
00045 #if !(defined(ACE_LACKS_LONGLONG_T) || defined(ACE_LACKS_UNSIGNEDLONGLONG_T))
00046 # ifdef __GNUC__
00047
00048
00049 __extension__
00050 # endif
00051 template<> struct Sign_Check<unsigned long long> { ACE_STATIC_CONSTANT (bool, is_signed = 0); };
00052 #else
00053 template<> struct Sign_Check<ACE_U_LongLong> { ACE_STATIC_CONSTANT (bool, is_signed = 0); };
00054 #endif
00055
00056
00057 template<> struct Sign_Check<signed char> { ACE_STATIC_CONSTANT (bool, is_signed = 1); };
00058 template<> struct Sign_Check<signed short> { ACE_STATIC_CONSTANT (bool, is_signed = 1); };
00059 template<> struct Sign_Check<signed int> { ACE_STATIC_CONSTANT (bool, is_signed = 1); };
00060 template<> struct Sign_Check<signed long> { ACE_STATIC_CONSTANT (bool, is_signed = 1); };
00061 #ifndef ACE_LACKS_LONGLONG_T
00062 # ifdef __GNUC__
00063
00064
00065 __extension__
00066 # endif
00067 template<> struct Sign_Check<signed long long> { ACE_STATIC_CONSTANT (bool, is_signed = 1); };
00068 #endif
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 template<typename T> struct To_Unsigned;
00080
00081 template<>
00082 struct To_Unsigned<unsigned char>
00083 {
00084 typedef unsigned char unsigned_type;
00085
00086 unsigned_type operator() (unsigned_type x) { return x; }
00087 };
00088
00089 template<>
00090 struct To_Unsigned<unsigned short>
00091 {
00092 typedef unsigned short unsigned_type;
00093
00094 unsigned_type operator() (unsigned_type x) { return x; }
00095 };
00096
00097 template<>
00098 struct To_Unsigned<unsigned int>
00099 {
00100 typedef unsigned int unsigned_type;
00101
00102 unsigned_type operator() (unsigned_type x) { return x; }
00103 };
00104
00105 template<>
00106 struct To_Unsigned<unsigned long>
00107 {
00108 typedef unsigned long unsigned_type;
00109
00110 unsigned_type operator() (unsigned_type x) { return x; }
00111 };
00112
00113 #if !(defined(ACE_LACKS_LONGLONG_T) || defined(ACE_LACKS_UNSIGNEDLONGLONG_T))
00114 # ifdef __GNUC__
00115
00116
00117 __extension__
00118 # endif
00119 template<>
00120 struct To_Unsigned<unsigned long long>
00121 {
00122 typedef unsigned long long unsigned_type;
00123
00124 unsigned_type operator() (unsigned_type x) { return x; }
00125 };
00126 #else
00127 template<>
00128 struct To_Unsigned<ACE_U_LongLong>
00129 {
00130 typedef ACE_U_LongLong unsigned_type;
00131
00132 unsigned_type operator() (unsigned_type x) { return x; }
00133 };
00134 #endif
00135
00136
00137
00138 template<>
00139 struct To_Unsigned<signed char>
00140 {
00141 typedef signed char signed_type;
00142 typedef unsigned char unsigned_type;
00143
00144 unsigned_type operator() (signed_type x)
00145 {
00146 return static_cast<unsigned_type> (x);
00147 }
00148 };
00149
00150 template<>
00151 struct To_Unsigned<signed short>
00152 {
00153 typedef signed short signed_type;
00154 typedef unsigned short unsigned_type;
00155
00156 unsigned_type operator() (signed_type x)
00157 {
00158 return static_cast<unsigned_type> (x);
00159 }
00160 };
00161
00162 template<>
00163 struct To_Unsigned<signed int>
00164 {
00165 typedef signed int signed_type;
00166 typedef unsigned int unsigned_type;
00167
00168 unsigned_type operator() (signed_type x)
00169 {
00170 return static_cast<unsigned_type> (x);
00171 }
00172 };
00173
00174 template<>
00175 struct To_Unsigned<signed long>
00176 {
00177 typedef signed long signed_type;
00178 typedef unsigned long unsigned_type;
00179
00180 unsigned_type operator() (signed_type x)
00181 {
00182 return static_cast<unsigned_type> (x);
00183 }
00184 };
00185
00186 #if !(defined(ACE_LACKS_LONGLONG_T) || defined(ACE_LACKS_UNSIGNEDLONGLONG_T))
00187 # ifdef __GNUC__
00188
00189
00190 __extension__
00191 # endif
00192 template<>
00193 struct To_Unsigned<signed long long>
00194 {
00195 typedef signed long long signed_type;
00196 typedef unsigned long long unsigned_type;
00197
00198 unsigned_type operator() (signed_type x)
00199 {
00200 return static_cast<unsigned_type> (x);
00201 }
00202 };
00203 #endif
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 template<typename LEFT,
00220 typename RIGHT,
00221 bool IS_LEFT_SIGNED,
00222 bool IS_RIGHT_SIGNED> struct Safe_Comparator;
00223
00224
00225 template<typename LEFT, typename RIGHT>
00226 struct Safe_Comparator<LEFT, RIGHT, true, false>
00227 {
00228 static bool greater_than (LEFT lhs, RIGHT rhs)
00229 {
00230
00231 if (lhs < 0)
00232 return false;
00233 else
00234 {
00235
00236 return To_Unsigned<LEFT>() (lhs) > rhs;
00237 }
00238 }
00239 };
00240
00241
00242 template<typename LEFT, typename RIGHT>
00243 struct Safe_Comparator<LEFT, RIGHT, false, true>
00244 {
00245 static bool greater_than (LEFT lhs, RIGHT rhs)
00246 {
00247
00248 if (rhs < 0)
00249 return true;
00250 else
00251 {
00252
00253 return lhs > To_Unsigned<RIGHT>() (rhs);
00254 }
00255 }
00256 };
00257
00258
00259 template<typename LEFT, typename RIGHT>
00260 struct Safe_Comparator<LEFT, RIGHT, false, false>
00261 {
00262 static bool greater_than (LEFT lhs, RIGHT rhs)
00263 {
00264
00265 return lhs > rhs;
00266 }
00267 };
00268
00269
00270 template<typename LEFT, typename RIGHT>
00271 struct Safe_Comparator<LEFT, RIGHT, true, true>
00272 {
00273 static bool greater_than (LEFT lhs, RIGHT rhs)
00274 {
00275
00276 return lhs > rhs;
00277 }
00278 };
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 template<typename LEFT, typename RIGHT>
00296 struct Fast_Comparator
00297 {
00298 ACE_STATIC_CONSTANT (
00299 bool,
00300 USE_LEFT = ((sizeof (LEFT) > sizeof (RIGHT)
00301 && (Sign_Check<LEFT>::is_signed == 1
00302 || Sign_Check<RIGHT>::is_signed == 0))
00303
00304
00305
00306 || (sizeof (LEFT) == sizeof (RIGHT)
00307
00308
00309
00310
00311
00312
00313 && ((Sign_Check<LEFT>::is_signed == 1
00314 && Sign_Check<RIGHT>::is_signed == 1)
00315 || (Sign_Check<LEFT>::is_signed == 0
00316 && Sign_Check<RIGHT>::is_signed == 0)))));
00317
00318 ACE_STATIC_CONSTANT (
00319 bool,
00320 USE_RIGHT = (sizeof (RIGHT) > sizeof (LEFT)
00321 && (Sign_Check<RIGHT>::is_signed == 1
00322 || Sign_Check<LEFT>::is_signed == 0)));
00323
00324 ACE_STATIC_CONSTANT (bool, USABLE = (USE_LEFT || USE_RIGHT));
00325
00326 typedef typename ACE::If_Then_Else<
00327 USE_LEFT,
00328 LEFT,
00329 typename ACE::If_Then_Else<
00330 USE_RIGHT,
00331 RIGHT,
00332 void>::result_type>::result_type promote_type;
00333
00334 static bool greater_than (LEFT lhs, RIGHT rhs)
00335 {
00336
00337
00338 return
00339 (static_cast<promote_type> (lhs) > static_cast<promote_type> (rhs));
00340 }
00341
00342 };
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 template<typename LEFT, typename RIGHT>
00373 struct Comparator
00374 {
00375 typedef typename ACE::If_Then_Else<
00376 Fast_Comparator<LEFT, RIGHT>::USABLE,
00377 Fast_Comparator<LEFT, RIGHT>,
00378 Safe_Comparator<LEFT,
00379 RIGHT,
00380 Sign_Check<LEFT>::is_signed,
00381 Sign_Check<RIGHT>::is_signed> >::result_type comp_type;
00382 };
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 template<typename FROM, typename TO>
00395 struct Truncator
00396 {
00397 ACE_STATIC_CONSTANT (
00398 bool,
00399
00400 MAX_FROM_GT_MAX_TO = (sizeof(FROM) > sizeof (TO)
00401 || (sizeof(FROM) == sizeof (TO)
00402 && Sign_Check<FROM>::is_signed == 0)));
00403
00404 typedef typename ACE::If_Then_Else<
00405 MAX_FROM_GT_MAX_TO,
00406 FROM,
00407 TO>::result_type comp_to_type;
00408
00409
00410
00411
00412
00413 typedef typename ACE::If_Then_Else<
00414 MAX_FROM_GT_MAX_TO,
00415 Fast_Comparator<FROM, comp_to_type>,
00416 typename Comparator<FROM, comp_to_type>::comp_type>::result_type comparator;
00417
00418
00419
00420 TO operator() (FROM val)
00421 {
00422 return
00423 (comparator::greater_than (val, ACE_Numeric_Limits<TO>::max ())
00424 ? ACE_Numeric_Limits<TO>::max ()
00425 : static_cast<TO> (val));
00426 }
00427
00428 };
00429
00430
00431
00432 template<typename T>
00433 struct Truncator<T, T>
00434 {
00435 T operator() (T val)
00436 {
00437 return val;
00438 }
00439 };
00440
00441
00442 #if defined (ACE_LACKS_LONGLONG_T) || defined (ACE_LACKS_UNSIGNEDLONGLONG_T)
00443
00444
00445
00446
00447
00448 template<typename TO>
00449 struct Truncator<ACE_U_LongLong, TO>
00450 {
00451 TO operator() (ACE_U_LongLong const & val)
00452 {
00453
00454
00455
00456 return
00457 (val > ACE_Numeric_Limits<TO>::max ()
00458 ? ACE_Numeric_Limits<TO>::max ()
00459 : static_cast<TO> (val.lo ()));
00460 }
00461 };
00462 #endif
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 template<typename FROM, typename TO>
00475 struct Noop_Truncator
00476 {
00477 TO operator() (FROM val)
00478 {
00479 return static_cast<TO> (val);
00480 }
00481 };
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 template<typename TO, typename FROM>
00498 inline TO truncate_cast (FROM val)
00499 {
00500
00501
00502
00503 typedef typename ACE::If_Then_Else<
00504 (sizeof (FROM) < sizeof (TO)),
00505 Noop_Truncator<FROM, TO>,
00506 Truncator<FROM, TO> >::result_type truncator;
00507
00508 return truncator() (val);
00509 }
00510
00511 }
00512
00513 ACE_END_VERSIONED_NAMESPACE_DECL
00514
00515 #include "ace/post.h"
00516
00517 #endif