00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00047 #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_TRUNCATION_TEST
00048 #define STLSOFT_INCL_STLSOFT_CONVERSION_HPP_TRUNCATION_TEST
00049
00050 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00051 # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_TRUNCATION_TEST_MAJOR 1
00052 # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_TRUNCATION_TEST_MINOR 0
00053 # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_TRUNCATION_TEST_REVISION 5
00054 # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_TRUNCATION_TEST_EDIT 47
00055 #endif
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00069 # include <stlsoft/stlsoft.h>
00070 #endif
00071
00072 #ifndef STLSOFT_INCL_STLSOFT_UTIL_H_LIMIT_TRAITS
00073 # include <stlsoft/util/limit_traits.h>
00074 #endif
00075 #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_SIGN_TRAITS
00076 # include <stlsoft/util/sign_traits.hpp>
00077 #endif
00078
00079 #ifndef STLSOFT_INCL_STLSOFT_META_HPP_IS_INTEGRAL_TYPE
00080 # include <stlsoft/meta/is_integral_type.hpp>
00081 #endif
00082 #ifndef STLSOFT_INCL_STLSOFT_META_HPP_IS_SIGNED_TYPE
00083 # include <stlsoft/meta/is_signed_type.hpp>
00084 #endif
00085
00086 #ifdef STLSOFT_UNITTEST
00087 # include <limits.h>
00088 #endif
00089 #if defined(STLSOFT_UNITTEST) || \
00090 defined(_DEBUG)
00091 # include <typeinfo>
00092 #endif
00093
00094
00095
00096
00097
00098 #ifndef _STLSOFT_NO_NAMESPACE
00099 namespace stlsoft
00100 {
00101 #endif
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 template< ss_typename_param_k TO
00169 , ss_typename_param_k FROM
00170 >
00171 inline bool truncation_test_helper_runtime_test_different_sign_FROM_is_signed(FROM from, yes_type, TO)
00172 {
00173 #ifdef _DEBUG
00174 char const *TO_ = typeid(TO).name();
00175 char const *FROM_ = typeid(FROM).name();
00176
00177 STLSOFT_SUPPRESS_UNUSED(TO_);
00178 STLSOFT_SUPPRESS_UNUSED(FROM_);
00179 #endif
00180
00181 enum { TO_is_signed = is_signed_type<TO>::value };
00182 enum { FROM_is_signed = is_signed_type<FROM>::value };
00183
00184 const ss_size_t sizeofFROM = sizeof(FROM);
00185 const ss_size_t sizeofTO = sizeof(TO);
00186
00187 STLSOFT_SUPPRESS_UNUSED(sizeofFROM);
00188 STLSOFT_SUPPRESS_UNUSED(sizeofTO);
00189
00190 STLSOFT_STATIC_ASSERT((0 == int(TO_is_signed)) != (0 == int(FROM_is_signed)));
00191 STLSOFT_STATIC_ASSERT(0 != int(FROM_is_signed));
00192 STLSOFT_STATIC_ASSERT(0 == int(TO_is_signed));
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 if(from < 0)
00204 {
00205 return false;
00206 }
00207 else if(sizeofFROM < sizeofTO)
00208 {
00209 return true;
00210 }
00211 else
00212 {
00213 if(sizeofFROM == sizeofTO)
00214 {
00215 TO toMax = limit_traits<TO>::maximum();
00216
00217 if(toMax < static_cast<TO>(from))
00218 {
00219 return false;
00220 }
00221 else
00222 {
00223 return true;
00224 }
00225 }
00226 else
00227 {
00228 FROM toMax = static_cast<FROM>(limit_traits<TO>::maximum());
00229
00230 if(from > toMax)
00231 {
00232 return false;
00233 }
00234 else
00235 {
00236 return true;
00237 }
00238 }
00239 }
00240 }
00241
00242 template< ss_typename_param_k TO
00243 , ss_typename_param_k FROM
00244 >
00245 inline bool truncation_test_helper_runtime_test_different_sign_FROM_is_signed(FROM from, no_type, TO)
00246 {
00247 #ifdef _DEBUG
00248 char const *TO_ = typeid(TO).name();
00249 char const *FROM_ = typeid(FROM).name();
00250
00251 STLSOFT_SUPPRESS_UNUSED(TO_);
00252 STLSOFT_SUPPRESS_UNUSED(FROM_);
00253 #endif
00254
00255 enum { TO_is_signed = is_signed_type<TO>::value };
00256 enum { FROM_is_signed = is_signed_type<FROM>::value };
00257
00258 const ss_size_t sizeofFROM = sizeof(FROM);
00259 const ss_size_t sizeofTO = sizeof(TO);
00260
00261 STLSOFT_SUPPRESS_UNUSED(sizeofFROM);
00262 STLSOFT_SUPPRESS_UNUSED(sizeofTO);
00263
00264 STLSOFT_STATIC_ASSERT((0 == int(TO_is_signed)) != (0 == int(FROM_is_signed)));
00265 STLSOFT_STATIC_ASSERT(0 == int(FROM_is_signed));
00266 STLSOFT_STATIC_ASSERT(0 != int(TO_is_signed));
00267
00268
00269
00270
00271
00272
00273 FROM toMax = static_cast<FROM>(limit_traits<TO>::maximum());
00274
00275 if(from > toMax)
00276 {
00277 return false;
00278 }
00279 else
00280 {
00281 return true;
00282 }
00283 }
00284
00285
00286 template< ss_typename_param_k TO
00287 , ss_typename_param_k FROM
00288 >
00289 inline bool truncation_test_helper_runtime_test_same_sign(FROM from, yes_type, TO)
00290 {
00291 #ifdef _DEBUG
00292 char const *TO_ = typeid(TO).name();
00293 char const *FROM_ = typeid(FROM).name();
00294
00295 STLSOFT_SUPPRESS_UNUSED(TO_);
00296 STLSOFT_SUPPRESS_UNUSED(FROM_);
00297 #endif
00298
00299 const ss_size_t sizeofFROM = sizeof(FROM);
00300 const ss_size_t sizeofTO = sizeof(TO);
00301
00302 STLSOFT_STATIC_ASSERT(sizeofTO < sizeofFROM);
00303
00304
00305
00306
00307
00308
00309 FROM toMax = static_cast<FROM>(limit_traits<TO>::maximum());
00310 FROM toMin = static_cast<FROM>(limit_traits<TO>::minimum());
00311
00312 if( from < toMin ||
00313 from > toMax)
00314 {
00315 return false;
00316 }
00317 else
00318 {
00319 return true;
00320 }
00321 }
00322
00323 template< ss_typename_param_k TO
00324 , ss_typename_param_k FROM
00325 >
00326 inline bool truncation_test_helper_runtime_test_same_sign(FROM from, no_type, TO)
00327 {
00328 #ifdef _DEBUG
00329 char const *TO_ = typeid(TO).name();
00330 char const *FROM_ = typeid(FROM).name();
00331
00332 STLSOFT_SUPPRESS_UNUSED(TO_);
00333 STLSOFT_SUPPRESS_UNUSED(FROM_);
00334 #endif
00335
00336 enum { TO_is_signed = is_signed_type<TO>::value };
00337 enum { FROM_is_signed = is_signed_type<FROM>::value };
00338
00339 const ss_size_t sizeofFROM = sizeof(FROM);
00340 const ss_size_t sizeofTO = sizeof(TO);
00341
00342 STLSOFT_SUPPRESS_UNUSED(sizeofFROM);
00343 STLSOFT_SUPPRESS_UNUSED(sizeofTO);
00344
00345 STLSOFT_STATIC_ASSERT((0 == int(TO_is_signed)) != (0 == int(FROM_is_signed)));
00346
00347 typedef ss_typename_param_k value_to_yesno_type<FROM_is_signed>::type same_sign_yesno_t;
00348
00349 return truncation_test_helper_runtime_test_different_sign_FROM_is_signed<TO>(from, same_sign_yesno_t(), TO());
00350 }
00351
00352
00353
00354 template< ss_typename_param_k TO
00355 , ss_typename_param_k FROM
00356 >
00357 inline bool truncation_test_helper_runtime_test(FROM from, no_type, TO )
00358 {
00359 #ifdef _DEBUG
00360 char const *TO_ = typeid(TO).name();
00361 char const *FROM_ = typeid(FROM).name();
00362
00363 STLSOFT_SUPPRESS_UNUSED(TO_);
00364 STLSOFT_SUPPRESS_UNUSED(FROM_);
00365 #endif
00366
00367
00368
00369
00370 enum { TO_is_signed = is_signed_type<TO>::value };
00371 enum { FROM_is_signed = is_signed_type<FROM>::value };
00372
00373 enum { types_have_same_sign = int(TO_is_signed) == int(FROM_is_signed) };
00374
00375 const ss_size_t sizeofFROM = sizeof(FROM);
00376 const ss_size_t sizeofTO = sizeof(TO);
00377
00378 STLSOFT_STATIC_ASSERT(sizeofFROM >= sizeofTO || FROM_is_signed);
00379
00380 typedef ss_typename_param_k value_to_yesno_type<types_have_same_sign>::type same_sign_yesno_t;
00381
00382 return truncation_test_helper_runtime_test_same_sign<TO>(from, same_sign_yesno_t(), TO());
00383 }
00384
00385 template <typename T>
00386 inline bool truncation_test_helper_runtime_test(T, yes_type, ...)
00387 {
00388 return true;
00389 }
00390
00391
00392 template< ss_typename_param_k TO
00393 , ss_typename_param_k FROM
00394 >
00395 inline bool truncation_test_(FROM from, TO dummy = TO())
00396 {
00397 #ifdef _DEBUG
00398 char const *TO_ = typeid(TO).name();
00399 char const *FROM_ = typeid(FROM).name();
00400
00401 STLSOFT_SUPPRESS_UNUSED(TO_);
00402 STLSOFT_SUPPRESS_UNUSED(FROM_);
00403 #endif
00404
00405
00406
00407
00408 STLSOFT_STATIC_ASSERT(0 != is_integral_type<TO>::value);
00409 STLSOFT_STATIC_ASSERT(0 != is_integral_type<FROM>::value);
00410
00411
00412
00413 const ss_size_t sizeofFROM = sizeof(FROM);
00414 const ss_size_t sizeofTO = sizeof(TO);
00415
00416
00417
00418 enum { TO_is_signed = is_signed_type<TO>::value };
00419 enum { FROM_is_signed = is_signed_type<FROM>::value };
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 enum { types_are_statically_compatible =
00433 ( int(TO_is_signed) == int(FROM_is_signed) &&
00434 sizeofFROM <= sizeofTO)
00435 ||
00436 ( !FROM_is_signed &&
00437 sizeofFROM < sizeofTO) };
00438
00439 typedef ss_typename_param_k value_to_yesno_type<types_are_statically_compatible>::type yesno_t;
00440
00441 # if defined(STLSOFT_COMPILER_IS_MSVC) && \
00442 defined(_Wp64) && \
00443 !defined(_WIN64)
00444 # pragma warning(push)
00445 # pragma warning(disable : 4267)
00446 # endif
00447
00448 return truncation_test_helper_runtime_test<TO>(from, yesno_t(), dummy);
00449
00450 # if defined(STLSOFT_COMPILER_IS_MSVC) && \
00451 defined(_Wp64) && \
00452 !defined(_WIN64)
00453 # pragma warning(pop)
00454 # endif
00455 }
00456
00457
00458 #if 0
00459 template<ss_typename_param_k TO>
00460 class truncation_test
00461 {
00462 public:
00463 template <ss_typename_param_k FROM>
00464 truncation_test(FROM from)
00465 : m_b(truncation_test_(from, get_to_()))
00466 {}
00467
00468 public:
00469 operator bool () const
00470 {
00471 return m_b;
00472 }
00473
00474 private:
00475 static TO get_to_()
00476 {
00477 return TO();
00478 }
00479
00480 private:
00481 const bool m_b;
00482 };
00483 #else
00484
00485 #endif
00486
00503 template< ss_typename_param_k TO
00504 , ss_typename_param_k FROM
00505 >
00506 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00507 inline bool truncation_test(FROM from, TO dummy = TO())
00508 #else
00509 inline bool truncation_test(FROM from)
00510 #endif
00511 {
00512 return truncation_test_(from, dummy);
00513 }
00514
00515 #endif
00516
00518
00519
00520 #ifdef STLSOFT_UNITTEST
00521 # include "./unittest/truncation_test_unittest_.h"
00522 #endif
00523
00524
00525
00526 #ifndef _STLSOFT_NO_NAMESPACE
00527 }
00528 #endif
00529
00530
00531
00532 #endif
00533
00534