[BACK]Return to mpfrxx.h CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp

Annotation of OpenXM_contrib/gmp/mpfrxx.h, Revision 1.1.1.1

1.1       ohara       1: /* mpfrxx.h -- C++ class wrapper for MPFR.  -*- C++ -*-
                      2:
                      3: Copyright 2001, 2002 Free Software Foundation, Inc.
                      4:
                      5: This file is part of the GNU MP Library.
                      6:
                      7: The GNU MP Library is free software; you can redistribute it and/or modify
                      8: it under the terms of the GNU Lesser General Public License as published by
                      9: the Free Software Foundation; either version 2.1 of the License, or (at your
                     10: option) any later version.
                     11:
                     12: The GNU MP Library is distributed in the hope that it will be useful, but
                     13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
                     15: License for more details.
                     16:
                     17: You should have received a copy of the GNU Lesser General Public License
                     18: along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
                     19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
                     20: MA 02111-1307, USA. */
                     21:
                     22: #ifndef __GMPFR_PLUSPLUS__
                     23: #define __GMPFR_PLUSPLUS__
                     24:
                     25: #include <iostream>
                     26: #include <string>
                     27: #include <gmp.h>
                     28: #include <mpfr.h>
                     29: #include "gmpxx.h"
                     30:
                     31:
                     32: class __gmpfr_value { };
                     33:
                     34: template <class T, class U>
                     35: void __gmp_set_expr(mpfr_ptr, const __gmp_expr<T, U> &);
                     36:
                     37: const int mpfr_default_base = 10;
                     38:
                     39:
                     40: /**************** Macros for in-class declarations ****************/
                     41:
                     42: #define __GMPFRR_DECLARE_COMPOUND_OPERATOR(fun)                             \
                     43:   template <class T, class U>                                               \
                     44:   __gmp_expr<__gmpfr_value, __gmpfr_value> & fun(const __gmp_expr<T, U> &);
                     45:
                     46: #define __GMPFRN_DECLARE_COMPOUND_OPERATOR(fun) \
                     47:   __gmp_expr & fun(signed char);                \
                     48:   __gmp_expr & fun(unsigned char);              \
                     49:   __gmp_expr & fun(signed int);                 \
                     50:   __gmp_expr & fun(unsigned int);               \
                     51:   __gmp_expr & fun(signed short int);           \
                     52:   __gmp_expr & fun(unsigned short int);         \
                     53:   __gmp_expr & fun(signed long int);            \
                     54:   __gmp_expr & fun(unsigned long int);          \
                     55:   __gmp_expr & fun(float);                      \
                     56:   __gmp_expr & fun(double);                     \
                     57:   __gmp_expr & fun(long double);
                     58:
                     59: #define __GMPFR_DECLARE_COMPOUND_OPERATOR(fun) \
                     60: __GMPFRR_DECLARE_COMPOUND_OPERATOR(fun)        \
                     61: __GMPFRN_DECLARE_COMPOUND_OPERATOR(fun)
                     62:
                     63: #define __GMPFR_DECLARE_COMPOUND_OPERATOR_UI(fun) \
                     64:   __gmp_expr & fun(unsigned long int);
                     65:
                     66: #define __GMPFR_DECLARE_INCREMENT_OPERATOR(fun) \
                     67:   inline __gmp_expr & fun();                    \
                     68:   inline __gmp_expr fun(int);
                     69:
                     70:
                     71: /**************** mpfr_class -- wrapper for mpfr_t ****************/
                     72:
                     73: template <>
                     74: class __gmp_expr<__gmpfr_value, __gmpfr_value>
                     75: {
                     76: private:
                     77:   mpfr_t mp;
                     78: public:
                     79:   // size information
                     80:   unsigned long int get_prec() const { return mpfr_get_prec(mp); }
                     81:
                     82:   // constructors and destructor
                     83:   __gmp_expr() { mpfr_init(mp); }
                     84:
                     85:   __gmp_expr(const __gmp_expr &f)
                     86:   {
                     87:     mpfr_init2(mp, f.get_prec());
                     88:     mpfr_set(mp, f.mp, __gmp_default_rounding_mode);
                     89:   }
                     90:   __gmp_expr(const __gmp_expr &f, unsigned long int prec,
                     91:             mp_rnd_t mode = __gmp_default_rounding_mode)
                     92:   { mpfr_init2(mp, prec); mpfr_set(mp, f.mp, mode); }
                     93:   template <class T, class U>
                     94:   __gmp_expr(const __gmp_expr<T, U> &expr)
                     95:   { mpfr_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
                     96:   template <class T, class U>
                     97:   __gmp_expr(const __gmp_expr<T, U> &expr, unsigned long int prec)
                     98:   { mpfr_init2(mp, prec); __gmp_set_expr(mp, expr); }
                     99:
                    100:   __gmp_expr(signed char c)
                    101:   { mpfr_init(mp); mpfr_set_si(mp, c, __gmp_default_rounding_mode); }
                    102:   __gmp_expr(signed char c, unsigned long int prec,
                    103:             mp_rnd_t mode = __gmp_default_rounding_mode)
                    104:   { mpfr_init2(mp, prec); mpfr_set_si(mp, c, mode); }
                    105:   __gmp_expr(unsigned char c)
                    106:   { mpfr_init(mp); mpfr_set_ui(mp, c, __gmp_default_rounding_mode); }
                    107:   __gmp_expr(unsigned char c, unsigned long int prec,
                    108:             mp_rnd_t mode = __gmp_default_rounding_mode)
                    109:   { mpfr_init2(mp, prec); mpfr_set_ui(mp, c, mode); }
                    110:
                    111:   __gmp_expr(signed int i)
                    112:   { mpfr_init(mp); mpfr_set_si(mp, i, __gmp_default_rounding_mode); }
                    113:   __gmp_expr(signed int i, unsigned long int prec,
                    114:             mp_rnd_t mode = __gmp_default_rounding_mode)
                    115:   { mpfr_init2(mp, prec); mpfr_set_si(mp, i, mode); }
                    116:   __gmp_expr(unsigned int i)
                    117:   { mpfr_init(mp); mpfr_set_ui(mp, i, __gmp_default_rounding_mode); }
                    118:   __gmp_expr(unsigned int i, unsigned long int prec,
                    119:             mp_rnd_t mode = __gmp_default_rounding_mode)
                    120:   { mpfr_init2(mp, prec); mpfr_set_ui(mp, i, mode); }
                    121:
                    122:   __gmp_expr(signed short int s)
                    123:   { mpfr_init(mp); mpfr_set_si(mp, s, __gmp_default_rounding_mode); }
                    124:   __gmp_expr(signed short int s, unsigned long int prec,
                    125:             mp_rnd_t mode = __gmp_default_rounding_mode)
                    126:   { mpfr_init2(mp, prec); mpfr_set_si(mp, s, mode); }
                    127:   __gmp_expr(unsigned short int s)
                    128:   { mpfr_init(mp); mpfr_set_ui(mp, s, __gmp_default_rounding_mode); }
                    129:   __gmp_expr(unsigned short int s, unsigned long int prec,
                    130:             mp_rnd_t mode = __gmp_default_rounding_mode)
                    131:   { mpfr_init2(mp, prec); mpfr_set_ui(mp, s, mode); }
                    132:
                    133:   __gmp_expr(signed long int l)
                    134:   { mpfr_init(mp); mpfr_set_si(mp, l, __gmp_default_rounding_mode); }
                    135:   __gmp_expr(signed long int l, unsigned long int prec,
                    136:             mp_rnd_t mode = __gmp_default_rounding_mode)
                    137:   { mpfr_init2(mp, prec); mpfr_set_si(mp, l, mode); }
                    138:   __gmp_expr(unsigned long int l)
                    139:   { mpfr_init(mp); mpfr_set_ui(mp, l, __gmp_default_rounding_mode); }
                    140:   __gmp_expr(unsigned long int l, unsigned long int prec,
                    141:             mp_rnd_t mode = __gmp_default_rounding_mode)
                    142:   { mpfr_init2(mp, prec); mpfr_set_ui(mp, l, mode); }
                    143:
                    144:   __gmp_expr(float f)
                    145:   { mpfr_init(mp); mpfr_set_d(mp, f, __gmp_default_rounding_mode); }
                    146:   __gmp_expr(float f, unsigned long int prec,
                    147:             mp_rnd_t mode = __gmp_default_rounding_mode)
                    148:   { mpfr_init2(mp, prec); mpfr_set_d(mp, f, mode); }
                    149:   __gmp_expr(double d)
                    150:   { mpfr_init(mp); mpfr_set_d(mp, d, __gmp_default_rounding_mode); }
                    151:   __gmp_expr(double d, unsigned long int prec,
                    152:             mp_rnd_t mode = __gmp_default_rounding_mode)
                    153:   { mpfr_init2(mp, prec); mpfr_set_d(mp, d, mode); }
                    154:   /*
                    155:   __gmp_expr(long double ld)
                    156:   { mpfr_init(mp); mpfr_set_d(mp, ld, __gmp_default_rounding_mode); }
                    157:   __gmp_expr(long double ld, unsigned long int prec,
                    158:             mp_rnd_t mode = __gmp_default_rounding_mode)
                    159:   { mpfr_init2(mp, prec); mpfr_set_d(mp, ld, mode); }
                    160:   */
                    161:
                    162:   /*
                    163:   explicit __gmp_expr(const char *s)
                    164:   { mpfr_init_set_str(mp, s, mpfr_default_base); }
                    165:   __gmp_expr(const char *s, int base) { mpfr_init_set_str(mp, s, base); }
                    166:   explicit __gmp_expr(const std::string &s)
                    167:   { mpfr_init_set_str(mp, s.c_str(), mpfr_default_base); }
                    168:   __gmp_expr(const std::string &s, int base)
                    169:   { mpfr_init_set_str(mp, s.c_str(), base); }
                    170:   */
                    171:
                    172:   explicit __gmp_expr(mpfr_srcptr f)
                    173:   {
                    174:     mpfr_init2(mp, mpfr_get_prec(f));
                    175:     mpfr_set(mp, f, __gmp_default_rounding_mode);
                    176:   }
                    177:   explicit __gmp_expr(mpfr_srcptr f, unsigned long int prec)
                    178:   {
                    179:     mpfr_init2(mp, prec);
                    180:     mpfr_set(mp, f, __gmp_default_rounding_mode);
                    181:   }
                    182:
                    183:   ~__gmp_expr() { mpfr_clear(mp); }
                    184:
                    185:   // assignment operators
                    186:   __gmp_expr & operator=(const __gmp_expr &f)
                    187:   { mpfr_set(mp, f.mp, __gmp_default_rounding_mode); return *this; }
                    188:   template <class T, class U>
                    189:   __gmp_expr<__gmpfr_value, __gmpfr_value> & operator=
                    190:   (const __gmp_expr<T, U> &expr)
                    191:   { __gmp_set_expr(mp, expr); return *this; }
                    192:
                    193:   __gmp_expr & operator=(signed char c)
                    194:   { mpfr_set_si(mp, c, __gmp_default_rounding_mode); return *this; }
                    195:   __gmp_expr & operator=(unsigned char c)
                    196:   { mpfr_set_ui(mp, c, __gmp_default_rounding_mode); return *this; }
                    197:
                    198:   __gmp_expr & operator=(signed int i)
                    199:   { mpfr_set_si(mp, i, __gmp_default_rounding_mode); return *this; }
                    200:   __gmp_expr & operator=(unsigned int i)
                    201:   { mpfr_set_ui(mp, i, __gmp_default_rounding_mode); return *this; }
                    202:
                    203:   __gmp_expr & operator=(signed short int s)
                    204:   { mpfr_set_si(mp, s, __gmp_default_rounding_mode); return *this; }
                    205:   __gmp_expr & operator=(unsigned short int s)
                    206:   { mpfr_set_ui(mp, s, __gmp_default_rounding_mode); return *this; }
                    207:
                    208:   __gmp_expr & operator=(signed long int l)
                    209:   { mpfr_set_si(mp, l, __gmp_default_rounding_mode); return *this; }
                    210:   __gmp_expr & operator=(unsigned long int l)
                    211:   { mpfr_set_ui(mp, l, __gmp_default_rounding_mode); return *this; }
                    212:
                    213:   __gmp_expr & operator=(float f)
                    214:   { mpfr_set_d(mp, f, __gmp_default_rounding_mode); return *this; }
                    215:   __gmp_expr & operator=(double d)
                    216:   { mpfr_set_d(mp, d, __gmp_default_rounding_mode); return *this; }
                    217:   /*
                    218:   __gmp_expr & operator=(long double ld)
                    219:   { mpfr_set_d(mp, ld, __gmp_default_rounding_mode); return *this; }
                    220:   */
                    221:
                    222:   /*
                    223:   __gmp_expr & operator=(const char *s)
                    224:   { mpfr_set_str(mp, s, mpfr_default_base); return *this; }
                    225:   __gmp_expr & operator=(const std::string &s)
                    226:   { mpfr_set_str(mp, s.c_str(), mpfr_default_base); return *this; }
                    227:
                    228:   // string input/output functions
                    229:   int set_str(const std::string &s, int base)
                    230:   { return mpfr_set_str(mp, s.c_str(), base); }
                    231:   */
                    232:   std::string get_str(mp_exp_t *expo, int base, size_t size,
                    233:                      mp_rnd_t rmode = __gmp_default_rounding_mode) const
                    234:   {
                    235:     __gmp_alloc_cstring temp(mpfr_get_str(0, expo, base, size, mp, rmode));
                    236:     return std::string(temp.str);
                    237:   }
                    238:
                    239:   // conversion functions
                    240:   mpfr_srcptr get_mpfr_t() const { return mp; }
                    241:   mpfr_ptr get_mpfr_t() { return mp; }
                    242:
                    243:   // signed long get_si() const { return mpfr_get_si(mp); }
                    244:   // unsigned long get_ui() const { return mpfr_get_ui(mp); }
                    245:   double get_d() const // should be long double
                    246:   { return mpfr_get_d(mp, __gmp_default_rounding_mode); }
                    247:
                    248:   // compound assignments
                    249:   __GMPFR_DECLARE_COMPOUND_OPERATOR(operator+=)
                    250:   __GMPFR_DECLARE_COMPOUND_OPERATOR(operator-=)
                    251:   __GMPFR_DECLARE_COMPOUND_OPERATOR(operator*=)
                    252:   __GMPFR_DECLARE_COMPOUND_OPERATOR(operator/=)
                    253:
                    254:   __GMPFR_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
                    255:   __GMPFR_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
                    256:
                    257:   __GMPFR_DECLARE_INCREMENT_OPERATOR(operator++)
                    258:   __GMPFR_DECLARE_INCREMENT_OPERATOR(operator--)
                    259: };
                    260:
                    261: typedef __gmp_expr<__gmpfr_value, __gmpfr_value> mpfr_class;
                    262:
                    263:
                    264: inline std::ostream & operator<<(std::ostream &o, const mpfr_class &f)
                    265: {
                    266:   mp_exp_t expo;
                    267:   int base = 10;
                    268:   __gmp_alloc_cstring temp(mpfr_get_str(0, &expo, base, 0, f.get_mpfr_t(),
                    269:                                        __gmp_default_rounding_mode));
                    270:
                    271:   // cancel terminating zeros
                    272:   for (size_t i=strlen(temp.str)-1; temp.str[i]=='0' && i>0; --i)
                    273:     temp.str[i] = '\0';
                    274:
                    275:   if (*temp.str == '-')
                    276:     o << "-0." << temp.str+1;
                    277:   else
                    278:     o << "0." << temp.str;
                    279:
                    280:   if (base <= 10)
                    281:     o << "e" << expo;
                    282:   else
                    283:     o << "@" << expo;
                    284:
                    285:   return o;
                    286: }
                    287:
                    288: template <class T>
                    289: inline std::ostream & operator<<
                    290: (std::ostream &o, const __gmp_expr<__gmpfr_value, T> &expr)
                    291: {
                    292:   mpfr_class temp(expr);
                    293:   return o << temp;
                    294: }
                    295:
                    296: inline std::istream & operator>>(std::istream &i, mpfr_class &f)
                    297: {
                    298:   mpf_t temp;
                    299:   mpf_init2(temp, f.get_prec());
                    300:   i >> temp;
                    301:   mpfr_set_f(f.get_mpfr_t(), temp, __gmp_default_rounding_mode);
                    302:   mpf_clear(temp);
                    303:   return i;
                    304: }
                    305:
                    306:
                    307: /**************** Classes for type conversion ****************/
                    308:
                    309: class __gmpfr_temp
                    310: {
                    311: private:
                    312:   mpfr_srcptr mp;
                    313:   bool is_temp;
                    314:   mpfr_t temp;
                    315:
                    316:   __gmpfr_temp();
                    317:   __gmpfr_temp(const __gmpfr_temp &);
                    318:   void operator=(const __gmpfr_temp &);
                    319: public:
                    320:   __gmpfr_temp(const mpfr_class &f) : mp(f.get_mpfr_t()), is_temp(false) { }
                    321:   __gmpfr_temp(const mpfr_class &f, unsigned long int)
                    322:     : mp(f.get_mpfr_t()), is_temp(false) { }
                    323:   template <class T, class U>
                    324:   __gmpfr_temp(const __gmp_expr<T, U> &expr)
                    325:   {
                    326:     mpfr_init2(temp, expr.get_prec());
                    327:     __gmp_set_expr(temp, expr);
                    328:     mp = temp;
                    329:     is_temp = true;
                    330:   }
                    331:   template <class T, class U>
                    332:   __gmpfr_temp(const __gmp_expr<T, U> &expr, unsigned long int prec)
                    333:   {
                    334:     mpfr_init2(temp, prec);
                    335:     __gmp_set_expr(temp, expr);
                    336:     mp = temp;
                    337:     is_temp = true;
                    338:   }
                    339:   ~__gmpfr_temp() { if (is_temp) mpfr_clear(temp); }
                    340:
                    341:   mpfr_srcptr get_mp() const { return mp; }
                    342: };
                    343:
                    344:
                    345: template <>
                    346: struct __gmp_resolve_expr<__gmpz_value, __gmpfr_value>
                    347: {
                    348:   typedef __gmpfr_value value_type;
                    349:   typedef __gmpfr_temp temp_type;
                    350: };
                    351:
                    352: template <>
                    353: struct __gmp_resolve_expr<__gmpfr_value, __gmpz_value>
                    354: {
                    355:   typedef __gmpfr_value value_type;
                    356:   typedef __gmpfr_temp temp_type;
                    357: };
                    358:
                    359: template <>
                    360: struct __gmp_resolve_expr<__gmpq_value, __gmpfr_value>
                    361: {
                    362:   typedef __gmpfr_value value_type;
                    363:   typedef __gmpfr_temp temp_type;
                    364: };
                    365:
                    366: template <>
                    367: struct __gmp_resolve_expr<__gmpfr_value, __gmpq_value>
                    368: {
                    369:   typedef __gmpfr_value value_type;
                    370:   typedef __gmpfr_temp temp_type;
                    371: };
                    372:
                    373: template <>
                    374: struct __gmp_resolve_expr<__gmpf_value, __gmpfr_value>
                    375: {
                    376:   typedef __gmpfr_value value_type;
                    377:   typedef __gmpfr_temp temp_type;
                    378: };
                    379:
                    380: template <>
                    381: struct __gmp_resolve_expr<__gmpfr_value, __gmpf_value>
                    382: {
                    383:   typedef __gmpfr_value value_type;
                    384:   typedef __gmpfr_temp temp_type;
                    385: };
                    386:
                    387: template <>
                    388: struct __gmp_resolve_expr<__gmpfr_value, __gmpfr_value>
                    389: {
                    390:   typedef __gmpfr_value value_type;
                    391:   typedef __gmpfr_temp temp_type;
                    392: };
                    393:
                    394:
                    395: /*
                    396: template <class T>
                    397: inline void __gmp_set_expr(mpz_ptr z, const mpfr_class &f)
                    398: {
                    399:   mpz_set_fr(z, f.get_mpfr_t());
                    400: }
                    401:
                    402: template <class T>
                    403: inline void __gmp_set_expr
                    404: (mpz_ptr z, const __gmp_expr<__gmpfr_value, T> &expr)
                    405: {
                    406:   mpfr_class temp(expr);
                    407:   mpz_set_fr(z, temp.get_mpfr_t());
                    408: }
                    409:
                    410: template <class T>
                    411: inline void __gmp_set_expr(mpq_ptr q, const mpfr_class &f)
                    412: {
                    413:   mpq_set_fr(q, f.get_mpfr_t());
                    414: }
                    415:
                    416: template <class T>
                    417: inline void __gmp_set_expr
                    418: (mpq_ptr q, const __gmp_expr<__gmpfr_value, T> &expr)
                    419: {
                    420:   mpfr_class temp(expr);
                    421:   mpq_set_fr(q, temp.get_mpfr_t());
                    422: }
                    423:
                    424: template <class T>
                    425: inline void __gmp_set_expr(mpf_ptr f, const mpfr_class &g)
                    426: {
                    427:   mpf_set_fr(f, g.get_mpfr_t());
                    428: }
                    429:
                    430: template <class T>
                    431: inline void __gmp_set_expr
                    432: (mpf_ptr f, const __gmp_expr<__gmpfr_value, T> &expr)
                    433: {
                    434:   mpfr_class temp(expr);
                    435:   mpf_set_fr(f, temp.get_mpfr_t());
                    436: }
                    437: */
                    438:
                    439: template <class T>
                    440: inline void __gmp_set_expr(mpfr_ptr f, const mpz_class &z)
                    441: {
                    442:   mpfr_set_z(f, z.get_mpz_t(), __gmp_default_rounding_mode);
                    443: }
                    444:
                    445: template <class T>
                    446: inline void __gmp_set_expr(mpfr_ptr f, const mpz_classref &z)
                    447: {
                    448:   mpfr_set_z(f, z.get_mpz_t(), __gmp_default_rounding_mode);
                    449: }
                    450:
                    451: template <class T>
                    452: inline void __gmp_set_expr
                    453: (mpfr_ptr f, const __gmp_expr<__gmpz_value, T> &expr)
                    454: {
                    455:   mpz_class temp(expr);
                    456:   mpfr_set_z(f, temp.get_mpz_t(), __gmp_default_rounding_mode);
                    457: }
                    458:
                    459: template <class T>
                    460: inline void __gmp_set_expr(mpfr_ptr f, const mpq_class &q)
                    461: {
                    462:   mpfr_set_q(f, q.get_mpq_t(), __gmp_default_rounding_mode);
                    463: }
                    464:
                    465: template <class T>
                    466: inline void __gmp_set_expr
                    467: (mpfr_ptr f, const __gmp_expr<__gmpq_value, T> &expr)
                    468: {
                    469:   mpq_class temp(expr);
                    470:   mpfr_set_q(f, temp.get_mpq_t(), __gmp_default_rounding_mode);
                    471: }
                    472:
                    473: template <class T>
                    474: inline void __gmp_set_expr(mpfr_ptr f, const mpf_class &g)
                    475: {
                    476:   mpfr_set_f(f, g.get_mpf_t(), __gmp_default_rounding_mode);
                    477: }
                    478:
                    479: template <class T>
                    480: inline void __gmp_set_expr
                    481: (mpfr_ptr f, const __gmp_expr<__gmpf_value, T> &expr)
                    482: {
                    483:   mpq_class temp(expr);
                    484:   mpfr_set_f(f, temp.get_mpf_t(), __gmp_default_rounding_mode);
                    485: }
                    486:
                    487: template <>
                    488: inline void __gmp_set_expr(mpfr_ptr f, const mpfr_class &g)
                    489: {
                    490:   mpfr_set(f, g.get_mpfr_t(), __gmp_default_rounding_mode);
                    491: }
                    492:
                    493: template <class T>
                    494: inline void __gmp_set_expr
                    495: (mpfr_ptr f, const __gmp_expr<__gmpfr_value, T> &expr)
                    496: {
                    497:   expr.eval(f, mpfr_get_prec(f));
                    498: }
                    499:
                    500:
                    501: /**************** Specializations of __gmp_expr ****************/
                    502:
                    503: // unary expressions
                    504:
                    505: template <class Op>
                    506: class __gmp_expr<__gmpfr_value, __gmp_unary_expr<mpfr_class, Op> >
                    507: {
                    508: private:
                    509:   __gmp_unary_expr<mpfr_class, Op> expr;
                    510: public:
                    511:   __gmp_expr(const mpfr_class &val) : expr(val) { }
                    512:   void eval(mpfr_ptr f, unsigned long int) const
                    513:   { Op::eval(f, expr.val.get_mpfr_t(), __gmp_default_rounding_mode); }
                    514:   unsigned long int get_prec() const
                    515:   { return mpfr_get_prec(expr.val.get_mpfr_t()); }
                    516: };
                    517:
                    518: template <class T, class U, class Op>
                    519: class __gmp_expr<__gmpfr_value, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
                    520: {
                    521: private:
                    522:   __gmp_unary_expr<__gmp_expr<T, U>, Op> expr;
                    523: public:
                    524:   __gmp_expr(const __gmp_expr<T, U> &val) : expr(val) { }
                    525:   void eval(mpfr_ptr f, unsigned long int prec) const
                    526:   {
                    527:     mpfr_class temp(expr.val, prec);
                    528:     Op::eval(f, temp.get_mpfr_t(), __gmp_default_rounding_mode);
                    529:   }
                    530:   unsigned long int get_prec() const { return expr.val.get_prec(); }
                    531: };
                    532:
                    533:
                    534: // binary expressions
                    535:
                    536: template <class Op>
                    537: class __gmp_expr
                    538: <__gmpfr_value, __gmp_binary_expr<mpfr_class, mpfr_class, Op> >
                    539: {
                    540: private:
                    541:   __gmp_binary_expr<mpfr_class, mpfr_class, Op> expr;
                    542: public:
                    543:   __gmp_expr(const mpfr_class &val1, const mpfr_class &val2)
                    544:     : expr(val1, val2) { }
                    545:   void eval(mpfr_ptr f, unsigned long int) const
                    546:   { Op::eval(f, expr.val1.get_mpfr_t(), expr.val2.get_mpfr_t(),
                    547:             __gmp_default_rounding_mode); }
                    548:   unsigned long int get_prec() const
                    549:   {
                    550:     unsigned long int prec1 = expr.val1.get_prec(),
                    551:       prec2 = expr.val2.get_prec();
                    552:     return (prec1 > prec2) ? prec1 : prec2;
                    553:   }
                    554: };
                    555:
                    556: template <class T, class Op>
                    557: class __gmp_expr<__gmpfr_value, __gmp_binary_expr<mpfr_class, T, Op> >
                    558: {
                    559: private:
                    560:   __gmp_binary_expr<mpfr_class, T, Op> expr;
                    561: public:
                    562:   __gmp_expr(const mpfr_class &val1, T val2) : expr(val1, val2) { }
                    563:   void eval(mpfr_ptr f, unsigned long int) const
                    564:   { Op::eval(f, expr.val1.get_mpfr_t(), expr.val2,
                    565:             __gmp_default_rounding_mode); }
                    566:   unsigned long int get_prec() const
                    567:   {
                    568:     unsigned long int prec1 = expr.val1.get_prec(),
                    569:       prec2 = mpf_get_default_prec();
                    570:     return (prec1 > prec2) ? prec1 : prec2;
                    571:   }
                    572: };
                    573:
                    574: template <class T, class Op>
                    575: class __gmp_expr<__gmpfr_value, __gmp_binary_expr<T, mpfr_class, Op> >
                    576: {
                    577: private:
                    578:   __gmp_binary_expr<T, mpfr_class, Op> expr;
                    579: public:
                    580:   __gmp_expr(T val1, const mpfr_class &val2) : expr(val1, val2) { }
                    581:   void eval(mpfr_ptr f, unsigned long int) const
                    582:   { Op::eval(f, expr.val1, expr.val2.get_mpfr_t(),
                    583:             __gmp_default_rounding_mode); }
                    584:   unsigned long int get_prec() const
                    585:   {
                    586:     unsigned long int prec1 = mpf_get_default_prec(),
                    587:       prec2 = expr.val2.get_prec();
                    588:     return (prec1 > prec2) ? prec1 : prec2;
                    589:   }
                    590: };
                    591:
                    592: template <class T, class U, class Op>
                    593: class __gmp_expr
                    594: <__gmpfr_value, __gmp_binary_expr<mpfr_class, __gmp_expr<T, U>, Op> >
                    595: {
                    596: private:
                    597:   __gmp_binary_expr<mpfr_class, __gmp_expr<T, U>, Op> expr;
                    598: public:
                    599:   __gmp_expr(const mpfr_class &val1, const __gmp_expr<T, U> &val2)
                    600:     : expr(val1, val2) { }
                    601:   void eval(mpfr_ptr f, unsigned long int prec) const
                    602:   {
                    603:     mpfr_class temp(expr.val2, prec);
                    604:     Op::eval(f, expr.val1.get_mpfr_t(), temp.get_mpfr_t(),
                    605:             __gmp_default_rounding_mode);
                    606:   }
                    607:   unsigned long int get_prec() const
                    608:   {
                    609:     unsigned long int prec1 = expr.val1.get_prec(),
                    610:       prec2 = expr.val2.get_prec();
                    611:     return (prec1 > prec2) ? prec1 : prec2;
                    612:   }
                    613: };
                    614:
                    615: template <class T, class U, class Op>
                    616: class __gmp_expr
                    617: <__gmpfr_value, __gmp_binary_expr<__gmp_expr<T, U>, mpfr_class, Op> >
                    618: {
                    619: private:
                    620:   __gmp_binary_expr<__gmp_expr<T, U>, mpfr_class, Op> expr;
                    621: public:
                    622:   __gmp_expr(const __gmp_expr<T, U> &val1, const mpfr_class &val2)
                    623:     : expr(val1, val2) { }
                    624:   void eval(mpfr_ptr f, unsigned long int prec) const
                    625:   {
                    626:     mpfr_class temp(expr.val1, prec);
                    627:     Op::eval(f, temp.get_mpfr_t(), expr.val2.get_mpfr_t(),
                    628:             __gmp_default_rounding_mode);
                    629:   }
                    630:   unsigned long int get_prec() const
                    631:   {
                    632:     unsigned long int prec1 = expr.val1.get_prec(),
                    633:       prec2 = expr.val2.get_prec();
                    634:     return (prec1 > prec2) ? prec1 : prec2;
                    635:   }
                    636: };
                    637:
                    638: template <class T, class U, class V, class Op>
                    639: class __gmp_expr<__gmpfr_value, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
                    640: {
                    641: private:
                    642:   __gmp_binary_expr<__gmp_expr<T, U>, V, Op> expr;
                    643: public:
                    644:   __gmp_expr(const __gmp_expr<T, U> &val1, V val2) : expr(val1, val2) { }
                    645:   void eval(mpfr_ptr f, unsigned long int prec) const
                    646:   {
                    647:     mpfr_class temp(expr.val1, prec);
                    648:     Op::eval(f, temp.get_mpfr_t(), expr.val2, __gmp_default_rounding_mode);
                    649:   }
                    650:   unsigned long int get_prec() const
                    651:   {
                    652:     unsigned long int prec1 = expr.val1.get_prec(),
                    653:       prec2 = mpf_get_default_prec();
                    654:     return (prec1 > prec2) ? prec1 : prec2;
                    655:   }
                    656: };
                    657:
                    658: template <class T, class U, class V, class Op>
                    659: class __gmp_expr<__gmpfr_value, __gmp_binary_expr<T, __gmp_expr<U, V>, Op> >
                    660: {
                    661: private:
                    662:   __gmp_binary_expr<T, __gmp_expr<U, V>, Op> expr;
                    663: public:
                    664:   __gmp_expr(T val1, const __gmp_expr<U, V> &val2) : expr(val1, val2) { }
                    665:   void eval(mpfr_ptr f, unsigned long int prec) const
                    666:   {
                    667:     mpfr_class temp(expr.val2, prec);
                    668:     Op::eval(f, expr.val1, temp.get_mpfr_t(), __gmp_default_rounding_mode);
                    669:   }
                    670:   unsigned long int get_prec() const
                    671:   {
                    672:     unsigned long int prec1 = mpf_get_default_prec(),
                    673:       prec2 = expr.val2.get_prec();
                    674:     return (prec1 > prec2) ? prec1 : prec2;
                    675:   }
                    676: };
                    677:
                    678: template <class T, class U, class V, class W, class Op>
                    679: class __gmp_expr
                    680: <__gmpfr_value, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
                    681: {
                    682: private:
                    683:   __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> expr;
                    684: public:
                    685:   __gmp_expr(const __gmp_expr<T, U> &val1, const __gmp_expr<V, W> &val2)
                    686:     : expr(val1, val2) { }
                    687:   void eval(mpfr_ptr f, unsigned long int prec) const
                    688:   {
                    689:     mpfr_class temp1(expr.val1, prec), temp2(expr.val2, prec);
                    690:     Op::eval(f, temp1.get_mpfr_t(), temp2.get_mpfr_t(),
                    691:             __gmp_default_rounding_mode);
                    692:   }
                    693:   unsigned long int get_prec() const
                    694:   {
                    695:     unsigned long int prec1 = expr.val1.get_prec(),
                    696:       prec2 = expr.val2.get_prec();
                    697:     return (prec1 > prec2) ? prec1 : prec2;
                    698:   }
                    699: };
                    700:
                    701:
                    702: /**************** Macros for defining functions ****************/
                    703:
                    704: #define __GMPFRR_DEFINE_COMPOUND_OPERATOR(fun, eval_fun)              \
                    705:                                                                       \
                    706: template <class T, class U>                                           \
                    707: inline mpfr_class & mpfr_class::fun(const __gmp_expr<T, U> &expr)     \
                    708: {                                                                     \
                    709:   __gmpfr_temp temp(expr, get_prec());                                \
                    710:   eval_fun::eval(mp, mp, temp.get_mp(), __gmp_default_rounding_mode); \
                    711:   return *this;                                                       \
                    712: }
                    713:
                    714: #define __GMPFRN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun)           \
                    715:                                                                    \
                    716: inline mpfr_class & mpfr_class::fun(signed char c)                 \
                    717: {                                                                  \
                    718:   eval_fun::eval(mp, mp, (signed long int) c,                      \
                    719:                  __gmp_default_rounding_mode);                     \
                    720:   return *this;                                                    \
                    721: }                                                                  \
                    722:                                                                    \
                    723: inline mpfr_class & mpfr_class::fun(unsigned char c)               \
                    724: {                                                                  \
                    725:   eval_fun::eval(mp, mp, (unsigned long int) c,                    \
                    726:                  __gmp_default_rounding_mode);                     \
                    727:   return *this;                                                    \
                    728: }                                                                  \
                    729:                                                                    \
                    730: inline mpfr_class & mpfr_class::fun(signed int i)                  \
                    731: {                                                                  \
                    732:   eval_fun::eval(mp, mp, (signed long int) i,                      \
                    733:                  __gmp_default_rounding_mode);                     \
                    734:   return *this;                                                    \
                    735: }                                                                  \
                    736:                                                                    \
                    737: inline mpfr_class & mpfr_class::fun(unsigned int i)                \
                    738: {                                                                  \
                    739:   eval_fun::eval(mp, mp, (unsigned long int) i,                    \
                    740:                  __gmp_default_rounding_mode);                     \
                    741:   return *this;                                                    \
                    742: }                                                                  \
                    743:                                                                    \
                    744: inline mpfr_class & mpfr_class::fun(signed short int s)            \
                    745: {                                                                  \
                    746:   eval_fun::eval(mp, mp, (signed long int) s,                      \
                    747:                  __gmp_default_rounding_mode);                     \
                    748:   return *this;                                                    \
                    749: }                                                                  \
                    750:                                                                    \
                    751: inline mpfr_class & mpfr_class::fun(unsigned short int s)          \
                    752: {                                                                  \
                    753:   eval_fun::eval(mp, mp, (unsigned long int) s,                    \
                    754:                  __gmp_default_rounding_mode);                     \
                    755:   return *this;                                                    \
                    756: }                                                                  \
                    757:                                                                    \
                    758: inline mpfr_class & mpfr_class::fun(signed long int l)             \
                    759: {                                                                  \
                    760:   eval_fun::eval(mp, mp, l, __gmp_default_rounding_mode);          \
                    761:   return *this;                                                    \
                    762: }                                                                  \
                    763:                                                                    \
                    764: inline mpfr_class & mpfr_class::fun(unsigned long int l)           \
                    765: {                                                                  \
                    766:   eval_fun::eval(mp, mp, l, __gmp_default_rounding_mode);          \
                    767:   return *this;                                                    \
                    768: }                                                                  \
                    769:                                                                    \
                    770: inline mpfr_class & mpfr_class::fun(float f)                       \
                    771: {                                                                  \
                    772:   eval_fun::eval(mp, mp, (double) f, __gmp_default_rounding_mode); \
                    773:   return *this;                                                    \
                    774: }                                                                  \
                    775:                                                                    \
                    776: inline mpfr_class & mpfr_class::fun(double d)                      \
                    777: {                                                                  \
                    778:   eval_fun::eval(mp, mp, d, __gmp_default_rounding_mode);          \
                    779:   return *this;                                                    \
                    780: }                                                                  \
                    781:                                                                    \
                    782: /*                                                                 \
                    783: inline mpfr_class & mpfr_class::fun(long double ld)                \
                    784: {                                                                  \
                    785:   eval_fun::eval(mp, mp, ld, __gmp_default_rounding_mode);         \
                    786:   return *this;                                                    \
                    787: } */
                    788:
                    789: #define __GMPFR_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
                    790: __GMPFRR_DEFINE_COMPOUND_OPERATOR(fun, eval_fun)        \
                    791: __GMPFRN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun)
                    792:
                    793: #define __GMPFR_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
                    794:                                                            \
                    795: inline mpfr_class & mpfr_class::fun(unsigned long int l)   \
                    796: {                                                          \
                    797:   eval_fun::eval(mp, mp, l, __gmp_default_rounding_mode);  \
                    798:   return *this;                                            \
                    799: }
                    800:
                    801: #define __GMPFR_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
                    802:                                                          \
                    803: inline mpfr_class & mpfr_class::fun()                    \
                    804: {                                                        \
                    805:   eval_fun::eval(mp, mp, __gmp_default_rounding_mode);   \
                    806:   return *this;                                          \
                    807: }                                                        \
                    808:                                                          \
                    809: inline mpfr_class mpfr_class::fun(int)                   \
                    810: {                                                        \
                    811:   mpfr_class temp(*this);                                \
                    812:   eval_fun::eval(mp, mp, __gmp_default_rounding_mode);   \
                    813:   return temp;                                           \
                    814: }
                    815:
                    816:
                    817: /**************** Arithmetic operators and functions ****************/
                    818:
                    819: __GMPFR_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
                    820: __GMPFR_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
                    821: __GMPFR_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
                    822: __GMPFR_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
                    823:
                    824: __GMPFR_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
                    825: __GMPFR_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
                    826:
                    827: __GMPFR_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
                    828: __GMPFR_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
                    829:
                    830:
                    831: /**************** #undef all private macros ****************/
                    832:
                    833: #undef __GMPFRR_DECLARE_COMPOUND_OPERATOR
                    834: #undef __GMPFRN_DECLARE_COMPOUND_OPERATOR
                    835: #undef __GMPFR_DECLARE_COMPOUND_OPERATOR
                    836: #undef __GMPFR_DECLARE_COMPOUND_OPERATOR_UI
                    837: #undef __GMPFR_DECLARE_INCREMENT_OPERATOR
                    838:
                    839: #undef __GMPFRR_DEFINE_COMPOUND_OPERATOR
                    840: #undef __GMPFRN_DEFINE_COMPOUND_OPERATOR
                    841: #undef __GMPFR_DEFINE_COMPOUND_OPERATOR
                    842: #undef __GMPFR_DEFINE_COMPOUND_OPERATOR_UI
                    843: #undef __GMPFR_DEFINE_INCREMENT_OPERATOR
                    844:
                    845:
                    846: #endif /* __GMPFR_PLUSPLUS__ */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>