number.hpp 79 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright 2011 John Maddock. Distributed under the Boost
  3. // Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_MATH_EXTENDED_REAL_HPP
  6. #define BOOST_MATH_EXTENDED_REAL_HPP
  7. #include <boost/cstdint.hpp>
  8. #include <boost/mpl/max.hpp>
  9. #include <boost/mpl/plus.hpp>
  10. #include <boost/mpl/or.hpp>
  11. #include <boost/mpl/find_if.hpp>
  12. #include <boost/assert.hpp>
  13. #include <boost/type_traits/remove_pointer.hpp>
  14. #include <boost/type_traits/is_signed.hpp>
  15. #include <boost/type_traits/is_unsigned.hpp>
  16. #include <boost/type_traits/is_floating_point.hpp>
  17. #include <boost/type_traits/is_integral.hpp>
  18. #include <boost/type_traits/is_complex.hpp>
  19. #include <boost/type_traits/make_unsigned.hpp>
  20. #include <boost/throw_exception.hpp>
  21. #include <boost/multiprecision/detail/generic_interconvert.hpp>
  22. #include <boost/multiprecision/detail/number_compare.hpp>
  23. #include <boost/multiprecision/traits/is_restricted_conversion.hpp>
  24. #include <boost/container_hash/hash.hpp>
  25. #include <istream> // stream operators
  26. #include <cstdio> // EOF
  27. #include <cctype> // isspace
  28. namespace boost{ namespace multiprecision{
  29. #ifdef BOOST_MSVC
  30. // warning C4127: conditional expression is constant
  31. // warning C4714: function marked as __forceinline not inlined
  32. #pragma warning(push)
  33. #pragma warning(disable:4127 4714 6326)
  34. #endif
  35. template <class Backend, expression_template_option ExpressionTemplates>
  36. class number
  37. {
  38. typedef number<Backend, ExpressionTemplates> self_type;
  39. public:
  40. typedef Backend backend_type;
  41. typedef typename component_type<self_type>::type value_type;
  42. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number() BOOST_MP_NOEXCEPT_IF(noexcept(Backend())) {}
  43. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number& e) BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>()))) : m_backend(e.m_backend){}
  44. template <class V>
  45. BOOST_MP_FORCEINLINE number(const V& v, typename boost::enable_if_c<
  46. (boost::is_arithmetic<V>::value || is_same<std::string, V>::value || is_convertible<V, const char*>::value)
  47. && !is_convertible<typename detail::canonical<V, Backend>::type, Backend>::value
  48. && !detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value
  49. #ifdef BOOST_HAS_FLOAT128
  50. && !boost::is_same<V, __float128>::value
  51. #endif
  52. >::type* = 0)
  53. {
  54. m_backend = canonical_value(v);
  55. }
  56. template <class V>
  57. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const V& v, typename boost::enable_if_c<
  58. is_convertible<typename detail::canonical<V, Backend>::type, Backend>::value
  59. && !detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value
  60. >::type* = 0)
  61. #ifndef BOOST_INTEL
  62. BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<typename detail::canonical<V, Backend>::type const&>())))
  63. #endif
  64. : m_backend(canonical_value(v)) {}
  65. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number& e, unsigned digits10)
  66. BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>(), std::declval<unsigned>())))
  67. : m_backend(e.m_backend, digits10){}
  68. template <class V>
  69. explicit BOOST_MP_FORCEINLINE number(const V& v, typename boost::enable_if_c<
  70. (boost::is_arithmetic<V>::value || is_same<std::string, V>::value || is_convertible<V, const char*>::value)
  71. && !detail::is_explicitly_convertible<typename detail::canonical<V, Backend>::type, Backend>::value
  72. && detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value
  73. >::type* = 0)
  74. BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<typename detail::canonical<V, Backend>::type const&>()))
  75. {
  76. m_backend = canonical_value(v);
  77. }
  78. template <class V>
  79. explicit BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const V& v, typename boost::enable_if_c<
  80. detail::is_explicitly_convertible<typename detail::canonical<V, Backend>::type, Backend>::value
  81. && (detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value
  82. || !is_convertible<typename detail::canonical<V, Backend>::type, Backend>::value)
  83. >::type* = 0)
  84. BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<typename detail::canonical<V, Backend>::type const&>())))
  85. : m_backend(canonical_value(v)) {}
  86. /*
  87. //
  88. // This conflicts with component based initialization (for rational and complex types)
  89. // which is arguably more useful. Disabled for now.
  90. //
  91. template <class V>
  92. number(V v, unsigned digits10, typename boost::enable_if<mpl::or_<boost::is_arithmetic<V>, is_same<std::string, V>, is_convertible<V, const char*> > >::type* dummy1 = 0)
  93. {
  94. m_backend.precision(digits10);
  95. m_backend = canonical_value(v);
  96. }
  97. */
  98. template<expression_template_option ET>
  99. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number<Backend, ET>& val)
  100. BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>()))) : m_backend(val.backend()) {}
  101. template <class Other, expression_template_option ET>
  102. BOOST_MP_FORCEINLINE number(const number<Other, ET>& val,
  103. typename boost::enable_if_c<(boost::is_convertible<Other, Backend>::value && !detail::is_restricted_conversion<Other, Backend>::value)>::type* = 0)
  104. BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Other const&>())))
  105. : m_backend(val.backend()) {}
  106. template <class Other, expression_template_option ET>
  107. explicit number(const number<Other, ET>& val, typename boost::enable_if_c<
  108. (!detail::is_explicitly_convertible<Other, Backend>::value)
  109. >::type* = 0)
  110. {
  111. //
  112. // Attempt a generic interconvertion:
  113. //
  114. using detail::generic_interconvert;
  115. generic_interconvert(backend(), val.backend(), number_category<Backend>(), number_category<Other>());
  116. }
  117. template <class Other, expression_template_option ET>
  118. explicit BOOST_MP_FORCEINLINE number(const number<Other, ET>& val, typename boost::enable_if_c<
  119. (detail::is_explicitly_convertible<Other, Backend>::value
  120. && (detail::is_restricted_conversion<Other, Backend>::value || !boost::is_convertible<Other, Backend>::value))
  121. >::type* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Other const&>())))
  122. : m_backend(val.backend()) {}
  123. template <class V, class U>
  124. BOOST_MP_FORCEINLINE number(const V& v1, const U& v2,
  125. typename boost::enable_if_c<(is_convertible<V, value_type>::value && is_convertible<U, value_type>::value && !is_same<typename component_type<self_type>::type, self_type>::value)>::type* = 0)
  126. {
  127. using default_ops::assign_components;
  128. assign_components(m_backend, canonical_value(detail::evaluate_if_expression(v1)), canonical_value(detail::evaluate_if_expression(v2)));
  129. }
  130. template <class V, class U>
  131. BOOST_MP_FORCEINLINE explicit number(const V& v1, const U& v2,
  132. typename boost::enable_if_c<((is_constructible<value_type, V>::value || is_convertible<V, std::string>::value) && (is_constructible<value_type, U>::value || is_convertible<U, std::string>::value) && !is_same<typename component_type<self_type>::type, self_type>::value) && !(is_convertible<V, value_type>::value && is_convertible<U, value_type>::value)>::type* = 0)
  133. {
  134. using default_ops::assign_components;
  135. assign_components(m_backend, canonical_value(detail::evaluate_if_expression(v1)), canonical_value(detail::evaluate_if_expression(v2)));
  136. }
  137. template <class Other, expression_template_option ET>
  138. BOOST_MP_FORCEINLINE number(const number<Other, ET>& v1, const number<Other, ET>& v2, typename boost::enable_if<boost::is_convertible<Other, Backend> >::type* = 0)
  139. {
  140. using default_ops::assign_components;
  141. assign_components(m_backend, v1.backend(), v2.backend());
  142. }
  143. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  144. typename boost::enable_if<is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>, number&>::type operator=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
  145. {
  146. typedef typename is_same<number, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::type tag_type;
  147. do_assign(e, tag_type());
  148. return *this;
  149. }
  150. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  151. number& assign(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
  152. {
  153. typedef typename is_same<number, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::type tag_type;
  154. do_assign(e, tag_type());
  155. return *this;
  156. }
  157. BOOST_MP_FORCEINLINE number& operator=(const number& e)
  158. BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<Backend const&>()))
  159. {
  160. m_backend = e.m_backend;
  161. return *this;
  162. }
  163. template <class V>
  164. BOOST_MP_FORCEINLINE typename boost::enable_if<is_convertible<V, self_type>, number<Backend, ExpressionTemplates>& >::type
  165. operator=(const V& v)
  166. BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<const typename detail::canonical<V, Backend>::type&>()))
  167. {
  168. m_backend = canonical_value(v);
  169. return *this;
  170. }
  171. template <class V>
  172. BOOST_MP_FORCEINLINE number<Backend, ExpressionTemplates>& assign(const V& v)
  173. BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<const typename detail::canonical<V, Backend>::type&>()))
  174. {
  175. m_backend = canonical_value(v);
  176. return *this;
  177. }
  178. template <class Other, expression_template_option ET>
  179. typename boost::disable_if<boost::multiprecision::detail::is_explicitly_convertible<Other, Backend>, number<Backend, ExpressionTemplates>& >::type
  180. assign(const number<Other, ET>& v)
  181. {
  182. //
  183. // Attempt a generic interconvertion:
  184. //
  185. using detail::generic_interconvert;
  186. generic_interconvert(backend(), v.backend(), number_category<Backend>(), number_category<Other>());
  187. return *this;
  188. }
  189. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  190. number(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e, typename boost::enable_if_c<is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value>::type* = 0)
  191. {
  192. *this = e;
  193. }
  194. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  195. explicit number(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e,
  196. typename boost::enable_if_c<!is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value
  197. && boost::multiprecision::detail::is_explicitly_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value>::type* = 0)
  198. {
  199. assign(e);
  200. }
  201. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  202. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(number&& r)
  203. BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend>())))
  204. : m_backend(static_cast<Backend&&>(r.m_backend)){}
  205. BOOST_MP_FORCEINLINE number& operator=(number&& r) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<Backend>()))
  206. {
  207. m_backend = static_cast<Backend&&>(r.m_backend);
  208. return *this;
  209. }
  210. #endif
  211. number& operator+=(const self_type& val)
  212. {
  213. do_add(detail::expression<detail::terminal, self_type>(val), detail::terminal());
  214. return *this;
  215. }
  216. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  217. typename boost::enable_if<is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>, number&>::type operator+=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
  218. {
  219. // Create a copy if e contains this, but not if we're just doing a
  220. // x += x
  221. if(contains_self(e) && !is_self(e))
  222. {
  223. self_type temp(e);
  224. do_add(detail::expression<detail::terminal, self_type>(temp), detail::terminal());
  225. }
  226. else
  227. {
  228. do_add(e, tag());
  229. }
  230. return *this;
  231. }
  232. template <class Arg1, class Arg2, class Arg3, class Arg4>
  233. number& operator+=(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& e)
  234. {
  235. //
  236. // Fused multiply-add:
  237. //
  238. using default_ops::eval_multiply_add;
  239. eval_multiply_add(m_backend, canonical_value(e.left_ref()), canonical_value(e.right_ref()));
  240. return *this;
  241. }
  242. template <class V>
  243. typename boost::enable_if<boost::is_convertible<V, self_type>, number<Backend, ExpressionTemplates>& >::type
  244. operator+=(const V& v)
  245. {
  246. using default_ops::eval_add;
  247. eval_add(m_backend, canonical_value(v));
  248. return *this;
  249. }
  250. number& operator-=(const self_type& val)
  251. {
  252. do_subtract(detail::expression<detail::terminal, self_type>(val), detail::terminal());
  253. return *this;
  254. }
  255. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  256. typename boost::enable_if<is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>, number&>::type operator-=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
  257. {
  258. // Create a copy if e contains this:
  259. if(contains_self(e))
  260. {
  261. self_type temp(e);
  262. do_subtract(detail::expression<detail::terminal, self_type>(temp), detail::terminal());
  263. }
  264. else
  265. {
  266. do_subtract(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type());
  267. }
  268. return *this;
  269. }
  270. template <class V>
  271. typename boost::enable_if<boost::is_convertible<V, self_type>, number<Backend, ExpressionTemplates>& >::type
  272. operator-=(const V& v)
  273. {
  274. using default_ops::eval_subtract;
  275. eval_subtract(m_backend, canonical_value(v));
  276. return *this;
  277. }
  278. template <class Arg1, class Arg2, class Arg3, class Arg4>
  279. number& operator-=(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& e)
  280. {
  281. //
  282. // Fused multiply-subtract:
  283. //
  284. using default_ops::eval_multiply_subtract;
  285. eval_multiply_subtract(m_backend, canonical_value(e.left_ref()), canonical_value(e.right_ref()));
  286. return *this;
  287. }
  288. number& operator *= (const self_type& e)
  289. {
  290. do_multiplies(detail::expression<detail::terminal, self_type>(e), detail::terminal());
  291. return *this;
  292. }
  293. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  294. typename boost::enable_if<is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>, number&>::type operator*=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
  295. {
  296. // Create a temporary if the RHS references *this, but not
  297. // if we're just doing an x *= x;
  298. if(contains_self(e) && !is_self(e))
  299. {
  300. self_type temp(e);
  301. do_multiplies(detail::expression<detail::terminal, self_type>(temp), detail::terminal());
  302. }
  303. else
  304. {
  305. do_multiplies(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type());
  306. }
  307. return *this;
  308. }
  309. template <class V>
  310. typename boost::enable_if<boost::is_convertible<V, self_type>, number<Backend, ExpressionTemplates>& >::type
  311. operator*=(const V& v)
  312. {
  313. using default_ops::eval_multiply;
  314. eval_multiply(m_backend, canonical_value(v));
  315. return *this;
  316. }
  317. number& operator%=(const self_type& e)
  318. {
  319. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
  320. do_modulus(detail::expression<detail::terminal, self_type>(e), detail::terminal());
  321. return *this;
  322. }
  323. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  324. typename boost::enable_if<is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>, number&>::type operator%=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
  325. {
  326. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
  327. // Create a temporary if the RHS references *this:
  328. if(contains_self(e))
  329. {
  330. self_type temp(e);
  331. do_modulus(detail::expression<detail::terminal, self_type>(temp), detail::terminal());
  332. }
  333. else
  334. {
  335. do_modulus(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type());
  336. }
  337. return *this;
  338. }
  339. template <class V>
  340. typename boost::enable_if<boost::is_convertible<V, self_type>, number<Backend, ExpressionTemplates>& >::type
  341. operator%=(const V& v)
  342. {
  343. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
  344. using default_ops::eval_modulus;
  345. eval_modulus(m_backend, canonical_value(v));
  346. return *this;
  347. }
  348. //
  349. // These operators are *not* proto-ized.
  350. // The issue is that the increment/decrement must happen
  351. // even if the result of the operator *is never used*.
  352. // Possibly we could modify our expression wrapper to
  353. // execute the increment/decrement on destruction, but
  354. // correct implementation will be tricky, so defered for now...
  355. //
  356. BOOST_MP_FORCEINLINE number& operator++()
  357. {
  358. using default_ops::eval_increment;
  359. eval_increment(m_backend);
  360. return *this;
  361. }
  362. BOOST_MP_FORCEINLINE number& operator--()
  363. {
  364. using default_ops::eval_decrement;
  365. eval_decrement(m_backend);
  366. return *this;
  367. }
  368. inline number operator++(int)
  369. {
  370. using default_ops::eval_increment;
  371. self_type temp(*this);
  372. eval_increment(m_backend);
  373. return BOOST_MP_MOVE(temp);
  374. }
  375. inline number operator--(int)
  376. {
  377. using default_ops::eval_decrement;
  378. self_type temp(*this);
  379. eval_decrement(m_backend);
  380. return BOOST_MP_MOVE(temp);
  381. }
  382. template <class V>
  383. BOOST_MP_FORCEINLINE typename boost::enable_if<is_integral<V>, number&>::type operator <<= (V val)
  384. {
  385. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The left-shift operation is only valid for integer types");
  386. detail::check_shift_range(val, mpl::bool_<(sizeof(V) > sizeof(std::size_t))>(), is_signed<V>());
  387. eval_left_shift(m_backend, static_cast<std::size_t>(canonical_value(val)));
  388. return *this;
  389. }
  390. template <class V>
  391. BOOST_MP_FORCEINLINE typename boost::enable_if<is_integral<V>, number&>::type operator >>= (V val)
  392. {
  393. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The right-shift operation is only valid for integer types");
  394. detail::check_shift_range(val, mpl::bool_<(sizeof(V) > sizeof(std::size_t))>(), is_signed<V>());
  395. eval_right_shift(m_backend, static_cast<std::size_t>(canonical_value(val)));
  396. return *this;
  397. }
  398. BOOST_MP_FORCEINLINE number& operator /= (const self_type& e)
  399. {
  400. do_divide(detail::expression<detail::terminal, self_type>(e), detail::terminal());
  401. return *this;
  402. }
  403. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  404. typename boost::enable_if<is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>, number&>::type operator/=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
  405. {
  406. // Create a temporary if the RHS references *this:
  407. if(contains_self(e))
  408. {
  409. self_type temp(e);
  410. do_divide(detail::expression<detail::terminal, self_type>(temp), detail::terminal());
  411. }
  412. else
  413. {
  414. do_divide(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type());
  415. }
  416. return *this;
  417. }
  418. template <class V>
  419. BOOST_MP_FORCEINLINE typename boost::enable_if<boost::is_convertible<V, self_type>, number<Backend, ExpressionTemplates>& >::type
  420. operator/=(const V& v)
  421. {
  422. using default_ops::eval_divide;
  423. eval_divide(m_backend, canonical_value(v));
  424. return *this;
  425. }
  426. BOOST_MP_FORCEINLINE number& operator&=(const self_type& e)
  427. {
  428. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise & operation is only valid for integer types");
  429. do_bitwise_and(detail::expression<detail::terminal, self_type>(e), detail::terminal());
  430. return *this;
  431. }
  432. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  433. typename boost::enable_if<is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>, number&>::type operator&=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
  434. {
  435. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise & operation is only valid for integer types");
  436. // Create a temporary if the RHS references *this, but not
  437. // if we're just doing an x &= x;
  438. if(contains_self(e) && !is_self(e))
  439. {
  440. self_type temp(e);
  441. do_bitwise_and(detail::expression<detail::terminal, self_type>(temp), detail::terminal());
  442. }
  443. else
  444. {
  445. do_bitwise_and(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type());
  446. }
  447. return *this;
  448. }
  449. template <class V>
  450. BOOST_MP_FORCEINLINE typename boost::enable_if<boost::is_convertible<V, self_type>, number<Backend, ExpressionTemplates>& >::type
  451. operator&=(const V& v)
  452. {
  453. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise & operation is only valid for integer types");
  454. using default_ops::eval_bitwise_and;
  455. eval_bitwise_and(m_backend, canonical_value(v));
  456. return *this;
  457. }
  458. BOOST_MP_FORCEINLINE number& operator|=(const self_type& e)
  459. {
  460. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise | operation is only valid for integer types");
  461. do_bitwise_or(detail::expression<detail::terminal, self_type>(e), detail::terminal());
  462. return *this;
  463. }
  464. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  465. typename boost::enable_if<is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>, number&>::type operator|=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
  466. {
  467. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise | operation is only valid for integer types");
  468. // Create a temporary if the RHS references *this, but not
  469. // if we're just doing an x |= x;
  470. if(contains_self(e) && !is_self(e))
  471. {
  472. self_type temp(e);
  473. do_bitwise_or(detail::expression<detail::terminal, self_type>(temp), detail::terminal());
  474. }
  475. else
  476. {
  477. do_bitwise_or(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type());
  478. }
  479. return *this;
  480. }
  481. template <class V>
  482. BOOST_MP_FORCEINLINE typename boost::enable_if<boost::is_convertible<V, self_type>, number<Backend, ExpressionTemplates>& >::type
  483. operator|=(const V& v)
  484. {
  485. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise | operation is only valid for integer types");
  486. using default_ops::eval_bitwise_or;
  487. eval_bitwise_or(m_backend, canonical_value(v));
  488. return *this;
  489. }
  490. BOOST_MP_FORCEINLINE number& operator^=(const self_type& e)
  491. {
  492. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise ^ operation is only valid for integer types");
  493. do_bitwise_xor(detail::expression<detail::terminal, self_type>(e), detail::terminal());
  494. return *this;
  495. }
  496. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  497. typename boost::enable_if<is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>, number&>::type operator^=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
  498. {
  499. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise ^ operation is only valid for integer types");
  500. if(contains_self(e))
  501. {
  502. self_type temp(e);
  503. do_bitwise_xor(detail::expression<detail::terminal, self_type>(temp), detail::terminal());
  504. }
  505. else
  506. {
  507. do_bitwise_xor(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type());
  508. }
  509. return *this;
  510. }
  511. template <class V>
  512. BOOST_MP_FORCEINLINE typename boost::enable_if<boost::is_convertible<V, self_type>, number<Backend, ExpressionTemplates>& >::type
  513. operator^=(const V& v)
  514. {
  515. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise ^ operation is only valid for integer types");
  516. using default_ops::eval_bitwise_xor;
  517. eval_bitwise_xor(m_backend, canonical_value(v));
  518. return *this;
  519. }
  520. //
  521. // swap:
  522. //
  523. BOOST_MP_FORCEINLINE void swap(self_type& other) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend>().swap(std::declval<Backend&>())))
  524. {
  525. m_backend.swap(other.backend());
  526. }
  527. //
  528. // Zero and sign:
  529. //
  530. BOOST_MP_FORCEINLINE bool is_zero()const
  531. {
  532. using default_ops::eval_is_zero;
  533. return eval_is_zero(m_backend);
  534. }
  535. BOOST_MP_FORCEINLINE int sign()const
  536. {
  537. using default_ops::eval_get_sign;
  538. return eval_get_sign(m_backend);
  539. }
  540. //
  541. // String conversion functions:
  542. //
  543. std::string str(std::streamsize digits = 0, std::ios_base::fmtflags f = std::ios_base::fmtflags(0))const
  544. {
  545. return m_backend.str(digits, f);
  546. }
  547. template<class Archive>
  548. void serialize(Archive & ar, const unsigned int /*version*/)
  549. {
  550. ar & m_backend;
  551. }
  552. private:
  553. template <class T>
  554. void convert_to_imp(T* result)const
  555. {
  556. using default_ops::eval_convert_to;
  557. eval_convert_to(result, m_backend);
  558. }
  559. template <class B2, expression_template_option ET>
  560. void convert_to_imp(number<B2, ET>* result)const
  561. {
  562. result->assign(*this);
  563. }
  564. void convert_to_imp(std::string* result)const
  565. {
  566. *result = this->str();
  567. }
  568. public:
  569. template <class T>
  570. T convert_to()const
  571. {
  572. T result;
  573. convert_to_imp(&result);
  574. return result;
  575. }
  576. //
  577. // Use in boolean context, and explicit conversion operators:
  578. //
  579. #ifndef BOOST_MP_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
  580. # if (defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7) && !defined(__clang__)) || (defined(BOOST_INTEL) && (BOOST_INTEL <= 1500))
  581. //
  582. // Horrible workaround for gcc-4.6.x which always prefers the template
  583. // operator bool() rather than the non-template operator when converting to
  584. // an arithmetic type:
  585. //
  586. template <class T, typename boost::enable_if<is_same<T, bool>, int>::type = 0>
  587. explicit operator T ()const
  588. {
  589. using default_ops::eval_is_zero;
  590. return !eval_is_zero(backend());
  591. }
  592. template <class T, typename boost::disable_if_c<is_same<T, bool>::value || is_void<T>::value, int>::type = 0>
  593. explicit operator T ()const
  594. {
  595. return this->template convert_to<T>();
  596. }
  597. # else
  598. #if BOOST_WORKAROUND(BOOST_MSVC, < 1900) || (defined(__APPLE_CC__) && BOOST_WORKAROUND(__clang_major__, < 9))
  599. template <class T>
  600. #else
  601. template <class T, class = typename boost::disable_if_c<boost::is_constructible<T, self_type const&>::value || !boost::is_default_constructible<T>::value || (!boost::is_arithmetic<T>::value && !boost::is_complex<T>::value), T>::type>
  602. #endif
  603. explicit operator T ()const
  604. {
  605. return this->template convert_to<T>();
  606. }
  607. BOOST_MP_FORCEINLINE explicit operator bool()const
  608. {
  609. return !is_zero();
  610. }
  611. #if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40800)
  612. BOOST_MP_FORCEINLINE explicit operator void()const {}
  613. #endif
  614. # endif
  615. #else
  616. typedef bool (self_type::*unmentionable_type)()const;
  617. BOOST_MP_FORCEINLINE operator unmentionable_type()const
  618. {
  619. return is_zero() ? 0 : &self_type::is_zero;
  620. }
  621. #endif
  622. //
  623. // Default precision:
  624. //
  625. static unsigned default_precision() BOOST_NOEXCEPT
  626. {
  627. return Backend::default_precision();
  628. }
  629. static void default_precision(unsigned digits10)
  630. {
  631. Backend::default_precision(digits10);
  632. }
  633. unsigned precision()const BOOST_NOEXCEPT
  634. {
  635. return m_backend.precision();
  636. }
  637. void precision(unsigned digits10)
  638. {
  639. m_backend.precision(digits10);
  640. }
  641. //
  642. // Comparison:
  643. //
  644. BOOST_MP_FORCEINLINE int compare(const number<Backend, ExpressionTemplates>& o)const
  645. BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend>().compare(std::declval<Backend>())))
  646. {
  647. return m_backend.compare(o.m_backend);
  648. }
  649. template <class V>
  650. BOOST_MP_FORCEINLINE typename boost::enable_if_c<is_arithmetic<V>::value && (number_category<Backend>::value != number_kind_complex), int>::type compare(const V& o)const
  651. {
  652. using default_ops::eval_get_sign;
  653. if(o == 0)
  654. return eval_get_sign(m_backend);
  655. return m_backend.compare(canonical_value(o));
  656. }
  657. template <class V>
  658. BOOST_MP_FORCEINLINE typename boost::enable_if_c<is_arithmetic<V>::value && (number_category<Backend>::value == number_kind_complex), int>::type compare(const V& o)const
  659. {
  660. using default_ops::eval_get_sign;
  661. return m_backend.compare(canonical_value(o));
  662. }
  663. //
  664. // Direct access to the underlying backend:
  665. //
  666. BOOST_MP_FORCEINLINE Backend& backend() BOOST_NOEXCEPT
  667. {
  668. return m_backend;
  669. }
  670. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const Backend& backend()const BOOST_NOEXCEPT
  671. {
  672. return m_backend;
  673. }
  674. //
  675. // Complex number real and imag:
  676. //
  677. typename scalar_result_from_possible_complex<number<Backend, ExpressionTemplates> >::type
  678. real()const
  679. {
  680. using default_ops::eval_real;
  681. typename scalar_result_from_possible_complex<multiprecision::number<Backend, ExpressionTemplates> >::type result;
  682. eval_real(result.backend(), backend());
  683. return result;
  684. }
  685. typename scalar_result_from_possible_complex<number<Backend, ExpressionTemplates> >::type
  686. imag()const
  687. {
  688. using default_ops::eval_imag;
  689. typename scalar_result_from_possible_complex<multiprecision::number<Backend, ExpressionTemplates> >::type result;
  690. eval_imag(result.backend(), backend());
  691. return result;
  692. }
  693. template <class T>
  694. inline typename enable_if_c<boost::is_convertible<T, self_type>::value, self_type&>::type real(const T& val)
  695. {
  696. using default_ops::eval_set_real;
  697. eval_set_real(backend(), canonical_value(val));
  698. return *this;
  699. }
  700. template <class T>
  701. inline typename enable_if_c<boost::is_convertible<T, self_type>::value && number_category<self_type>::value == number_kind_complex, self_type&>::type imag(const T& val)
  702. {
  703. using default_ops::eval_set_imag;
  704. eval_set_imag(backend(), canonical_value(val));
  705. return *this;
  706. }
  707. private:
  708. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  709. void do_assign(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e, const mpl::true_&)
  710. {
  711. do_assign(e, tag());
  712. }
  713. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  714. void do_assign(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e, const mpl::false_&)
  715. {
  716. // The result of the expression isn't the same type as this -
  717. // create a temporary result and assign it to *this:
  718. typedef typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type temp_type;
  719. temp_type t(e);
  720. this->assign(t);
  721. }
  722. template <class Exp>
  723. void do_assign(const Exp& e, const detail::add_immediates&)
  724. {
  725. using default_ops::eval_add;
  726. eval_add(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
  727. }
  728. template <class Exp>
  729. void do_assign(const Exp& e, const detail::subtract_immediates&)
  730. {
  731. using default_ops::eval_subtract;
  732. eval_subtract(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
  733. }
  734. template <class Exp>
  735. void do_assign(const Exp& e, const detail::multiply_immediates&)
  736. {
  737. using default_ops::eval_multiply;
  738. eval_multiply(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
  739. }
  740. template <class Exp>
  741. void do_assign(const Exp& e, const detail::multiply_add&)
  742. {
  743. using default_ops::eval_multiply_add;
  744. eval_multiply_add(m_backend, canonical_value(e.left().value()), canonical_value(e.middle().value()), canonical_value(e.right().value()));
  745. }
  746. template <class Exp>
  747. void do_assign(const Exp& e, const detail::multiply_subtract&)
  748. {
  749. using default_ops::eval_multiply_subtract;
  750. eval_multiply_subtract(m_backend, canonical_value(e.left().value()), canonical_value(e.middle().value()), canonical_value(e.right().value()));
  751. }
  752. template <class Exp>
  753. void do_assign(const Exp& e, const detail::divide_immediates&)
  754. {
  755. using default_ops::eval_divide;
  756. eval_divide(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
  757. }
  758. template <class Exp>
  759. void do_assign(const Exp& e, const detail::negate&)
  760. {
  761. typedef typename Exp::left_type left_type;
  762. do_assign(e.left(), typename left_type::tag_type());
  763. m_backend.negate();
  764. }
  765. template <class Exp>
  766. void do_assign(const Exp& e, const detail::plus&)
  767. {
  768. typedef typename Exp::left_type left_type;
  769. typedef typename Exp::right_type right_type;
  770. static int const left_depth = left_type::depth;
  771. static int const right_depth = right_type::depth;
  772. bool bl = contains_self(e.left());
  773. bool br = contains_self(e.right());
  774. if(bl && br)
  775. {
  776. self_type temp(e);
  777. temp.m_backend.swap(this->m_backend);
  778. }
  779. else if(bl && is_self(e.left()))
  780. {
  781. // Ignore the left node, it's *this, just add the right:
  782. do_add(e.right(), typename right_type::tag_type());
  783. }
  784. else if(br && is_self(e.right()))
  785. {
  786. // Ignore the right node, it's *this, just add the left:
  787. do_add(e.left(), typename left_type::tag_type());
  788. }
  789. else if(!br && (bl || (left_depth >= right_depth)))
  790. { // br is always false, but if bl is true we must take the this branch:
  791. do_assign(e.left(), typename left_type::tag_type());
  792. do_add(e.right(), typename right_type::tag_type());
  793. }
  794. else
  795. {
  796. do_assign(e.right(), typename right_type::tag_type());
  797. do_add(e.left(), typename left_type::tag_type());
  798. }
  799. }
  800. template <class Exp>
  801. void do_assign(const Exp& e, const detail::minus&)
  802. {
  803. typedef typename Exp::left_type left_type;
  804. typedef typename Exp::right_type right_type;
  805. static int const left_depth = left_type::depth;
  806. static int const right_depth = right_type::depth;
  807. bool bl = contains_self(e.left());
  808. bool br = contains_self(e.right());
  809. if(bl && br)
  810. {
  811. self_type temp(e);
  812. temp.m_backend.swap(this->m_backend);
  813. }
  814. else if(bl && is_self(e.left()))
  815. {
  816. // Ignore the left node, it's *this, just subtract the right:
  817. do_subtract(e.right(), typename right_type::tag_type());
  818. }
  819. else if(br && is_self(e.right()))
  820. {
  821. // Ignore the right node, it's *this, just subtract the left and negate the result:
  822. do_subtract(e.left(), typename left_type::tag_type());
  823. m_backend.negate();
  824. }
  825. else if(!br && (bl || (left_depth >= right_depth)))
  826. { // br is always false, but if bl is true we must take the this branch:
  827. do_assign(e.left(), typename left_type::tag_type());
  828. do_subtract(e.right(), typename right_type::tag_type());
  829. }
  830. else
  831. {
  832. do_assign(e.right(), typename right_type::tag_type());
  833. do_subtract(e.left(), typename left_type::tag_type());
  834. m_backend.negate();
  835. }
  836. }
  837. template <class Exp>
  838. void do_assign(const Exp& e, const detail::multiplies&)
  839. {
  840. typedef typename Exp::left_type left_type;
  841. typedef typename Exp::right_type right_type;
  842. static int const left_depth = left_type::depth;
  843. static int const right_depth = right_type::depth;
  844. bool bl = contains_self(e.left());
  845. bool br = contains_self(e.right());
  846. if(bl && br)
  847. {
  848. self_type temp(e);
  849. temp.m_backend.swap(this->m_backend);
  850. }
  851. else if(bl && is_self(e.left()))
  852. {
  853. // Ignore the left node, it's *this, just add the right:
  854. do_multiplies(e.right(), typename right_type::tag_type());
  855. }
  856. else if(br && is_self(e.right()))
  857. {
  858. // Ignore the right node, it's *this, just add the left:
  859. do_multiplies(e.left(), typename left_type::tag_type());
  860. }
  861. else if(!br && (bl || (left_depth >= right_depth)))
  862. { // br is always false, but if bl is true we must take the this branch:
  863. do_assign(e.left(), typename left_type::tag_type());
  864. do_multiplies(e.right(), typename right_type::tag_type());
  865. }
  866. else
  867. {
  868. do_assign(e.right(), typename right_type::tag_type());
  869. do_multiplies(e.left(), typename left_type::tag_type());
  870. }
  871. }
  872. template <class Exp>
  873. void do_assign(const Exp& e, const detail::divides&)
  874. {
  875. typedef typename Exp::left_type left_type;
  876. typedef typename Exp::right_type right_type;
  877. bool bl = contains_self(e.left());
  878. bool br = contains_self(e.right());
  879. if(bl && is_self(e.left()))
  880. {
  881. // Ignore the left node, it's *this, just add the right:
  882. do_divide(e.right(), typename right_type::tag_type());
  883. }
  884. else if(br)
  885. {
  886. self_type temp(e);
  887. temp.m_backend.swap(this->m_backend);
  888. }
  889. else
  890. {
  891. do_assign(e.left(), typename left_type::tag_type());
  892. do_divide(e.right(), typename right_type::tag_type());
  893. }
  894. }
  895. template <class Exp>
  896. void do_assign(const Exp& e, const detail::modulus&)
  897. {
  898. //
  899. // This operation is only valid for integer backends:
  900. //
  901. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
  902. typedef typename Exp::left_type left_type;
  903. typedef typename Exp::right_type right_type;
  904. bool bl = contains_self(e.left());
  905. bool br = contains_self(e.right());
  906. if(bl && is_self(e.left()))
  907. {
  908. // Ignore the left node, it's *this, just add the right:
  909. do_modulus(e.right(), typename right_type::tag_type());
  910. }
  911. else if(br)
  912. {
  913. self_type temp(e);
  914. temp.m_backend.swap(this->m_backend);
  915. }
  916. else
  917. {
  918. do_assign(e.left(), typename left_type::tag_type());
  919. do_modulus(e.right(), typename right_type::tag_type());
  920. }
  921. }
  922. template <class Exp>
  923. void do_assign(const Exp& e, const detail::modulus_immediates&)
  924. {
  925. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
  926. using default_ops::eval_modulus;
  927. eval_modulus(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
  928. }
  929. template <class Exp>
  930. void do_assign(const Exp& e, const detail::bitwise_and&)
  931. {
  932. //
  933. // This operation is only valid for integer backends:
  934. //
  935. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types");
  936. typedef typename Exp::left_type left_type;
  937. typedef typename Exp::right_type right_type;
  938. static int const left_depth = left_type::depth;
  939. static int const right_depth = right_type::depth;
  940. bool bl = contains_self(e.left());
  941. bool br = contains_self(e.right());
  942. if(bl && is_self(e.left()))
  943. {
  944. // Ignore the left node, it's *this, just add the right:
  945. do_bitwise_and(e.right(), typename right_type::tag_type());
  946. }
  947. else if(br && is_self(e.right()))
  948. {
  949. do_bitwise_and(e.left(), typename left_type::tag_type());
  950. }
  951. else if(!br && (bl || (left_depth >= right_depth)))
  952. {
  953. do_assign(e.left(), typename left_type::tag_type());
  954. do_bitwise_and(e.right(), typename right_type::tag_type());
  955. }
  956. else
  957. {
  958. do_assign(e.right(), typename right_type::tag_type());
  959. do_bitwise_and(e.left(), typename left_type::tag_type());
  960. }
  961. }
  962. template <class Exp>
  963. void do_assign(const Exp& e, const detail::bitwise_and_immediates&)
  964. {
  965. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types");
  966. using default_ops::eval_bitwise_and;
  967. eval_bitwise_and(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
  968. }
  969. template <class Exp>
  970. void do_assign(const Exp& e, const detail::bitwise_or&)
  971. {
  972. //
  973. // This operation is only valid for integer backends:
  974. //
  975. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types");
  976. typedef typename Exp::left_type left_type;
  977. typedef typename Exp::right_type right_type;
  978. static int const left_depth = left_type::depth;
  979. static int const right_depth = right_type::depth;
  980. bool bl = contains_self(e.left());
  981. bool br = contains_self(e.right());
  982. if(bl && is_self(e.left()))
  983. {
  984. // Ignore the left node, it's *this, just add the right:
  985. do_bitwise_or(e.right(), typename right_type::tag_type());
  986. }
  987. else if(br && is_self(e.right()))
  988. {
  989. do_bitwise_or(e.left(), typename left_type::tag_type());
  990. }
  991. else if(!br && (bl || (left_depth >= right_depth)))
  992. {
  993. do_assign(e.left(), typename left_type::tag_type());
  994. do_bitwise_or(e.right(), typename right_type::tag_type());
  995. }
  996. else
  997. {
  998. do_assign(e.right(), typename right_type::tag_type());
  999. do_bitwise_or(e.left(), typename left_type::tag_type());
  1000. }
  1001. }
  1002. template <class Exp>
  1003. void do_assign(const Exp& e, const detail::bitwise_or_immediates&)
  1004. {
  1005. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types");
  1006. using default_ops::eval_bitwise_or;
  1007. eval_bitwise_or(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
  1008. }
  1009. template <class Exp>
  1010. void do_assign(const Exp& e, const detail::bitwise_xor&)
  1011. {
  1012. //
  1013. // This operation is only valid for integer backends:
  1014. //
  1015. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types");
  1016. typedef typename Exp::left_type left_type;
  1017. typedef typename Exp::right_type right_type;
  1018. static int const left_depth = left_type::depth;
  1019. static int const right_depth = right_type::depth;
  1020. bool bl = contains_self(e.left());
  1021. bool br = contains_self(e.right());
  1022. if(bl && is_self(e.left()))
  1023. {
  1024. // Ignore the left node, it's *this, just add the right:
  1025. do_bitwise_xor(e.right(), typename right_type::tag_type());
  1026. }
  1027. else if(br && is_self(e.right()))
  1028. {
  1029. do_bitwise_xor(e.left(), typename left_type::tag_type());
  1030. }
  1031. else if(!br && (bl || (left_depth >= right_depth)))
  1032. {
  1033. do_assign(e.left(), typename left_type::tag_type());
  1034. do_bitwise_xor(e.right(), typename right_type::tag_type());
  1035. }
  1036. else
  1037. {
  1038. do_assign(e.right(), typename right_type::tag_type());
  1039. do_bitwise_xor(e.left(), typename left_type::tag_type());
  1040. }
  1041. }
  1042. template <class Exp>
  1043. void do_assign(const Exp& e, const detail::bitwise_xor_immediates&)
  1044. {
  1045. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types");
  1046. using default_ops::eval_bitwise_xor;
  1047. eval_bitwise_xor(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
  1048. }
  1049. template <class Exp>
  1050. void do_assign(const Exp& e, const detail::terminal&)
  1051. {
  1052. if(!is_self(e))
  1053. {
  1054. m_backend = canonical_value(e.value());
  1055. }
  1056. }
  1057. template <class Exp>
  1058. void do_assign(const Exp& e, const detail::function&)
  1059. {
  1060. typedef typename Exp::arity tag_type;
  1061. do_assign_function(e, tag_type());
  1062. }
  1063. template <class Exp>
  1064. void do_assign(const Exp& e, const detail::shift_left&)
  1065. {
  1066. // We can only shift by an integer value, not an arbitrary expression:
  1067. typedef typename Exp::left_type left_type;
  1068. typedef typename Exp::right_type right_type;
  1069. typedef typename right_type::arity right_arity;
  1070. BOOST_STATIC_ASSERT_MSG(right_arity::value == 0, "The left shift operator requires an integer value for the shift operand.");
  1071. typedef typename right_type::result_type right_value_type;
  1072. BOOST_STATIC_ASSERT_MSG(is_integral<right_value_type>::value, "The left shift operator requires an integer value for the shift operand.");
  1073. typedef typename left_type::tag_type tag_type;
  1074. do_assign_left_shift(e.left(), canonical_value(e.right().value()), tag_type());
  1075. }
  1076. template <class Exp>
  1077. void do_assign(const Exp& e, const detail::shift_right&)
  1078. {
  1079. // We can only shift by an integer value, not an arbitrary expression:
  1080. typedef typename Exp::left_type left_type;
  1081. typedef typename Exp::right_type right_type;
  1082. typedef typename right_type::arity right_arity;
  1083. BOOST_STATIC_ASSERT_MSG(right_arity::value == 0, "The left shift operator requires an integer value for the shift operand.");
  1084. typedef typename right_type::result_type right_value_type;
  1085. BOOST_STATIC_ASSERT_MSG(is_integral<right_value_type>::value, "The left shift operator requires an integer value for the shift operand.");
  1086. typedef typename left_type::tag_type tag_type;
  1087. do_assign_right_shift(e.left(), canonical_value(e.right().value()), tag_type());
  1088. }
  1089. template <class Exp>
  1090. void do_assign(const Exp& e, const detail::bitwise_complement&)
  1091. {
  1092. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise ~ operation is only valid for integer types");
  1093. using default_ops::eval_complement;
  1094. self_type temp(e.left());
  1095. eval_complement(m_backend, temp.backend());
  1096. }
  1097. template <class Exp>
  1098. void do_assign(const Exp& e, const detail::complement_immediates&)
  1099. {
  1100. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise ~ operation is only valid for integer types");
  1101. using default_ops::eval_complement;
  1102. eval_complement(m_backend, canonical_value(e.left().value()));
  1103. }
  1104. template <class Exp, class Val>
  1105. void do_assign_right_shift(const Exp& e, const Val& val, const detail::terminal&)
  1106. {
  1107. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The right shift operation is only valid for integer types");
  1108. using default_ops::eval_right_shift;
  1109. detail::check_shift_range(val, mpl::bool_<(sizeof(Val) > sizeof(std::size_t))>(), is_signed<Val>());
  1110. eval_right_shift(m_backend, canonical_value(e.value()), static_cast<std::size_t>(val));
  1111. }
  1112. template <class Exp, class Val>
  1113. void do_assign_left_shift(const Exp& e, const Val& val, const detail::terminal&)
  1114. {
  1115. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The left shift operation is only valid for integer types");
  1116. using default_ops::eval_left_shift;
  1117. detail::check_shift_range(val, mpl::bool_<(sizeof(Val) > sizeof(std::size_t))>(), is_signed<Val>());
  1118. eval_left_shift(m_backend, canonical_value(e.value()), static_cast<std::size_t>(val));
  1119. }
  1120. template <class Exp, class Val, class Tag>
  1121. void do_assign_right_shift(const Exp& e, const Val& val, const Tag&)
  1122. {
  1123. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The right shift operation is only valid for integer types");
  1124. using default_ops::eval_right_shift;
  1125. self_type temp(e);
  1126. detail::check_shift_range(val, mpl::bool_<(sizeof(Val) > sizeof(std::size_t))>(), is_signed<Val>());
  1127. eval_right_shift(m_backend, temp.backend(), static_cast<std::size_t>(val));
  1128. }
  1129. template <class Exp, class Val, class Tag>
  1130. void do_assign_left_shift(const Exp& e, const Val& val, const Tag&)
  1131. {
  1132. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The left shift operation is only valid for integer types");
  1133. using default_ops::eval_left_shift;
  1134. self_type temp(e);
  1135. detail::check_shift_range(val, mpl::bool_<(sizeof(Val) > sizeof(std::size_t))>(), is_signed<Val>());
  1136. eval_left_shift(m_backend, temp.backend(), static_cast<std::size_t>(val));
  1137. }
  1138. template <class Exp>
  1139. void do_assign_function(const Exp& e, const mpl::int_<1>&)
  1140. {
  1141. e.left().value()(&m_backend);
  1142. }
  1143. template <class Exp>
  1144. void do_assign_function(const Exp& e, const mpl::int_<2>&)
  1145. {
  1146. typedef typename Exp::right_type right_type;
  1147. typedef typename right_type::tag_type tag_type;
  1148. do_assign_function_1(e.left().value(), e.right_ref(), tag_type());
  1149. }
  1150. template <class F, class Exp>
  1151. void do_assign_function_1(const F& f, const Exp& val, const detail::terminal&)
  1152. {
  1153. f(m_backend, function_arg_value(val));
  1154. }
  1155. template <class F, class Exp, class Tag>
  1156. void do_assign_function_1(const F& f, const Exp& val, const Tag&)
  1157. {
  1158. typename Exp::result_type t(val);
  1159. f(m_backend, t.backend());
  1160. }
  1161. template <class Exp>
  1162. void do_assign_function(const Exp& e, const mpl::int_<3>&)
  1163. {
  1164. typedef typename Exp::middle_type middle_type;
  1165. typedef typename middle_type::tag_type tag_type;
  1166. typedef typename Exp::right_type end_type;
  1167. typedef typename end_type::tag_type end_tag;
  1168. do_assign_function_2(e.left().value(), e.middle_ref(), e.right_ref(), tag_type(), end_tag());
  1169. }
  1170. template <class F, class Exp1, class Exp2>
  1171. void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const detail::terminal&, const detail::terminal&)
  1172. {
  1173. f(m_backend, function_arg_value(val1), function_arg_value(val2));
  1174. }
  1175. template <class F, class Exp1, class Exp2, class Tag1>
  1176. void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const Tag1&, const detail::terminal&)
  1177. {
  1178. typename Exp1::result_type temp1(val1);
  1179. f(m_backend, BOOST_MP_MOVE(temp1.backend()), function_arg_value(val2));
  1180. }
  1181. template <class F, class Exp1, class Exp2, class Tag2>
  1182. void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const detail::terminal&, const Tag2&)
  1183. {
  1184. typename Exp2::result_type temp2(val2);
  1185. f(m_backend, function_arg_value(val1), BOOST_MP_MOVE(temp2.backend()));
  1186. }
  1187. template <class F, class Exp1, class Exp2, class Tag1, class Tag2>
  1188. void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const Tag1&, const Tag2&)
  1189. {
  1190. typename Exp1::result_type temp1(val1);
  1191. typename Exp2::result_type temp2(val2);
  1192. f(m_backend, BOOST_MP_MOVE(temp1.backend()), BOOST_MP_MOVE(temp2.backend()));
  1193. }
  1194. template <class Exp>
  1195. void do_assign_function(const Exp& e, const mpl::int_<4>&)
  1196. {
  1197. typedef typename Exp::left_middle_type left_type;
  1198. typedef typename left_type::tag_type left_tag_type;
  1199. typedef typename Exp::right_middle_type middle_type;
  1200. typedef typename middle_type::tag_type middle_tag_type;
  1201. typedef typename Exp::right_type right_type;
  1202. typedef typename right_type::tag_type right_tag_type;
  1203. do_assign_function_3a(e.left().value(), e.left_middle_ref(), e.right_middle_ref(), e.right_ref(), left_tag_type(), middle_tag_type(), right_tag_type());
  1204. }
  1205. template <class F, class Exp1, class Exp2, class Exp3, class Tag2, class Tag3>
  1206. void do_assign_function_3a(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const detail::terminal&, const Tag2& t2, const Tag3& t3)
  1207. {
  1208. do_assign_function_3b(f, val1, val2, val3, t2, t3);
  1209. }
  1210. template <class F, class Exp1, class Exp2, class Exp3, class Tag1, class Tag2, class Tag3>
  1211. void do_assign_function_3a(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const Tag1&, const Tag2& t2, const Tag3& t3)
  1212. {
  1213. typename Exp1::result_type t(val1);
  1214. do_assign_function_3b(f, BOOST_MP_MOVE(t), val2, val3, t2, t3);
  1215. }
  1216. template <class F, class Exp1, class Exp2, class Exp3, class Tag3>
  1217. void do_assign_function_3b(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const detail::terminal&, const Tag3& t3)
  1218. {
  1219. do_assign_function_3c(f, val1, val2, val3, t3);
  1220. }
  1221. template <class F, class Exp1, class Exp2, class Exp3, class Tag2, class Tag3>
  1222. void do_assign_function_3b(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const Tag2& /*t2*/, const Tag3& t3)
  1223. {
  1224. typename Exp2::result_type t(val2);
  1225. do_assign_function_3c(f, val1, BOOST_MP_MOVE(t), val3, t3);
  1226. }
  1227. template <class F, class Exp1, class Exp2, class Exp3>
  1228. void do_assign_function_3c(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const detail::terminal&)
  1229. {
  1230. f(m_backend, function_arg_value(val1), function_arg_value(val2), function_arg_value(val3));
  1231. }
  1232. template <class F, class Exp1, class Exp2, class Exp3, class Tag3>
  1233. void do_assign_function_3c(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const Tag3& /*t3*/)
  1234. {
  1235. typename Exp3::result_type t(val3);
  1236. do_assign_function_3c(f, val1, val2, BOOST_MP_MOVE(t), detail::terminal());
  1237. }
  1238. template <class Exp>
  1239. void do_add(const Exp& e, const detail::terminal&)
  1240. {
  1241. using default_ops::eval_add;
  1242. eval_add(m_backend, canonical_value(e.value()));
  1243. }
  1244. template <class Exp>
  1245. void do_add(const Exp& e, const detail::negate&)
  1246. {
  1247. typedef typename Exp::left_type left_type;
  1248. do_subtract(e.left(), typename left_type::tag_type());
  1249. }
  1250. template <class Exp>
  1251. void do_add(const Exp& e, const detail::plus&)
  1252. {
  1253. typedef typename Exp::left_type left_type;
  1254. typedef typename Exp::right_type right_type;
  1255. do_add(e.left(), typename left_type::tag_type());
  1256. do_add(e.right(), typename right_type::tag_type());
  1257. }
  1258. template <class Exp>
  1259. void do_add(const Exp& e, const detail::minus&)
  1260. {
  1261. typedef typename Exp::left_type left_type;
  1262. typedef typename Exp::right_type right_type;
  1263. do_add(e.left(), typename left_type::tag_type());
  1264. do_subtract(e.right(), typename right_type::tag_type());
  1265. }
  1266. template <class Exp, class unknown>
  1267. void do_add(const Exp& e, const unknown&)
  1268. {
  1269. self_type temp(e);
  1270. do_add(detail::expression<detail::terminal, self_type>(temp), detail::terminal());
  1271. }
  1272. template <class Exp>
  1273. void do_add(const Exp& e, const detail::add_immediates&)
  1274. {
  1275. using default_ops::eval_add;
  1276. eval_add(m_backend, canonical_value(e.left().value()));
  1277. eval_add(m_backend, canonical_value(e.right().value()));
  1278. }
  1279. template <class Exp>
  1280. void do_add(const Exp& e, const detail::subtract_immediates&)
  1281. {
  1282. using default_ops::eval_add;
  1283. using default_ops::eval_subtract;
  1284. eval_add(m_backend, canonical_value(e.left().value()));
  1285. eval_subtract(m_backend, canonical_value(e.right().value()));
  1286. }
  1287. template <class Exp>
  1288. void do_subtract(const Exp& e, const detail::terminal&)
  1289. {
  1290. using default_ops::eval_subtract;
  1291. eval_subtract(m_backend, canonical_value(e.value()));
  1292. }
  1293. template <class Exp>
  1294. void do_subtract(const Exp& e, const detail::negate&)
  1295. {
  1296. typedef typename Exp::left_type left_type;
  1297. do_add(e.left(), typename left_type::tag_type());
  1298. }
  1299. template <class Exp>
  1300. void do_subtract(const Exp& e, const detail::plus&)
  1301. {
  1302. typedef typename Exp::left_type left_type;
  1303. typedef typename Exp::right_type right_type;
  1304. do_subtract(e.left(), typename left_type::tag_type());
  1305. do_subtract(e.right(), typename right_type::tag_type());
  1306. }
  1307. template <class Exp>
  1308. void do_subtract(const Exp& e, const detail::minus&)
  1309. {
  1310. typedef typename Exp::left_type left_type;
  1311. typedef typename Exp::right_type right_type;
  1312. do_subtract(e.left(), typename left_type::tag_type());
  1313. do_add(e.right(), typename right_type::tag_type());
  1314. }
  1315. template <class Exp>
  1316. void do_subtract(const Exp& e, const detail::add_immediates&)
  1317. {
  1318. using default_ops::eval_subtract;
  1319. eval_subtract(m_backend, canonical_value(e.left().value()));
  1320. eval_subtract(m_backend, canonical_value(e.right().value()));
  1321. }
  1322. template <class Exp>
  1323. void do_subtract(const Exp& e, const detail::subtract_immediates&)
  1324. {
  1325. using default_ops::eval_add;
  1326. using default_ops::eval_subtract;
  1327. eval_subtract(m_backend, canonical_value(e.left().value()));
  1328. eval_add(m_backend, canonical_value(e.right().value()));
  1329. }
  1330. template <class Exp, class unknown>
  1331. void do_subtract(const Exp& e, const unknown&)
  1332. {
  1333. self_type temp(e);
  1334. do_subtract(detail::expression<detail::terminal, self_type>(temp), detail::terminal());
  1335. }
  1336. template <class Exp>
  1337. void do_multiplies(const Exp& e, const detail::terminal&)
  1338. {
  1339. using default_ops::eval_multiply;
  1340. eval_multiply(m_backend, canonical_value(e.value()));
  1341. }
  1342. template <class Exp>
  1343. void do_multiplies(const Exp& e, const detail::negate&)
  1344. {
  1345. typedef typename Exp::left_type left_type;
  1346. do_multiplies(e.left(), typename left_type::tag_type());
  1347. m_backend.negate();
  1348. }
  1349. template <class Exp>
  1350. void do_multiplies(const Exp& e, const detail::multiplies&)
  1351. {
  1352. typedef typename Exp::left_type left_type;
  1353. typedef typename Exp::right_type right_type;
  1354. do_multiplies(e.left(), typename left_type::tag_type());
  1355. do_multiplies(e.right(), typename right_type::tag_type());
  1356. }
  1357. //
  1358. // This rearrangement is disabled for integer types, the test on sizeof(Exp) is simply to make
  1359. // the disable_if dependent on the template argument (the size of 1 can never occur in practice).
  1360. //
  1361. template <class Exp>
  1362. typename boost::disable_if_c<boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer || sizeof(Exp) == 1>::type
  1363. do_multiplies(const Exp& e, const detail::divides&)
  1364. {
  1365. typedef typename Exp::left_type left_type;
  1366. typedef typename Exp::right_type right_type;
  1367. do_multiplies(e.left(), typename left_type::tag_type());
  1368. do_divide(e.right(), typename right_type::tag_type());
  1369. }
  1370. template <class Exp>
  1371. void do_multiplies(const Exp& e, const detail::multiply_immediates&)
  1372. {
  1373. using default_ops::eval_multiply;
  1374. eval_multiply(m_backend, canonical_value(e.left().value()));
  1375. eval_multiply(m_backend, canonical_value(e.right().value()));
  1376. }
  1377. //
  1378. // This rearrangement is disabled for integer types, the test on sizeof(Exp) is simply to make
  1379. // the disable_if dependent on the template argument (the size of 1 can never occur in practice).
  1380. //
  1381. template <class Exp>
  1382. typename boost::disable_if_c<boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer || sizeof(Exp) == 1>::type
  1383. do_multiplies(const Exp& e, const detail::divide_immediates&)
  1384. {
  1385. using default_ops::eval_multiply;
  1386. using default_ops::eval_divide;
  1387. eval_multiply(m_backend, canonical_value(e.left().value()));
  1388. eval_divide(m_backend, canonical_value(e.right().value()));
  1389. }
  1390. template <class Exp, class unknown>
  1391. void do_multiplies(const Exp& e, const unknown&)
  1392. {
  1393. using default_ops::eval_multiply;
  1394. self_type temp(e);
  1395. eval_multiply(m_backend, temp.m_backend);
  1396. }
  1397. template <class Exp>
  1398. void do_divide(const Exp& e, const detail::terminal&)
  1399. {
  1400. using default_ops::eval_divide;
  1401. eval_divide(m_backend, canonical_value(e.value()));
  1402. }
  1403. template <class Exp>
  1404. void do_divide(const Exp& e, const detail::negate&)
  1405. {
  1406. typedef typename Exp::left_type left_type;
  1407. do_divide(e.left(), typename left_type::tag_type());
  1408. m_backend.negate();
  1409. }
  1410. //
  1411. // This rearrangement is disabled for integer types, the test on sizeof(Exp) is simply to make
  1412. // the disable_if dependent on the template argument (the size of 1 can never occur in practice).
  1413. //
  1414. template <class Exp>
  1415. typename boost::disable_if_c<boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer || sizeof(Exp) == 1>::type
  1416. do_divide(const Exp& e, const detail::multiplies&)
  1417. {
  1418. typedef typename Exp::left_type left_type;
  1419. typedef typename Exp::right_type right_type;
  1420. do_divide(e.left(), typename left_type::tag_type());
  1421. do_divide(e.right(), typename right_type::tag_type());
  1422. }
  1423. //
  1424. // This rearrangement is disabled for integer types, the test on sizeof(Exp) is simply to make
  1425. // the disable_if dependent on the template argument (the size of 1 can never occur in practice).
  1426. //
  1427. template <class Exp>
  1428. typename boost::disable_if_c<boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer || sizeof(Exp) == 1>::type
  1429. do_divide(const Exp& e, const detail::divides&)
  1430. {
  1431. typedef typename Exp::left_type left_type;
  1432. typedef typename Exp::right_type right_type;
  1433. do_divide(e.left(), typename left_type::tag_type());
  1434. do_multiplies(e.right(), typename right_type::tag_type());
  1435. }
  1436. //
  1437. // This rearrangement is disabled for integer types, the test on sizeof(Exp) is simply to make
  1438. // the disable_if dependent on the template argument (the size of 1 can never occur in practice).
  1439. //
  1440. template <class Exp>
  1441. typename boost::disable_if_c<boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer || sizeof(Exp) == 1>::type
  1442. do_divides(const Exp& e, const detail::multiply_immediates&)
  1443. {
  1444. using default_ops::eval_divide;
  1445. eval_divide(m_backend, canonical_value(e.left().value()));
  1446. eval_divide(m_backend, canonical_value(e.right().value()));
  1447. }
  1448. //
  1449. // This rearrangement is disabled for integer types, the test on sizeof(Exp) is simply to make
  1450. // the disable_if dependent on the template argument (the size of 1 can never occur in practice).
  1451. //
  1452. template <class Exp>
  1453. typename boost::disable_if_c<boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer || sizeof(Exp) == 1>::type
  1454. do_divides(const Exp& e, const detail::divide_immediates&)
  1455. {
  1456. using default_ops::eval_multiply;
  1457. using default_ops::eval_divide;
  1458. eval_divide(m_backend, canonical_value(e.left().value()));
  1459. mutiply(m_backend, canonical_value(e.right().value()));
  1460. }
  1461. template <class Exp, class unknown>
  1462. void do_divide(const Exp& e, const unknown&)
  1463. {
  1464. using default_ops::eval_multiply;
  1465. self_type temp(e);
  1466. eval_divide(m_backend, temp.m_backend);
  1467. }
  1468. template <class Exp>
  1469. void do_modulus(const Exp& e, const detail::terminal&)
  1470. {
  1471. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
  1472. using default_ops::eval_modulus;
  1473. eval_modulus(m_backend, canonical_value(e.value()));
  1474. }
  1475. template <class Exp, class Unknown>
  1476. void do_modulus(const Exp& e, const Unknown&)
  1477. {
  1478. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
  1479. using default_ops::eval_modulus;
  1480. self_type temp(e);
  1481. eval_modulus(m_backend, canonical_value(temp));
  1482. }
  1483. template <class Exp>
  1484. void do_bitwise_and(const Exp& e, const detail::terminal&)
  1485. {
  1486. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise & operation is only valid for integer types");
  1487. using default_ops::eval_bitwise_and;
  1488. eval_bitwise_and(m_backend, canonical_value(e.value()));
  1489. }
  1490. template <class Exp>
  1491. void do_bitwise_and(const Exp& e, const detail::bitwise_and&)
  1492. {
  1493. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise & operation is only valid for integer types");
  1494. typedef typename Exp::left_type left_type;
  1495. typedef typename Exp::right_type right_type;
  1496. do_bitwise_and(e.left(), typename left_type::tag_type());
  1497. do_bitwise_and(e.right(), typename right_type::tag_type());
  1498. }
  1499. template <class Exp, class unknown>
  1500. void do_bitwise_and(const Exp& e, const unknown&)
  1501. {
  1502. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise & operation is only valid for integer types");
  1503. using default_ops::eval_bitwise_and;
  1504. self_type temp(e);
  1505. eval_bitwise_and(m_backend, temp.m_backend);
  1506. }
  1507. template <class Exp>
  1508. void do_bitwise_or(const Exp& e, const detail::terminal&)
  1509. {
  1510. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise | operation is only valid for integer types");
  1511. using default_ops::eval_bitwise_or;
  1512. eval_bitwise_or(m_backend, canonical_value(e.value()));
  1513. }
  1514. template <class Exp>
  1515. void do_bitwise_or(const Exp& e, const detail::bitwise_or&)
  1516. {
  1517. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise | operation is only valid for integer types");
  1518. typedef typename Exp::left_type left_type;
  1519. typedef typename Exp::right_type right_type;
  1520. do_bitwise_or(e.left(), typename left_type::tag_type());
  1521. do_bitwise_or(e.right(), typename right_type::tag_type());
  1522. }
  1523. template <class Exp, class unknown>
  1524. void do_bitwise_or(const Exp& e, const unknown&)
  1525. {
  1526. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise | operation is only valid for integer types");
  1527. using default_ops::eval_bitwise_or;
  1528. self_type temp(e);
  1529. eval_bitwise_or(m_backend, temp.m_backend);
  1530. }
  1531. template <class Exp>
  1532. void do_bitwise_xor(const Exp& e, const detail::terminal&)
  1533. {
  1534. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise ^ operation is only valid for integer types");
  1535. using default_ops::eval_bitwise_xor;
  1536. eval_bitwise_xor(m_backend, canonical_value(e.value()));
  1537. }
  1538. template <class Exp>
  1539. void do_bitwise_xor(const Exp& e, const detail::bitwise_xor&)
  1540. {
  1541. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise ^ operation is only valid for integer types");
  1542. typedef typename Exp::left_type left_type;
  1543. typedef typename Exp::right_type right_type;
  1544. do_bitwise_xor(e.left(), typename left_type::tag_type());
  1545. do_bitwise_xor(e.right(), typename right_type::tag_type());
  1546. }
  1547. template <class Exp, class unknown>
  1548. void do_bitwise_xor(const Exp& e, const unknown&)
  1549. {
  1550. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The bitwise ^ operation is only valid for integer types");
  1551. using default_ops::eval_bitwise_xor;
  1552. self_type temp(e);
  1553. eval_bitwise_xor(m_backend, temp.m_backend);
  1554. }
  1555. // Tests if the expression contains a reference to *this:
  1556. template <class Exp>
  1557. BOOST_MP_FORCEINLINE bool contains_self(const Exp& e)const BOOST_NOEXCEPT
  1558. {
  1559. return contains_self(e, typename Exp::arity());
  1560. }
  1561. template <class Exp>
  1562. BOOST_MP_FORCEINLINE bool contains_self(const Exp& e, mpl::int_<0> const&)const BOOST_NOEXCEPT
  1563. {
  1564. return is_realy_self(e.value());
  1565. }
  1566. template <class Exp>
  1567. BOOST_MP_FORCEINLINE bool contains_self(const Exp& e, mpl::int_<1> const&)const BOOST_NOEXCEPT
  1568. {
  1569. typedef typename Exp::left_type child_type;
  1570. return contains_self(e.left(), typename child_type::arity());
  1571. }
  1572. template <class Exp>
  1573. BOOST_MP_FORCEINLINE bool contains_self(const Exp& e, mpl::int_<2> const&)const BOOST_NOEXCEPT
  1574. {
  1575. typedef typename Exp::left_type child0_type;
  1576. typedef typename Exp::right_type child1_type;
  1577. return contains_self(e.left(), typename child0_type::arity())
  1578. || contains_self(e.right(), typename child1_type::arity());
  1579. }
  1580. template <class Exp>
  1581. BOOST_MP_FORCEINLINE bool contains_self(const Exp& e, mpl::int_<3> const&)const BOOST_NOEXCEPT
  1582. {
  1583. typedef typename Exp::left_type child0_type;
  1584. typedef typename Exp::middle_type child1_type;
  1585. typedef typename Exp::right_type child2_type;
  1586. return contains_self(e.left(), typename child0_type::arity())
  1587. || contains_self(e.middle(), typename child1_type::arity())
  1588. || contains_self(e.right(), typename child2_type::arity());
  1589. }
  1590. // Test if the expression is a reference to *this:
  1591. template <class Exp>
  1592. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool is_self(const Exp& e)const BOOST_NOEXCEPT
  1593. {
  1594. return is_self(e, typename Exp::arity());
  1595. }
  1596. template <class Exp>
  1597. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool is_self(const Exp& e, mpl::int_<0> const&)const BOOST_NOEXCEPT
  1598. {
  1599. return is_realy_self(e.value());
  1600. }
  1601. template <class Exp, int v>
  1602. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool is_self(const Exp&, mpl::int_<v> const&)const BOOST_NOEXCEPT
  1603. {
  1604. return false;
  1605. }
  1606. template <class Val>
  1607. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool is_realy_self(const Val&)const BOOST_NOEXCEPT{ return false; }
  1608. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool is_realy_self(const self_type& v)const BOOST_NOEXCEPT{ return &v == this; }
  1609. static BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const Backend& function_arg_value(const self_type& v) BOOST_NOEXCEPT { return v.backend(); }
  1610. template <class Other, expression_template_option ET2>
  1611. static BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const Other& function_arg_value(const number<Other, ET2>& v) BOOST_NOEXCEPT { return v.backend(); }
  1612. template <class V>
  1613. static BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const V& function_arg_value(const V& v) BOOST_NOEXCEPT { return v; }
  1614. template <class A1, class A2, class A3, class A4>
  1615. static BOOST_MP_FORCEINLINE const A1& function_arg_value(const detail::expression<detail::terminal, A1, A2, A3, A4>& exp) BOOST_NOEXCEPT { return exp.value(); }
  1616. template <class A2, class A3, class A4>
  1617. static BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const Backend& function_arg_value(const detail::expression<detail::terminal, number<Backend>, A2, A3, A4>& exp) BOOST_NOEXCEPT { return exp.value().backend(); }
  1618. Backend m_backend;
  1619. public:
  1620. //
  1621. // These shouldn't really need to be public, or even member functions, but it makes implementing
  1622. // the non-member operators way easier if they are:
  1623. //
  1624. static BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const Backend& canonical_value(const self_type& v) BOOST_NOEXCEPT { return v.m_backend; }
  1625. template <class B2, expression_template_option ET>
  1626. static BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const B2& canonical_value(const number<B2, ET>& v) BOOST_NOEXCEPT { return v.backend(); }
  1627. template <class V>
  1628. static BOOST_MP_FORCEINLINE BOOST_CONSTEXPR typename boost::disable_if<is_same<typename detail::canonical<V, Backend>::type, V>, typename detail::canonical<V, Backend>::type>::type
  1629. canonical_value(const V& v) BOOST_NOEXCEPT { return static_cast<typename detail::canonical<V, Backend>::type>(v); }
  1630. template <class V>
  1631. static BOOST_MP_FORCEINLINE BOOST_CONSTEXPR typename boost::enable_if<is_same<typename detail::canonical<V, Backend>::type, V>, const V&>::type
  1632. canonical_value(const V& v) BOOST_NOEXCEPT { return v; }
  1633. static BOOST_MP_FORCEINLINE typename detail::canonical<std::string, Backend>::type canonical_value(const std::string& v) BOOST_NOEXCEPT { return v.c_str(); }
  1634. };
  1635. template <class Backend, expression_template_option ExpressionTemplates>
  1636. inline std::ostream& operator << (std::ostream& os, const number<Backend, ExpressionTemplates>& r)
  1637. {
  1638. std::streamsize d = os.precision();
  1639. std::string s = r.str(d, os.flags());
  1640. std::streamsize ss = os.width();
  1641. if(ss > static_cast<std::streamsize>(s.size()))
  1642. {
  1643. char fill = os.fill();
  1644. if((os.flags() & std::ios_base::left) == std::ios_base::left)
  1645. s.append(static_cast<std::string::size_type>(ss - s.size()), fill);
  1646. else
  1647. s.insert(static_cast<std::string::size_type>(0), static_cast<std::string::size_type>(ss - s.size()), fill);
  1648. }
  1649. return os << s;
  1650. }
  1651. namespace detail{
  1652. template <class tag, class A1, class A2, class A3, class A4>
  1653. inline std::ostream& operator << (std::ostream& os, const expression<tag, A1, A2, A3, A4>& r)
  1654. {
  1655. typedef typename expression<tag, A1, A2, A3, A4>::result_type value_type;
  1656. value_type temp(r);
  1657. return os << temp;
  1658. }
  1659. //
  1660. // What follows is the input streaming code: this is not "proper" iostream code at all
  1661. // but that's fiendishly hard to write when dealing with multiple backends all
  1662. // with different requirements... yes we could deligate this to the backend author...
  1663. // but we really want backends to be EASY to write!
  1664. // For now just pull in all the characters that could possibly form the number
  1665. // and let the backend's string parser make use of it. This fixes most use cases
  1666. // including CSV type formats such as those used by the Random lib.
  1667. //
  1668. inline std::string read_string_while(std::istream& is, std::string const& permitted_chars)
  1669. {
  1670. std::ios_base::iostate state = std::ios_base::goodbit;
  1671. const std::istream::sentry sentry_check(is);
  1672. std::string result;
  1673. if(sentry_check)
  1674. {
  1675. int c = is.rdbuf()->sgetc();
  1676. for(;; c = is.rdbuf()->snextc())
  1677. if(std::istream::traits_type::eq_int_type(std::istream::traits_type::eof(), c))
  1678. { // end of file:
  1679. state |= std::ios_base::eofbit;
  1680. break;
  1681. }
  1682. else if(permitted_chars.find_first_of(std::istream::traits_type::to_char_type(c)) == std::string::npos)
  1683. {
  1684. // Invalid numeric character, stop reading:
  1685. //is.rdbuf()->sputbackc(static_cast<char>(c));
  1686. break;
  1687. }
  1688. else
  1689. {
  1690. result.append(1, std::istream::traits_type::to_char_type(c));
  1691. }
  1692. }
  1693. if(!result.size())
  1694. state |= std::ios_base::failbit;
  1695. is.setstate(state);
  1696. return result;
  1697. }
  1698. } // namespace detail
  1699. template <class Backend, expression_template_option ExpressionTemplates>
  1700. inline std::istream& operator >> (std::istream& is, number<Backend, ExpressionTemplates>& r)
  1701. {
  1702. bool hex_format = (is.flags() & std::ios_base::hex) == std::ios_base::hex;
  1703. bool oct_format = (is.flags() & std::ios_base::oct) == std::ios_base::oct;
  1704. std::string s;
  1705. switch(boost::multiprecision::number_category<number<Backend, ExpressionTemplates> >::value)
  1706. {
  1707. case boost::multiprecision::number_kind_integer:
  1708. if(oct_format)
  1709. s = detail::read_string_while(is, "+-01234567");
  1710. else if(hex_format)
  1711. s = detail::read_string_while(is, "+-xXabcdefABCDEF0123456789");
  1712. else
  1713. s = detail::read_string_while(is, "+-0123456789");
  1714. break;
  1715. case boost::multiprecision::number_kind_floating_point:
  1716. s = detail::read_string_while(is, "+-eE.0123456789infINFnanNANinfinityINFINITY");
  1717. break;
  1718. default:
  1719. is >> s;
  1720. }
  1721. if(s.size())
  1722. {
  1723. if(hex_format && (number_category<Backend>::value == number_kind_integer) && ((s[0] != '0') || (s[1] != 'x')))
  1724. s.insert(s.find_first_not_of("+-"), "0x");
  1725. if(oct_format && (number_category<Backend>::value == number_kind_integer) && (s[0] != '0'))
  1726. s.insert(s.find_first_not_of("+-"), "0");
  1727. r.assign(s);
  1728. }
  1729. else if(!is.fail())
  1730. is.setstate(std::istream::failbit);
  1731. return is;
  1732. }
  1733. template <class Backend, expression_template_option ExpressionTemplates>
  1734. BOOST_MP_FORCEINLINE void swap(number<Backend, ExpressionTemplates>& a, number<Backend, ExpressionTemplates>& b)
  1735. BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<number<Backend, ExpressionTemplates>&>() = std::declval<number<Backend, ExpressionTemplates>&>()))
  1736. {
  1737. a.swap(b);
  1738. }
  1739. //
  1740. // Boost.Hash support, just call hash_value for the backend, which may or may not be supported:
  1741. //
  1742. template <class Backend, expression_template_option ExpressionTemplates>
  1743. inline std::size_t hash_value(const number<Backend, ExpressionTemplates>& val)
  1744. {
  1745. return hash_value(val.backend());
  1746. }
  1747. } // namespace multiprecision
  1748. template <class T>
  1749. class rational;
  1750. template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
  1751. inline std::istream& operator >> (std::istream& is, rational<multiprecision::number<Backend, ExpressionTemplates> >& r)
  1752. {
  1753. std::string s1;
  1754. multiprecision::number<Backend, ExpressionTemplates> v1, v2;
  1755. char c;
  1756. bool have_hex = false;
  1757. bool hex_format = (is.flags() & std::ios_base::hex) == std::ios_base::hex;
  1758. bool oct_format = (is.flags() & std::ios_base::oct) == std::ios_base::oct;
  1759. while((EOF != (c = static_cast<char>(is.peek()))) && (c == 'x' || c == 'X' || c == '-' || c == '+' || (c >= '0' && c <= '9') || (have_hex && (c >= 'a' && c <= 'f')) || (have_hex && (c >= 'A' && c <= 'F'))))
  1760. {
  1761. if(c == 'x' || c == 'X')
  1762. have_hex = true;
  1763. s1.append(1, c);
  1764. is.get();
  1765. }
  1766. if(hex_format && ((s1[0] != '0') || (s1[1] != 'x')))
  1767. s1.insert(static_cast<std::string::size_type>(0), "0x");
  1768. if(oct_format && (s1[0] != '0'))
  1769. s1.insert(static_cast<std::string::size_type>(0), "0");
  1770. v1.assign(s1);
  1771. s1.erase();
  1772. if(c == '/')
  1773. {
  1774. is.get();
  1775. while((EOF != (c = static_cast<char>(is.peek()))) && (c == 'x' || c == 'X' || c == '-' || c == '+' || (c >= '0' && c <= '9') || (have_hex && (c >= 'a' && c <= 'f')) || (have_hex && (c >= 'A' && c <= 'F'))))
  1776. {
  1777. if(c == 'x' || c == 'X')
  1778. have_hex = true;
  1779. s1.append(1, c);
  1780. is.get();
  1781. }
  1782. if(hex_format && ((s1[0] != '0') || (s1[1] != 'x')))
  1783. s1.insert(static_cast<std::string::size_type>(0), "0x");
  1784. if(oct_format && (s1[0] != '0'))
  1785. s1.insert(static_cast<std::string::size_type>(0), "0");
  1786. v2.assign(s1);
  1787. }
  1788. else
  1789. v2 = 1;
  1790. r.assign(v1, v2);
  1791. return is;
  1792. }
  1793. template <class T, multiprecision::expression_template_option ExpressionTemplates>
  1794. inline multiprecision::number<T, ExpressionTemplates> numerator(const rational<multiprecision::number<T, ExpressionTemplates> >& a)
  1795. {
  1796. return a.numerator();
  1797. }
  1798. template <class T, multiprecision::expression_template_option ExpressionTemplates>
  1799. inline multiprecision::number<T, ExpressionTemplates> denominator(const rational<multiprecision::number<T, ExpressionTemplates> >& a)
  1800. {
  1801. return a.denominator();
  1802. }
  1803. template <class T, multiprecision::expression_template_option ExpressionTemplates>
  1804. inline std::size_t hash_value(const rational<multiprecision::number<T, ExpressionTemplates> >& val)
  1805. {
  1806. std::size_t result = hash_value(val.numerator());
  1807. boost::hash_combine(result, hash_value(val.denominator()));
  1808. return result;
  1809. }
  1810. namespace multiprecision
  1811. {
  1812. template <class I>
  1813. struct component_type<boost::rational<I> >
  1814. {
  1815. typedef I type;
  1816. };
  1817. }
  1818. #ifdef BOOST_MSVC
  1819. #pragma warning(pop)
  1820. #endif
  1821. } // namespaces
  1822. #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
  1823. #include <functional>
  1824. namespace std {
  1825. template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
  1826. struct hash<boost::multiprecision::number<Backend, ExpressionTemplates> >
  1827. {
  1828. std::size_t operator()(const boost::multiprecision::number<Backend, ExpressionTemplates>& val)const { return hash_value(val); }
  1829. };
  1830. template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
  1831. struct hash<boost::rational<boost::multiprecision::number<Backend, ExpressionTemplates> > >
  1832. {
  1833. std::size_t operator()(const boost::rational<boost::multiprecision::number<Backend, ExpressionTemplates> >& val)const
  1834. {
  1835. std::size_t result = hash_value(val.numerator());
  1836. boost::hash_combine(result, hash_value(val.denominator()));
  1837. return result;
  1838. }
  1839. };
  1840. }
  1841. #endif
  1842. #include <boost/multiprecision/detail/ublas_interop.hpp>
  1843. #endif