rational.hpp

Go to the documentation of this file.
00001 /*********************************************************************
00002     
00003     rational.h
00004 
00005     N.Yu.Zolotykh 1999
00006     University of Nizhni Novgorod, Russia
00007 
00008 *********************************************************************/
00009 
00010 
00011 #ifndef _ARAGELI_rational_hpp_
00012 #define _ARAGELI_rational_hpp_
00013 
00014 #include "config.hpp"
00015 
00016 #include <iostream>
00017 #include <cstdlib>
00018 #include <sstream>
00019 #include <string>
00020 #include <cctype>
00021 #include <cmath>
00022 #include <functional>
00023 
00024 #include "type_traits.hpp"
00025 #include "type_pair_traits.hpp"
00026 #include "exception.hpp"
00027 #include "factory.hpp"
00028 #include "cmp.hpp"
00029 #include "io.hpp"
00030 #include "powerest.hpp"
00031 #include "big_int.hpp"
00032 
00033 #include "std_import.hpp"
00034 
00042 namespace Arageli
00043 {
00044 
00045 
00046 
00048 class rational_base
00049 {
00050 public:
00051 
00053     class exception : public virtual Arageli::exception
00054     {
00055         std::string msg_m;
00056     public:
00057         exception (const std::string& msg_a) : msg_m(msg_a) {}
00058         virtual std::string msg () const { return msg_m; }
00059     };
00060 };
00061 
00062 
00064 
00067 template <typename T = big_int>
00068 class rational : public rational_base
00069 {
00070     template <typename T1>
00071     friend class rational;
00072 
00073 public:
00074 
00076     typedef T value_type;
00077 
00079     rational () : p(factory<T>::null()), q(factory<T>::unit()) {}
00080     
00082     rational (const char* str);
00083     
00085     template <typename T1>
00086     rational (const rational<T1>& x)
00087     {
00088         ARAGELI_ASSERT_1
00089         (
00090             reinterpret_cast<const void*>(this) !=
00091             reinterpret_cast<const void*>(&x)
00092         );
00093 
00094         p = x.p; q = x.q;
00095     }
00096 
00098 
00099     template <typename T1>
00100     rational (const T1& w) : p(w), q(factory<T>::unit(p)) {}
00101     
00103 
00104     rational (const T& u, const T& v) : p(u), q(v)
00105     { ARAGELI_ASSERT_0(!Arageli::is_null(q)); normalize(); }
00106 
00107 
00108     rational (double x)
00109     {
00110         if(x == 0)
00111         {
00112             p = null<T>();
00113             q = unit<T>();
00114         }
00115         else
00116         {
00117             int pp;
00118             static const double powdig2 = pow(2.0, std::numeric_limits<double>::digits);
00119             p = powdig2 * frexp(x, &pp);
00120             q = powdig2;
00121             if(pp > 0)p *= pow(T(2), pp);
00122             else if(pp < 0)q *= pow(T(2), -pp);
00123             normalize();
00124         }
00125     }
00126 
00127     
00130     //operator T () const
00131     //{
00132     //  ARAGELI_ASSERT_0(is_normal());
00133     //  return numerator()/denominator();
00134     //}
00135 
00136     #define _ARAGELI_RATIONAL_OPERATOR_TO(TYPE) \
00137         operator TYPE () const { return double(*this); }
00138 
00140     _ARAGELI_RATIONAL_OPERATOR_TO(int);
00141 
00143     operator big_int () const
00144     {
00145         ARAGELI_ASSERT_0(is_normal());
00146         return numerator()/denominator();
00147     }
00148 
00150 
00155     operator float () const
00156     {
00157         ARAGELI_ASSERT_0(is_normal());
00158         return float(numerator())/float(denominator());
00159     }
00160 
00162 
00167     operator double () const
00168     {
00169         ARAGELI_ASSERT_0(is_normal());
00170         return double(numerator())/double(denominator());
00171     }
00172 
00174 
00180     operator long double () const
00181     {
00182         ARAGELI_ASSERT_0(is_normal());
00183         return (long double)(numerator())/(long double)(denominator());
00184     }
00185 
00187     operator bool () const
00188     {
00189         ARAGELI_ASSERT_0(is_normal());
00190         return !Arageli::is_null(numerator());
00191     }
00192 
00193     bool operator! () const { return !bool(*this); }
00194 
00195     //operator int () const
00196     //{
00197     //  ARAGELI_ASSERT_0(is_normal());
00198     //  return numerator()/denominator();
00199     //}
00200 
00202     template <typename T1>
00203     rational& operator= (const rational<T1>& x)
00204     {
00205         ARAGELI_ASSERT_1
00206         (
00207             reinterpret_cast<const void*>(this) !=
00208             reinterpret_cast<const void*>(&x)
00209         );
00210 
00211         p = x.p; q = x.q;
00212         return *this;
00213     }
00214     
00216 
00217     template <typename T1>
00218     rational& operator= (const T1& x)
00219     {
00220         p = x;
00221         q = unit(p);
00222         return *this;
00223     }
00224 
00225     rational& operator= (double x)
00226     { return *this = rational(x); }
00227 
00228 
00229     rational& operator= (const char* s)
00230     { return *this = rational(s); }
00231 
00232 
00234     const T& numerator () const { return p; }
00235     
00237     const T& denominator () const { return q; }
00238 
00240     T& numerator () { return p; }
00241 
00243     T& denominator () { return q; }
00244 
00246 
00248     rational operator- () const { return rational(Arageli::opposite(p), q); }
00249     
00251     const rational& operator+ () const { return *this; }
00252 
00253     
00254     rational& operator++ ()
00255     {
00256         p += q;
00257         normalize();
00258         return *this;
00259     }
00260 
00261     rational operator++ (int) { rational t = *this; operator++(); return t; }
00262 
00263     rational& operator-- ()
00264     {
00265         p -= q;
00266         normalize();
00267         return *this;
00268     }
00269 
00270     rational operator-- (int) { rational t = *this; operator--(); return t; }
00271 
00272 
00274 
00276     rational& opposite () { Arageli::opposite(&p); return *this; }
00277 
00279 
00282     rational& inverse ();
00283 
00284 
00286 
00290     int sign () const;
00291 
00293 
00294     bool is_integer () const { return Arageli::is_unit(q); }
00295 
00297 
00298     bool is_null () const { return Arageli::is_null(p); }
00299 
00301 
00302     bool is_unit () const { return Arageli::is_unit(p) && Arageli::is_unit(q); }
00303     
00305 
00306     bool is_opposite_unit () const
00307     { return Arageli::is_opposite_unit(p) && Arageli::is_unit(q); }
00308 
00310 
00313     void normalize ();
00314 
00316 
00318     bool is_normal () const;
00319 
00320     
00322     template <typename T1>
00323     void swap (rational<T1>& x)
00324     {
00325         std::swap(p, x.p);
00326         std::swap(q, x.q);
00327     }
00328 
00329 private:
00330 
00331     T p;    // numerator
00332     T q;    // denominator
00333 
00334 };
00335 
00336 
00337 extern const char* rational_output_list_first_bracket_default;
00338 extern const char* rational_output_list_second_bracket_default;
00339 extern const char* rational_output_list_separator_default;
00340 extern const char* rational_input_list_first_bracket_default;
00341 extern const char* rational_input_list_second_bracket_default;
00342 extern const char* rational_input_list_separator_default;
00343 extern const char* rational_output_default_oblique_default;
00344 extern const char* rational_input_default_oblique_default;
00345 
00346 
00347 template <typename T, typename Ch, typename ChT>
00348 inline std::basic_ostream<Ch, ChT>& output_list
00349 (
00350     std::basic_ostream<Ch, ChT>& out,
00351     const rational<T>& x,
00352     const Ch* first_bracket = rational_output_list_first_bracket_default,
00353     const Ch* second_bracket = rational_output_list_second_bracket_default,
00354     const Ch* separator = rational_output_list_separator_default
00355 )
00356 {
00357     return
00358         out << first_bracket << x.numerator()
00359         << separator << x.denominator() << second_bracket;
00360 }
00361 
00362 
00363 template <typename T, typename Ch, typename ChT>
00364 std::basic_istream<Ch, ChT>& input_list
00365 (
00366     std::basic_istream<Ch, ChT>& in,
00367     rational<T>& x,
00368     const Ch* first_bracket = rational_input_list_first_bracket_default,
00369     const Ch* second_bracket = rational_input_list_second_bracket_default,
00370     const Ch* separator = rational_input_list_separator_default
00371 );
00372 
00373 
00374 template <typename T, typename Ch, typename ChT>
00375 std::basic_ostream<Ch, ChT>& output_default
00376 (
00377     std::basic_ostream<Ch, ChT>& out,
00378     const rational<T>& x,
00379     const Ch* oblique = rational_output_default_oblique_default
00380 );
00381 
00382 
00383 template <typename T, typename Ch, typename ChT>
00384 std::basic_istream<Ch, ChT>& input_default
00385 (
00386     std::basic_istream<Ch, ChT>& in,
00387     rational<T>& x,
00388     const Ch* oblique = rational_input_default_oblique_default
00389 );
00390 
00391 
00393 
00394 template <typename T, typename Ch, typename ChT>
00395 inline std::basic_ostream<Ch, ChT>& operator<<
00396 (
00397     std::basic_ostream<Ch, ChT>& out,
00398     const rational<T>& x
00399 )
00400 { return output_default(out, x); }
00401 
00402 
00404 
00405 template <typename T, typename Ch, typename ChT>
00406 inline std::basic_istream<Ch, ChT>& operator>>
00407 (
00408     std::basic_istream<Ch, ChT>& in,
00409     rational<T>& x
00410 )
00411 { return input_default(in, x); }
00412 
00413 
00415 // @{
00416 
00417 template <typename T1, typename T2>
00418 rational<T1> operator+
00419 (const rational<T1>& b, const rational<T2>& c);
00420 
00421 template <typename T1, typename T2>
00422 rational<T1> operator-
00423 (const rational<T1>& b, const rational<T2>& c);
00424 
00425 template <typename T1, typename T2>
00426 rational<T1> operator*
00427 (const rational<T1>& b, const rational<T2>& c);
00428 
00429 template <typename T1, typename T2>
00430 rational<T1> operator/
00431 (const rational<T1>& b, const rational<T2>& c);
00432 
00433 template <typename T1, typename T2>
00434 inline rational<T1> operator%
00435 (const rational<T1>& b, const rational<T2>& c)
00436 {
00437     ARAGELI_ASSERT_0(!is_null(c));
00438     return null(b);
00439 }
00440 
00441 // @}
00442 
00443 
00444 #define _ARAGELI_RATIONAL_OPERS(OPER)           \
00445     template <typename T1, typename T2>         \
00446     inline rational<T1>& operator OPER##=       \
00447     (rational<T1>& a, const rational<T2>& b)    \
00448     { return a = a OPER b; }                    \
00449                                                 \
00450     template <typename T1, typename T2>         \
00451     inline rational<T1>& operator OPER##=       \
00452     (rational<T1>& a, const T2& b)              \
00453     { return a = a OPER rational<T1>(b); }      \
00454                                                 \
00455     template <typename T1, typename T2>         \
00456     inline rational<T1> operator OPER           \
00457     (const rational<T1>& a, const T2& b)        \
00458     { return a OPER rational<T1>(b); }          \
00459                                                 \
00460     template <typename T1, typename T2>         \
00461     inline rational<T1> operator OPER           \
00462     (const T2& a, const rational<T1>& b)        \
00463     { return rational<T1>(a) OPER b; }
00464 
00465 
00467 // @{
00468 
00469 _ARAGELI_RATIONAL_OPERS(+)
00470 _ARAGELI_RATIONAL_OPERS(-)
00471 _ARAGELI_RATIONAL_OPERS(*)
00472 _ARAGELI_RATIONAL_OPERS(/)
00473 _ARAGELI_RATIONAL_OPERS(%)
00474 
00475 // @}
00476 
00477 
00478 //template <typename T>
00479 //int rational<T>::sign () const;
00480 
00481 
00483 
00487 template <typename T1, typename T2>
00488 inline int cmp
00489 (
00490     const rational<T1>& a,
00491     const rational<T2>& b
00492 )
00493 { return (a - b).sign(); }
00494 
00495 
00496 template <typename T>
00497 inline int sign (const rational<T>& x)
00498 { return x.sign(); }
00499 
00500 template <typename T>
00501 inline bool is_coprime
00502 (const rational<T>& a, const rational<T>& b)
00503 { return true; }
00504 
00505 template <typename T>
00506 inline rational<T> gcd
00507 (const rational<T>& a, const rational<T>& b)
00508 {
00509     if(is_null(a) && is_null(b))return a;   // WARNING!
00510     else return unit(a);
00511 }
00512 
00513 
00514 
00515 #define _ARAGELI_RATIONAL_CMP1(OPER)                            \
00516     template <typename T1, typename T2>                         \
00517     inline bool operator OPER                                   \
00518     (const rational<T1>& a, const rational<T2>& b)              \
00519     { return cmp(a, b) OPER 0; }                                \
00520                                                                 \
00521     template <typename T1, typename T2>                         \
00522     inline bool operator OPER                                   \
00523     (const rational<T1>& a, const T2& b)                        \
00524     { return cmp(a, rational<T2>(b)) OPER 0; }  /* WARNING! */  \
00525                                                                 \
00526     template <typename T1, typename T2>                         \
00527     inline bool operator OPER                                   \
00528     (const T1& a, const rational<T2>& b)                        \
00529     { return cmp(rational<T1>(a), b) OPER 0; }  /* WARNING! */
00530 
00531 
00533 // @{
00534 
00535 _ARAGELI_RATIONAL_CMP1(<)
00536 _ARAGELI_RATIONAL_CMP1(>)
00537 _ARAGELI_RATIONAL_CMP1(==)
00538 _ARAGELI_RATIONAL_CMP1(!=)
00539 _ARAGELI_RATIONAL_CMP1(<=)
00540 _ARAGELI_RATIONAL_CMP1(>=)
00541 
00542 // @}
00543 
00544 
00545 //template <typename T>
00546 //void rational<T>::normalize ();
00547 
00549 
00550 template <typename T>
00551 T ifloor (const rational<T>& x);
00552 
00554 
00555 template <typename T>
00556 T iceil (const rational<T>& x);
00557 
00559 
00560 template <typename T>
00561 inline rational<T> frac (const rational<T>& x)
00562 { return x - ifloor(x); }
00563 
00564 //  WARNING! In the following selectors we have non reference as return value.
00565 
00567 template <typename T>
00568 struct select_numer : public std::unary_function<rational<T>, T>
00569 { T operator() (const rational<T>& x) const { return x.numerator(); } };
00570 
00572 template <typename T>
00573 struct select_denom : public std::unary_function<rational<T>, T>
00574 { T operator() (const rational<T>& x) const { return x.denominator(); } };
00575 
00576 template <typename T1>
00577 struct factory<rational<T1> >
00578 {
00579 private:
00580     
00581     typedef rational<T1> T;
00582 
00583 public:
00584 
00585     static const bool is_specialized = true;
00586 
00587     static const T& unit ()
00588     {
00589         static const T unit_s(Arageli::unit<T1>());
00590         return unit_s;
00591     }
00592     
00593     static T unit (const T& x)
00594     { return T(Arageli::unit(x.numerator()), Arageli::unit(x.denominator())); }
00595 
00596     static const T& opposite_unit ()
00597     {
00598         static const T opposite_unit_s(Arageli::opposite_unit<T1>());
00599         return opposite_unit_s;
00600     }
00601     
00602     static T opposite_unit (const T& x)
00603     { return T(Arageli::opposite_unit(x.numerator()), Arageli::unit(x.denominator())); }
00604 
00605     static const T& null ()
00606     {
00607         static const T null_s(Arageli::null<T1>());
00608         return null_s;
00609     }
00610     
00611     static T null (const T& x)
00612     { return T(Arageli::null(x.numerator()), Arageli::unit(x.denominator())); }
00613 
00614 
00615 };
00616 
00618 //static T bitwise_not (const T& x) { return ~x; }
00619 
00621 //static T& bitwise_not (const T& x, T* y) { return *y = ~x; }
00622 
00624 //static T& bitwise_not (T* x) { return *x = ~*x; }
00625 
00626 
00627 template <typename T1>
00628 inline bool is_null (const rational<T1>& x)
00629 { return x.is_null(); }
00630 
00631 template <typename T1>
00632 inline rational<T1> opposite (const rational<T1>& x)
00633 { return -x; }
00634 
00635 template <typename T1>
00636 inline rational<T1>& opposite (const rational<T1>& x, rational<T1>* y)
00637 { return *y = -x; }
00638 
00639 template <typename T1>
00640 inline rational<T1>& opposite (rational<T1>* x)
00641 { return x->opposite(); }
00642 
00643 template <typename T1>
00644 inline rational<T1> inverse (const rational<T1>& x)
00645 {
00646     rational<T1> xx = x;
00647     return xx.inverse();
00648 }
00649 
00650 template <typename T1>
00651 inline rational<T1>& inverse (const rational<T1>& x, rational<T1>* y)
00652 {
00653     *y = x;
00654     return y->inverse();
00655 }
00656 
00657 template <typename T1>
00658 inline rational<T1>& inverse (rational<T1>* x)
00659 { return x->inverse(); }
00660 
00661 //template <typename T1>
00662 //inline rational<T1> logical_not (const rational<T1>& x)
00663 //{ return x.is_null(); }
00664 //
00665 //template <typename T1>
00666 //inline bool blogical_not (const rational<T1>& x)
00667 //{ return x.is_null(); }
00668 //
00669 //template <typename T1>
00670 //inline rational<T1>& logical_not (const rational<T1>& x, rational<T1>* y)
00671 //{ return *y = x.is_null(); }
00672 //
00673 //template <typename T1>
00674 //inline rational<T1>& logical_not (rational<T1>* x)
00675 //{ return *x = x->is_null(); }
00676 
00677 template <typename T1>
00678 inline std::ostream& output_polynom_first (std::ostream& out, const rational<T1>& x)
00679 { return output_polynom_first_default(out, x); }
00680 
00681 template <typename T1>
00682 inline std::ostream& output_polynom_internal
00683 (std::ostream& out, const rational<T1>& x)
00684 { return output_polynom_internal_default(out, x); }
00685 
00686 template <typename T1>
00687 inline std::ostream& output_pow (std::ostream& out, const rational<T1>& x)
00688 { return output_pow_default(out, x); }
00689 
00690 template <typename T1>
00691 inline std::istream& input_polynom_first (std::istream& in, rational<T1>& x)
00692 { return input_polynom_first_default(in, x); }
00693 
00694 template <typename T1>
00695 inline std::istream& input_polynom_internal
00696 (std::istream& in, rational<T1>& x)
00697 { return input_polynom_internal_default(in, x); }
00698 
00699 template <typename T1>
00700 inline std::istream& input_pow (std::istream& in, rational<T1>& x)
00701 { return input_pow_default(in, x); }
00702 
00704 template <typename T>
00705 inline rational<T> abs (const rational<T>& x)
00706 { if(x.sign() < 0)return -x; else return x; }
00707 
00709 
00710 template <typename T>
00711 inline rational<T> floor (const rational<T>& x)
00712 { return ifloor(x); }
00713 
00715 
00716 template <typename T>
00717 inline rational<T> ceil (const rational<T>& x)
00718 { return iceil(x); }
00719 
00720 } // namespace Arageli
00721 
00722 
00723 namespace std
00724 {
00725 
00727 template <typename T>
00728 inline Arageli::rational<T> abs (const Arageli::rational<T>& x)
00729 { return Arageli::abs(x); }
00730 
00732 
00733 template <typename T>
00734 inline Arageli::rational<T> floor (const Arageli::rational<T>& x)
00735 { return Arageli::floor(x); }
00736 
00738 
00739 template <typename T>
00740 inline Arageli::rational<T> ceil (const Arageli::rational<T>& x)
00741 { return Arageli::ceil(x); }
00742 
00743 
00745 template <typename T> class numeric_limits<Arageli::rational<T> >
00746 {
00747     typedef Arageli::rational<T> TTT;
00748 
00749 public:
00750 
00751     static const bool is_specialized = true;
00752 
00753     // 'min' and 'max' return values like floating types
00754     // meaningfull if is_bounded only
00755 
00756     static TTT min () throw() { return TTT(Arageli::factory<T>::unit(), numeric_limits<T>::max()); }
00757     static TTT max () throw() { return TTT(numeric_limits<T>::max, Arageli::factory<T>::unit()); }
00758     
00759     static const int digits = 2*numeric_limits<T>::digits;
00760     static const int digits10 = 2*numeric_limits<T>::digits10;
00761     static const bool is_signed = numeric_limits<T>::is_signed;
00762     static const bool is_integer = false;
00763     static const bool is_exact = numeric_limits<T>::is_exact;
00764     static const int radix = 2;
00765     static TTT epsilon () throw() { return TTT(); }
00766     static TTT round_error () throw() { return TTT(); }
00767     static const int min_exponent = 0;
00768     static const int min_exponent10 = 0;
00769     static const int max_exponent = 0;
00770     static const int max_exponent10 = 0;
00771     static const bool has_infinity = false;
00772     static const bool has_quiet_NaN = false;
00773     static const bool has_signaling_NaN = false;
00774     static const float_denorm_style has_denorm = denorm_absent;
00775     static const bool has_denorm_loss = false;
00776     static TTT infinity () throw() { return TTT(); }
00777     static TTT quiet_NaN () throw() { return TTT(); }
00778     static TTT signaling_NaN () throw() { return TTT(); }
00779     static TTT denorm_min () throw() { return TTT(); }
00780     static const bool is_iec559 = false;
00781     static const bool is_bounded = numeric_limits<T>::is_bounded;
00782     static const bool is_modulo = false;
00783     static const bool traps = true;
00784     static const bool tinyness_before = false;
00785     static const float_round_style round = round_toward_zero;
00786 };
00787 
00788 
00790 template <typename T>
00791 void swap (Arageli::rational<T>& a, Arageli::rational<T>& b)
00792 { a.swap(b); }
00793 
00795 template <typename T1, typename T2>
00796 void swap (Arageli::rational<T1>& a, Arageli::rational<T2>& b)
00797 { a.swap(b); }
00798 
00799 
00800 }
00801 
00802 
00803 namespace Arageli
00804 {
00805 
00807 template <typename T>
00808 struct type_traits<rational<T> >
00809     : public type_traits_default<rational<T> >
00810 {
00811     static const bool is_specialized = type_traits<T>::is_specialized;
00812     static const bool is_number = type_traits<T>::is_number;
00813     static const bool is_rational = true;
00814     static const bool is_integer_number = false;
00815     static const bool is_polynom = false;
00816     static const bool is_real_number = false;
00817     static const bool is_rational_number = type_traits<T>::is_number;
00818     static const bool is_complex_number = false;
00819     static const bool is_ring = type_traits<T>::is_ring;
00820     static const bool is_field = type_traits<T>::is_ring;
00821     static const bool is_finite = type_traits<T>::is_finite;
00822 
00823     static const bool is_additive_group =
00824                         type_traits<T>::is_additive_group &&
00825                         type_traits<T>::is_ring;
00826 
00827     static const bool is_multiplicative_group =
00828                         type_traits<T>::is_additive_group &&
00829                         type_traits<T>::is_ring;
00830 
00831     static const bool has_zero_divisor = type_traits<T>::has_zero_divisor;
00832     static const bool is_integer_modulo_ring = false;
00833     static const bool is_matrix = false;
00834     static const bool is_vector = false;
00835     
00836     static const bool has_commutative_multiplication =
00837                         type_traits<T>::has_commutative_multiplication;
00838     
00839     static const bool has_commutative_addition =
00840                         type_traits<T>::has_commutative_multiplication &&
00841                         type_traits<T>::has_commutative_addition;
00842     
00843     static const bool has_null = type_traits<T>::has_null;
00844     static const bool has_unit = type_traits<T>::has_unit;
00845     
00846     static const bool has_opposite_unit =
00847                         type_traits<T>::has_opposite_unit &&
00848                         type_traits<T>::has_unit;
00849 
00850     static const bool is_aggregate = true;
00851     typedef T element_type;
00852     typedef type_category::rational category_type;
00853     static const category_type category_value;
00854 };
00855 
00856 template <typename T>
00857 const type_category::rational
00858     type_traits<rational<T> >::category_value =
00859     type_category::rational();
00860 
00861 
00862 #if 0
00863 
00865 
00868 template <typename TE1, typename T2>
00869 struct type_pair_traits<rational<TE1>, T2>
00870 {
00871     static const bool is_specialized =
00872         type_traits<TE1>::is_specialized &&
00873         type_traits<T2>::is_specialized;
00874 
00875     static const bool is_convertible =
00876         type_pair_traits<TE1, T2>::is_convertible;
00877 
00878     static const bool is_safe_convertible =
00879         type_traits<T2>::is_rational &&
00880         type_traits<T2>::is_aggregate &&
00881         type_pair_traits<TE1, typename type_traits<T2>::element_type>::is_specialized &&
00882         type_pair_traits<TE1, typename type_traits<T2>::element_type>::is_safe_convertible;
00883     
00884     static const bool is_assignable = is_convertible;
00885     static const bool is_safe_assignable = is_safe_convertible;
00886     static const bool is_initializable = is_convertible;
00887     static const bool is_safe_initializable = is_safe_convertible;
00888 };
00889 
00890 
00892 template <typename T1, typename TE2>
00893 struct type_pair_traits<T1, rational<TE2> >
00894     : public type_pair_traits_for_unknown_and_rational<T1, rational<TE2> > {};
00895 
00896 
00898 template <typename TE1, typename TE2>
00899 struct type_pair_traits<rational<TE1>, rational<TE2> >
00900     : public type_pair_traits_for_similar_aggregates
00901         <rational<TE1>, rational<TE2> > {};
00902 
00903 
00905 template <typename TE>
00906 struct type_pair_traits<rational<TE>, rational<TE> >
00907     : public type_pair_traits_for_the_same
00908         <rational<TE>, rational<TE> > {};
00909 
00910 
00912 template <typename TE2>
00913 struct type_pair_traits<big_int, rational<TE2> >
00914     : public type_pair_traits_for_unknown_and_rational<big_int, rational<TE2> > {};
00915 
00916 
00918 template <typename TE1>
00919 struct type_pair_traits<rational<TE1>, big_int>
00920 {
00921     static const bool is_specialized =
00922         type_traits<TE1>::is_specialized &&
00923         type_traits<big_int>::is_specialized;
00924 
00925     static const bool is_convertible =
00926         type_pair_traits<TE1, big_int>::is_convertible;
00927 
00928     static const bool is_safe_convertible = false;
00929     static const bool is_assignable = is_convertible;
00930     static const bool is_safe_assignable = is_safe_convertible;
00931     static const bool is_initializable = is_convertible;
00932     static const bool is_safe_initializable = is_safe_convertible;
00933 };
00934 
00936 //template <typename TE1>
00937 //struct type_pair_traits<rational<TE1>, big_int>
00938 //  : public type_pair_traits_for_unknown_and_rational<big_int, rational<TE2> > {};
00939 
00940 
00942 template <typename TE1, typename TE2, bool REFCNTE2>
00943 struct type_pair_traits<rational<TE1>, matrix<TE2, REFCNTE2> >
00944     : public type_pair_traits_for_unknown_and_vector_matrix
00945         <rational<TE1>, matrix<TE2, REFCNTE2> > {};
00946 
00948 template <typename TE1, typename TE2, typename TD2, bool REFCNTE2>
00949 struct type_pair_traits<rational<TE1>, sparse_polynom<TE2, TD2, REFCNTE2> >
00950     : public type_pair_traits_for_unknown_and_polynom
00951         <rational<TE1>, sparse_polynom<TE2, TD2, REFCNTE2> > {};
00952 
00953 #endif
00954 
00955 
00956 }
00957 
00958 
00959 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
00960     #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_RATIONAL
00961     #include "rational.cpp"
00962     #undef  ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_RATIONAL
00963 #endif
00964 
00965 
00966 #endif

Generated on Thu Aug 31 17:38:09 2006 for Arageli by  doxygen 1.4.7