00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PPL_checked_inlines_hh
00025 #define PPL_checked_inlines_hh 1
00026
00027 #include "globals.types.hh"
00028 #include "meta_programming.hh"
00029 #include "C_Integer.hh"
00030 #include "assert.hh"
00031
00038 #define PPL_LT_SILENT(a, b) ((a) < (b))
00039 #define PPL_GT_SILENT(a, b) ((a) > (b))
00040
00041 namespace Parma_Polyhedra_Library {
00042
00043 namespace Checked {
00044
00045 template <typename T1, typename T2>
00046 struct Safe_Conversion : public False {
00047 };
00048 template <typename T>
00049 struct Safe_Conversion<T, T> : public True {
00050 };
00051
00052 #define PPL_SAFE_CONVERSION(To, From) \
00053 template <> struct Safe_Conversion<To, From> : public True { }
00054
00055 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
00056 PPL_SAFE_CONVERSION(signed short, char);
00057 #endif
00058 PPL_SAFE_CONVERSION(signed short, signed char);
00059 #if PPL_SIZEOF_CHAR < PPL_SIZEOF_SHORT
00060 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
00061 PPL_SAFE_CONVERSION(signed short, char);
00062 #endif
00063 PPL_SAFE_CONVERSION(signed short, unsigned char);
00064 #endif
00065
00066 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
00067 PPL_SAFE_CONVERSION(signed int, char);
00068 #endif
00069 PPL_SAFE_CONVERSION(signed int, signed char);
00070 PPL_SAFE_CONVERSION(signed int, signed short);
00071 #if PPL_SIZEOF_CHAR < PPL_SIZEOF_INT
00072 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
00073 PPL_SAFE_CONVERSION(signed int, char);
00074 #endif
00075 PPL_SAFE_CONVERSION(signed int, unsigned char);
00076 #endif
00077 #if PPL_SIZEOF_SHORT < PPL_SIZEOF_INT
00078 PPL_SAFE_CONVERSION(signed int, unsigned short);
00079 #endif
00080
00081 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
00082 PPL_SAFE_CONVERSION(signed long, char);
00083 #endif
00084 PPL_SAFE_CONVERSION(signed long, signed char);
00085 PPL_SAFE_CONVERSION(signed long, signed short);
00086 PPL_SAFE_CONVERSION(signed long, signed int);
00087 #if PPL_SIZEOF_CHAR < PPL_SIZEOF_LONG
00088 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
00089 PPL_SAFE_CONVERSION(signed long, char);
00090 #endif
00091 PPL_SAFE_CONVERSION(signed long, unsigned char);
00092 #endif
00093 #if PPL_SIZEOF_SHORT < PPL_SIZEOF_LONG
00094 PPL_SAFE_CONVERSION(signed long, unsigned short);
00095 #endif
00096 #if PPL_SIZEOF_INT < PPL_SIZEOF_LONG
00097 PPL_SAFE_CONVERSION(signed long, unsigned int);
00098 #endif
00099
00100 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
00101 PPL_SAFE_CONVERSION(signed long long, char);
00102 #endif
00103 PPL_SAFE_CONVERSION(signed long long, signed char);
00104 PPL_SAFE_CONVERSION(signed long long, signed short);
00105 PPL_SAFE_CONVERSION(signed long long, signed int);
00106 PPL_SAFE_CONVERSION(signed long long, signed long);
00107 #if PPL_SIZEOF_CHAR < PPL_SIZEOF_LONG_LONG
00108 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
00109 PPL_SAFE_CONVERSION(signed long long, char);
00110 #endif
00111 PPL_SAFE_CONVERSION(signed long long, unsigned char);
00112 #endif
00113 #if PPL_SIZEOF_SHORT < PPL_SIZEOF_LONG_LONG
00114 PPL_SAFE_CONVERSION(signed long long, unsigned short);
00115 #endif
00116 #if PPL_SIZEOF_INT < PPL_SIZEOF_LONG_LONG
00117 PPL_SAFE_CONVERSION(signed long long, unsigned int);
00118 #endif
00119 #if PPL_SIZEOF_LONG < PPL_SIZEOF_LONG_LONG
00120 PPL_SAFE_CONVERSION(signed long long, unsigned long);
00121 #endif
00122
00123 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
00124 PPL_SAFE_CONVERSION(unsigned short, char);
00125 #endif
00126 PPL_SAFE_CONVERSION(unsigned short, unsigned char);
00127
00128 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
00129 PPL_SAFE_CONVERSION(unsigned int, char);
00130 #endif
00131 PPL_SAFE_CONVERSION(unsigned int, unsigned char);
00132 PPL_SAFE_CONVERSION(unsigned int, unsigned short);
00133
00134 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
00135 PPL_SAFE_CONVERSION(unsigned long, char);
00136 #endif
00137 PPL_SAFE_CONVERSION(unsigned long, unsigned char);
00138 PPL_SAFE_CONVERSION(unsigned long, unsigned short);
00139 PPL_SAFE_CONVERSION(unsigned long, unsigned int);
00140
00141 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
00142 PPL_SAFE_CONVERSION(unsigned long long, char);
00143 #endif
00144 PPL_SAFE_CONVERSION(unsigned long long, unsigned char);
00145 PPL_SAFE_CONVERSION(unsigned long long, unsigned short);
00146 PPL_SAFE_CONVERSION(unsigned long long, unsigned int);
00147 PPL_SAFE_CONVERSION(unsigned long long, unsigned long);
00148
00149
00150 #if PPL_SIZEOF_CHAR <= PPL_SIZEOF_FLOAT - 2
00151 PPL_SAFE_CONVERSION(float, char);
00152 PPL_SAFE_CONVERSION(float, signed char);
00153 PPL_SAFE_CONVERSION(float, unsigned char);
00154 #endif
00155 #if PPL_SIZEOF_SHORT <= PPL_SIZEOF_FLOAT - 2
00156 PPL_SAFE_CONVERSION(float, signed short);
00157 PPL_SAFE_CONVERSION(float, unsigned short);
00158 #endif
00159 #if PPL_SIZEOF_INT <= PPL_SIZEOF_FLOAT - 2
00160 PPL_SAFE_CONVERSION(float, signed int);
00161 PPL_SAFE_CONVERSION(float, unsigned int);
00162 #endif
00163 #if PPL_SIZEOF_LONG <= PPL_SIZEOF_FLOAT - 2
00164 PPL_SAFE_CONVERSION(float, signed long);
00165 PPL_SAFE_CONVERSION(float, unsigned long);
00166 #endif
00167 #if PPL_SIZEOF_LONG_LONG <= PPL_SIZEOF_FLOAT - 2
00168 PPL_SAFE_CONVERSION(float, signed long long);
00169 PPL_SAFE_CONVERSION(float, unsigned long long);
00170 #endif
00171
00172 #if PPL_SIZEOF_CHAR <= PPL_SIZEOF_DOUBLE - 4
00173 PPL_SAFE_CONVERSION(double, char);
00174 PPL_SAFE_CONVERSION(double, signed char);
00175 PPL_SAFE_CONVERSION(double, unsigned char);
00176 #endif
00177 #if PPL_SIZEOF_SHORT <= PPL_SIZEOF_DOUBLE - 4
00178 PPL_SAFE_CONVERSION(double, signed short);
00179 PPL_SAFE_CONVERSION(double, unsigned short);
00180 #endif
00181 #if PPL_SIZEOF_INT <= PPL_SIZEOF_DOUBLE - 4
00182 PPL_SAFE_CONVERSION(double, signed int);
00183 PPL_SAFE_CONVERSION(double, unsigned int);
00184 #endif
00185 #if PPL_SIZEOF_LONG <= PPL_SIZEOF_DOUBLE - 4
00186 PPL_SAFE_CONVERSION(double, signed long);
00187 PPL_SAFE_CONVERSION(double, unsigned long);
00188 #endif
00189 #if PPL_SIZEOF_LONG_LONG <= PPL_SIZEOF_DOUBLE - 4
00190 PPL_SAFE_CONVERSION(double, signed long long);
00191 PPL_SAFE_CONVERSION(double, unsigned long long);
00192 #endif
00193 PPL_SAFE_CONVERSION(double, float);
00194
00195 #if PPL_SIZEOF_CHAR <= PPL_SIZEOF_LONG_DOUBLE - 4
00196 PPL_SAFE_CONVERSION(long double, char);
00197 PPL_SAFE_CONVERSION(long double, signed char);
00198 PPL_SAFE_CONVERSION(long double, unsigned char);
00199 #endif
00200 #if PPL_SIZEOF_SHORT <= PPL_SIZEOF_LONG_DOUBLE - 4
00201 PPL_SAFE_CONVERSION(long double, signed short);
00202 PPL_SAFE_CONVERSION(long double, unsigned short);
00203 #endif
00204 #if PPL_SIZEOF_INT <= PPL_SIZEOF_LONG_DOUBLE - 4
00205 PPL_SAFE_CONVERSION(long double, signed int);
00206 PPL_SAFE_CONVERSION(long double, unsigned int);
00207 #endif
00208 #if PPL_SIZEOF_LONG <= PPL_SIZEOF_LONG_DOUBLE - 4
00209 PPL_SAFE_CONVERSION(long double, signed long);
00210 PPL_SAFE_CONVERSION(long double, unsigned long);
00211 #endif
00212 #if PPL_SIZEOF_LONG_LONG <= PPL_SIZEOF_LONG_DOUBLE - 4
00213 PPL_SAFE_CONVERSION(long double, signed long long);
00214 PPL_SAFE_CONVERSION(long double, unsigned long long);
00215 #endif
00216 PPL_SAFE_CONVERSION(long double, float);
00217 PPL_SAFE_CONVERSION(long double, double);
00218
00219 PPL_SAFE_CONVERSION(mpz_class, char);
00220 PPL_SAFE_CONVERSION(mpz_class, signed char);
00221 PPL_SAFE_CONVERSION(mpz_class, signed short);
00222 PPL_SAFE_CONVERSION(mpz_class, signed int);
00223 PPL_SAFE_CONVERSION(mpz_class, signed long);
00224
00225 PPL_SAFE_CONVERSION(mpz_class, unsigned char);
00226 PPL_SAFE_CONVERSION(mpz_class, unsigned short);
00227 PPL_SAFE_CONVERSION(mpz_class, unsigned int);
00228 PPL_SAFE_CONVERSION(mpz_class, unsigned long);
00229
00230
00231 PPL_SAFE_CONVERSION(mpq_class, char);
00232 PPL_SAFE_CONVERSION(mpq_class, signed char);
00233 PPL_SAFE_CONVERSION(mpq_class, signed short);
00234 PPL_SAFE_CONVERSION(mpq_class, signed int);
00235 PPL_SAFE_CONVERSION(mpq_class, signed long);
00236
00237 PPL_SAFE_CONVERSION(mpq_class, unsigned char);
00238 PPL_SAFE_CONVERSION(mpq_class, unsigned short);
00239 PPL_SAFE_CONVERSION(mpq_class, unsigned int);
00240 PPL_SAFE_CONVERSION(mpq_class, unsigned long);
00241
00242 PPL_SAFE_CONVERSION(mpq_class, float);
00243 PPL_SAFE_CONVERSION(mpq_class, double);
00244
00245
00246 #undef PPL_SAFE_CONVERSION
00247
00248 template <typename Policy, typename Type>
00249 struct PPL_FUNCTION_CLASS(construct)<Policy, Policy, Type, Type> {
00250 static inline Result function(Type& to, const Type& from, Rounding_Dir) {
00251 new (&to) Type(from);
00252 return V_EQ;
00253 }
00254 };
00255
00256 template <typename To_Policy, typename From_Policy, typename To, typename From>
00257 struct PPL_FUNCTION_CLASS(construct) {
00258 static inline Result function(To& to, const From& from, Rounding_Dir dir) {
00259 new (&to) To();
00260 return assign<To_Policy, From_Policy>(to, from, dir);
00261 }
00262 };
00263
00264 template <typename To_Policy, typename To>
00265 struct PPL_FUNCTION_CLASS(construct_special) {
00266 static inline Result function(To& to, Result_Class r, Rounding_Dir dir) {
00267 new (&to) To();
00268 return assign_special<To_Policy>(to, r, dir);
00269 }
00270 };
00271
00272 template <typename To_Policy, typename From_Policy, typename To, typename From>
00273 inline Result
00274 assign_exact(To& to, const From& from, Rounding_Dir) {
00275 to = from;
00276 return V_EQ;
00277 }
00278
00279 template <typename To_Policy, typename From_Policy, typename Type>
00280 inline typename Enable_If<Is_Same<To_Policy, From_Policy>::value, void>::type
00281 copy_generic(Type& to, const Type& from) {
00282 to = from;
00283 }
00284
00285 template <typename To_Policy, typename From_Policy, typename To, typename From>
00286 inline Result
00287 abs_generic(To& to, const From& from, Rounding_Dir dir) {
00288 if (from < 0)
00289 return neg<To_Policy, From_Policy>(to, from, dir);
00290 else
00291 return assign<To_Policy, From_Policy>(to, from, dir);
00292 }
00293
00294 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
00295 typename To, typename From>
00296 inline void
00297 gcd_exact_noabs(To& to, const From& x, const From& y) {
00298 To nx = x;
00299 To ny = y;
00300 To rm;
00301 while (ny != 0) {
00302
00303
00304
00305 rem<To_Policy, From1_Policy, From2_Policy>(rm, nx, ny, ROUND_NOT_NEEDED);
00306 nx = ny;
00307 ny = rm;
00308 }
00309 to = nx;
00310 }
00311
00312 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
00313 typename To, typename From1, typename From2>
00314 inline Result
00315 gcd_exact(To& to, const From1& x, const From2& y, Rounding_Dir dir) {
00316 gcd_exact_noabs<To_Policy, From1_Policy, From2_Policy>(to, x, y);
00317 return abs<To_Policy, To_Policy>(to, to, dir);
00318 }
00319
00320 template <typename To1_Policy, typename To2_Policy, typename To3_Policy,
00321 typename From1_Policy, typename From2_Policy,
00322 typename To1, typename To2, typename To3,
00323 typename From1, typename From2>
00324 inline Result
00325 gcdext_exact(To1& to, To2& s, To3& t, const From1& x, const From2& y,
00326 Rounding_Dir dir) {
00327
00328
00329
00330
00331 if (y == 0) {
00332 if (x == 0) {
00333 s = 0;
00334 t = 1;
00335 return V_EQ;
00336 }
00337 else {
00338 if (x < 0)
00339 s = -1;
00340 else
00341 s = 1;
00342 t = 0;
00343 return abs<To1_Policy, From1_Policy>(to, x, dir);
00344 }
00345 }
00346
00347 s = 1;
00348 t = 0;
00349 bool negative_x = x < 0;
00350 bool negative_y = y < 0;
00351
00352 Result r;
00353 r = abs<To1_Policy, From1_Policy>(to, x, dir);
00354 if (r != V_EQ)
00355 return r;
00356
00357 From2 ay;
00358 r = abs<To1_Policy, From2_Policy>(ay, y, dir);
00359 if (r != V_EQ)
00360 return r;
00361
00362
00363
00364
00365
00366 #define PPL_MATCH_GMP_GCDEXT 1
00367 #ifdef PPL_MATCH_GMP_GCDEXT
00368 if (to == ay)
00369 goto sign_check;
00370 #endif
00371
00372 {
00373 To2 v1 = 0;
00374 To3 v2 = 1;
00375 To1 v3 = static_cast<To1>(ay);
00376 while (true) {
00377 To1 q = to / v3;
00378
00379 To1 t3 = to - q*v3;
00380 To2 t1 = s - static_cast<To2>(q)*v1;
00381 To3 t2 = t - static_cast<To3>(q)*v2;
00382 s = v1;
00383 t = v2;
00384 to = v3;
00385 if (t3 == 0)
00386 break;
00387 v1 = t1;
00388 v2 = t2;
00389 v3 = t3;
00390 }
00391 }
00392
00393 #ifdef PPL_MATCH_GMP_GCDEXT
00394 sign_check:
00395 #endif
00396 if (negative_x) {
00397 r = neg<To2_Policy, To2_Policy>(s, s, dir);
00398 if (r != V_EQ)
00399 return r;
00400 }
00401 if (negative_y)
00402 return neg<To3_Policy, To3_Policy>(t, t, dir);
00403 return V_EQ;
00404 #undef PPL_MATCH_GMP_GCDEXT
00405 }
00406
00407 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
00408 typename To, typename From1, typename From2>
00409 inline Result
00410 lcm_gcd_exact(To& to, const From1& x, const From2& y, Rounding_Dir dir) {
00411 if (x == 0 || y == 0) {
00412 to = 0;
00413 return V_EQ;
00414 }
00415 To nx, ny;
00416 Result r;
00417 r = abs<From1_Policy, From1_Policy>(nx, x, dir);
00418 if (r != V_EQ)
00419 return r;
00420 r = abs<From2_Policy, From2_Policy>(ny, y, dir);
00421 if (r != V_EQ)
00422 return r;
00423 To gcd;
00424 gcd_exact_noabs<To_Policy, From1_Policy, From2_Policy>(gcd, nx, ny);
00425
00426
00427
00428 div<To_Policy, From1_Policy, To_Policy>(to, nx, gcd, ROUND_NOT_NEEDED);
00429 return mul<To_Policy, To_Policy, From2_Policy>(to, to, ny, dir);
00430 }
00431
00432 template <typename Policy, typename Type>
00433 inline Result_Relation
00434 sgn_generic(const Type& x) {
00435 if (x > 0)
00436 return VR_GT;
00437 if (x == 0)
00438 return VR_EQ;
00439 return VR_LT;
00440 }
00441
00442 template <typename T1, typename T2, typename Enable = void>
00443 struct Safe_Int_Comparison : public False {
00444 };
00445
00446 template <typename T1, typename T2>
00447 struct Safe_Int_Comparison<T1, T2, typename Enable_If<(C_Integer<T1>::value && C_Integer<T2>::value)>::type>
00448 : public Bool<(C_Integer<T1>::is_signed
00449 ? (C_Integer<T2>::is_signed
00450 || sizeof(T2) < sizeof(T1)
00451 || sizeof(T2) < sizeof(int))
00452 : (!C_Integer<T2>::is_signed
00453 || sizeof(T1) < sizeof(T2)
00454 || sizeof(T1) < sizeof(int)))> {
00455 };
00456
00457
00458 template <typename T1, typename T2>
00459 inline typename Enable_If<(Safe_Int_Comparison<T1, T2>::value
00460 || Safe_Conversion<T1, T2>::value
00461 || Safe_Conversion<T2, T1>::value), bool>::type
00462 lt(const T1& x, const T2& y) {
00463 return x < y;
00464 }
00465 template <typename T1, typename T2>
00466 inline typename Enable_If<(Safe_Int_Comparison<T1, T2>::value
00467 || Safe_Conversion<T1, T2>::value
00468 || Safe_Conversion<T2, T1>::value), bool>::type
00469 le(const T1& x, const T2& y) {
00470 return x <= y;
00471 }
00472 template <typename T1, typename T2>
00473 inline typename Enable_If<(Safe_Int_Comparison<T1, T2>::value
00474 || Safe_Conversion<T1, T2>::value
00475 || Safe_Conversion<T2, T1>::value), bool>::type
00476 eq(const T1& x, const T2& y) {
00477 return x == y;
00478 }
00479
00480 template <typename S, typename U>
00481 inline typename Enable_If<(!Safe_Int_Comparison<S, U>::value
00482 && C_Integer<U>::value
00483 && C_Integer<S>::is_signed), bool>::type
00484 lt(const S& x, const U& y) {
00485 return x < 0 || static_cast<typename C_Integer<S>::other_type>(x) < y;
00486 }
00487
00488 template <typename U, typename S>
00489 inline typename Enable_If<(!Safe_Int_Comparison<S, U>::value
00490 && C_Integer<U>::value
00491 && C_Integer<S>::is_signed), bool>::type
00492 lt(const U& x, const S& y) {
00493 return y >= 0 && x < static_cast<typename C_Integer<S>::other_type>(y);
00494 }
00495
00496 template <typename S, typename U>
00497 inline typename Enable_If<(!Safe_Int_Comparison<S, U>::value
00498 && C_Integer<U>::value
00499 && C_Integer<S>::is_signed), bool>::type
00500 le(const S& x, const U& y) {
00501 return x < 0 || static_cast<typename C_Integer<S>::other_type>(x) <= y;
00502 }
00503
00504 template <typename U, typename S>
00505 inline typename Enable_If<(!Safe_Int_Comparison<S, U>::value
00506 && C_Integer<U>::value
00507 && C_Integer<S>::is_signed), bool>::type
00508 le(const U& x, const S& y) {
00509 return y >= 0 && x <= static_cast<typename C_Integer<S>::other_type>(y);
00510 }
00511
00512 template <typename S, typename U>
00513 inline typename Enable_If<(!Safe_Int_Comparison<S, U>::value
00514 && C_Integer<U>::value
00515 && C_Integer<S>::is_signed), bool>::type
00516 eq(const S& x, const U& y) {
00517 return x >= 0 && static_cast<typename C_Integer<S>::other_type>(x) == y;
00518 }
00519
00520 template <typename U, typename S>
00521 inline typename Enable_If<(!Safe_Int_Comparison<S, U>::value
00522 && C_Integer<U>::value
00523 && C_Integer<S>::is_signed), bool>::type
00524 eq(const U& x, const S& y) {
00525 return y >= 0 && x == static_cast<typename C_Integer<S>::other_type>(y);
00526 }
00527
00528 template <typename T1, typename T2>
00529 inline typename Enable_If<(!Safe_Conversion<T1, T2>::value
00530 && !Safe_Conversion<T2, T1>::value
00531 && (!C_Integer<T1>::value || !C_Integer<T2>::value)), bool>::type
00532 eq(const T1& x, const T2& y) {
00533 PPL_DIRTY_TEMP(T1, tmp);
00534 Result r = assign_r(tmp, y, ROUND_CHECK);
00535
00536
00537
00538
00539 PPL_ASSERT(r != V_LE && r != V_GE && r != V_LGE);
00540 return r == V_EQ && x == tmp;
00541 }
00542
00543 template <typename T1, typename T2>
00544 inline typename Enable_If<(!Safe_Conversion<T1, T2>::value
00545 && !Safe_Conversion<T2, T1>::value
00546 && (!C_Integer<T1>::value || !C_Integer<T2>::value)), bool>::type
00547 lt(const T1& x, const T2& y) {
00548 PPL_DIRTY_TEMP(T1, tmp);
00549 Result r = assign_r(tmp, y, ROUND_UP);
00550 if (!result_representable(r))
00551 return true;
00552 switch (result_relation(r)) {
00553 case VR_EQ:
00554 case VR_LT:
00555 case VR_LE:
00556 return x < tmp;
00557 default:
00558 return false;
00559 }
00560 }
00561
00562 template <typename T1, typename T2>
00563 inline typename
00564 Enable_If<(!Safe_Conversion<T1, T2>::value
00565 && !Safe_Conversion<T2, T1>::value
00566 && (!C_Integer<T1>::value || !C_Integer<T2>::value)), bool>::type
00567 le(const T1& x, const T2& y) {
00568 PPL_DIRTY_TEMP(T1, tmp);
00569 Result r
00570 = assign_r(tmp,
00571 y,
00572 static_cast<Rounding_Dir>(ROUND_UP | ROUND_STRICT_RELATION));
00573 if (!result_representable(r))
00574 return true;
00575 switch (result_relation(r)) {
00576 case VR_EQ:
00577 return x <= tmp;
00578 case VR_LT:
00579 return x < tmp;
00580 case VR_LE:
00581 case VR_GE:
00582 case VR_LGE:
00583
00584 PPL_ASSERT(0);
00585 default:
00586 return false;
00587 }
00588 }
00589
00590 template <typename Policy1, typename Policy2,
00591 typename Type1, typename Type2>
00592 inline bool
00593 lt_p(const Type1& x, const Type2& y) {
00594 return lt(x, y);
00595 }
00596
00597 template <typename Policy1, typename Policy2,
00598 typename Type1, typename Type2>
00599 inline bool
00600 le_p(const Type1& x, const Type2& y) {
00601 return le(x, y);
00602 }
00603
00604 template <typename Policy1, typename Policy2,
00605 typename Type1, typename Type2>
00606 inline bool
00607 eq_p(const Type1& x, const Type2& y) {
00608 return eq(x, y);
00609 }
00610
00611 template <typename Policy1, typename Policy2,
00612 typename Type1, typename Type2>
00613 inline Result_Relation
00614 cmp_generic(const Type1& x, const Type2& y) {
00615 if (lt(y, x))
00616 return VR_GT;
00617 if (lt(x, y))
00618 return VR_LT;
00619 return VR_EQ;
00620 }
00621
00622 template <typename Policy, typename Type>
00623 inline Result
00624 assign_nan(Type& to, Result r) {
00625 assign_special<Policy>(to, VC_NAN, ROUND_IGNORE);
00626 return r;
00627 }
00628
00629 template <typename Policy, typename Type>
00630 inline Result
00631 input_generic(Type& to, std::istream& is, Rounding_Dir dir) {
00632 PPL_DIRTY_TEMP0(mpq_class, q);
00633 Result r = input_mpq(q, is);
00634 Result_Class c = result_class(r);
00635 switch (c) {
00636 case VC_MINUS_INFINITY:
00637 case VC_PLUS_INFINITY:
00638 return assign_special<Policy>(to, c, dir);
00639 case VC_NAN:
00640 return assign_nan<Policy>(to, r);
00641 default:
00642 break;
00643 }
00644 PPL_ASSERT(r == V_EQ);
00645 return assign<Policy, void>(to, q, dir);
00646 }
00647
00648 }
00649
00650 }
00651
00652 #endif