gmpxx.h 126 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703
  1. /* gmpxx.h -- C++ class wrapper for GMP types. -*- C++ -*-
  2. Copyright 2001-2003, 2006, 2008, 2011-2015, 2018 Free Software
  3. Foundation, Inc.
  4. This file is part of the GNU MP Library.
  5. The GNU MP Library is free software; you can redistribute it and/or modify
  6. it under the terms of either:
  7. * the GNU Lesser General Public License as published by the Free
  8. Software Foundation; either version 3 of the License, or (at your
  9. option) any later version.
  10. or
  11. * the GNU General Public License as published by the Free Software
  12. Foundation; either version 2 of the License, or (at your option) any
  13. later version.
  14. or both in parallel, as here.
  15. The GNU MP Library is distributed in the hope that it will be useful, but
  16. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  18. for more details.
  19. You should have received copies of the GNU General Public License and the
  20. GNU Lesser General Public License along with the GNU MP Library. If not,
  21. see https://www.gnu.org/licenses/. */
  22. #ifndef __GMP_PLUSPLUS__
  23. #define __GMP_PLUSPLUS__
  24. #include <iosfwd>
  25. #include <cstring> /* for strlen */
  26. #include <limits> /* numeric_limits */
  27. #include <utility>
  28. #include <algorithm> /* swap */
  29. #include <string>
  30. #include <stdexcept>
  31. #include <cfloat>
  32. #include <gmp.h>
  33. // wrapper for gcc's __builtin_constant_p
  34. // __builtin_constant_p has been in gcc since forever,
  35. // but g++-3.4 miscompiles it.
  36. #if __GMP_GNUC_PREREQ(4, 2)
  37. #define __GMPXX_CONSTANT(X) __builtin_constant_p(X)
  38. #else
  39. #define __GMPXX_CONSTANT(X) false
  40. #endif
  41. #define __GMPXX_CONSTANT_TRUE(X) (__GMPXX_CONSTANT(X) && (X))
  42. // Use C++11 features
  43. #ifndef __GMPXX_USE_CXX11
  44. #if __cplusplus >= 201103L
  45. #define __GMPXX_USE_CXX11 1
  46. #else
  47. #define __GMPXX_USE_CXX11 0
  48. #endif
  49. #endif
  50. #if __GMPXX_USE_CXX11
  51. #define __GMPXX_NOEXCEPT noexcept
  52. #include <type_traits> // for common_type
  53. #else
  54. #define __GMPXX_NOEXCEPT
  55. #endif
  56. // Max allocations for plain types when converted to GMP types
  57. #if GMP_NAIL_BITS != 0 && ! defined _LONG_LONG_LIMB
  58. #define __GMPZ_ULI_LIMBS 2
  59. #else
  60. #define __GMPZ_ULI_LIMBS 1
  61. #endif
  62. #define __GMPXX_BITS_TO_LIMBS(n) (((n) + (GMP_NUMB_BITS - 1)) / GMP_NUMB_BITS)
  63. #define __GMPZ_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MAX_EXP)+1
  64. #define __GMPQ_NUM_DBL_LIMBS __GMPZ_DBL_LIMBS
  65. #define __GMPQ_DEN_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MANT_DIG+1-DBL_MIN_EXP)+1
  66. // The final +1s are a security margin. The current implementation of
  67. // mpq_set_d seems to need it for the denominator.
  68. inline void __mpz_set_ui_safe(mpz_ptr p, unsigned long l)
  69. {
  70. p->_mp_size = (l != 0);
  71. p->_mp_d[0] = l & GMP_NUMB_MASK;
  72. #if __GMPZ_ULI_LIMBS > 1
  73. l >>= GMP_NUMB_BITS;
  74. p->_mp_d[1] = l;
  75. p->_mp_size += (l != 0);
  76. #endif
  77. }
  78. inline void __mpz_set_si_safe(mpz_ptr p, long l)
  79. {
  80. if(l < 0)
  81. {
  82. __mpz_set_ui_safe(p, -static_cast<unsigned long>(l));
  83. mpz_neg(p, p);
  84. }
  85. else
  86. __mpz_set_ui_safe(p, l);
  87. // Note: we know the high bit of l is 0 so we could do slightly better
  88. }
  89. // Fake temporary variables
  90. #define __GMPXX_TMPZ_UI \
  91. mpz_t temp; \
  92. mp_limb_t limbs[__GMPZ_ULI_LIMBS]; \
  93. temp->_mp_d = limbs; \
  94. __mpz_set_ui_safe (temp, l)
  95. #define __GMPXX_TMPZ_SI \
  96. mpz_t temp; \
  97. mp_limb_t limbs[__GMPZ_ULI_LIMBS]; \
  98. temp->_mp_d = limbs; \
  99. __mpz_set_si_safe (temp, l)
  100. #define __GMPXX_TMPZ_D \
  101. mpz_t temp; \
  102. mp_limb_t limbs[__GMPZ_DBL_LIMBS]; \
  103. temp->_mp_d = limbs; \
  104. temp->_mp_alloc = __GMPZ_DBL_LIMBS; \
  105. mpz_set_d (temp, d)
  106. #define __GMPXX_TMPQ_UI \
  107. mpq_t temp; \
  108. mp_limb_t limbs[__GMPZ_ULI_LIMBS+1]; \
  109. mpq_numref(temp)->_mp_d = limbs; \
  110. __mpz_set_ui_safe (mpq_numref(temp), l); \
  111. mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS; \
  112. mpq_denref(temp)->_mp_size = 1; \
  113. mpq_denref(temp)->_mp_d[0] = 1
  114. #define __GMPXX_TMPQ_SI \
  115. mpq_t temp; \
  116. mp_limb_t limbs[__GMPZ_ULI_LIMBS+1]; \
  117. mpq_numref(temp)->_mp_d = limbs; \
  118. __mpz_set_si_safe (mpq_numref(temp), l); \
  119. mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS; \
  120. mpq_denref(temp)->_mp_size = 1; \
  121. mpq_denref(temp)->_mp_d[0] = 1
  122. #define __GMPXX_TMPQ_D \
  123. mpq_t temp; \
  124. mp_limb_t limbs[__GMPQ_NUM_DBL_LIMBS + __GMPQ_DEN_DBL_LIMBS]; \
  125. mpq_numref(temp)->_mp_d = limbs; \
  126. mpq_numref(temp)->_mp_alloc = __GMPQ_NUM_DBL_LIMBS; \
  127. mpq_denref(temp)->_mp_d = limbs + __GMPQ_NUM_DBL_LIMBS; \
  128. mpq_denref(temp)->_mp_alloc = __GMPQ_DEN_DBL_LIMBS; \
  129. mpq_set_d (temp, d)
  130. inline unsigned long __gmpxx_abs_ui (signed long l)
  131. {
  132. return l >= 0 ? static_cast<unsigned long>(l)
  133. : -static_cast<unsigned long>(l);
  134. }
  135. /**************** Function objects ****************/
  136. /* Any evaluation of a __gmp_expr ends up calling one of these functions
  137. all intermediate functions being inline, the evaluation should optimize
  138. to a direct call to the relevant function, thus yielding no overhead
  139. over the C interface. */
  140. struct __gmp_unary_plus
  141. {
  142. static void eval(mpz_ptr z, mpz_srcptr w) { mpz_set(z, w); }
  143. static void eval(mpq_ptr q, mpq_srcptr r) { mpq_set(q, r); }
  144. static void eval(mpf_ptr f, mpf_srcptr g) { mpf_set(f, g); }
  145. };
  146. struct __gmp_unary_minus
  147. {
  148. static void eval(mpz_ptr z, mpz_srcptr w) { mpz_neg(z, w); }
  149. static void eval(mpq_ptr q, mpq_srcptr r) { mpq_neg(q, r); }
  150. static void eval(mpf_ptr f, mpf_srcptr g) { mpf_neg(f, g); }
  151. };
  152. struct __gmp_unary_com
  153. {
  154. static void eval(mpz_ptr z, mpz_srcptr w) { mpz_com(z, w); }
  155. };
  156. struct __gmp_binary_plus
  157. {
  158. static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  159. { mpz_add(z, w, v); }
  160. static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  161. {
  162. // Ideally, those checks should happen earlier so that the tree
  163. // generated for a+0+b would just be sum(a,b).
  164. if (__GMPXX_CONSTANT(l) && l == 0)
  165. {
  166. if (z != w) mpz_set(z, w);
  167. }
  168. else
  169. mpz_add_ui(z, w, l);
  170. }
  171. static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  172. { eval(z, w, l); }
  173. static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  174. {
  175. if (l >= 0)
  176. eval(z, w, static_cast<unsigned long>(l));
  177. else
  178. mpz_sub_ui(z, w, -static_cast<unsigned long>(l));
  179. }
  180. static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  181. { eval(z, w, l); }
  182. static void eval(mpz_ptr z, mpz_srcptr w, double d)
  183. { __GMPXX_TMPZ_D; mpz_add (z, w, temp); }
  184. static void eval(mpz_ptr z, double d, mpz_srcptr w)
  185. { eval(z, w, d); }
  186. static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
  187. { mpq_add(q, r, s); }
  188. static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
  189. {
  190. if (__GMPXX_CONSTANT(l) && l == 0)
  191. {
  192. if (q != r) mpq_set(q, r);
  193. }
  194. else if (__GMPXX_CONSTANT(l) && l == 1)
  195. {
  196. mpz_add (mpq_numref(q), mpq_numref(r), mpq_denref(r));
  197. if (q != r) mpz_set(mpq_denref(q), mpq_denref(r));
  198. }
  199. else
  200. {
  201. if (q == r)
  202. mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
  203. else
  204. {
  205. mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
  206. mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
  207. mpz_set(mpq_denref(q), mpq_denref(r));
  208. }
  209. }
  210. }
  211. static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
  212. { eval(q, r, l); }
  213. static inline void eval(mpq_ptr q, mpq_srcptr r, signed long int l);
  214. // defined after __gmp_binary_minus
  215. static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
  216. { eval(q, r, l); }
  217. static void eval(mpq_ptr q, mpq_srcptr r, double d)
  218. { __GMPXX_TMPQ_D; mpq_add (q, r, temp); }
  219. static void eval(mpq_ptr q, double d, mpq_srcptr r)
  220. { eval(q, r, d); }
  221. static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
  222. {
  223. if (q == r)
  224. mpz_addmul(mpq_numref(q), mpq_denref(q), z);
  225. else
  226. {
  227. mpz_mul(mpq_numref(q), mpq_denref(r), z);
  228. mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
  229. mpz_set(mpq_denref(q), mpq_denref(r));
  230. }
  231. }
  232. static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
  233. { eval(q, r, z); }
  234. static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
  235. { mpf_add(f, g, h); }
  236. static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
  237. { mpf_add_ui(f, g, l); }
  238. static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
  239. { mpf_add_ui(f, g, l); }
  240. static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
  241. {
  242. if (l >= 0)
  243. mpf_add_ui(f, g, l);
  244. else
  245. mpf_sub_ui(f, g, -static_cast<unsigned long>(l));
  246. }
  247. static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
  248. { eval(f, g, l); }
  249. static void eval(mpf_ptr f, mpf_srcptr g, double d)
  250. {
  251. mpf_t temp;
  252. mpf_init2(temp, 8*sizeof(double));
  253. mpf_set_d(temp, d);
  254. mpf_add(f, g, temp);
  255. mpf_clear(temp);
  256. }
  257. static void eval(mpf_ptr f, double d, mpf_srcptr g)
  258. { eval(f, g, d); }
  259. };
  260. struct __gmp_binary_minus
  261. {
  262. static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  263. { mpz_sub(z, w, v); }
  264. static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  265. {
  266. if (__GMPXX_CONSTANT(l) && l == 0)
  267. {
  268. if (z != w) mpz_set(z, w);
  269. }
  270. else
  271. mpz_sub_ui(z, w, l);
  272. }
  273. static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  274. {
  275. if (__GMPXX_CONSTANT(l) && l == 0)
  276. {
  277. mpz_neg(z, w);
  278. }
  279. else
  280. mpz_ui_sub(z, l, w);
  281. }
  282. static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  283. {
  284. if (l >= 0)
  285. eval(z, w, static_cast<unsigned long>(l));
  286. else
  287. mpz_add_ui(z, w, -static_cast<unsigned long>(l));
  288. }
  289. static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  290. {
  291. if (l >= 0)
  292. eval(z, static_cast<unsigned long>(l), w);
  293. else
  294. {
  295. mpz_add_ui(z, w, -static_cast<unsigned long>(l));
  296. mpz_neg(z, z);
  297. }
  298. }
  299. static void eval(mpz_ptr z, mpz_srcptr w, double d)
  300. { __GMPXX_TMPZ_D; mpz_sub (z, w, temp); }
  301. static void eval(mpz_ptr z, double d, mpz_srcptr w)
  302. { __GMPXX_TMPZ_D; mpz_sub (z, temp, w); }
  303. static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
  304. { mpq_sub(q, r, s); }
  305. static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
  306. {
  307. if (__GMPXX_CONSTANT(l) && l == 0)
  308. {
  309. if (q != r) mpq_set(q, r);
  310. }
  311. else if (__GMPXX_CONSTANT(l) && l == 1)
  312. {
  313. mpz_sub (mpq_numref(q), mpq_numref(r), mpq_denref(r));
  314. if (q != r) mpz_set(mpq_denref(q), mpq_denref(r));
  315. }
  316. else
  317. {
  318. if (q == r)
  319. mpz_submul_ui(mpq_numref(q), mpq_denref(q), l);
  320. else
  321. {
  322. mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
  323. mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
  324. mpz_set(mpq_denref(q), mpq_denref(r));
  325. }
  326. }
  327. }
  328. static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
  329. { eval(q, r, l); mpq_neg(q, q); }
  330. static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
  331. {
  332. if (l >= 0)
  333. eval(q, r, static_cast<unsigned long>(l));
  334. else
  335. __gmp_binary_plus::eval(q, r, -static_cast<unsigned long>(l));
  336. }
  337. static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
  338. { eval(q, r, l); mpq_neg(q, q); }
  339. static void eval(mpq_ptr q, mpq_srcptr r, double d)
  340. { __GMPXX_TMPQ_D; mpq_sub (q, r, temp); }
  341. static void eval(mpq_ptr q, double d, mpq_srcptr r)
  342. { __GMPXX_TMPQ_D; mpq_sub (q, temp, r); }
  343. static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
  344. {
  345. if (q == r)
  346. mpz_submul(mpq_numref(q), mpq_denref(q), z);
  347. else
  348. {
  349. mpz_mul(mpq_numref(q), mpq_denref(r), z);
  350. mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
  351. mpz_set(mpq_denref(q), mpq_denref(r));
  352. }
  353. }
  354. static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
  355. { eval(q, r, z); mpq_neg(q, q); }
  356. static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
  357. { mpf_sub(f, g, h); }
  358. static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
  359. { mpf_sub_ui(f, g, l); }
  360. static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
  361. { mpf_ui_sub(f, l, g); }
  362. static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
  363. {
  364. if (l >= 0)
  365. mpf_sub_ui(f, g, l);
  366. else
  367. mpf_add_ui(f, g, -static_cast<unsigned long>(l));
  368. }
  369. static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
  370. {
  371. if (l >= 0)
  372. mpf_sub_ui(f, g, l);
  373. else
  374. mpf_add_ui(f, g, -static_cast<unsigned long>(l));
  375. mpf_neg(f, f);
  376. }
  377. static void eval(mpf_ptr f, mpf_srcptr g, double d)
  378. {
  379. mpf_t temp;
  380. mpf_init2(temp, 8*sizeof(double));
  381. mpf_set_d(temp, d);
  382. mpf_sub(f, g, temp);
  383. mpf_clear(temp);
  384. }
  385. static void eval(mpf_ptr f, double d, mpf_srcptr g)
  386. {
  387. mpf_t temp;
  388. mpf_init2(temp, 8*sizeof(double));
  389. mpf_set_d(temp, d);
  390. mpf_sub(f, temp, g);
  391. mpf_clear(temp);
  392. }
  393. };
  394. // defined here so it can reference __gmp_binary_minus
  395. inline void
  396. __gmp_binary_plus::eval(mpq_ptr q, mpq_srcptr r, signed long int l)
  397. {
  398. if (l >= 0)
  399. eval(q, r, static_cast<unsigned long>(l));
  400. else
  401. __gmp_binary_minus::eval(q, r, -static_cast<unsigned long>(l));
  402. }
  403. struct __gmp_binary_lshift
  404. {
  405. static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
  406. {
  407. if (__GMPXX_CONSTANT(l) && (l == 0))
  408. {
  409. if (z != w) mpz_set(z, w);
  410. }
  411. else
  412. mpz_mul_2exp(z, w, l);
  413. }
  414. static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
  415. {
  416. if (__GMPXX_CONSTANT(l) && (l == 0))
  417. {
  418. if (q != r) mpq_set(q, r);
  419. }
  420. else
  421. mpq_mul_2exp(q, r, l);
  422. }
  423. static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
  424. { mpf_mul_2exp(f, g, l); }
  425. };
  426. struct __gmp_binary_rshift
  427. {
  428. static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
  429. {
  430. if (__GMPXX_CONSTANT(l) && (l == 0))
  431. {
  432. if (z != w) mpz_set(z, w);
  433. }
  434. else
  435. mpz_fdiv_q_2exp(z, w, l);
  436. }
  437. static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
  438. {
  439. if (__GMPXX_CONSTANT(l) && (l == 0))
  440. {
  441. if (q != r) mpq_set(q, r);
  442. }
  443. else
  444. mpq_div_2exp(q, r, l);
  445. }
  446. static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
  447. { mpf_div_2exp(f, g, l); }
  448. };
  449. struct __gmp_binary_multiplies
  450. {
  451. static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  452. { mpz_mul(z, w, v); }
  453. static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  454. {
  455. // gcc-3.3 doesn't have __builtin_ctzl. Don't bother optimizing for old gcc.
  456. #if __GMP_GNUC_PREREQ(3, 4)
  457. if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
  458. {
  459. if (l == 0)
  460. {
  461. z->_mp_size = 0;
  462. }
  463. else
  464. {
  465. __gmp_binary_lshift::eval(z, w, __builtin_ctzl(l));
  466. }
  467. }
  468. else
  469. #endif
  470. mpz_mul_ui(z, w, l);
  471. }
  472. static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  473. { eval(z, w, l); }
  474. static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  475. {
  476. if (__GMPXX_CONSTANT_TRUE(l >= 0))
  477. eval(z, w, static_cast<unsigned long>(l));
  478. else if (__GMPXX_CONSTANT_TRUE(l <= 0))
  479. {
  480. eval(z, w, -static_cast<unsigned long>(l));
  481. mpz_neg(z, z);
  482. }
  483. else
  484. mpz_mul_si (z, w, l);
  485. }
  486. static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  487. { eval(z, w, l); }
  488. static void eval(mpz_ptr z, mpz_srcptr w, double d)
  489. { __GMPXX_TMPZ_D; mpz_mul (z, w, temp); }
  490. static void eval(mpz_ptr z, double d, mpz_srcptr w)
  491. { eval(z, w, d); }
  492. static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
  493. { mpq_mul(q, r, s); }
  494. static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
  495. {
  496. #if __GMP_GNUC_PREREQ(3, 4)
  497. if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
  498. {
  499. if (l == 0)
  500. {
  501. mpq_set_ui(q, 0, 1);
  502. }
  503. else
  504. {
  505. __gmp_binary_lshift::eval(q, r, __builtin_ctzl(l));
  506. }
  507. }
  508. else
  509. #endif
  510. {
  511. __GMPXX_TMPQ_UI;
  512. mpq_mul (q, r, temp);
  513. }
  514. }
  515. static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
  516. { eval(q, r, l); }
  517. static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
  518. {
  519. if (__GMPXX_CONSTANT_TRUE(l >= 0))
  520. eval(q, r, static_cast<unsigned long>(l));
  521. else if (__GMPXX_CONSTANT_TRUE(l <= 0))
  522. {
  523. eval(q, r, -static_cast<unsigned long>(l));
  524. mpq_neg(q, q);
  525. }
  526. else
  527. {
  528. __GMPXX_TMPQ_SI;
  529. mpq_mul (q, r, temp);
  530. }
  531. }
  532. static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
  533. { eval(q, r, l); }
  534. static void eval(mpq_ptr q, mpq_srcptr r, double d)
  535. { __GMPXX_TMPQ_D; mpq_mul (q, r, temp); }
  536. static void eval(mpq_ptr q, double d, mpq_srcptr r)
  537. { eval(q, r, d); }
  538. static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
  539. { mpf_mul(f, g, h); }
  540. static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
  541. { mpf_mul_ui(f, g, l); }
  542. static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
  543. { mpf_mul_ui(f, g, l); }
  544. static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
  545. {
  546. if (l >= 0)
  547. mpf_mul_ui(f, g, l);
  548. else
  549. {
  550. mpf_mul_ui(f, g, -static_cast<unsigned long>(l));
  551. mpf_neg(f, f);
  552. }
  553. }
  554. static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
  555. { eval(f, g, l); }
  556. static void eval(mpf_ptr f, mpf_srcptr g, double d)
  557. {
  558. mpf_t temp;
  559. mpf_init2(temp, 8*sizeof(double));
  560. mpf_set_d(temp, d);
  561. mpf_mul(f, g, temp);
  562. mpf_clear(temp);
  563. }
  564. static void eval(mpf_ptr f, double d, mpf_srcptr g)
  565. { eval(f, g, d); }
  566. };
  567. struct __gmp_binary_divides
  568. {
  569. static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  570. { mpz_tdiv_q(z, w, v); }
  571. static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  572. {
  573. #if __GMP_GNUC_PREREQ(3, 4)
  574. // Don't optimize division by 0...
  575. if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
  576. {
  577. if (l == 1)
  578. {
  579. if (z != w) mpz_set(z, w);
  580. }
  581. else
  582. mpz_tdiv_q_2exp(z, w, __builtin_ctzl(l));
  583. // warning: do not use rshift (fdiv)
  584. }
  585. else
  586. #endif
  587. mpz_tdiv_q_ui(z, w, l);
  588. }
  589. static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  590. {
  591. if (mpz_sgn(w) >= 0)
  592. {
  593. if (mpz_fits_ulong_p(w))
  594. mpz_set_ui(z, l / mpz_get_ui(w));
  595. else
  596. mpz_set_ui(z, 0);
  597. }
  598. else
  599. {
  600. mpz_neg(z, w);
  601. if (mpz_fits_ulong_p(z))
  602. {
  603. mpz_set_ui(z, l / mpz_get_ui(z));
  604. mpz_neg(z, z);
  605. }
  606. else
  607. mpz_set_ui(z, 0);
  608. }
  609. }
  610. static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  611. {
  612. if (l >= 0)
  613. eval(z, w, static_cast<unsigned long>(l));
  614. else
  615. {
  616. eval(z, w, -static_cast<unsigned long>(l));
  617. mpz_neg(z, z);
  618. }
  619. }
  620. static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  621. {
  622. if (mpz_fits_slong_p(w))
  623. mpz_set_si(z, l / mpz_get_si(w));
  624. else
  625. {
  626. /* if w is bigger than a long then the quotient must be zero, unless
  627. l==LONG_MIN and w==-LONG_MIN in which case the quotient is -1 */
  628. mpz_set_si (z, (mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? -1 : 0));
  629. }
  630. }
  631. static void eval(mpz_ptr z, mpz_srcptr w, double d)
  632. { __GMPXX_TMPZ_D; mpz_tdiv_q (z, w, temp); }
  633. static void eval(mpz_ptr z, double d, mpz_srcptr w)
  634. { __GMPXX_TMPZ_D; mpz_tdiv_q (z, temp, w); }
  635. static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
  636. { mpq_div(q, r, s); }
  637. static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
  638. {
  639. #if __GMP_GNUC_PREREQ(3, 4)
  640. if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
  641. __gmp_binary_rshift::eval(q, r, __builtin_ctzl(l));
  642. else
  643. #endif
  644. {
  645. __GMPXX_TMPQ_UI;
  646. mpq_div (q, r, temp);
  647. }
  648. }
  649. static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
  650. {
  651. if (__GMPXX_CONSTANT_TRUE(l == 0))
  652. mpq_set_ui(q, 0, 1);
  653. else if (__GMPXX_CONSTANT_TRUE(l == 1))
  654. mpq_inv(q, r);
  655. else
  656. {
  657. __GMPXX_TMPQ_UI;
  658. mpq_div (q, temp, r);
  659. }
  660. }
  661. static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
  662. {
  663. if (__GMPXX_CONSTANT_TRUE(l >= 0))
  664. eval(q, r, static_cast<unsigned long>(l));
  665. else if (__GMPXX_CONSTANT_TRUE(l <= 0))
  666. {
  667. eval(q, r, -static_cast<unsigned long>(l));
  668. mpq_neg(q, q);
  669. }
  670. else
  671. {
  672. __GMPXX_TMPQ_SI;
  673. mpq_div (q, r, temp);
  674. }
  675. }
  676. static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
  677. {
  678. if (__GMPXX_CONSTANT_TRUE(l == 0))
  679. mpq_set_ui(q, 0, 1);
  680. else if (__GMPXX_CONSTANT_TRUE(l == 1))
  681. mpq_inv(q, r);
  682. else if (__GMPXX_CONSTANT_TRUE(l == -1))
  683. {
  684. mpq_inv(q, r);
  685. mpq_neg(q, q);
  686. }
  687. else
  688. {
  689. __GMPXX_TMPQ_SI;
  690. mpq_div (q, temp, r);
  691. }
  692. }
  693. static void eval(mpq_ptr q, mpq_srcptr r, double d)
  694. { __GMPXX_TMPQ_D; mpq_div (q, r, temp); }
  695. static void eval(mpq_ptr q, double d, mpq_srcptr r)
  696. { __GMPXX_TMPQ_D; mpq_div (q, temp, r); }
  697. static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
  698. { mpf_div(f, g, h); }
  699. static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
  700. { mpf_div_ui(f, g, l); }
  701. static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
  702. { mpf_ui_div(f, l, g); }
  703. static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
  704. {
  705. if (l >= 0)
  706. mpf_div_ui(f, g, l);
  707. else
  708. {
  709. mpf_div_ui(f, g, -static_cast<unsigned long>(l));
  710. mpf_neg(f, f);
  711. }
  712. }
  713. static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
  714. {
  715. if (l >= 0)
  716. mpf_ui_div(f, l, g);
  717. else
  718. {
  719. mpf_ui_div(f, -static_cast<unsigned long>(l), g);
  720. mpf_neg(f, f);
  721. }
  722. }
  723. static void eval(mpf_ptr f, mpf_srcptr g, double d)
  724. {
  725. mpf_t temp;
  726. mpf_init2(temp, 8*sizeof(double));
  727. mpf_set_d(temp, d);
  728. mpf_div(f, g, temp);
  729. mpf_clear(temp);
  730. }
  731. static void eval(mpf_ptr f, double d, mpf_srcptr g)
  732. {
  733. mpf_t temp;
  734. mpf_init2(temp, 8*sizeof(double));
  735. mpf_set_d(temp, d);
  736. mpf_div(f, temp, g);
  737. mpf_clear(temp);
  738. }
  739. };
  740. struct __gmp_binary_modulus
  741. {
  742. static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  743. { mpz_tdiv_r(z, w, v); }
  744. static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  745. { mpz_tdiv_r_ui(z, w, l); }
  746. static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  747. {
  748. if (mpz_sgn(w) >= 0)
  749. {
  750. if (mpz_fits_ulong_p(w))
  751. mpz_set_ui(z, l % mpz_get_ui(w));
  752. else
  753. mpz_set_ui(z, l);
  754. }
  755. else
  756. {
  757. mpz_neg(z, w);
  758. if (mpz_fits_ulong_p(z))
  759. mpz_set_ui(z, l % mpz_get_ui(z));
  760. else
  761. mpz_set_ui(z, l);
  762. }
  763. }
  764. static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  765. {
  766. mpz_tdiv_r_ui (z, w, __gmpxx_abs_ui(l));
  767. }
  768. static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  769. {
  770. if (mpz_fits_slong_p(w))
  771. mpz_set_si(z, l % mpz_get_si(w));
  772. else
  773. {
  774. /* if w is bigger than a long then the remainder is l unchanged,
  775. unless l==LONG_MIN and w==-LONG_MIN in which case it's 0 */
  776. mpz_set_si (z, mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? 0 : l);
  777. }
  778. }
  779. static void eval(mpz_ptr z, mpz_srcptr w, double d)
  780. { __GMPXX_TMPZ_D; mpz_tdiv_r (z, w, temp); }
  781. static void eval(mpz_ptr z, double d, mpz_srcptr w)
  782. { __GMPXX_TMPZ_D; mpz_tdiv_r (z, temp, w); }
  783. };
  784. struct __gmp_binary_and
  785. {
  786. static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  787. { mpz_and(z, w, v); }
  788. static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  789. { __GMPXX_TMPZ_UI; mpz_and (z, w, temp); }
  790. static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  791. { eval(z, w, l); }
  792. static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  793. { __GMPXX_TMPZ_SI; mpz_and (z, w, temp); }
  794. static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  795. { eval(z, w, l); }
  796. static void eval(mpz_ptr z, mpz_srcptr w, double d)
  797. { __GMPXX_TMPZ_D; mpz_and (z, w, temp); }
  798. static void eval(mpz_ptr z, double d, mpz_srcptr w)
  799. { eval(z, w, d); }
  800. };
  801. struct __gmp_binary_ior
  802. {
  803. static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  804. { mpz_ior(z, w, v); }
  805. static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  806. { __GMPXX_TMPZ_UI; mpz_ior (z, w, temp); }
  807. static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  808. { eval(z, w, l); }
  809. static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  810. { __GMPXX_TMPZ_SI; mpz_ior (z, w, temp); }
  811. static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  812. { eval(z, w, l); }
  813. static void eval(mpz_ptr z, mpz_srcptr w, double d)
  814. { __GMPXX_TMPZ_D; mpz_ior (z, w, temp); }
  815. static void eval(mpz_ptr z, double d, mpz_srcptr w)
  816. { eval(z, w, d); }
  817. };
  818. struct __gmp_binary_xor
  819. {
  820. static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  821. { mpz_xor(z, w, v); }
  822. static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  823. { __GMPXX_TMPZ_UI; mpz_xor (z, w, temp); }
  824. static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  825. { eval(z, w, l); }
  826. static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  827. { __GMPXX_TMPZ_SI; mpz_xor (z, w, temp); }
  828. static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  829. { eval(z, w, l); }
  830. static void eval(mpz_ptr z, mpz_srcptr w, double d)
  831. { __GMPXX_TMPZ_D; mpz_xor (z, w, temp); }
  832. static void eval(mpz_ptr z, double d, mpz_srcptr w)
  833. { eval(z, w, d); }
  834. };
  835. struct __gmp_cmp_function
  836. {
  837. static int eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w); }
  838. static int eval(mpz_srcptr z, unsigned long int l)
  839. { return mpz_cmp_ui(z, l); }
  840. static int eval(unsigned long int l, mpz_srcptr z)
  841. { return -mpz_cmp_ui(z, l); }
  842. static int eval(mpz_srcptr z, signed long int l)
  843. { return mpz_cmp_si(z, l); }
  844. static int eval(signed long int l, mpz_srcptr z)
  845. { return -mpz_cmp_si(z, l); }
  846. static int eval(mpz_srcptr z, double d)
  847. { return mpz_cmp_d(z, d); }
  848. static int eval(double d, mpz_srcptr z)
  849. { return -mpz_cmp_d(z, d); }
  850. static int eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r); }
  851. static int eval(mpq_srcptr q, unsigned long int l)
  852. { return mpq_cmp_ui(q, l, 1); }
  853. static int eval(unsigned long int l, mpq_srcptr q)
  854. { return -mpq_cmp_ui(q, l, 1); }
  855. static int eval(mpq_srcptr q, signed long int l)
  856. { return mpq_cmp_si(q, l, 1); }
  857. static int eval(signed long int l, mpq_srcptr q)
  858. { return -mpq_cmp_si(q, l, 1); }
  859. static int eval(mpq_srcptr q, double d)
  860. { __GMPXX_TMPQ_D; return mpq_cmp (q, temp); }
  861. static int eval(double d, mpq_srcptr q)
  862. { __GMPXX_TMPQ_D; return mpq_cmp (temp, q); }
  863. static int eval(mpq_srcptr q, mpz_srcptr z)
  864. { return mpq_cmp_z(q, z); }
  865. static int eval(mpz_srcptr z, mpq_srcptr q)
  866. { return -mpq_cmp_z(q, z); }
  867. static int eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g); }
  868. static int eval(mpf_srcptr f, unsigned long int l)
  869. { return mpf_cmp_ui(f, l); }
  870. static int eval(unsigned long int l, mpf_srcptr f)
  871. { return -mpf_cmp_ui(f, l); }
  872. static int eval(mpf_srcptr f, signed long int l)
  873. { return mpf_cmp_si(f, l); }
  874. static int eval(signed long int l, mpf_srcptr f)
  875. { return -mpf_cmp_si(f, l); }
  876. static int eval(mpf_srcptr f, double d)
  877. { return mpf_cmp_d(f, d); }
  878. static int eval(double d, mpf_srcptr f)
  879. { return -mpf_cmp_d(f, d); }
  880. static int eval(mpf_srcptr f, mpz_srcptr z)
  881. { return mpf_cmp_z(f, z); }
  882. static int eval(mpz_srcptr z, mpf_srcptr f)
  883. { return -mpf_cmp_z(f, z); }
  884. static int eval(mpf_srcptr f, mpq_srcptr q)
  885. {
  886. mpf_t qf;
  887. mpf_init(qf); /* Should we use the precision of f? */
  888. mpf_set_q(qf, q);
  889. int ret = eval(f, qf);
  890. mpf_clear(qf);
  891. return ret;
  892. }
  893. static int eval(mpq_srcptr q, mpf_srcptr f)
  894. { return -eval(f, q); }
  895. };
  896. struct __gmp_binary_equal
  897. {
  898. static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) == 0; }
  899. static bool eval(mpz_srcptr z, unsigned long int l)
  900. { return mpz_cmp_ui(z, l) == 0; }
  901. static bool eval(unsigned long int l, mpz_srcptr z)
  902. { return eval(z, l); }
  903. static bool eval(mpz_srcptr z, signed long int l)
  904. { return mpz_cmp_si(z, l) == 0; }
  905. static bool eval(signed long int l, mpz_srcptr z)
  906. { return eval(z, l); }
  907. static bool eval(mpz_srcptr z, double d)
  908. { return mpz_cmp_d(z, d) == 0; }
  909. static bool eval(double d, mpz_srcptr z)
  910. { return eval(z, d); }
  911. static bool eval(mpq_srcptr q, mpq_srcptr r)
  912. { return mpq_equal(q, r) != 0; }
  913. static bool eval(mpq_srcptr q, unsigned long int l)
  914. { return ((__GMPXX_CONSTANT(l) && l == 0) ||
  915. mpz_cmp_ui(mpq_denref(q), 1) == 0) &&
  916. mpz_cmp_ui(mpq_numref(q), l) == 0; }
  917. static bool eval(unsigned long int l, mpq_srcptr q)
  918. { return eval(q, l); }
  919. static bool eval(mpq_srcptr q, signed long int l)
  920. { return ((__GMPXX_CONSTANT(l) && l == 0) ||
  921. mpz_cmp_ui(mpq_denref(q), 1) == 0) &&
  922. mpz_cmp_si(mpq_numref(q), l) == 0; }
  923. static bool eval(signed long int l, mpq_srcptr q)
  924. { return eval(q, l); }
  925. static bool eval(mpq_srcptr q, double d)
  926. { __GMPXX_TMPQ_D; return mpq_equal (q, temp) != 0; }
  927. static bool eval(double d, mpq_srcptr q)
  928. { return eval(q, d); }
  929. static bool eval(mpq_srcptr q, mpz_srcptr z)
  930. { return mpz_cmp_ui(mpq_denref(q), 1) == 0 && mpz_cmp(mpq_numref(q), z) == 0; }
  931. static bool eval(mpz_srcptr z, mpq_srcptr q)
  932. { return eval(q, z); }
  933. static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) == 0; }
  934. static bool eval(mpf_srcptr f, unsigned long int l)
  935. { return mpf_cmp_ui(f, l) == 0; }
  936. static bool eval(unsigned long int l, mpf_srcptr f)
  937. { return eval(f, l); }
  938. static bool eval(mpf_srcptr f, signed long int l)
  939. { return mpf_cmp_si(f, l) == 0; }
  940. static bool eval(signed long int l, mpf_srcptr f)
  941. { return eval(f, l); }
  942. static bool eval(mpf_srcptr f, double d)
  943. { return mpf_cmp_d(f, d) == 0; }
  944. static bool eval(double d, mpf_srcptr f)
  945. { return eval(f, d); }
  946. static bool eval(mpf_srcptr f, mpz_srcptr z)
  947. { return mpf_cmp_z(f, z) == 0; }
  948. static bool eval(mpz_srcptr z, mpf_srcptr f)
  949. { return eval(f, z); }
  950. static bool eval(mpf_srcptr f, mpq_srcptr q)
  951. { return __gmp_cmp_function::eval(f, q) == 0; }
  952. static bool eval(mpq_srcptr q, mpf_srcptr f)
  953. { return eval(f, q); }
  954. };
  955. struct __gmp_binary_less
  956. {
  957. static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) < 0; }
  958. static bool eval(mpz_srcptr z, unsigned long int l)
  959. { return mpz_cmp_ui(z, l) < 0; }
  960. static bool eval(unsigned long int l, mpz_srcptr z)
  961. { return mpz_cmp_ui(z, l) > 0; }
  962. static bool eval(mpz_srcptr z, signed long int l)
  963. { return mpz_cmp_si(z, l) < 0; }
  964. static bool eval(signed long int l, mpz_srcptr z)
  965. { return mpz_cmp_si(z, l) > 0; }
  966. static bool eval(mpz_srcptr z, double d)
  967. { return mpz_cmp_d(z, d) < 0; }
  968. static bool eval(double d, mpz_srcptr z)
  969. { return mpz_cmp_d(z, d) > 0; }
  970. static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) < 0; }
  971. static bool eval(mpq_srcptr q, unsigned long int l)
  972. { return mpq_cmp_ui(q, l, 1) < 0; }
  973. static bool eval(unsigned long int l, mpq_srcptr q)
  974. { return mpq_cmp_ui(q, l, 1) > 0; }
  975. static bool eval(mpq_srcptr q, signed long int l)
  976. { return mpq_cmp_si(q, l, 1) < 0; }
  977. static bool eval(signed long int l, mpq_srcptr q)
  978. { return mpq_cmp_si(q, l, 1) > 0; }
  979. static bool eval(mpq_srcptr q, double d)
  980. { __GMPXX_TMPQ_D; return mpq_cmp (q, temp) < 0; }
  981. static bool eval(double d, mpq_srcptr q)
  982. { __GMPXX_TMPQ_D; return mpq_cmp (temp, q) < 0; }
  983. static bool eval(mpq_srcptr q, mpz_srcptr z)
  984. { return mpq_cmp_z(q, z) < 0; }
  985. static bool eval(mpz_srcptr z, mpq_srcptr q)
  986. { return mpq_cmp_z(q, z) > 0; }
  987. static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) < 0; }
  988. static bool eval(mpf_srcptr f, unsigned long int l)
  989. { return mpf_cmp_ui(f, l) < 0; }
  990. static bool eval(unsigned long int l, mpf_srcptr f)
  991. { return mpf_cmp_ui(f, l) > 0; }
  992. static bool eval(mpf_srcptr f, signed long int l)
  993. { return mpf_cmp_si(f, l) < 0; }
  994. static bool eval(signed long int l, mpf_srcptr f)
  995. { return mpf_cmp_si(f, l) > 0; }
  996. static bool eval(mpf_srcptr f, double d)
  997. { return mpf_cmp_d(f, d) < 0; }
  998. static bool eval(double d, mpf_srcptr f)
  999. { return mpf_cmp_d(f, d) > 0; }
  1000. static bool eval(mpf_srcptr f, mpz_srcptr z)
  1001. { return mpf_cmp_z(f, z) < 0; }
  1002. static bool eval(mpz_srcptr z, mpf_srcptr f)
  1003. { return mpf_cmp_z(f, z) > 0; }
  1004. static bool eval(mpf_srcptr f, mpq_srcptr q)
  1005. { return __gmp_cmp_function::eval(f, q) < 0; }
  1006. static bool eval(mpq_srcptr q, mpf_srcptr f)
  1007. { return __gmp_cmp_function::eval(q, f) < 0; }
  1008. };
  1009. struct __gmp_binary_greater
  1010. {
  1011. template <class T, class U>
  1012. static inline bool eval(T t, U u) { return __gmp_binary_less::eval(u, t); }
  1013. };
  1014. struct __gmp_unary_increment
  1015. {
  1016. static void eval(mpz_ptr z) { mpz_add_ui(z, z, 1); }
  1017. static void eval(mpq_ptr q)
  1018. { mpz_add(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
  1019. static void eval(mpf_ptr f) { mpf_add_ui(f, f, 1); }
  1020. };
  1021. struct __gmp_unary_decrement
  1022. {
  1023. static void eval(mpz_ptr z) { mpz_sub_ui(z, z, 1); }
  1024. static void eval(mpq_ptr q)
  1025. { mpz_sub(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
  1026. static void eval(mpf_ptr f) { mpf_sub_ui(f, f, 1); }
  1027. };
  1028. struct __gmp_abs_function
  1029. {
  1030. static void eval(mpz_ptr z, mpz_srcptr w) { mpz_abs(z, w); }
  1031. static void eval(mpq_ptr q, mpq_srcptr r) { mpq_abs(q, r); }
  1032. static void eval(mpf_ptr f, mpf_srcptr g) { mpf_abs(f, g); }
  1033. };
  1034. struct __gmp_trunc_function
  1035. {
  1036. static void eval(mpf_ptr f, mpf_srcptr g) { mpf_trunc(f, g); }
  1037. };
  1038. struct __gmp_floor_function
  1039. {
  1040. static void eval(mpf_ptr f, mpf_srcptr g) { mpf_floor(f, g); }
  1041. };
  1042. struct __gmp_ceil_function
  1043. {
  1044. static void eval(mpf_ptr f, mpf_srcptr g) { mpf_ceil(f, g); }
  1045. };
  1046. struct __gmp_sqrt_function
  1047. {
  1048. static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sqrt(z, w); }
  1049. static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sqrt(f, g); }
  1050. };
  1051. struct __gmp_hypot_function
  1052. {
  1053. static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
  1054. {
  1055. mpf_t temp;
  1056. mpf_init2(temp, mpf_get_prec(f));
  1057. mpf_mul(temp, g, g);
  1058. mpf_mul(f, h, h);
  1059. mpf_add(f, f, temp);
  1060. mpf_sqrt(f, f);
  1061. mpf_clear(temp);
  1062. }
  1063. static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
  1064. {
  1065. mpf_t temp;
  1066. mpf_init2(temp, mpf_get_prec(f));
  1067. mpf_mul(temp, g, g);
  1068. mpf_set_ui(f, l);
  1069. mpf_mul_ui(f, f, l);
  1070. mpf_add(f, f, temp);
  1071. mpf_clear(temp);
  1072. mpf_sqrt(f, f);
  1073. }
  1074. static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
  1075. { eval(f, g, l); }
  1076. static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
  1077. { eval(f, g, __gmpxx_abs_ui(l)); }
  1078. static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
  1079. { eval(f, g, l); }
  1080. static void eval(mpf_ptr f, mpf_srcptr g, double d)
  1081. {
  1082. mpf_t temp;
  1083. mpf_init2(temp, mpf_get_prec(f));
  1084. mpf_mul(temp, g, g);
  1085. mpf_set_d(f, d);
  1086. mpf_mul(f, f, f);
  1087. mpf_add(f, f, temp);
  1088. mpf_sqrt(f, f);
  1089. mpf_clear(temp);
  1090. }
  1091. static void eval(mpf_ptr f, double d, mpf_srcptr g)
  1092. { eval(f, g, d); }
  1093. };
  1094. struct __gmp_sgn_function
  1095. {
  1096. static int eval(mpz_srcptr z) { return mpz_sgn(z); }
  1097. static int eval(mpq_srcptr q) { return mpq_sgn(q); }
  1098. static int eval(mpf_srcptr f) { return mpf_sgn(f); }
  1099. };
  1100. struct __gmp_gcd_function
  1101. {
  1102. static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  1103. { mpz_gcd(z, w, v); }
  1104. static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  1105. { mpz_gcd_ui(z, w, l); }
  1106. static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  1107. { eval(z, w, l); }
  1108. static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  1109. { eval(z, w, __gmpxx_abs_ui(l)); }
  1110. static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  1111. { eval(z, w, l); }
  1112. static void eval(mpz_ptr z, mpz_srcptr w, double d)
  1113. { __GMPXX_TMPZ_D; mpz_gcd (z, w, temp); }
  1114. static void eval(mpz_ptr z, double d, mpz_srcptr w)
  1115. { eval(z, w, d); }
  1116. };
  1117. struct __gmp_lcm_function
  1118. {
  1119. static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  1120. { mpz_lcm(z, w, v); }
  1121. static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  1122. { mpz_lcm_ui(z, w, l); }
  1123. static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  1124. { eval(z, w, l); }
  1125. static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  1126. { eval(z, w, __gmpxx_abs_ui(l)); }
  1127. static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  1128. { eval(z, w, l); }
  1129. static void eval(mpz_ptr z, mpz_srcptr w, double d)
  1130. { __GMPXX_TMPZ_D; mpz_lcm (z, w, temp); }
  1131. static void eval(mpz_ptr z, double d, mpz_srcptr w)
  1132. { eval(z, w, d); }
  1133. };
  1134. struct __gmp_rand_function
  1135. {
  1136. static void eval(mpz_ptr z, gmp_randstate_t s, mp_bitcnt_t l)
  1137. { mpz_urandomb(z, s, l); }
  1138. static void eval(mpz_ptr z, gmp_randstate_t s, mpz_srcptr w)
  1139. { mpz_urandomm(z, s, w); }
  1140. static void eval(mpf_ptr f, gmp_randstate_t s, mp_bitcnt_t prec)
  1141. { mpf_urandomb(f, s, prec); }
  1142. };
  1143. struct __gmp_fac_function
  1144. {
  1145. static void eval(mpz_ptr z, unsigned long l) { mpz_fac_ui(z, l); }
  1146. static void eval(mpz_ptr z, signed long l)
  1147. {
  1148. if (l < 0)
  1149. throw std::domain_error ("factorial(negative)");
  1150. eval(z, static_cast<unsigned long>(l));
  1151. }
  1152. static void eval(mpz_ptr z, mpz_srcptr w)
  1153. {
  1154. if (!mpz_fits_ulong_p(w))
  1155. {
  1156. if (mpz_sgn(w) < 0)
  1157. throw std::domain_error ("factorial(negative)");
  1158. else
  1159. throw std::bad_alloc(); // or std::overflow_error ("factorial")?
  1160. }
  1161. eval(z, mpz_get_ui(w));
  1162. }
  1163. static void eval(mpz_ptr z, double d)
  1164. { __GMPXX_TMPZ_D; eval (z, temp); }
  1165. };
  1166. struct __gmp_primorial_function
  1167. {
  1168. static void eval(mpz_ptr z, unsigned long l) { mpz_primorial_ui(z, l); }
  1169. static void eval(mpz_ptr z, signed long l)
  1170. {
  1171. if (l < 0)
  1172. throw std::domain_error ("primorial(negative)");
  1173. eval(z, static_cast<unsigned long>(l));
  1174. }
  1175. static void eval(mpz_ptr z, mpz_srcptr w)
  1176. {
  1177. if (!mpz_fits_ulong_p(w))
  1178. {
  1179. if (mpz_sgn(w) < 0)
  1180. throw std::domain_error ("primorial(negative)");
  1181. else
  1182. throw std::bad_alloc(); // or std::overflow_error ("primorial")?
  1183. }
  1184. eval(z, mpz_get_ui(w));
  1185. }
  1186. static void eval(mpz_ptr z, double d)
  1187. { __GMPXX_TMPZ_D; eval (z, temp); }
  1188. };
  1189. struct __gmp_fib_function
  1190. {
  1191. static void eval(mpz_ptr z, unsigned long l) { mpz_fib_ui(z, l); }
  1192. static void eval(mpz_ptr z, signed long l)
  1193. {
  1194. if (l < 0)
  1195. {
  1196. eval(z, -static_cast<unsigned long>(l));
  1197. if ((l & 1) == 0)
  1198. mpz_neg(z, z);
  1199. }
  1200. else
  1201. eval(z, static_cast<unsigned long>(l));
  1202. }
  1203. static void eval(mpz_ptr z, mpz_srcptr w)
  1204. {
  1205. if (!mpz_fits_slong_p(w))
  1206. throw std::bad_alloc(); // or std::overflow_error ("fibonacci")?
  1207. eval(z, mpz_get_si(w));
  1208. }
  1209. static void eval(mpz_ptr z, double d)
  1210. { __GMPXX_TMPZ_D; eval (z, temp); }
  1211. };
  1212. /**************** Auxiliary classes ****************/
  1213. /* this is much the same as gmp_allocated_string in gmp-impl.h
  1214. since gmp-impl.h is not publicly available, I redefine it here
  1215. I use a different name to avoid possible clashes */
  1216. extern "C" {
  1217. typedef void (*__gmp_freefunc_t) (void *, size_t);
  1218. }
  1219. struct __gmp_alloc_cstring
  1220. {
  1221. char *str;
  1222. __gmp_alloc_cstring(char *s) { str = s; }
  1223. ~__gmp_alloc_cstring()
  1224. {
  1225. __gmp_freefunc_t freefunc;
  1226. mp_get_memory_functions (NULL, NULL, &freefunc);
  1227. (*freefunc) (str, std::strlen(str)+1);
  1228. }
  1229. };
  1230. // general expression template class
  1231. template <class T, class U>
  1232. class __gmp_expr;
  1233. // templates for resolving expression types
  1234. template <class T>
  1235. struct __gmp_resolve_ref
  1236. {
  1237. typedef T ref_type;
  1238. };
  1239. template <class T, class U>
  1240. struct __gmp_resolve_ref<__gmp_expr<T, U> >
  1241. {
  1242. typedef const __gmp_expr<T, U> & ref_type;
  1243. };
  1244. template <class T, class U = T>
  1245. struct __gmp_resolve_expr;
  1246. template <>
  1247. struct __gmp_resolve_expr<mpz_t>
  1248. {
  1249. typedef mpz_t value_type;
  1250. typedef mpz_ptr ptr_type;
  1251. typedef mpz_srcptr srcptr_type;
  1252. };
  1253. template <>
  1254. struct __gmp_resolve_expr<mpq_t>
  1255. {
  1256. typedef mpq_t value_type;
  1257. typedef mpq_ptr ptr_type;
  1258. typedef mpq_srcptr srcptr_type;
  1259. };
  1260. template <>
  1261. struct __gmp_resolve_expr<mpf_t>
  1262. {
  1263. typedef mpf_t value_type;
  1264. typedef mpf_ptr ptr_type;
  1265. typedef mpf_srcptr srcptr_type;
  1266. };
  1267. template <>
  1268. struct __gmp_resolve_expr<mpz_t, mpq_t>
  1269. {
  1270. typedef mpq_t value_type;
  1271. };
  1272. template <>
  1273. struct __gmp_resolve_expr<mpq_t, mpz_t>
  1274. {
  1275. typedef mpq_t value_type;
  1276. };
  1277. template <>
  1278. struct __gmp_resolve_expr<mpz_t, mpf_t>
  1279. {
  1280. typedef mpf_t value_type;
  1281. };
  1282. template <>
  1283. struct __gmp_resolve_expr<mpf_t, mpz_t>
  1284. {
  1285. typedef mpf_t value_type;
  1286. };
  1287. template <>
  1288. struct __gmp_resolve_expr<mpq_t, mpf_t>
  1289. {
  1290. typedef mpf_t value_type;
  1291. };
  1292. template <>
  1293. struct __gmp_resolve_expr<mpf_t, mpq_t>
  1294. {
  1295. typedef mpf_t value_type;
  1296. };
  1297. #if __GMPXX_USE_CXX11
  1298. namespace std {
  1299. template <class T, class U, class V, class W>
  1300. struct common_type <__gmp_expr<T, U>, __gmp_expr<V, W> >
  1301. {
  1302. private:
  1303. typedef typename __gmp_resolve_expr<T, V>::value_type X;
  1304. public:
  1305. typedef __gmp_expr<X, X> type;
  1306. };
  1307. template <class T, class U>
  1308. struct common_type <__gmp_expr<T, U> >
  1309. {
  1310. typedef __gmp_expr<T, T> type;
  1311. };
  1312. #define __GMPXX_DECLARE_COMMON_TYPE(typ) \
  1313. template <class T, class U> \
  1314. struct common_type <__gmp_expr<T, U>, typ > \
  1315. { \
  1316. typedef __gmp_expr<T, T> type; \
  1317. }; \
  1318. \
  1319. template <class T, class U> \
  1320. struct common_type <typ, __gmp_expr<T, U> > \
  1321. { \
  1322. typedef __gmp_expr<T, T> type; \
  1323. }
  1324. __GMPXX_DECLARE_COMMON_TYPE(signed char);
  1325. __GMPXX_DECLARE_COMMON_TYPE(unsigned char);
  1326. __GMPXX_DECLARE_COMMON_TYPE(signed int);
  1327. __GMPXX_DECLARE_COMMON_TYPE(unsigned int);
  1328. __GMPXX_DECLARE_COMMON_TYPE(signed short int);
  1329. __GMPXX_DECLARE_COMMON_TYPE(unsigned short int);
  1330. __GMPXX_DECLARE_COMMON_TYPE(signed long int);
  1331. __GMPXX_DECLARE_COMMON_TYPE(unsigned long int);
  1332. __GMPXX_DECLARE_COMMON_TYPE(float);
  1333. __GMPXX_DECLARE_COMMON_TYPE(double);
  1334. #undef __GMPXX_DECLARE_COMMON_TYPE
  1335. }
  1336. #endif
  1337. // classes for evaluating unary and binary expressions
  1338. template <class T, class Op>
  1339. struct __gmp_unary_expr
  1340. {
  1341. typename __gmp_resolve_ref<T>::ref_type val;
  1342. __gmp_unary_expr(const T &v) : val(v) { }
  1343. private:
  1344. __gmp_unary_expr();
  1345. };
  1346. template <class T, class U, class Op>
  1347. struct __gmp_binary_expr
  1348. {
  1349. typename __gmp_resolve_ref<T>::ref_type val1;
  1350. typename __gmp_resolve_ref<U>::ref_type val2;
  1351. __gmp_binary_expr(const T &v1, const U &v2) : val1(v1), val2(v2) { }
  1352. private:
  1353. __gmp_binary_expr();
  1354. };
  1355. /**************** Macros for in-class declarations ****************/
  1356. /* This is just repetitive code that is easier to maintain if it's written
  1357. only once */
  1358. #define __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
  1359. template <class T, class U> \
  1360. __gmp_expr<value_type, value_type> & fun(const __gmp_expr<T, U> &);
  1361. #define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \
  1362. __gmp_expr & fun(signed char); \
  1363. __gmp_expr & fun(unsigned char); \
  1364. __gmp_expr & fun(signed int); \
  1365. __gmp_expr & fun(unsigned int); \
  1366. __gmp_expr & fun(signed short int); \
  1367. __gmp_expr & fun(unsigned short int); \
  1368. __gmp_expr & fun(signed long int); \
  1369. __gmp_expr & fun(unsigned long int); \
  1370. __gmp_expr & fun(float); \
  1371. __gmp_expr & fun(double); \
  1372. /* __gmp_expr & fun(long double); */
  1373. #define __GMP_DECLARE_COMPOUND_OPERATOR(fun) \
  1374. __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
  1375. __GMPN_DECLARE_COMPOUND_OPERATOR(fun)
  1376. #define __GMP_DECLARE_COMPOUND_OPERATOR_UI(fun) \
  1377. __gmp_expr & fun(mp_bitcnt_t);
  1378. #define __GMP_DECLARE_INCREMENT_OPERATOR(fun) \
  1379. inline __gmp_expr & fun(); \
  1380. inline __gmp_expr fun(int);
  1381. #define __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS \
  1382. __gmp_expr(signed char c) { init_si(c); } \
  1383. __gmp_expr(unsigned char c) { init_ui(c); } \
  1384. __gmp_expr(signed int i) { init_si(i); } \
  1385. __gmp_expr(unsigned int i) { init_ui(i); } \
  1386. __gmp_expr(signed short int s) { init_si(s); } \
  1387. __gmp_expr(unsigned short int s) { init_ui(s); } \
  1388. __gmp_expr(signed long int l) { init_si(l); } \
  1389. __gmp_expr(unsigned long int l) { init_ui(l); } \
  1390. __gmp_expr(float f) { init_d(f); } \
  1391. __gmp_expr(double d) { init_d(d); }
  1392. #define __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS \
  1393. __gmp_expr & operator=(signed char c) { assign_si(c); return *this; } \
  1394. __gmp_expr & operator=(unsigned char c) { assign_ui(c); return *this; } \
  1395. __gmp_expr & operator=(signed int i) { assign_si(i); return *this; } \
  1396. __gmp_expr & operator=(unsigned int i) { assign_ui(i); return *this; } \
  1397. __gmp_expr & operator=(signed short int s) { assign_si(s); return *this; } \
  1398. __gmp_expr & operator=(unsigned short int s) { assign_ui(s); return *this; } \
  1399. __gmp_expr & operator=(signed long int l) { assign_si(l); return *this; } \
  1400. __gmp_expr & operator=(unsigned long int l) { assign_ui(l); return *this; } \
  1401. __gmp_expr & operator=(float f) { assign_d(f); return *this; } \
  1402. __gmp_expr & operator=(double d) { assign_d(d); return *this; }
  1403. #define __GMPP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
  1404. template <class U> \
  1405. static __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
  1406. fun(const __gmp_expr<T, U> &expr);
  1407. #define __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, bigtype) \
  1408. static inline __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> > \
  1409. fun(type expr);
  1410. #define __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
  1411. __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, signed long)
  1412. #define __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
  1413. __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, unsigned long)
  1414. #define __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
  1415. __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, double)
  1416. #define __GMPN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
  1417. __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char) \
  1418. __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char) \
  1419. __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int) \
  1420. __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int) \
  1421. __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int) \
  1422. __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int) \
  1423. __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int) \
  1424. __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int) \
  1425. __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, float) \
  1426. __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, double)
  1427. #define __GMP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
  1428. __GMPP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
  1429. __GMPN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)
  1430. /**************** mpz_class -- wrapper for mpz_t ****************/
  1431. template <>
  1432. class __gmp_expr<mpz_t, mpz_t>
  1433. {
  1434. private:
  1435. typedef mpz_t value_type;
  1436. value_type mp;
  1437. // Helper functions used for all arithmetic types
  1438. void assign_ui(unsigned long l)
  1439. {
  1440. if (__GMPXX_CONSTANT_TRUE(l == 0))
  1441. mp->_mp_size = 0;
  1442. else
  1443. mpz_set_ui(mp, l);
  1444. }
  1445. void assign_si(signed long l)
  1446. {
  1447. if (__GMPXX_CONSTANT_TRUE(l >= 0))
  1448. assign_ui(l);
  1449. else if (__GMPXX_CONSTANT_TRUE(l <= 0))
  1450. {
  1451. assign_ui(-static_cast<unsigned long>(l));
  1452. mpz_neg(mp, mp);
  1453. }
  1454. else
  1455. mpz_set_si(mp, l);
  1456. }
  1457. void assign_d (double d)
  1458. {
  1459. mpz_set_d (mp, d);
  1460. }
  1461. void init_ui(unsigned long l)
  1462. {
  1463. if (__GMPXX_CONSTANT_TRUE(l == 0))
  1464. mpz_init(mp);
  1465. else
  1466. mpz_init_set_ui(mp, l);
  1467. }
  1468. void init_si(signed long l)
  1469. {
  1470. if (__GMPXX_CONSTANT_TRUE(l >= 0))
  1471. init_ui(l);
  1472. else if (__GMPXX_CONSTANT_TRUE(l <= 0))
  1473. {
  1474. init_ui(-static_cast<unsigned long>(l));
  1475. mpz_neg(mp, mp);
  1476. }
  1477. else
  1478. mpz_init_set_si(mp, l);
  1479. }
  1480. void init_d (double d)
  1481. {
  1482. mpz_init_set_d (mp, d);
  1483. }
  1484. public:
  1485. mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
  1486. // constructors and destructor
  1487. __gmp_expr() __GMPXX_NOEXCEPT { mpz_init(mp); }
  1488. __gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); }
  1489. #if __GMPXX_USE_CXX11
  1490. __gmp_expr(__gmp_expr &&z) noexcept
  1491. { *mp = *z.mp; mpz_init(z.mp); }
  1492. #endif
  1493. template <class T>
  1494. __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
  1495. { mpz_init(mp); __gmp_set_expr(mp, expr); }
  1496. template <class T, class U>
  1497. explicit __gmp_expr(const __gmp_expr<T, U> &expr)
  1498. { mpz_init(mp); __gmp_set_expr(mp, expr); }
  1499. __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
  1500. explicit __gmp_expr(const char *s, int base = 0)
  1501. {
  1502. if (mpz_init_set_str (mp, s, base) != 0)
  1503. {
  1504. mpz_clear (mp);
  1505. throw std::invalid_argument ("mpz_set_str");
  1506. }
  1507. }
  1508. explicit __gmp_expr(const std::string &s, int base = 0)
  1509. {
  1510. if (mpz_init_set_str(mp, s.c_str(), base) != 0)
  1511. {
  1512. mpz_clear (mp);
  1513. throw std::invalid_argument ("mpz_set_str");
  1514. }
  1515. }
  1516. explicit __gmp_expr(mpz_srcptr z) { mpz_init_set(mp, z); }
  1517. ~__gmp_expr() { mpz_clear(mp); }
  1518. void swap(__gmp_expr& z) __GMPXX_NOEXCEPT { std::swap(*mp, *z.mp); }
  1519. // assignment operators
  1520. __gmp_expr & operator=(const __gmp_expr &z)
  1521. { mpz_set(mp, z.mp); return *this; }
  1522. #if __GMPXX_USE_CXX11
  1523. __gmp_expr & operator=(__gmp_expr &&z) noexcept
  1524. { swap(z); return *this; }
  1525. #endif
  1526. template <class T, class U>
  1527. __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
  1528. { __gmp_set_expr(mp, expr); return *this; }
  1529. __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
  1530. __gmp_expr & operator=(const char *s)
  1531. {
  1532. if (mpz_set_str (mp, s, 0) != 0)
  1533. throw std::invalid_argument ("mpz_set_str");
  1534. return *this;
  1535. }
  1536. __gmp_expr & operator=(const std::string &s)
  1537. {
  1538. if (mpz_set_str(mp, s.c_str(), 0) != 0)
  1539. throw std::invalid_argument ("mpz_set_str");
  1540. return *this;
  1541. }
  1542. // string input/output functions
  1543. int set_str(const char *s, int base)
  1544. { return mpz_set_str(mp, s, base); }
  1545. int set_str(const std::string &s, int base)
  1546. { return mpz_set_str(mp, s.c_str(), base); }
  1547. std::string get_str(int base = 10) const
  1548. {
  1549. __gmp_alloc_cstring temp(mpz_get_str(0, base, mp));
  1550. return std::string(temp.str);
  1551. }
  1552. // conversion functions
  1553. mpz_srcptr __get_mp() const { return mp; }
  1554. mpz_ptr __get_mp() { return mp; }
  1555. mpz_srcptr get_mpz_t() const { return mp; }
  1556. mpz_ptr get_mpz_t() { return mp; }
  1557. signed long int get_si() const { return mpz_get_si(mp); }
  1558. unsigned long int get_ui() const { return mpz_get_ui(mp); }
  1559. double get_d() const { return mpz_get_d(mp); }
  1560. // bool fits_schar_p() const { return mpz_fits_schar_p(mp); }
  1561. // bool fits_uchar_p() const { return mpz_fits_uchar_p(mp); }
  1562. bool fits_sint_p() const { return mpz_fits_sint_p(mp); }
  1563. bool fits_uint_p() const { return mpz_fits_uint_p(mp); }
  1564. bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); }
  1565. bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); }
  1566. bool fits_slong_p() const { return mpz_fits_slong_p(mp); }
  1567. bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); }
  1568. // bool fits_float_p() const { return mpz_fits_float_p(mp); }
  1569. // bool fits_double_p() const { return mpz_fits_double_p(mp); }
  1570. // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); }
  1571. #if __GMPXX_USE_CXX11
  1572. explicit operator bool() const { return mp->_mp_size != 0; }
  1573. #endif
  1574. // member operators
  1575. __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
  1576. __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
  1577. __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
  1578. __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
  1579. __GMP_DECLARE_COMPOUND_OPERATOR(operator%=)
  1580. __GMP_DECLARE_COMPOUND_OPERATOR(operator&=)
  1581. __GMP_DECLARE_COMPOUND_OPERATOR(operator|=)
  1582. __GMP_DECLARE_COMPOUND_OPERATOR(operator^=)
  1583. __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
  1584. __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
  1585. __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
  1586. __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
  1587. __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, factorial, __gmp_fac_function)
  1588. __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, primorial, __gmp_primorial_function)
  1589. __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, fibonacci, __gmp_fib_function)
  1590. };
  1591. typedef __gmp_expr<mpz_t, mpz_t> mpz_class;
  1592. /**************** mpq_class -- wrapper for mpq_t ****************/
  1593. template <>
  1594. class __gmp_expr<mpq_t, mpq_t>
  1595. {
  1596. private:
  1597. typedef mpq_t value_type;
  1598. value_type mp;
  1599. // Helper functions used for all arithmetic types
  1600. void assign_ui(unsigned long l) { mpq_set_ui(mp, l, 1); }
  1601. void assign_si(signed long l)
  1602. {
  1603. if (__GMPXX_CONSTANT_TRUE(l >= 0))
  1604. assign_ui(l);
  1605. else
  1606. mpq_set_si(mp, l, 1);
  1607. }
  1608. void assign_d (double d) { mpq_set_d (mp, d); }
  1609. void init_ui(unsigned long l) { mpq_init(mp); get_num() = l; }
  1610. void init_si(signed long l) { mpq_init(mp); get_num() = l; }
  1611. void init_d (double d) { mpq_init(mp); assign_d (d); }
  1612. public:
  1613. mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
  1614. void canonicalize() { mpq_canonicalize(mp); }
  1615. // constructors and destructor
  1616. __gmp_expr() { mpq_init(mp); }
  1617. __gmp_expr(const __gmp_expr &q)
  1618. {
  1619. mpz_init_set(mpq_numref(mp), mpq_numref(q.mp));
  1620. mpz_init_set(mpq_denref(mp), mpq_denref(q.mp));
  1621. }
  1622. #if __GMPXX_USE_CXX11
  1623. __gmp_expr(__gmp_expr &&q)
  1624. { *mp = *q.mp; mpq_init(q.mp); }
  1625. #endif
  1626. template <class T>
  1627. __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
  1628. { mpq_init(mp); __gmp_set_expr(mp, expr); }
  1629. template <class T>
  1630. __gmp_expr(const __gmp_expr<mpq_t, T> &expr)
  1631. { mpq_init(mp); __gmp_set_expr(mp, expr); }
  1632. template <class T, class U>
  1633. explicit __gmp_expr(const __gmp_expr<T, U> &expr)
  1634. { mpq_init(mp); __gmp_set_expr(mp, expr); }
  1635. __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
  1636. explicit __gmp_expr(const char *s, int base = 0)
  1637. {
  1638. mpq_init (mp);
  1639. // If s is the literal 0, we meant to call another constructor.
  1640. // If s just happens to evaluate to 0, we would crash, so whatever.
  1641. if (s == 0)
  1642. {
  1643. // Don't turn mpq_class(0,0) into 0
  1644. mpz_set_si(mpq_denref(mp), base);
  1645. }
  1646. else if (mpq_set_str(mp, s, base) != 0)
  1647. {
  1648. mpq_clear (mp);
  1649. throw std::invalid_argument ("mpq_set_str");
  1650. }
  1651. }
  1652. explicit __gmp_expr(const std::string &s, int base = 0)
  1653. {
  1654. mpq_init(mp);
  1655. if (mpq_set_str (mp, s.c_str(), base) != 0)
  1656. {
  1657. mpq_clear (mp);
  1658. throw std::invalid_argument ("mpq_set_str");
  1659. }
  1660. }
  1661. explicit __gmp_expr(mpq_srcptr q)
  1662. {
  1663. mpz_init_set(mpq_numref(mp), mpq_numref(q));
  1664. mpz_init_set(mpq_denref(mp), mpq_denref(q));
  1665. }
  1666. __gmp_expr(const mpz_class &num, const mpz_class &den)
  1667. {
  1668. mpz_init_set(mpq_numref(mp), num.get_mpz_t());
  1669. mpz_init_set(mpq_denref(mp), den.get_mpz_t());
  1670. }
  1671. ~__gmp_expr() { mpq_clear(mp); }
  1672. void swap(__gmp_expr& q) __GMPXX_NOEXCEPT { std::swap(*mp, *q.mp); }
  1673. // assignment operators
  1674. __gmp_expr & operator=(const __gmp_expr &q)
  1675. { mpq_set(mp, q.mp); return *this; }
  1676. #if __GMPXX_USE_CXX11
  1677. __gmp_expr & operator=(__gmp_expr &&q) noexcept
  1678. { swap(q); return *this; }
  1679. __gmp_expr & operator=(mpz_class &&z) noexcept
  1680. { get_num() = std::move(z); get_den() = 1u; return *this; }
  1681. #endif
  1682. template <class T, class U>
  1683. __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
  1684. { __gmp_set_expr(mp, expr); return *this; }
  1685. __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
  1686. __gmp_expr & operator=(const char *s)
  1687. {
  1688. if (mpq_set_str (mp, s, 0) != 0)
  1689. throw std::invalid_argument ("mpq_set_str");
  1690. return *this;
  1691. }
  1692. __gmp_expr & operator=(const std::string &s)
  1693. {
  1694. if (mpq_set_str(mp, s.c_str(), 0) != 0)
  1695. throw std::invalid_argument ("mpq_set_str");
  1696. return *this;
  1697. }
  1698. // string input/output functions
  1699. int set_str(const char *s, int base)
  1700. { return mpq_set_str(mp, s, base); }
  1701. int set_str(const std::string &s, int base)
  1702. { return mpq_set_str(mp, s.c_str(), base); }
  1703. std::string get_str(int base = 10) const
  1704. {
  1705. __gmp_alloc_cstring temp(mpq_get_str(0, base, mp));
  1706. return std::string(temp.str);
  1707. }
  1708. // conversion functions
  1709. // casting a reference to an mpz_t to mpz_class & is a dirty hack,
  1710. // but works because the internal representation of mpz_class is
  1711. // exactly an mpz_t
  1712. const mpz_class & get_num() const
  1713. { return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); }
  1714. mpz_class & get_num()
  1715. { return reinterpret_cast<mpz_class &>(*mpq_numref(mp)); }
  1716. const mpz_class & get_den() const
  1717. { return reinterpret_cast<const mpz_class &>(*mpq_denref(mp)); }
  1718. mpz_class & get_den()
  1719. { return reinterpret_cast<mpz_class &>(*mpq_denref(mp)); }
  1720. mpq_srcptr __get_mp() const { return mp; }
  1721. mpq_ptr __get_mp() { return mp; }
  1722. mpq_srcptr get_mpq_t() const { return mp; }
  1723. mpq_ptr get_mpq_t() { return mp; }
  1724. mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); }
  1725. mpz_ptr get_num_mpz_t() { return mpq_numref(mp); }
  1726. mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); }
  1727. mpz_ptr get_den_mpz_t() { return mpq_denref(mp); }
  1728. double get_d() const { return mpq_get_d(mp); }
  1729. #if __GMPXX_USE_CXX11
  1730. explicit operator bool() const { return mpq_numref(mp)->_mp_size != 0; }
  1731. #endif
  1732. // compound assignments
  1733. __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
  1734. __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
  1735. __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
  1736. __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
  1737. __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
  1738. __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
  1739. __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
  1740. __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
  1741. };
  1742. typedef __gmp_expr<mpq_t, mpq_t> mpq_class;
  1743. /**************** mpf_class -- wrapper for mpf_t ****************/
  1744. template <>
  1745. class __gmp_expr<mpf_t, mpf_t>
  1746. {
  1747. private:
  1748. typedef mpf_t value_type;
  1749. value_type mp;
  1750. // Helper functions used for all arithmetic types
  1751. void assign_ui(unsigned long l) { mpf_set_ui(mp, l); }
  1752. void assign_si(signed long l)
  1753. {
  1754. if (__GMPXX_CONSTANT_TRUE(l >= 0))
  1755. assign_ui(l);
  1756. else
  1757. mpf_set_si(mp, l);
  1758. }
  1759. void assign_d (double d) { mpf_set_d (mp, d); }
  1760. void init_ui(unsigned long l)
  1761. {
  1762. if (__GMPXX_CONSTANT_TRUE(l == 0))
  1763. mpf_init(mp);
  1764. else
  1765. mpf_init_set_ui(mp, l);
  1766. }
  1767. void init_si(signed long l)
  1768. {
  1769. if (__GMPXX_CONSTANT_TRUE(l >= 0))
  1770. init_ui(l);
  1771. else
  1772. mpf_init_set_si(mp, l);
  1773. }
  1774. void init_d (double d) { mpf_init_set_d (mp, d); }
  1775. public:
  1776. mp_bitcnt_t get_prec() const { return mpf_get_prec(mp); }
  1777. void set_prec(mp_bitcnt_t prec) { mpf_set_prec(mp, prec); }
  1778. void set_prec_raw(mp_bitcnt_t prec) { mpf_set_prec_raw(mp, prec); }
  1779. // constructors and destructor
  1780. __gmp_expr() { mpf_init(mp); }
  1781. __gmp_expr(const __gmp_expr &f)
  1782. { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); }
  1783. #if __GMPXX_USE_CXX11
  1784. __gmp_expr(__gmp_expr &&f)
  1785. { *mp = *f.mp; mpf_init2(f.mp, get_prec()); }
  1786. #endif
  1787. __gmp_expr(const __gmp_expr &f, mp_bitcnt_t prec)
  1788. { mpf_init2(mp, prec); mpf_set(mp, f.mp); }
  1789. template <class T, class U>
  1790. __gmp_expr(const __gmp_expr<T, U> &expr)
  1791. { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
  1792. template <class T, class U>
  1793. __gmp_expr(const __gmp_expr<T, U> &expr, mp_bitcnt_t prec)
  1794. { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); }
  1795. __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
  1796. __gmp_expr(signed char c, mp_bitcnt_t prec)
  1797. { mpf_init2(mp, prec); mpf_set_si(mp, c); }
  1798. __gmp_expr(unsigned char c, mp_bitcnt_t prec)
  1799. { mpf_init2(mp, prec); mpf_set_ui(mp, c); }
  1800. __gmp_expr(signed int i, mp_bitcnt_t prec)
  1801. { mpf_init2(mp, prec); mpf_set_si(mp, i); }
  1802. __gmp_expr(unsigned int i, mp_bitcnt_t prec)
  1803. { mpf_init2(mp, prec); mpf_set_ui(mp, i); }
  1804. __gmp_expr(signed short int s, mp_bitcnt_t prec)
  1805. { mpf_init2(mp, prec); mpf_set_si(mp, s); }
  1806. __gmp_expr(unsigned short int s, mp_bitcnt_t prec)
  1807. { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
  1808. __gmp_expr(signed long int l, mp_bitcnt_t prec)
  1809. { mpf_init2(mp, prec); mpf_set_si(mp, l); }
  1810. __gmp_expr(unsigned long int l, mp_bitcnt_t prec)
  1811. { mpf_init2(mp, prec); mpf_set_ui(mp, l); }
  1812. __gmp_expr(float f, mp_bitcnt_t prec)
  1813. { mpf_init2(mp, prec); mpf_set_d(mp, f); }
  1814. __gmp_expr(double d, mp_bitcnt_t prec)
  1815. { mpf_init2(mp, prec); mpf_set_d(mp, d); }
  1816. // __gmp_expr(long double ld) { mpf_init_set_d(mp, ld); }
  1817. // __gmp_expr(long double ld, mp_bitcnt_t prec)
  1818. // { mpf_init2(mp, prec); mpf_set_d(mp, ld); }
  1819. explicit __gmp_expr(const char *s)
  1820. {
  1821. if (mpf_init_set_str (mp, s, 0) != 0)
  1822. {
  1823. mpf_clear (mp);
  1824. throw std::invalid_argument ("mpf_set_str");
  1825. }
  1826. }
  1827. __gmp_expr(const char *s, mp_bitcnt_t prec, int base = 0)
  1828. {
  1829. mpf_init2(mp, prec);
  1830. if (mpf_set_str(mp, s, base) != 0)
  1831. {
  1832. mpf_clear (mp);
  1833. throw std::invalid_argument ("mpf_set_str");
  1834. }
  1835. }
  1836. explicit __gmp_expr(const std::string &s)
  1837. {
  1838. if (mpf_init_set_str(mp, s.c_str(), 0) != 0)
  1839. {
  1840. mpf_clear (mp);
  1841. throw std::invalid_argument ("mpf_set_str");
  1842. }
  1843. }
  1844. __gmp_expr(const std::string &s, mp_bitcnt_t prec, int base = 0)
  1845. {
  1846. mpf_init2(mp, prec);
  1847. if (mpf_set_str(mp, s.c_str(), base) != 0)
  1848. {
  1849. mpf_clear (mp);
  1850. throw std::invalid_argument ("mpf_set_str");
  1851. }
  1852. }
  1853. explicit __gmp_expr(mpf_srcptr f)
  1854. { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); }
  1855. __gmp_expr(mpf_srcptr f, mp_bitcnt_t prec)
  1856. { mpf_init2(mp, prec); mpf_set(mp, f); }
  1857. ~__gmp_expr() { mpf_clear(mp); }
  1858. void swap(__gmp_expr& f) __GMPXX_NOEXCEPT { std::swap(*mp, *f.mp); }
  1859. // assignment operators
  1860. __gmp_expr & operator=(const __gmp_expr &f)
  1861. { mpf_set(mp, f.mp); return *this; }
  1862. #if __GMPXX_USE_CXX11
  1863. __gmp_expr & operator=(__gmp_expr &&f) noexcept
  1864. { swap(f); return *this; }
  1865. #endif
  1866. template <class T, class U>
  1867. __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
  1868. { __gmp_set_expr(mp, expr); return *this; }
  1869. __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
  1870. __gmp_expr & operator=(const char *s)
  1871. {
  1872. if (mpf_set_str (mp, s, 0) != 0)
  1873. throw std::invalid_argument ("mpf_set_str");
  1874. return *this;
  1875. }
  1876. __gmp_expr & operator=(const std::string &s)
  1877. {
  1878. if (mpf_set_str(mp, s.c_str(), 0) != 0)
  1879. throw std::invalid_argument ("mpf_set_str");
  1880. return *this;
  1881. }
  1882. // string input/output functions
  1883. int set_str(const char *s, int base)
  1884. { return mpf_set_str(mp, s, base); }
  1885. int set_str(const std::string &s, int base)
  1886. { return mpf_set_str(mp, s.c_str(), base); }
  1887. std::string get_str(mp_exp_t &expo, int base = 10, size_t size = 0) const
  1888. {
  1889. __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp));
  1890. return std::string(temp.str);
  1891. }
  1892. // conversion functions
  1893. mpf_srcptr __get_mp() const { return mp; }
  1894. mpf_ptr __get_mp() { return mp; }
  1895. mpf_srcptr get_mpf_t() const { return mp; }
  1896. mpf_ptr get_mpf_t() { return mp; }
  1897. signed long int get_si() const { return mpf_get_si(mp); }
  1898. unsigned long int get_ui() const { return mpf_get_ui(mp); }
  1899. double get_d() const { return mpf_get_d(mp); }
  1900. // bool fits_schar_p() const { return mpf_fits_schar_p(mp); }
  1901. // bool fits_uchar_p() const { return mpf_fits_uchar_p(mp); }
  1902. bool fits_sint_p() const { return mpf_fits_sint_p(mp); }
  1903. bool fits_uint_p() const { return mpf_fits_uint_p(mp); }
  1904. bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); }
  1905. bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); }
  1906. bool fits_slong_p() const { return mpf_fits_slong_p(mp); }
  1907. bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); }
  1908. // bool fits_float_p() const { return mpf_fits_float_p(mp); }
  1909. // bool fits_double_p() const { return mpf_fits_double_p(mp); }
  1910. // bool fits_ldouble_p() const { return mpf_fits_ldouble_p(mp); }
  1911. #if __GMPXX_USE_CXX11
  1912. explicit operator bool() const { return mpf_sgn(mp) != 0; }
  1913. #endif
  1914. // compound assignments
  1915. __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
  1916. __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
  1917. __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
  1918. __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
  1919. __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
  1920. __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
  1921. __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
  1922. __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
  1923. };
  1924. typedef __gmp_expr<mpf_t, mpf_t> mpf_class;
  1925. /**************** User-defined literals ****************/
  1926. #if __GMPXX_USE_CXX11
  1927. inline mpz_class operator"" _mpz(const char* s)
  1928. {
  1929. return mpz_class(s);
  1930. }
  1931. inline mpq_class operator"" _mpq(const char* s)
  1932. {
  1933. mpq_class q;
  1934. q.get_num() = s;
  1935. return q;
  1936. }
  1937. inline mpf_class operator"" _mpf(const char* s)
  1938. {
  1939. return mpf_class(s);
  1940. }
  1941. #endif
  1942. /**************** I/O operators ****************/
  1943. // these should (and will) be provided separately
  1944. template <class T, class U>
  1945. inline std::ostream & operator<<
  1946. (std::ostream &o, const __gmp_expr<T, U> &expr)
  1947. {
  1948. __gmp_expr<T, T> const& temp(expr);
  1949. return o << temp.__get_mp();
  1950. }
  1951. template <class T>
  1952. inline std::istream & operator>>(std::istream &i, __gmp_expr<T, T> &expr)
  1953. {
  1954. return i >> expr.__get_mp();
  1955. }
  1956. /*
  1957. // you might want to uncomment this
  1958. inline std::istream & operator>>(std::istream &i, mpq_class &q)
  1959. {
  1960. i >> q.get_mpq_t();
  1961. q.canonicalize();
  1962. return i;
  1963. }
  1964. */
  1965. /**************** Functions for type conversion ****************/
  1966. inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w)
  1967. {
  1968. mpz_set(z, w.get_mpz_t());
  1969. }
  1970. template <class T>
  1971. inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpz_t, T> &expr)
  1972. {
  1973. expr.eval(z);
  1974. }
  1975. template <class T>
  1976. inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpq_t, T> &expr)
  1977. {
  1978. mpq_class const& temp(expr);
  1979. mpz_set_q(z, temp.get_mpq_t());
  1980. }
  1981. template <class T>
  1982. inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpf_t, T> &expr)
  1983. {
  1984. mpf_class const& temp(expr);
  1985. mpz_set_f(z, temp.get_mpf_t());
  1986. }
  1987. inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z)
  1988. {
  1989. mpq_set_z(q, z.get_mpz_t());
  1990. }
  1991. template <class T>
  1992. inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpz_t, T> &expr)
  1993. {
  1994. __gmp_set_expr(mpq_numref(q), expr);
  1995. mpz_set_ui(mpq_denref(q), 1);
  1996. }
  1997. inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r)
  1998. {
  1999. mpq_set(q, r.get_mpq_t());
  2000. }
  2001. template <class T>
  2002. inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpq_t, T> &expr)
  2003. {
  2004. expr.eval(q);
  2005. }
  2006. template <class T>
  2007. inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpf_t, T> &expr)
  2008. {
  2009. mpf_class const& temp(expr);
  2010. mpq_set_f(q, temp.get_mpf_t());
  2011. }
  2012. template <class T>
  2013. inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpz_t, T> &expr)
  2014. {
  2015. mpz_class const& temp(expr);
  2016. mpf_set_z(f, temp.get_mpz_t());
  2017. }
  2018. template <class T>
  2019. inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpq_t, T> &expr)
  2020. {
  2021. mpq_class const& temp(expr);
  2022. mpf_set_q(f, temp.get_mpq_t());
  2023. }
  2024. inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g)
  2025. {
  2026. mpf_set(f, g.get_mpf_t());
  2027. }
  2028. template <class T>
  2029. inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpf_t, T> &expr)
  2030. {
  2031. expr.eval(f);
  2032. }
  2033. /* Temporary objects */
  2034. template <class T>
  2035. class __gmp_temp
  2036. {
  2037. __gmp_expr<T, T> val;
  2038. public:
  2039. template<class U, class V>
  2040. __gmp_temp(U const& u, V) : val (u) {}
  2041. typename __gmp_resolve_expr<T>::srcptr_type
  2042. __get_mp() const { return val.__get_mp(); }
  2043. };
  2044. template <>
  2045. class __gmp_temp <mpf_t>
  2046. {
  2047. mpf_class val;
  2048. public:
  2049. template<class U>
  2050. __gmp_temp(U const& u, mpf_ptr res) : val (u, mpf_get_prec(res)) {}
  2051. mpf_srcptr __get_mp() const { return val.__get_mp(); }
  2052. };
  2053. /**************** Specializations of __gmp_expr ****************/
  2054. /* The eval() method of __gmp_expr<T, U> evaluates the corresponding
  2055. expression and assigns the result to its argument, which is either an
  2056. mpz_t, mpq_t, or mpf_t as specified by the T argument.
  2057. Compound expressions are evaluated recursively (temporaries are created
  2058. to hold intermediate values), while for simple expressions the eval()
  2059. method of the appropriate function object (available as the Op argument
  2060. of either __gmp_unary_expr<T, Op> or __gmp_binary_expr<T, U, Op>) is
  2061. called. */
  2062. /**************** Unary expressions ****************/
  2063. /* cases:
  2064. - simple: argument is mp*_class, that is, __gmp_expr<T, T>
  2065. - compound: argument is __gmp_expr<T, U> (with U not equal to T) */
  2066. // simple expressions
  2067. template <class T, class Op>
  2068. class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
  2069. {
  2070. private:
  2071. typedef __gmp_expr<T, T> val_type;
  2072. __gmp_unary_expr<val_type, Op> expr;
  2073. public:
  2074. explicit __gmp_expr(const val_type &val) : expr(val) { }
  2075. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2076. { Op::eval(p, expr.val.__get_mp()); }
  2077. const val_type & get_val() const { return expr.val; }
  2078. mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
  2079. };
  2080. // simple expressions, U is a built-in numerical type
  2081. template <class T, class U, class Op>
  2082. class __gmp_expr<T, __gmp_unary_expr<U, Op> >
  2083. {
  2084. private:
  2085. typedef U val_type;
  2086. __gmp_unary_expr<val_type, Op> expr;
  2087. public:
  2088. explicit __gmp_expr(const val_type &val) : expr(val) { }
  2089. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2090. { Op::eval(p, expr.val); }
  2091. const val_type & get_val() const { return expr.val; }
  2092. mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
  2093. };
  2094. // compound expressions
  2095. template <class T, class U, class Op>
  2096. class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
  2097. {
  2098. private:
  2099. typedef __gmp_expr<T, U> val_type;
  2100. __gmp_unary_expr<val_type, Op> expr;
  2101. public:
  2102. explicit __gmp_expr(const val_type &val) : expr(val) { }
  2103. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2104. { expr.val.eval(p); Op::eval(p, p); }
  2105. const val_type & get_val() const { return expr.val; }
  2106. mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
  2107. };
  2108. /**************** Binary expressions ****************/
  2109. /* simple:
  2110. - arguments are both mp*_class
  2111. - one argument is mp*_class, one is a built-in type
  2112. compound:
  2113. - one is mp*_class, one is __gmp_expr<T, U>
  2114. - one is __gmp_expr<T, U>, one is built-in
  2115. - both arguments are __gmp_expr<...> */
  2116. // simple expressions
  2117. template <class T, class Op>
  2118. class __gmp_expr
  2119. <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
  2120. {
  2121. private:
  2122. typedef __gmp_expr<T, T> val1_type;
  2123. typedef __gmp_expr<T, T> val2_type;
  2124. __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2125. public:
  2126. __gmp_expr(const val1_type &val1, const val2_type &val2)
  2127. : expr(val1, val2) { }
  2128. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2129. { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); }
  2130. const val1_type & get_val1() const { return expr.val1; }
  2131. const val2_type & get_val2() const { return expr.val2; }
  2132. mp_bitcnt_t get_prec() const
  2133. {
  2134. mp_bitcnt_t prec1 = expr.val1.get_prec(),
  2135. prec2 = expr.val2.get_prec();
  2136. return (prec1 > prec2) ? prec1 : prec2;
  2137. }
  2138. };
  2139. // simple expressions, U is a built-in numerical type
  2140. template <class T, class U, class Op>
  2141. class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
  2142. {
  2143. private:
  2144. typedef __gmp_expr<T, T> val1_type;
  2145. typedef U val2_type;
  2146. __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2147. public:
  2148. __gmp_expr(const val1_type &val1, const val2_type &val2)
  2149. : expr(val1, val2) { }
  2150. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2151. { Op::eval(p, expr.val1.__get_mp(), expr.val2); }
  2152. const val1_type & get_val1() const { return expr.val1; }
  2153. const val2_type & get_val2() const { return expr.val2; }
  2154. mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
  2155. };
  2156. template <class T, class U, class Op>
  2157. class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
  2158. {
  2159. private:
  2160. typedef U val1_type;
  2161. typedef __gmp_expr<T, T> val2_type;
  2162. __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2163. public:
  2164. __gmp_expr(const val1_type &val1, const val2_type &val2)
  2165. : expr(val1, val2) { }
  2166. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2167. { Op::eval(p, expr.val1, expr.val2.__get_mp()); }
  2168. const val1_type & get_val1() const { return expr.val1; }
  2169. const val2_type & get_val2() const { return expr.val2; }
  2170. mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
  2171. };
  2172. // compound expressions, one argument is a subexpression
  2173. template <class T, class U, class V, class Op>
  2174. class __gmp_expr
  2175. <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
  2176. {
  2177. private:
  2178. typedef __gmp_expr<T, T> val1_type;
  2179. typedef __gmp_expr<U, V> val2_type;
  2180. __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2181. public:
  2182. __gmp_expr(const val1_type &val1, const val2_type &val2)
  2183. : expr(val1, val2) { }
  2184. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2185. {
  2186. if(p != expr.val1.__get_mp())
  2187. {
  2188. __gmp_set_expr(p, expr.val2);
  2189. Op::eval(p, expr.val1.__get_mp(), p);
  2190. }
  2191. else
  2192. {
  2193. __gmp_temp<T> temp(expr.val2, p);
  2194. Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
  2195. }
  2196. }
  2197. const val1_type & get_val1() const { return expr.val1; }
  2198. const val2_type & get_val2() const { return expr.val2; }
  2199. mp_bitcnt_t get_prec() const
  2200. {
  2201. mp_bitcnt_t prec1 = expr.val1.get_prec(),
  2202. prec2 = expr.val2.get_prec();
  2203. return (prec1 > prec2) ? prec1 : prec2;
  2204. }
  2205. };
  2206. template <class T, class U, class V, class Op>
  2207. class __gmp_expr
  2208. <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
  2209. {
  2210. private:
  2211. typedef __gmp_expr<U, V> val1_type;
  2212. typedef __gmp_expr<T, T> val2_type;
  2213. __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2214. public:
  2215. __gmp_expr(const val1_type &val1, const val2_type &val2)
  2216. : expr(val1, val2) { }
  2217. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2218. {
  2219. if(p != expr.val2.__get_mp())
  2220. {
  2221. __gmp_set_expr(p, expr.val1);
  2222. Op::eval(p, p, expr.val2.__get_mp());
  2223. }
  2224. else
  2225. {
  2226. __gmp_temp<T> temp(expr.val1, p);
  2227. Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
  2228. }
  2229. }
  2230. const val1_type & get_val1() const { return expr.val1; }
  2231. const val2_type & get_val2() const { return expr.val2; }
  2232. mp_bitcnt_t get_prec() const
  2233. {
  2234. mp_bitcnt_t prec1 = expr.val1.get_prec(),
  2235. prec2 = expr.val2.get_prec();
  2236. return (prec1 > prec2) ? prec1 : prec2;
  2237. }
  2238. };
  2239. template <class T, class U, class Op>
  2240. class __gmp_expr
  2241. <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
  2242. {
  2243. private:
  2244. typedef __gmp_expr<T, T> val1_type;
  2245. typedef __gmp_expr<T, U> val2_type;
  2246. __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2247. public:
  2248. __gmp_expr(const val1_type &val1, const val2_type &val2)
  2249. : expr(val1, val2) { }
  2250. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2251. {
  2252. if(p != expr.val1.__get_mp())
  2253. {
  2254. __gmp_set_expr(p, expr.val2);
  2255. Op::eval(p, expr.val1.__get_mp(), p);
  2256. }
  2257. else
  2258. {
  2259. __gmp_temp<T> temp(expr.val2, p);
  2260. Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
  2261. }
  2262. }
  2263. const val1_type & get_val1() const { return expr.val1; }
  2264. const val2_type & get_val2() const { return expr.val2; }
  2265. mp_bitcnt_t get_prec() const
  2266. {
  2267. mp_bitcnt_t prec1 = expr.val1.get_prec(),
  2268. prec2 = expr.val2.get_prec();
  2269. return (prec1 > prec2) ? prec1 : prec2;
  2270. }
  2271. };
  2272. template <class T, class U, class Op>
  2273. class __gmp_expr
  2274. <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
  2275. {
  2276. private:
  2277. typedef __gmp_expr<T, U> val1_type;
  2278. typedef __gmp_expr<T, T> val2_type;
  2279. __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2280. public:
  2281. __gmp_expr(const val1_type &val1, const val2_type &val2)
  2282. : expr(val1, val2) { }
  2283. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2284. {
  2285. if(p != expr.val2.__get_mp())
  2286. {
  2287. __gmp_set_expr(p, expr.val1);
  2288. Op::eval(p, p, expr.val2.__get_mp());
  2289. }
  2290. else
  2291. {
  2292. __gmp_temp<T> temp(expr.val1, p);
  2293. Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
  2294. }
  2295. }
  2296. const val1_type & get_val1() const { return expr.val1; }
  2297. const val2_type & get_val2() const { return expr.val2; }
  2298. mp_bitcnt_t get_prec() const
  2299. {
  2300. mp_bitcnt_t prec1 = expr.val1.get_prec(),
  2301. prec2 = expr.val2.get_prec();
  2302. return (prec1 > prec2) ? prec1 : prec2;
  2303. }
  2304. };
  2305. // one argument is a subexpression, one is a built-in
  2306. template <class T, class U, class V, class Op>
  2307. class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
  2308. {
  2309. private:
  2310. typedef __gmp_expr<T, U> val1_type;
  2311. typedef V val2_type;
  2312. __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2313. public:
  2314. __gmp_expr(const val1_type &val1, const val2_type &val2)
  2315. : expr(val1, val2) { }
  2316. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2317. {
  2318. expr.val1.eval(p);
  2319. Op::eval(p, p, expr.val2);
  2320. }
  2321. const val1_type & get_val1() const { return expr.val1; }
  2322. const val2_type & get_val2() const { return expr.val2; }
  2323. mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
  2324. };
  2325. template <class T, class U, class V, class Op>
  2326. class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
  2327. {
  2328. private:
  2329. typedef U val1_type;
  2330. typedef __gmp_expr<T, V> val2_type;
  2331. __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2332. public:
  2333. __gmp_expr(const val1_type &val1, const val2_type &val2)
  2334. : expr(val1, val2) { }
  2335. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2336. {
  2337. expr.val2.eval(p);
  2338. Op::eval(p, expr.val1, p);
  2339. }
  2340. const val1_type & get_val1() const { return expr.val1; }
  2341. const val2_type & get_val2() const { return expr.val2; }
  2342. mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
  2343. };
  2344. // both arguments are subexpressions
  2345. template <class T, class U, class V, class W, class Op>
  2346. class __gmp_expr
  2347. <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
  2348. {
  2349. private:
  2350. typedef __gmp_expr<T, U> val1_type;
  2351. typedef __gmp_expr<V, W> val2_type;
  2352. __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2353. public:
  2354. __gmp_expr(const val1_type &val1, const val2_type &val2)
  2355. : expr(val1, val2) { }
  2356. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2357. {
  2358. __gmp_temp<T> temp2(expr.val2, p);
  2359. expr.val1.eval(p);
  2360. Op::eval(p, p, temp2.__get_mp());
  2361. }
  2362. const val1_type & get_val1() const { return expr.val1; }
  2363. const val2_type & get_val2() const { return expr.val2; }
  2364. mp_bitcnt_t get_prec() const
  2365. {
  2366. mp_bitcnt_t prec1 = expr.val1.get_prec(),
  2367. prec2 = expr.val2.get_prec();
  2368. return (prec1 > prec2) ? prec1 : prec2;
  2369. }
  2370. };
  2371. template <class T, class U, class V, class W, class Op>
  2372. class __gmp_expr
  2373. <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
  2374. {
  2375. private:
  2376. typedef __gmp_expr<U, V> val1_type;
  2377. typedef __gmp_expr<T, W> val2_type;
  2378. __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2379. public:
  2380. __gmp_expr(const val1_type &val1, const val2_type &val2)
  2381. : expr(val1, val2) { }
  2382. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2383. {
  2384. __gmp_temp<T> temp1(expr.val1, p);
  2385. expr.val2.eval(p);
  2386. Op::eval(p, temp1.__get_mp(), p);
  2387. }
  2388. const val1_type & get_val1() const { return expr.val1; }
  2389. const val2_type & get_val2() const { return expr.val2; }
  2390. mp_bitcnt_t get_prec() const
  2391. {
  2392. mp_bitcnt_t prec1 = expr.val1.get_prec(),
  2393. prec2 = expr.val2.get_prec();
  2394. return (prec1 > prec2) ? prec1 : prec2;
  2395. }
  2396. };
  2397. template <class T, class U, class V, class Op>
  2398. class __gmp_expr
  2399. <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
  2400. {
  2401. private:
  2402. typedef __gmp_expr<T, U> val1_type;
  2403. typedef __gmp_expr<T, V> val2_type;
  2404. __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2405. public:
  2406. __gmp_expr(const val1_type &val1, const val2_type &val2)
  2407. : expr(val1, val2) { }
  2408. void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2409. {
  2410. __gmp_temp<T> temp2(expr.val2, p);
  2411. expr.val1.eval(p);
  2412. Op::eval(p, p, temp2.__get_mp());
  2413. }
  2414. const val1_type & get_val1() const { return expr.val1; }
  2415. const val2_type & get_val2() const { return expr.val2; }
  2416. mp_bitcnt_t get_prec() const
  2417. {
  2418. mp_bitcnt_t prec1 = expr.val1.get_prec(),
  2419. prec2 = expr.val2.get_prec();
  2420. return (prec1 > prec2) ? prec1 : prec2;
  2421. }
  2422. };
  2423. /**************** Special cases ****************/
  2424. /* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments
  2425. can be done directly without first converting the mpz to mpq.
  2426. Appropriate specializations of __gmp_expr are required. */
  2427. #define __GMPZQ_DEFINE_EXPR(eval_fun) \
  2428. \
  2429. template <> \
  2430. class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
  2431. { \
  2432. private: \
  2433. typedef mpz_class val1_type; \
  2434. typedef mpq_class val2_type; \
  2435. \
  2436. __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
  2437. public: \
  2438. __gmp_expr(const val1_type &val1, const val2_type &val2) \
  2439. : expr(val1, val2) { } \
  2440. void eval(mpq_ptr q) const \
  2441. { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); } \
  2442. const val1_type & get_val1() const { return expr.val1; } \
  2443. const val2_type & get_val2() const { return expr.val2; } \
  2444. mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
  2445. }; \
  2446. \
  2447. template <> \
  2448. class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
  2449. { \
  2450. private: \
  2451. typedef mpq_class val1_type; \
  2452. typedef mpz_class val2_type; \
  2453. \
  2454. __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
  2455. public: \
  2456. __gmp_expr(const val1_type &val1, const val2_type &val2) \
  2457. : expr(val1, val2) { } \
  2458. void eval(mpq_ptr q) const \
  2459. { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); } \
  2460. const val1_type & get_val1() const { return expr.val1; } \
  2461. const val2_type & get_val2() const { return expr.val2; } \
  2462. mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
  2463. }; \
  2464. \
  2465. template <class T> \
  2466. class __gmp_expr \
  2467. <mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> > \
  2468. { \
  2469. private: \
  2470. typedef mpz_class val1_type; \
  2471. typedef __gmp_expr<mpq_t, T> val2_type; \
  2472. \
  2473. __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
  2474. public: \
  2475. __gmp_expr(const val1_type &val1, const val2_type &val2) \
  2476. : expr(val1, val2) { } \
  2477. void eval(mpq_ptr q) const \
  2478. { \
  2479. mpq_class temp(expr.val2); \
  2480. eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t()); \
  2481. } \
  2482. const val1_type & get_val1() const { return expr.val1; } \
  2483. const val2_type & get_val2() const { return expr.val2; } \
  2484. mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
  2485. }; \
  2486. \
  2487. template <class T> \
  2488. class __gmp_expr \
  2489. <mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> > \
  2490. { \
  2491. private: \
  2492. typedef mpq_class val1_type; \
  2493. typedef __gmp_expr<mpz_t, T> val2_type; \
  2494. \
  2495. __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
  2496. public: \
  2497. __gmp_expr(const val1_type &val1, const val2_type &val2) \
  2498. : expr(val1, val2) { } \
  2499. void eval(mpq_ptr q) const \
  2500. { \
  2501. mpz_class temp(expr.val2); \
  2502. eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t()); \
  2503. } \
  2504. const val1_type & get_val1() const { return expr.val1; } \
  2505. const val2_type & get_val2() const { return expr.val2; } \
  2506. mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
  2507. }; \
  2508. \
  2509. template <class T> \
  2510. class __gmp_expr \
  2511. <mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> > \
  2512. { \
  2513. private: \
  2514. typedef __gmp_expr<mpz_t, T> val1_type; \
  2515. typedef mpq_class val2_type; \
  2516. \
  2517. __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
  2518. public: \
  2519. __gmp_expr(const val1_type &val1, const val2_type &val2) \
  2520. : expr(val1, val2) { } \
  2521. void eval(mpq_ptr q) const \
  2522. { \
  2523. mpz_class temp(expr.val1); \
  2524. eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t()); \
  2525. } \
  2526. const val1_type & get_val1() const { return expr.val1; } \
  2527. const val2_type & get_val2() const { return expr.val2; } \
  2528. mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
  2529. }; \
  2530. \
  2531. template <class T> \
  2532. class __gmp_expr \
  2533. <mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> > \
  2534. { \
  2535. private: \
  2536. typedef __gmp_expr<mpq_t, T> val1_type; \
  2537. typedef mpz_class val2_type; \
  2538. \
  2539. __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
  2540. public: \
  2541. __gmp_expr(const val1_type &val1, const val2_type &val2) \
  2542. : expr(val1, val2) { } \
  2543. void eval(mpq_ptr q) const \
  2544. { \
  2545. mpq_class temp(expr.val1); \
  2546. eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t()); \
  2547. } \
  2548. const val1_type & get_val1() const { return expr.val1; } \
  2549. const val2_type & get_val2() const { return expr.val2; } \
  2550. mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
  2551. }; \
  2552. \
  2553. template <class T, class U> \
  2554. class __gmp_expr<mpq_t, __gmp_binary_expr \
  2555. <__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> > \
  2556. { \
  2557. private: \
  2558. typedef __gmp_expr<mpz_t, T> val1_type; \
  2559. typedef __gmp_expr<mpq_t, U> val2_type; \
  2560. \
  2561. __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
  2562. public: \
  2563. __gmp_expr(const val1_type &val1, const val2_type &val2) \
  2564. : expr(val1, val2) { } \
  2565. void eval(mpq_ptr q) const \
  2566. { \
  2567. mpz_class temp1(expr.val1); \
  2568. expr.val2.eval(q); \
  2569. eval_fun::eval(q, temp1.get_mpz_t(), q); \
  2570. } \
  2571. const val1_type & get_val1() const { return expr.val1; } \
  2572. const val2_type & get_val2() const { return expr.val2; } \
  2573. mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
  2574. }; \
  2575. \
  2576. template <class T, class U> \
  2577. class __gmp_expr<mpq_t, __gmp_binary_expr \
  2578. <__gmp_expr<mpq_t, T>, __gmp_expr<mpz_t, U>, eval_fun> > \
  2579. { \
  2580. private: \
  2581. typedef __gmp_expr<mpq_t, T> val1_type; \
  2582. typedef __gmp_expr<mpz_t, U> val2_type; \
  2583. \
  2584. __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
  2585. public: \
  2586. __gmp_expr(const val1_type &val1, const val2_type &val2) \
  2587. : expr(val1, val2) { } \
  2588. void eval(mpq_ptr q) const \
  2589. { \
  2590. mpz_class temp2(expr.val2); \
  2591. expr.val1.eval(q); \
  2592. eval_fun::eval(q, q, temp2.get_mpz_t()); \
  2593. } \
  2594. const val1_type & get_val1() const { return expr.val1; } \
  2595. const val2_type & get_val2() const { return expr.val2; } \
  2596. mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
  2597. };
  2598. __GMPZQ_DEFINE_EXPR(__gmp_binary_plus)
  2599. __GMPZQ_DEFINE_EXPR(__gmp_binary_minus)
  2600. /**************** Macros for defining functions ****************/
  2601. /* Results of operators and functions are instances of __gmp_expr<T, U>.
  2602. T determines the numerical type of the expression: it can be either
  2603. mpz_t, mpq_t, or mpf_t. When the arguments of a binary
  2604. expression have different numerical types, __gmp_resolve_expr is used
  2605. to determine the "larger" type.
  2606. U is either __gmp_unary_expr<V, Op> or __gmp_binary_expr<V, W, Op>,
  2607. where V and W are the arguments' types -- they can in turn be
  2608. expressions, thus allowing to build compound expressions to any
  2609. degree of complexity.
  2610. Op is a function object that must have an eval() method accepting
  2611. appropriate arguments.
  2612. Actual evaluation of a __gmp_expr<T, U> object is done when it gets
  2613. assigned to an mp*_class ("lazy" evaluation): this is done by calling
  2614. its eval() method. */
  2615. // non-member unary operators and functions
  2616. #define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun) \
  2617. \
  2618. template <class T, class U> \
  2619. inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
  2620. fun(const __gmp_expr<T, U> &expr) \
  2621. { \
  2622. return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
  2623. }
  2624. // variant that only works for one of { mpz, mpq, mpf }
  2625. #define __GMP_DEFINE_UNARY_FUNCTION_1(T, fun, eval_fun) \
  2626. \
  2627. template <class U> \
  2628. inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
  2629. fun(const __gmp_expr<T, U> &expr) \
  2630. { \
  2631. return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
  2632. }
  2633. #define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
  2634. \
  2635. template <class T, class U> \
  2636. inline type fun(const __gmp_expr<T, U> &expr) \
  2637. { \
  2638. __gmp_expr<T, T> const& temp(expr); \
  2639. return eval_fun::eval(temp.__get_mp()); \
  2640. }
  2641. // non-member binary operators and functions
  2642. #define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
  2643. \
  2644. template <class T, class U, class V, class W> \
  2645. inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
  2646. __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
  2647. fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2) \
  2648. { \
  2649. return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
  2650. __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
  2651. (expr1, expr2); \
  2652. }
  2653. #define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype) \
  2654. \
  2655. template <class T, class U> \
  2656. inline __gmp_expr \
  2657. <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> > \
  2658. fun(const __gmp_expr<T, U> &expr, type t) \
  2659. { \
  2660. return __gmp_expr \
  2661. <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
  2662. } \
  2663. \
  2664. template <class T, class U> \
  2665. inline __gmp_expr \
  2666. <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> > \
  2667. fun(type t, const __gmp_expr<T, U> &expr) \
  2668. { \
  2669. return __gmp_expr \
  2670. <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
  2671. }
  2672. #define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
  2673. __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int)
  2674. #define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
  2675. __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int)
  2676. #define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
  2677. __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double)
  2678. #define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
  2679. __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double)
  2680. #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
  2681. __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \
  2682. __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \
  2683. __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \
  2684. __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \
  2685. __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \
  2686. __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \
  2687. __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \
  2688. __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \
  2689. __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float) \
  2690. __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double) \
  2691. /* __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double) */
  2692. #define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
  2693. __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
  2694. __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)
  2695. // variant that only works for one of { mpz, mpq, mpf }
  2696. #define __GMPP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
  2697. \
  2698. template <class U, class W> \
  2699. inline __gmp_expr<T, \
  2700. __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, W>, eval_fun> > \
  2701. fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<T, W> &expr2) \
  2702. { \
  2703. return __gmp_expr<T, \
  2704. __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, W>, eval_fun> > \
  2705. (expr1, expr2); \
  2706. }
  2707. #define __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, bigtype) \
  2708. \
  2709. template <class U> \
  2710. inline __gmp_expr \
  2711. <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> > \
  2712. fun(const __gmp_expr<T, U> &expr, type t) \
  2713. { \
  2714. return __gmp_expr \
  2715. <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
  2716. } \
  2717. \
  2718. template <class U> \
  2719. inline __gmp_expr \
  2720. <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> > \
  2721. fun(type t, const __gmp_expr<T, U> &expr) \
  2722. { \
  2723. return __gmp_expr \
  2724. <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
  2725. }
  2726. #define __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
  2727. __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, signed long int)
  2728. #define __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
  2729. __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, unsigned long int)
  2730. #define __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
  2731. __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, double)
  2732. #define __GMPNLD_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
  2733. __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, long double)
  2734. #define __GMPN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
  2735. __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed char) \
  2736. __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned char) \
  2737. __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed int) \
  2738. __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned int) \
  2739. __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed short int) \
  2740. __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned short int) \
  2741. __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed long int) \
  2742. __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned long int) \
  2743. __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, float) \
  2744. __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, double) \
  2745. /* __GMPNLD_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, long double) */
  2746. #define __GMP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
  2747. __GMPP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
  2748. __GMPN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun)
  2749. #define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun) \
  2750. \
  2751. template <class T, class U> \
  2752. inline __gmp_expr \
  2753. <T, __gmp_binary_expr<__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> > \
  2754. fun(const __gmp_expr<T, U> &expr, mp_bitcnt_t l) \
  2755. { \
  2756. return __gmp_expr<T, __gmp_binary_expr \
  2757. <__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> >(expr, l); \
  2758. }
  2759. #define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
  2760. \
  2761. template <class T, class U, class V, class W> \
  2762. inline type fun(const __gmp_expr<T, U> &expr1, \
  2763. const __gmp_expr<V, W> &expr2) \
  2764. { \
  2765. __gmp_expr<T, T> const& temp1(expr1); \
  2766. __gmp_expr<V, V> const& temp2(expr2); \
  2767. return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp()); \
  2768. }
  2769. #define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
  2770. type2, bigtype) \
  2771. \
  2772. template <class T, class U> \
  2773. inline type fun(const __gmp_expr<T, U> &expr, type2 t) \
  2774. { \
  2775. __gmp_expr<T, T> const& temp(expr); \
  2776. return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
  2777. } \
  2778. \
  2779. template <class T, class U> \
  2780. inline type fun(type2 t, const __gmp_expr<T, U> &expr) \
  2781. { \
  2782. __gmp_expr<T, T> const& temp(expr); \
  2783. return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
  2784. }
  2785. #define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
  2786. __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
  2787. type2, signed long int)
  2788. #define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
  2789. __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
  2790. type2, unsigned long int)
  2791. #define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
  2792. __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double)
  2793. #define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
  2794. __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double)
  2795. #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
  2796. __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \
  2797. __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \
  2798. __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \
  2799. __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \
  2800. __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \
  2801. __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \
  2802. __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \
  2803. __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \
  2804. __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float) \
  2805. __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double) \
  2806. /* __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double) */
  2807. #define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
  2808. __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
  2809. __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)
  2810. // member operators
  2811. #define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
  2812. \
  2813. template <class T, class U> \
  2814. inline type##_class & type##_class::fun(const __gmp_expr<T, U> &expr) \
  2815. { \
  2816. __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
  2817. <type##_class, __gmp_expr<T, U>, eval_fun> >(*this, expr)); \
  2818. return *this; \
  2819. }
  2820. #define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
  2821. type2, bigtype) \
  2822. \
  2823. inline type##_class & type##_class::fun(type2 t) \
  2824. { \
  2825. __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
  2826. <type##_class, bigtype, eval_fun> >(*this, t)); \
  2827. return *this; \
  2828. }
  2829. #define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
  2830. __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
  2831. type2, signed long int)
  2832. #define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
  2833. __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
  2834. type2, unsigned long int)
  2835. #define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
  2836. __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double)
  2837. #define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
  2838. __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double)
  2839. #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
  2840. __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \
  2841. __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \
  2842. __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \
  2843. __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \
  2844. __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \
  2845. __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \
  2846. __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \
  2847. __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \
  2848. __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float) \
  2849. __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double) \
  2850. /* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */
  2851. #define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
  2852. __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
  2853. __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)
  2854. #define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
  2855. __GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
  2856. #define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
  2857. __GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun)
  2858. #define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
  2859. __GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun)
  2860. #define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun) \
  2861. \
  2862. inline type##_class & type##_class::fun(mp_bitcnt_t l) \
  2863. { \
  2864. __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
  2865. <type##_class, mp_bitcnt_t, eval_fun> >(*this, l)); \
  2866. return *this; \
  2867. }
  2868. #define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
  2869. __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun)
  2870. #define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
  2871. __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun)
  2872. #define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
  2873. __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun)
  2874. #define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \
  2875. \
  2876. inline type##_class & type##_class::fun() \
  2877. { \
  2878. eval_fun::eval(mp); \
  2879. return *this; \
  2880. } \
  2881. \
  2882. inline type##_class type##_class::fun(int) \
  2883. { \
  2884. type##_class temp(*this); \
  2885. eval_fun::eval(mp); \
  2886. return temp; \
  2887. }
  2888. #define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
  2889. __GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun)
  2890. #define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
  2891. __GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun)
  2892. #define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
  2893. __GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun)
  2894. #define __GMPP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
  2895. template <class U> \
  2896. __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
  2897. fun(const __gmp_expr<T, U> &expr) \
  2898. { \
  2899. return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
  2900. }
  2901. #define __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, bigtype) \
  2902. inline __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> > \
  2903. fun(type expr) \
  2904. { \
  2905. return __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> >(expr); \
  2906. }
  2907. #define __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
  2908. __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, signed long)
  2909. #define __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
  2910. __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, unsigned long)
  2911. #define __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
  2912. __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, double)
  2913. #define __GMPN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
  2914. __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char) \
  2915. __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char) \
  2916. __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int) \
  2917. __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int) \
  2918. __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int) \
  2919. __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int) \
  2920. __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int) \
  2921. __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int) \
  2922. __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, float) \
  2923. __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, double) \
  2924. #define __GMP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
  2925. __GMPP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
  2926. __GMPN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
  2927. /**************** Arithmetic operators and functions ****************/
  2928. // non-member operators and functions
  2929. __GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus)
  2930. __GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus)
  2931. __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, operator~, __gmp_unary_com)
  2932. __GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus)
  2933. __GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus)
  2934. __GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies)
  2935. __GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides)
  2936. __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator%, __gmp_binary_modulus)
  2937. __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator&, __gmp_binary_and)
  2938. __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator|, __gmp_binary_ior)
  2939. __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator^, __gmp_binary_xor)
  2940. __GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift)
  2941. __GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift)
  2942. __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal)
  2943. __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, ! __gmp_binary_equal)
  2944. __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less)
  2945. __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, ! __gmp_binary_greater)
  2946. __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater)
  2947. __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, ! __gmp_binary_less)
  2948. __GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function)
  2949. __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, trunc, __gmp_trunc_function)
  2950. __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, floor, __gmp_floor_function)
  2951. __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, ceil, __gmp_ceil_function)
  2952. __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, sqrt, __gmp_sqrt_function)
  2953. __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, sqrt, __gmp_sqrt_function)
  2954. __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, factorial, __gmp_fac_function)
  2955. __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, primorial, __gmp_primorial_function)
  2956. __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, fibonacci, __gmp_fib_function)
  2957. __GMP_DEFINE_BINARY_FUNCTION_1(mpf_t, hypot, __gmp_hypot_function)
  2958. __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, gcd, __gmp_gcd_function)
  2959. __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, lcm, __gmp_lcm_function)
  2960. __GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function)
  2961. __GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function)
  2962. template <class T>
  2963. void swap(__gmp_expr<T, T>& x, __gmp_expr<T, T>& y) __GMPXX_NOEXCEPT
  2964. { x.swap(y); }
  2965. // member operators for mpz_class
  2966. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
  2967. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
  2968. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
  2969. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
  2970. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus)
  2971. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
  2972. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
  2973. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
  2974. __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
  2975. __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
  2976. __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
  2977. __GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
  2978. __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::factorial, __gmp_fac_function)
  2979. __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::primorial, __gmp_primorial_function)
  2980. __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::fibonacci, __gmp_fib_function)
  2981. // member operators for mpq_class
  2982. __GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
  2983. __GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
  2984. __GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
  2985. __GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
  2986. __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
  2987. __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
  2988. __GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
  2989. __GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
  2990. // member operators for mpf_class
  2991. __GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
  2992. __GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
  2993. __GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
  2994. __GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
  2995. __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
  2996. __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
  2997. __GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
  2998. __GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
  2999. /**************** Class wrapper for gmp_randstate_t ****************/
  3000. class __gmp_urandomb_value { };
  3001. class __gmp_urandomm_value { };
  3002. template <>
  3003. class __gmp_expr<mpz_t, __gmp_urandomb_value>
  3004. {
  3005. private:
  3006. __gmp_randstate_struct *state;
  3007. mp_bitcnt_t bits;
  3008. public:
  3009. __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
  3010. void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); }
  3011. mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
  3012. };
  3013. template <>
  3014. class __gmp_expr<mpz_t, __gmp_urandomm_value>
  3015. {
  3016. private:
  3017. __gmp_randstate_struct *state;
  3018. mpz_class range;
  3019. public:
  3020. __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { }
  3021. void eval(mpz_ptr z) const
  3022. { __gmp_rand_function::eval(z, state, range.get_mpz_t()); }
  3023. mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
  3024. };
  3025. template <>
  3026. class __gmp_expr<mpf_t, __gmp_urandomb_value>
  3027. {
  3028. private:
  3029. __gmp_randstate_struct *state;
  3030. mp_bitcnt_t bits;
  3031. public:
  3032. __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
  3033. void eval(mpf_ptr f) const
  3034. {
  3035. __gmp_rand_function::eval(f, state,
  3036. (bits>0) ? bits : mpf_get_prec(f));
  3037. }
  3038. mp_bitcnt_t get_prec() const
  3039. {
  3040. if (bits == 0)
  3041. return mpf_get_default_prec();
  3042. else
  3043. return bits;
  3044. }
  3045. };
  3046. extern "C" {
  3047. typedef void __gmp_randinit_default_t (gmp_randstate_t);
  3048. typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, unsigned long int, mp_bitcnt_t);
  3049. typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, mp_bitcnt_t);
  3050. }
  3051. class gmp_randclass
  3052. {
  3053. private:
  3054. gmp_randstate_t state;
  3055. // copy construction and assignment not allowed
  3056. gmp_randclass(const gmp_randclass &);
  3057. void operator=(const gmp_randclass &);
  3058. public:
  3059. // constructors and destructor
  3060. gmp_randclass(gmp_randalg_t alg, unsigned long int size)
  3061. {
  3062. switch (alg)
  3063. {
  3064. case GMP_RAND_ALG_LC: // no other cases for now
  3065. default:
  3066. gmp_randinit(state, alg, size);
  3067. break;
  3068. }
  3069. }
  3070. // gmp_randinit_default
  3071. gmp_randclass(__gmp_randinit_default_t* f) { f(state); }
  3072. // gmp_randinit_lc_2exp
  3073. gmp_randclass(__gmp_randinit_lc_2exp_t* f,
  3074. mpz_class z, unsigned long int l1, mp_bitcnt_t l2)
  3075. { f(state, z.get_mpz_t(), l1, l2); }
  3076. // gmp_randinit_lc_2exp_size
  3077. gmp_randclass(__gmp_randinit_lc_2exp_size_t* f,
  3078. mp_bitcnt_t size)
  3079. {
  3080. if (f (state, size) == 0)
  3081. throw std::length_error ("gmp_randinit_lc_2exp_size");
  3082. }
  3083. ~gmp_randclass() { gmp_randclear(state); }
  3084. // initialize
  3085. void seed(); // choose a random seed some way (?)
  3086. void seed(unsigned long int s) { gmp_randseed_ui(state, s); }
  3087. void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); }
  3088. // get random number
  3089. __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(mp_bitcnt_t l)
  3090. { return __gmp_expr<mpz_t, __gmp_urandomb_value>(state, l); }
  3091. __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(const mpz_class &z)
  3092. { return get_z_bits(z.get_ui()); }
  3093. // FIXME: z.get_bitcnt_t() ?
  3094. __gmp_expr<mpz_t, __gmp_urandomm_value> get_z_range(const mpz_class &z)
  3095. { return __gmp_expr<mpz_t, __gmp_urandomm_value>(state, z); }
  3096. __gmp_expr<mpf_t, __gmp_urandomb_value> get_f(mp_bitcnt_t prec = 0)
  3097. { return __gmp_expr<mpf_t, __gmp_urandomb_value>(state, prec); }
  3098. };
  3099. /**************** Specialize std::numeric_limits ****************/
  3100. namespace std {
  3101. template <> class numeric_limits<mpz_class>
  3102. {
  3103. public:
  3104. static const bool is_specialized = true;
  3105. static mpz_class min() { return mpz_class(); }
  3106. static mpz_class max() { return mpz_class(); }
  3107. static mpz_class lowest() { return mpz_class(); }
  3108. static const int digits = 0;
  3109. static const int digits10 = 0;
  3110. static const int max_digits10 = 0;
  3111. static const bool is_signed = true;
  3112. static const bool is_integer = true;
  3113. static const bool is_exact = true;
  3114. static const int radix = 2;
  3115. static mpz_class epsilon() { return mpz_class(); }
  3116. static mpz_class round_error() { return mpz_class(); }
  3117. static const int min_exponent = 0;
  3118. static const int min_exponent10 = 0;
  3119. static const int max_exponent = 0;
  3120. static const int max_exponent10 = 0;
  3121. static const bool has_infinity = false;
  3122. static const bool has_quiet_NaN = false;
  3123. static const bool has_signaling_NaN = false;
  3124. static const float_denorm_style has_denorm = denorm_absent;
  3125. static const bool has_denorm_loss = false;
  3126. static mpz_class infinity() { return mpz_class(); }
  3127. static mpz_class quiet_NaN() { return mpz_class(); }
  3128. static mpz_class signaling_NaN() { return mpz_class(); }
  3129. static mpz_class denorm_min() { return mpz_class(); }
  3130. static const bool is_iec559 = false;
  3131. static const bool is_bounded = false;
  3132. static const bool is_modulo = false;
  3133. static const bool traps = false;
  3134. static const bool tinyness_before = false;
  3135. static const float_round_style round_style = round_toward_zero;
  3136. };
  3137. template <> class numeric_limits<mpq_class>
  3138. {
  3139. public:
  3140. static const bool is_specialized = true;
  3141. static mpq_class min() { return mpq_class(); }
  3142. static mpq_class max() { return mpq_class(); }
  3143. static mpq_class lowest() { return mpq_class(); }
  3144. static const int digits = 0;
  3145. static const int digits10 = 0;
  3146. static const int max_digits10 = 0;
  3147. static const bool is_signed = true;
  3148. static const bool is_integer = false;
  3149. static const bool is_exact = true;
  3150. static const int radix = 2;
  3151. static mpq_class epsilon() { return mpq_class(); }
  3152. static mpq_class round_error() { return mpq_class(); }
  3153. static const int min_exponent = 0;
  3154. static const int min_exponent10 = 0;
  3155. static const int max_exponent = 0;
  3156. static const int max_exponent10 = 0;
  3157. static const bool has_infinity = false;
  3158. static const bool has_quiet_NaN = false;
  3159. static const bool has_signaling_NaN = false;
  3160. static const float_denorm_style has_denorm = denorm_absent;
  3161. static const bool has_denorm_loss = false;
  3162. static mpq_class infinity() { return mpq_class(); }
  3163. static mpq_class quiet_NaN() { return mpq_class(); }
  3164. static mpq_class signaling_NaN() { return mpq_class(); }
  3165. static mpq_class denorm_min() { return mpq_class(); }
  3166. static const bool is_iec559 = false;
  3167. static const bool is_bounded = false;
  3168. static const bool is_modulo = false;
  3169. static const bool traps = false;
  3170. static const bool tinyness_before = false;
  3171. static const float_round_style round_style = round_toward_zero;
  3172. };
  3173. template <> class numeric_limits<mpf_class>
  3174. {
  3175. public:
  3176. static const bool is_specialized = true;
  3177. static mpf_class min() { return mpf_class(); }
  3178. static mpf_class max() { return mpf_class(); }
  3179. static mpf_class lowest() { return mpf_class(); }
  3180. static const int digits = 0;
  3181. static const int digits10 = 0;
  3182. static const int max_digits10 = 0;
  3183. static const bool is_signed = true;
  3184. static const bool is_integer = false;
  3185. static const bool is_exact = false;
  3186. static const int radix = 2;
  3187. static mpf_class epsilon() { return mpf_class(); }
  3188. static mpf_class round_error() { return mpf_class(); }
  3189. static const int min_exponent = 0;
  3190. static const int min_exponent10 = 0;
  3191. static const int max_exponent = 0;
  3192. static const int max_exponent10 = 0;
  3193. static const bool has_infinity = false;
  3194. static const bool has_quiet_NaN = false;
  3195. static const bool has_signaling_NaN = false;
  3196. static const float_denorm_style has_denorm = denorm_absent;
  3197. static const bool has_denorm_loss = false;
  3198. static mpf_class infinity() { return mpf_class(); }
  3199. static mpf_class quiet_NaN() { return mpf_class(); }
  3200. static mpf_class signaling_NaN() { return mpf_class(); }
  3201. static mpf_class denorm_min() { return mpf_class(); }
  3202. static const bool is_iec559 = false;
  3203. static const bool is_bounded = false;
  3204. static const bool is_modulo = false;
  3205. static const bool traps = false;
  3206. static const bool tinyness_before = false;
  3207. static const float_round_style round_style = round_indeterminate;
  3208. };
  3209. }
  3210. /**************** #undef all private macros ****************/
  3211. #undef __GMPP_DECLARE_COMPOUND_OPERATOR
  3212. #undef __GMPN_DECLARE_COMPOUND_OPERATOR
  3213. #undef __GMP_DECLARE_COMPOUND_OPERATOR
  3214. #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
  3215. #undef __GMP_DECLARE_INCREMENT_OPERATOR
  3216. #undef __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
  3217. #undef __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
  3218. #undef __GMPZQ_DEFINE_EXPR
  3219. #undef __GMP_DEFINE_UNARY_FUNCTION_1
  3220. #undef __GMP_DEFINE_UNARY_FUNCTION
  3221. #undef __GMP_DEFINE_UNARY_TYPE_FUNCTION
  3222. #undef __GMPP_DEFINE_BINARY_FUNCTION
  3223. #undef __GMPNN_DEFINE_BINARY_FUNCTION
  3224. #undef __GMPNS_DEFINE_BINARY_FUNCTION
  3225. #undef __GMPNU_DEFINE_BINARY_FUNCTION
  3226. #undef __GMPND_DEFINE_BINARY_FUNCTION
  3227. #undef __GMPNLD_DEFINE_BINARY_FUNCTION
  3228. #undef __GMPN_DEFINE_BINARY_FUNCTION
  3229. #undef __GMP_DEFINE_BINARY_FUNCTION
  3230. #undef __GMP_DEFINE_BINARY_FUNCTION_UI
  3231. #undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION
  3232. #undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION
  3233. #undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION
  3234. #undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION
  3235. #undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION
  3236. #undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION
  3237. #undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION
  3238. #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION
  3239. #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
  3240. #undef __GMPP_DEFINE_COMPOUND_OPERATOR
  3241. #undef __GMPNN_DEFINE_COMPOUND_OPERATOR
  3242. #undef __GMPNS_DEFINE_COMPOUND_OPERATOR
  3243. #undef __GMPNU_DEFINE_COMPOUND_OPERATOR
  3244. #undef __GMPND_DEFINE_COMPOUND_OPERATOR
  3245. #undef __GMPNLD_DEFINE_COMPOUND_OPERATOR
  3246. #undef __GMPN_DEFINE_COMPOUND_OPERATOR
  3247. #undef __GMP_DEFINE_COMPOUND_OPERATOR
  3248. #undef __GMPQ_DEFINE_COMPOUND_OPERATOR
  3249. #undef __GMPF_DEFINE_COMPOUND_OPERATOR
  3250. #undef __GMP_DEFINE_COMPOUND_OPERATOR_UI
  3251. #undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI
  3252. #undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI
  3253. #undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI
  3254. #undef __GMP_DEFINE_INCREMENT_OPERATOR
  3255. #undef __GMPZ_DEFINE_INCREMENT_OPERATOR
  3256. #undef __GMPQ_DEFINE_INCREMENT_OPERATOR
  3257. #undef __GMPF_DEFINE_INCREMENT_OPERATOR
  3258. #undef __GMPXX_CONSTANT_TRUE
  3259. #undef __GMPXX_CONSTANT
  3260. #endif /* __GMP_PLUSPLUS__ */