cpp_int.hpp 84 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979
  1. //////////////////3/////////////////////////////////////////////
  2. // Copyright 2012 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_
  5. #ifndef BOOST_MP_CPP_INT_HPP
  6. #define BOOST_MP_CPP_INT_HPP
  7. #include <iostream>
  8. #include <iomanip>
  9. #include <boost/cstdint.hpp>
  10. #include <boost/multiprecision/number.hpp>
  11. #include <boost/multiprecision/detail/integer_ops.hpp>
  12. #include <boost/array.hpp>
  13. #include <boost/type_traits/is_integral.hpp>
  14. #include <boost/type_traits/is_floating_point.hpp>
  15. #include <boost/multiprecision/cpp_int/cpp_int_config.hpp>
  16. #include <boost/multiprecision/rational_adaptor.hpp>
  17. #include <boost/multiprecision/traits/is_byte_container.hpp>
  18. #include <boost/detail/endian.hpp>
  19. #include <boost/integer/static_min_max.hpp>
  20. #include <boost/type_traits/common_type.hpp>
  21. #include <boost/type_traits/make_signed.hpp>
  22. #include <boost/multiprecision/cpp_int/checked.hpp>
  23. #ifdef BOOST_MP_USER_DEFINED_LITERALS
  24. #include <boost/multiprecision/cpp_int/value_pack.hpp>
  25. #endif
  26. namespace boost{
  27. namespace multiprecision{
  28. namespace backends{
  29. using boost::enable_if;
  30. #ifdef BOOST_MSVC
  31. #pragma warning(push)
  32. #pragma warning(disable:4307) // integral constant overflow (oveflow is in a branch not taken when it would overflow)
  33. #pragma warning(disable:4127) // conditional expression is constant
  34. #pragma warning(disable:4702) // Unreachable code (reachability depends on template params)
  35. #endif
  36. template <unsigned MinBits = 0, unsigned MaxBits = 0, boost::multiprecision::cpp_integer_type SignType = signed_magnitude, cpp_int_check_type Checked = unchecked, class Allocator = typename mpl::if_c<MinBits && (MinBits == MaxBits), void, std::allocator<limb_type> >::type >
  37. struct cpp_int_backend;
  38. } // namespace backends
  39. namespace detail {
  40. template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
  41. struct is_byte_container<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> > : public boost::false_type {};
  42. } // namespace detail
  43. namespace backends{
  44. template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, bool trivial = false>
  45. struct cpp_int_base;
  46. //
  47. // Traits class determines the maximum and minimum precision values:
  48. //
  49. template <class T> struct max_precision;
  50. template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
  51. struct max_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
  52. {
  53. static const unsigned value = is_void<Allocator>::value ?
  54. static_unsigned_max<MinBits, MaxBits>::value
  55. : (((MaxBits >= MinBits) && MaxBits) ? MaxBits : UINT_MAX);
  56. };
  57. template <class T> struct min_precision;
  58. template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
  59. struct min_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
  60. {
  61. static const unsigned value = (is_void<Allocator>::value ? static_unsigned_max<MinBits, MaxBits>::value : MinBits);
  62. };
  63. //
  64. // Traits class determines whether the number of bits precision requested could fit in a native type,
  65. // we call this a "trivial" cpp_int:
  66. //
  67. template <class T>
  68. struct is_trivial_cpp_int
  69. {
  70. static const bool value = false;
  71. };
  72. template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
  73. struct is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
  74. {
  75. typedef cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> self;
  76. static const bool value = is_void<Allocator>::value && (max_precision<self>::value <= (sizeof(double_limb_type) * CHAR_BIT) - (SignType == signed_packed ? 1 : 0));
  77. };
  78. template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
  79. struct is_trivial_cpp_int<cpp_int_base<MinBits, MaxBits, SignType, Checked, Allocator, true> >
  80. {
  81. static const bool value = true;
  82. };
  83. } // namespace backends
  84. //
  85. // Traits class to determine whether a cpp_int_backend is signed or not:
  86. //
  87. template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
  88. struct is_unsigned_number<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
  89. : public mpl::bool_<(SignType == unsigned_magnitude) || (SignType == unsigned_packed)>{};
  90. namespace backends{
  91. //
  92. // Traits class determines whether T should be implicitly convertible to U, or
  93. // whether the constructor should be made explicit. The latter happens if we
  94. // are losing the sign, or have fewer digits precision in the target type:
  95. //
  96. template <class T, class U>
  97. struct is_implicit_cpp_int_conversion;
  98. template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  99. struct is_implicit_cpp_int_conversion<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >
  100. {
  101. typedef cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> t1;
  102. typedef cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> t2;
  103. static const bool value =
  104. (is_signed_number<t2>::value || !is_signed_number<t1>::value)
  105. && (max_precision<t1>::value <= max_precision<t2>::value);
  106. };
  107. //
  108. // Traits class to determine whether operations on a cpp_int may throw:
  109. //
  110. template <class T>
  111. struct is_non_throwing_cpp_int : public mpl::false_{};
  112. template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType>
  113. struct is_non_throwing_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, unchecked, void> > : public mpl::true_ {};
  114. //
  115. // Traits class, determines whether the cpp_int is fixed precision or not:
  116. //
  117. template <class T>
  118. struct is_fixed_precision;
  119. template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
  120. struct is_fixed_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
  121. : public mpl::bool_<max_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value != UINT_MAX> {};
  122. namespace detail{
  123. inline void verify_new_size(unsigned new_size, unsigned min_size, const mpl::int_<checked>&)
  124. {
  125. if(new_size < min_size)
  126. BOOST_THROW_EXCEPTION(std::overflow_error("Unable to allocate sufficient storage for the value of the result: value overflows the maximum allowable magnitude."));
  127. }
  128. inline void verify_new_size(unsigned /*new_size*/, unsigned /*min_size*/, const mpl::int_<unchecked>&){}
  129. template <class U>
  130. inline void verify_limb_mask(bool b, U limb, U mask, const mpl::int_<checked>&)
  131. {
  132. // When we mask out "limb" with "mask", do we loose bits? If so it's an overflow error:
  133. if(b && (limb & ~mask))
  134. BOOST_THROW_EXCEPTION(std::overflow_error("Overflow in cpp_int arithmetic: there is insufficient precision in the target type to hold all of the bits of the result."));
  135. }
  136. template <class U>
  137. inline void verify_limb_mask(bool /*b*/, U /*limb*/, U /*mask*/, const mpl::int_<unchecked>&){}
  138. }
  139. //
  140. // Now define the various data layouts that are possible as partial specializations of the base class,
  141. // starting with the default arbitrary precision signed integer type:
  142. //
  143. template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
  144. struct cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false> : private Allocator::template rebind<limb_type>::other
  145. {
  146. typedef typename Allocator::template rebind<limb_type>::other allocator_type;
  147. #ifdef BOOST_NO_CXX11_ALLOCATOR
  148. typedef typename allocator_type::pointer limb_pointer;
  149. typedef typename allocator_type::const_pointer const_limb_pointer;
  150. #else
  151. typedef typename std::allocator_traits<allocator_type>::pointer limb_pointer;
  152. typedef typename std::allocator_traits<allocator_type>::const_pointer const_limb_pointer;
  153. #endif
  154. typedef mpl::int_<Checked> checked_type;
  155. //
  156. // Interface invariants:
  157. //
  158. BOOST_STATIC_ASSERT(!is_void<Allocator>::value);
  159. private:
  160. struct limb_data
  161. {
  162. unsigned capacity;
  163. limb_pointer data;
  164. };
  165. public:
  166. BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(limb_type) * CHAR_BIT);
  167. BOOST_STATIC_CONSTANT(limb_type, max_limb_value = ~static_cast<limb_type>(0u));
  168. BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = static_cast<limb_type>(1u) << (limb_bits - 1));
  169. BOOST_STATIC_CONSTANT(unsigned, internal_limb_count =
  170. MinBits
  171. ? (MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0))
  172. : (sizeof(limb_data) / sizeof(limb_type)));
  173. BOOST_STATIC_CONSTANT(bool, variable = true);
  174. private:
  175. union data_type
  176. {
  177. limb_data ld;
  178. limb_type la[internal_limb_count];
  179. limb_type first;
  180. double_limb_type double_first;
  181. BOOST_CONSTEXPR data_type() : first(0) {}
  182. BOOST_CONSTEXPR data_type(limb_type i) : first(i) {}
  183. BOOST_CONSTEXPR data_type(signed_limb_type i) : first(i < 0 ? static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(i)) : i) {}
  184. #ifdef BOOST_LITTLE_ENDIAN
  185. BOOST_CONSTEXPR data_type(double_limb_type i) : double_first(i) {}
  186. BOOST_CONSTEXPR data_type(signed_double_limb_type i) : double_first(i < 0 ? static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) : i) {}
  187. #endif
  188. };
  189. data_type m_data;
  190. unsigned m_limbs;
  191. bool m_sign, m_internal;
  192. public:
  193. //
  194. // Direct construction:
  195. //
  196. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT
  197. : m_data(i), m_limbs(1), m_sign(false), m_internal(true) { }
  198. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT
  199. : m_data(i), m_limbs(1), m_sign(i < 0), m_internal(true) { }
  200. #if defined(BOOST_LITTLE_ENDIAN) && !defined(BOOST_MP_TEST_NO_LE)
  201. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT
  202. : m_data(i), m_limbs(i > max_limb_value ? 2 : 1), m_sign(false), m_internal(true) { }
  203. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT
  204. : m_data(i), m_limbs(i < 0 ? (static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) > static_cast<double_limb_type>(max_limb_value) ? 2 : 1) : (i > max_limb_value ? 2 : 1)),
  205. m_sign(i < 0), m_internal(true) { }
  206. #endif
  207. //
  208. // Helper functions for getting at our internal data, and manipulating storage:
  209. //
  210. BOOST_MP_FORCEINLINE allocator_type& allocator() BOOST_NOEXCEPT { return *this; }
  211. BOOST_MP_FORCEINLINE const allocator_type& allocator()const BOOST_NOEXCEPT { return *this; }
  212. BOOST_MP_FORCEINLINE unsigned size()const BOOST_NOEXCEPT { return m_limbs; }
  213. BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return m_internal ? m_data.la : m_data.ld.data; }
  214. BOOST_MP_FORCEINLINE const_limb_pointer limbs()const BOOST_NOEXCEPT { return m_internal ? m_data.la : m_data.ld.data; }
  215. BOOST_MP_FORCEINLINE unsigned capacity()const BOOST_NOEXCEPT { return m_internal ? internal_limb_count : m_data.ld.capacity; }
  216. BOOST_MP_FORCEINLINE bool sign()const BOOST_NOEXCEPT { return m_sign; }
  217. void sign(bool b) BOOST_NOEXCEPT
  218. {
  219. m_sign = b;
  220. // Check for zero value:
  221. if(m_sign && (m_limbs == 1))
  222. {
  223. if(limbs()[0] == 0)
  224. m_sign = false;
  225. }
  226. }
  227. void resize(unsigned new_size, unsigned min_size)
  228. {
  229. static const unsigned max_limbs = MaxBits / (CHAR_BIT * sizeof(limb_type)) + ((MaxBits % (CHAR_BIT * sizeof(limb_type))) ? 1 : 0);
  230. // We never resize beyond MaxSize:
  231. if(new_size > max_limbs)
  232. new_size = max_limbs;
  233. detail::verify_new_size(new_size, min_size, checked_type());
  234. // See if we have enough capacity already:
  235. unsigned cap = capacity();
  236. if(new_size > cap)
  237. {
  238. // Allocate a new buffer and copy everything over:
  239. cap = (std::min)((std::max)(cap * 4, new_size), max_limbs);
  240. limb_pointer pl = allocator().allocate(cap);
  241. std::memcpy(pl, limbs(), size() * sizeof(limbs()[0]));
  242. if(!m_internal)
  243. allocator().deallocate(limbs(), capacity());
  244. else
  245. m_internal = false;
  246. m_limbs = new_size;
  247. m_data.ld.capacity = cap;
  248. m_data.ld.data = pl;
  249. }
  250. else
  251. {
  252. m_limbs = new_size;
  253. }
  254. }
  255. BOOST_MP_FORCEINLINE void normalize() BOOST_NOEXCEPT
  256. {
  257. limb_pointer p = limbs();
  258. while((m_limbs-1) && !p[m_limbs - 1])--m_limbs;
  259. }
  260. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base() BOOST_NOEXCEPT : m_data(), m_limbs(1), m_sign(false), m_internal(true) {}
  261. BOOST_MP_FORCEINLINE cpp_int_base(const cpp_int_base& o) : allocator_type(o), m_limbs(0), m_internal(true)
  262. {
  263. resize(o.size(), o.size());
  264. std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0]));
  265. m_sign = o.m_sign;
  266. }
  267. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  268. cpp_int_base(cpp_int_base&& o)
  269. : allocator_type(static_cast<allocator_type&&>(o)), m_limbs(o.m_limbs), m_sign(o.m_sign), m_internal(o.m_internal)
  270. {
  271. if(m_internal)
  272. {
  273. std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0]));
  274. }
  275. else
  276. {
  277. m_data.ld = o.m_data.ld;
  278. o.m_limbs = 0;
  279. o.m_internal = true;
  280. }
  281. }
  282. cpp_int_base& operator = (cpp_int_base&& o) BOOST_NOEXCEPT
  283. {
  284. if(!m_internal)
  285. allocator().deallocate(m_data.ld.data, m_data.ld.capacity);
  286. *static_cast<allocator_type*>(this) = static_cast<allocator_type&&>(o);
  287. m_limbs = o.m_limbs;
  288. m_sign = o.m_sign;
  289. m_internal = o.m_internal;
  290. if(m_internal)
  291. {
  292. std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0]));
  293. }
  294. else
  295. {
  296. m_data.ld = o.m_data.ld;
  297. o.m_limbs = 0;
  298. o.m_internal = true;
  299. }
  300. return *this;
  301. }
  302. #endif
  303. BOOST_MP_FORCEINLINE ~cpp_int_base() BOOST_NOEXCEPT
  304. {
  305. if(!m_internal)
  306. allocator().deallocate(limbs(), capacity());
  307. }
  308. void assign(const cpp_int_base& o)
  309. {
  310. if(this != &o)
  311. {
  312. static_cast<allocator_type&>(*this) = static_cast<const allocator_type&>(o);
  313. m_limbs = 0;
  314. resize(o.size(), o.size());
  315. std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0]));
  316. m_sign = o.m_sign;
  317. }
  318. }
  319. BOOST_MP_FORCEINLINE void negate() BOOST_NOEXCEPT
  320. {
  321. m_sign = !m_sign;
  322. // Check for zero value:
  323. if(m_sign && (m_limbs == 1))
  324. {
  325. if(limbs()[0] == 0)
  326. m_sign = false;
  327. }
  328. }
  329. BOOST_MP_FORCEINLINE bool isneg()const BOOST_NOEXCEPT
  330. {
  331. return m_sign;
  332. }
  333. BOOST_MP_FORCEINLINE void do_swap(cpp_int_base& o) BOOST_NOEXCEPT
  334. {
  335. std::swap(m_data, o.m_data);
  336. std::swap(m_sign, o.m_sign);
  337. std::swap(m_internal, o.m_internal);
  338. std::swap(m_limbs, o.m_limbs);
  339. }
  340. protected:
  341. template <class A>
  342. void check_in_range(const A&) BOOST_NOEXCEPT {}
  343. };
  344. #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
  345. template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
  346. const unsigned cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::limb_bits;
  347. template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
  348. const limb_type cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::max_limb_value;
  349. template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
  350. const limb_type cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::sign_bit_mask;
  351. template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
  352. const unsigned cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::internal_limb_count;
  353. template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
  354. const bool cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::variable;
  355. #endif
  356. template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
  357. struct cpp_int_base<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator, false> : private Allocator::template rebind<limb_type>::other
  358. {
  359. //
  360. // There is currently no support for unsigned arbitrary precision arithmetic, largely
  361. // because it's not clear what subtraction should do:
  362. //
  363. BOOST_STATIC_ASSERT_MSG(((sizeof(Allocator) == 0) && !is_void<Allocator>::value), "There is curently no support for unsigned arbitrary precision integers.");
  364. };
  365. //
  366. // Fixed precision (i.e. no allocator), signed-magnitude type with limb-usage count:
  367. //
  368. template <unsigned MinBits, cpp_int_check_type Checked>
  369. struct cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>
  370. {
  371. typedef limb_type* limb_pointer;
  372. typedef const limb_type* const_limb_pointer;
  373. typedef mpl::int_<Checked> checked_type;
  374. //
  375. // Interface invariants:
  376. //
  377. BOOST_STATIC_ASSERT_MSG(MinBits > sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
  378. public:
  379. BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(limb_type) * CHAR_BIT);
  380. BOOST_STATIC_CONSTANT(limb_type, max_limb_value = ~static_cast<limb_type>(0u));
  381. BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = static_cast<limb_type>(1u) << (limb_bits - 1));
  382. BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0));
  383. BOOST_STATIC_CONSTANT(bool, variable = false);
  384. BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = (MinBits % limb_bits) ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0)));
  385. BOOST_STATIC_ASSERT_MSG(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs");
  386. private:
  387. union data_type{
  388. limb_type m_data[internal_limb_count];
  389. limb_type m_first_limb;
  390. double_limb_type m_double_first_limb;
  391. BOOST_CONSTEXPR data_type() : m_first_limb(0) {}
  392. BOOST_CONSTEXPR data_type(limb_type i) : m_first_limb(i) {}
  393. BOOST_CONSTEXPR data_type(double_limb_type i) : m_double_first_limb(i) {}
  394. #if defined(BOOST_MP_USER_DEFINED_LITERALS)
  395. template <limb_type...VALUES>
  396. BOOST_CONSTEXPR data_type(literals::detail::value_pack<VALUES...>) : m_data{ VALUES... } {}
  397. #endif
  398. } m_wrapper;
  399. boost::uint16_t m_limbs;
  400. bool m_sign;
  401. public:
  402. //
  403. // Direct construction:
  404. //
  405. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT
  406. : m_wrapper(i), m_limbs(1), m_sign(false) {}
  407. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT
  408. : m_wrapper(limb_type(i < 0 ? static_cast<limb_type>(-static_cast<signed_double_limb_type>(i)) : i)), m_limbs(1), m_sign(i < 0) {}
  409. #if defined(BOOST_LITTLE_ENDIAN) && !defined(BOOST_MP_TEST_NO_LE)
  410. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT
  411. : m_wrapper(i), m_limbs(i > max_limb_value ? 2 : 1), m_sign(false) {}
  412. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT
  413. : m_wrapper(double_limb_type(i < 0 ? static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) : i)),
  414. m_limbs(i < 0 ? (static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)),
  415. m_sign(i < 0) {}
  416. #endif
  417. #if defined(BOOST_MP_USER_DEFINED_LITERALS)
  418. template <limb_type...VALUES>
  419. BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<VALUES...> i)
  420. : m_wrapper(i), m_limbs(sizeof...(VALUES)), m_sign(false) {}
  421. BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<> i)
  422. : m_wrapper(i), m_limbs(1), m_sign(false) {}
  423. BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& a, const literals::detail::negate_tag&)
  424. : m_wrapper(a.m_wrapper), m_limbs(a.m_limbs), m_sign((a.m_limbs == 1) && (*a.limbs() == 0) ? false : !a.m_sign) {}
  425. #endif
  426. //
  427. // Helper functions for getting at our internal data, and manipulating storage:
  428. //
  429. BOOST_MP_FORCEINLINE unsigned size()const BOOST_NOEXCEPT { return m_limbs; }
  430. BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return m_wrapper.m_data; }
  431. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return m_wrapper.m_data; }
  432. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return m_sign; }
  433. BOOST_MP_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT
  434. {
  435. m_sign = b;
  436. // Check for zero value:
  437. if(m_sign && (m_limbs == 1))
  438. {
  439. if(limbs()[0] == 0)
  440. m_sign = false;
  441. }
  442. }
  443. BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
  444. {
  445. m_limbs = static_cast<boost::uint16_t>((std::min)(new_size, internal_limb_count));
  446. detail::verify_new_size(m_limbs, min_size, checked_type());
  447. }
  448. BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
  449. {
  450. limb_pointer p = limbs();
  451. detail::verify_limb_mask(m_limbs == internal_limb_count, p[internal_limb_count-1], upper_limb_mask, checked_type());
  452. p[internal_limb_count-1] &= upper_limb_mask;
  453. while((m_limbs-1) && !p[m_limbs - 1])--m_limbs;
  454. if((m_limbs == 1) && (!*p)) m_sign = false; // zero is always unsigned
  455. }
  456. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base()BOOST_NOEXCEPT : m_wrapper(limb_type(0u)), m_limbs(1), m_sign(false) {}
  457. // Not defaulted, it breaks constexpr support in the Intel compiler for some reason:
  458. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& o)BOOST_NOEXCEPT
  459. : m_wrapper(o.m_wrapper), m_limbs(o.m_limbs), m_sign(o.m_sign) {}
  460. // Defaulted functions:
  461. //~cpp_int_base() BOOST_NOEXCEPT {}
  462. void assign(const cpp_int_base& o) BOOST_NOEXCEPT
  463. {
  464. if(this != &o)
  465. {
  466. m_limbs = o.m_limbs;
  467. std::memcpy(limbs(), o.limbs(), o.size() * sizeof(o.limbs()[0]));
  468. m_sign = o.m_sign;
  469. }
  470. }
  471. BOOST_MP_FORCEINLINE void negate() BOOST_NOEXCEPT
  472. {
  473. m_sign = !m_sign;
  474. // Check for zero value:
  475. if(m_sign && (m_limbs == 1))
  476. {
  477. if(limbs()[0] == 0)
  478. m_sign = false;
  479. }
  480. }
  481. BOOST_MP_FORCEINLINE bool isneg()const BOOST_NOEXCEPT
  482. {
  483. return m_sign;
  484. }
  485. BOOST_MP_FORCEINLINE void do_swap(cpp_int_base& o) BOOST_NOEXCEPT
  486. {
  487. for(unsigned i = 0; i < (std::max)(size(), o.size()); ++i)
  488. std::swap(m_wrapper.m_data[i], o.m_wrapper.m_data[i]);
  489. std::swap(m_sign, o.m_sign);
  490. std::swap(m_limbs, o.m_limbs);
  491. }
  492. protected:
  493. template <class A>
  494. void check_in_range(const A&) BOOST_NOEXCEPT {}
  495. };
  496. #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
  497. template <unsigned MinBits, cpp_int_check_type Checked>
  498. const unsigned cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::limb_bits;
  499. template <unsigned MinBits, cpp_int_check_type Checked>
  500. const limb_type cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::max_limb_value;
  501. template <unsigned MinBits, cpp_int_check_type Checked>
  502. const limb_type cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::sign_bit_mask;
  503. template <unsigned MinBits, cpp_int_check_type Checked>
  504. const unsigned cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::internal_limb_count;
  505. template <unsigned MinBits, cpp_int_check_type Checked>
  506. const bool cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::variable;
  507. #endif
  508. //
  509. // Fixed precision (i.e. no allocator), unsigned type with limb-usage count:
  510. //
  511. template <unsigned MinBits, cpp_int_check_type Checked>
  512. struct cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>
  513. {
  514. typedef limb_type* limb_pointer;
  515. typedef const limb_type* const_limb_pointer;
  516. typedef mpl::int_<Checked> checked_type;
  517. //
  518. // Interface invariants:
  519. //
  520. BOOST_STATIC_ASSERT_MSG(MinBits > sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
  521. public:
  522. BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(limb_type) * CHAR_BIT);
  523. BOOST_STATIC_CONSTANT(limb_type, max_limb_value = ~static_cast<limb_type>(0u));
  524. BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = static_cast<limb_type>(1u) << (limb_bits - 1));
  525. BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0));
  526. BOOST_STATIC_CONSTANT(bool, variable = false);
  527. BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = (MinBits % limb_bits) ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0)));
  528. BOOST_STATIC_ASSERT_MSG(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs");
  529. private:
  530. union data_type{
  531. limb_type m_data[internal_limb_count];
  532. limb_type m_first_limb;
  533. double_limb_type m_double_first_limb;
  534. BOOST_CONSTEXPR data_type() : m_first_limb(0) {}
  535. BOOST_CONSTEXPR data_type(limb_type i) : m_first_limb(i) {}
  536. BOOST_CONSTEXPR data_type(double_limb_type i) : m_double_first_limb(i) {}
  537. #if defined(BOOST_MP_USER_DEFINED_LITERALS)
  538. template <limb_type...VALUES>
  539. BOOST_CONSTEXPR data_type(literals::detail::value_pack<VALUES...>) : m_data{ VALUES... } {}
  540. #endif
  541. } m_wrapper;
  542. limb_type m_limbs;
  543. public:
  544. //
  545. // Direct construction:
  546. //
  547. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT
  548. : m_wrapper(i), m_limbs(1) {}
  549. BOOST_MP_FORCEINLINE cpp_int_base(signed_limb_type i)BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
  550. : m_wrapper(limb_type(i < 0 ? static_cast<limb_type>(-static_cast<signed_double_limb_type>(i)) : i)), m_limbs(1) { if(i < 0) negate(); }
  551. #if defined(BOOST_LITTLE_ENDIAN) && !defined(BOOST_MP_TEST_NO_LE)
  552. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT
  553. : m_wrapper(i), m_limbs(i > max_limb_value ? 2 : 1) {}
  554. BOOST_MP_FORCEINLINE cpp_int_base(signed_double_limb_type i)BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
  555. : m_wrapper(double_limb_type(i < 0 ? static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) : i)),
  556. m_limbs(i < 0 ? (static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1))
  557. {
  558. if (i < 0) negate();
  559. }
  560. #endif
  561. #if defined(BOOST_MP_USER_DEFINED_LITERALS)
  562. template <limb_type...VALUES>
  563. BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<VALUES...> i)
  564. : m_wrapper(i), m_limbs(sizeof...(VALUES)) {}
  565. BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<>)
  566. : m_wrapper(static_cast<limb_type>(0u)), m_limbs(1) {}
  567. #endif
  568. //
  569. // Helper functions for getting at our internal data, and manipulating storage:
  570. //
  571. BOOST_MP_FORCEINLINE unsigned size()const BOOST_NOEXCEPT { return m_limbs; }
  572. BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return m_wrapper.m_data; }
  573. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return m_wrapper.m_data; }
  574. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return false; }
  575. BOOST_MP_FORCEINLINE void sign(bool b) BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { if(b) negate(); }
  576. BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
  577. {
  578. m_limbs = (std::min)(new_size, internal_limb_count);
  579. detail::verify_new_size(m_limbs, min_size, checked_type());
  580. }
  581. BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
  582. {
  583. limb_pointer p = limbs();
  584. detail::verify_limb_mask(m_limbs == internal_limb_count, p[internal_limb_count-1], upper_limb_mask, checked_type());
  585. p[internal_limb_count-1] &= upper_limb_mask;
  586. while((m_limbs-1) && !p[m_limbs - 1])--m_limbs;
  587. }
  588. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base() BOOST_NOEXCEPT
  589. : m_wrapper(limb_type(0u)), m_limbs(1) {}
  590. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT
  591. : m_wrapper(o.m_wrapper), m_limbs(o.m_limbs) {}
  592. // Defaulted functions:
  593. //~cpp_int_base() BOOST_NOEXCEPT {}
  594. BOOST_MP_FORCEINLINE void assign(const cpp_int_base& o) BOOST_NOEXCEPT
  595. {
  596. if(this != &o)
  597. {
  598. m_limbs = o.m_limbs;
  599. std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0]));
  600. }
  601. }
  602. private:
  603. void check_negate(const mpl::int_<checked>&)
  604. {
  605. BOOST_THROW_EXCEPTION(std::range_error("Attempt to negate an unsigned number."));
  606. }
  607. void check_negate(const mpl::int_<unchecked>&){}
  608. public:
  609. void negate() BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
  610. {
  611. // Not so much a negate as a complement - this gets called when subtraction
  612. // would result in a "negative" number:
  613. unsigned i;
  614. if((m_limbs == 1) && (m_wrapper.m_data[0] == 0))
  615. return; // negating zero is always zero, and always OK.
  616. check_negate(checked_type());
  617. for(i = m_limbs; i < internal_limb_count; ++i)
  618. m_wrapper.m_data[i] = 0;
  619. m_limbs = internal_limb_count;
  620. for(i = 0; i < internal_limb_count; ++i)
  621. m_wrapper.m_data[i] = ~m_wrapper.m_data[i];
  622. normalize();
  623. eval_increment(static_cast<cpp_int_backend<MinBits, MinBits, unsigned_magnitude, Checked, void>& >(*this));
  624. }
  625. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool isneg()const BOOST_NOEXCEPT
  626. {
  627. return false;
  628. }
  629. BOOST_MP_FORCEINLINE void do_swap(cpp_int_base& o) BOOST_NOEXCEPT
  630. {
  631. for(unsigned i = 0; i < (std::max)(size(), o.size()); ++i)
  632. std::swap(m_wrapper.m_data[i], o.m_wrapper.m_data[i]);
  633. std::swap(m_limbs, o.m_limbs);
  634. }
  635. protected:
  636. template <class A>
  637. void check_in_range(const A&) BOOST_NOEXCEPT {}
  638. };
  639. #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
  640. template <unsigned MinBits, cpp_int_check_type Checked>
  641. const unsigned cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::limb_bits;
  642. template <unsigned MinBits, cpp_int_check_type Checked>
  643. const limb_type cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::max_limb_value;
  644. template <unsigned MinBits, cpp_int_check_type Checked>
  645. const limb_type cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::sign_bit_mask;
  646. template <unsigned MinBits, cpp_int_check_type Checked>
  647. const unsigned cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::internal_limb_count;
  648. template <unsigned MinBits, cpp_int_check_type Checked>
  649. const bool cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::variable;
  650. #endif
  651. //
  652. // Traits classes to figure out a native type with N bits, these vary from boost::uint_t<N> only
  653. // because some platforms have native integer types longer than boost::long_long_type, "really boost::long_long_type" anyone??
  654. //
  655. template <unsigned N, bool s>
  656. struct trivial_limb_type_imp
  657. {
  658. typedef double_limb_type type;
  659. };
  660. template <unsigned N>
  661. struct trivial_limb_type_imp<N, true>
  662. {
  663. typedef typename boost::uint_t<N>::least type;
  664. };
  665. template <unsigned N>
  666. struct trivial_limb_type : public trivial_limb_type_imp<N, N <= sizeof(boost::long_long_type) * CHAR_BIT> {};
  667. //
  668. // Backend for fixed precision signed-magnitude type which will fit entirely inside a "double_limb_type":
  669. //
  670. template <unsigned MinBits, cpp_int_check_type Checked>
  671. struct cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, true>
  672. {
  673. typedef typename trivial_limb_type<MinBits>::type local_limb_type;
  674. typedef local_limb_type* limb_pointer;
  675. typedef const local_limb_type* const_limb_pointer;
  676. typedef mpl::int_<Checked> checked_type;
  677. protected:
  678. BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(local_limb_type) * CHAR_BIT);
  679. BOOST_STATIC_CONSTANT(local_limb_type, limb_mask = (MinBits < limb_bits) ? local_limb_type((local_limb_type(~local_limb_type(0))) >> (limb_bits - MinBits)) : local_limb_type(~local_limb_type(0)));
  680. private:
  681. local_limb_type m_data;
  682. bool m_sign;
  683. //
  684. // Interface invariants:
  685. //
  686. BOOST_STATIC_ASSERT_MSG(MinBits <= sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
  687. protected:
  688. template <class T>
  689. typename boost::disable_if_c<!boost::is_integral<T>::value || (std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::digits <= (int)MinBits))>::type
  690. check_in_range(T val, const mpl::int_<checked>&)
  691. {
  692. typedef typename common_type<typename make_unsigned<T>::type, local_limb_type>::type common_type;
  693. if(static_cast<common_type>(boost::multiprecision::detail::unsigned_abs(val)) > static_cast<common_type>(limb_mask))
  694. BOOST_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent."));
  695. }
  696. template <class T>
  697. typename boost::disable_if_c<boost::is_integral<T>::value || (std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::digits <= (int)MinBits))>::type
  698. check_in_range(T val, const mpl::int_<checked>&)
  699. {
  700. using std::abs;
  701. typedef typename common_type<T, local_limb_type>::type common_type;
  702. if (static_cast<common_type>(abs(val)) > static_cast<common_type>(limb_mask))
  703. BOOST_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent."));
  704. }
  705. template <class T, int C>
  706. void check_in_range(T, const mpl::int_<C>&) BOOST_NOEXCEPT {}
  707. template <class T>
  708. void check_in_range(T val) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type())))
  709. {
  710. check_in_range(val, checked_type());
  711. }
  712. public:
  713. //
  714. // Direct construction:
  715. //
  716. template <class SI>
  717. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == unchecked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
  718. : m_data(i < 0 ? static_cast<local_limb_type>(static_cast<typename make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask) : static_cast<local_limb_type>(i & limb_mask)), m_sign(i < 0) {}
  719. template <class SI>
  720. BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
  721. : m_data(i < 0 ? (static_cast<local_limb_type>(static_cast<typename make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask)) : static_cast<local_limb_type>(i & limb_mask)), m_sign(i < 0)
  722. { check_in_range(i); }
  723. template <class UI>
  724. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == unchecked)>::type const* = 0) BOOST_NOEXCEPT
  725. : m_data(static_cast<local_limb_type>(i) & limb_mask), m_sign(false) {}
  726. template <class UI>
  727. BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == checked)>::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>())))
  728. : m_data(static_cast<local_limb_type>(i) & limb_mask), m_sign(false) { check_in_range(i); }
  729. template <class F>
  730. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(F i, typename boost::enable_if_c<is_floating_point<F>::value && (Checked == unchecked)>::type const* = 0) BOOST_NOEXCEPT
  731. : m_data(static_cast<local_limb_type>(std::fabs(i)) & limb_mask), m_sign(i < 0) {}
  732. template <class F>
  733. BOOST_MP_FORCEINLINE cpp_int_base(F i, typename boost::enable_if_c<is_floating_point<F>::value && (Checked == checked)>::type const* = 0)
  734. : m_data(static_cast<local_limb_type>(std::fabs(i)) & limb_mask), m_sign(i < 0) { check_in_range(i); }
  735. #if defined(BOOST_MP_USER_DEFINED_LITERALS)
  736. BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<>) BOOST_NOEXCEPT
  737. : m_data(static_cast<local_limb_type>(0u)), m_sign(false) {}
  738. template <limb_type a>
  739. BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a>)BOOST_NOEXCEPT
  740. : m_data(static_cast<local_limb_type>(a)), m_sign(false) {}
  741. template <limb_type a, limb_type b>
  742. BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a, b>)BOOST_NOEXCEPT
  743. : m_data(static_cast<local_limb_type>(a) | (static_cast<local_limb_type>(b) << bits_per_limb)), m_sign(false) {}
  744. BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& a, const literals::detail::negate_tag&)BOOST_NOEXCEPT
  745. : m_data(a.m_data), m_sign(a.m_data ? !a.m_sign : false) {}
  746. #endif
  747. //
  748. // Helper functions for getting at our internal data, and manipulating storage:
  749. //
  750. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR unsigned size()const BOOST_NOEXCEPT { return 1; }
  751. BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return &m_data; }
  752. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return &m_data; }
  753. BOOST_MP_FORCEINLINE bool sign()const BOOST_NOEXCEPT { return m_sign; }
  754. BOOST_MP_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT
  755. {
  756. m_sign = b;
  757. // Check for zero value:
  758. if(m_sign && !m_data)
  759. {
  760. m_sign = false;
  761. }
  762. }
  763. BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size)
  764. {
  765. detail::verify_new_size(2, min_size, checked_type());
  766. }
  767. BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
  768. {
  769. if(!m_data)
  770. m_sign = false; // zero is always unsigned
  771. detail::verify_limb_mask(true, m_data, limb_mask, checked_type());
  772. m_data &= limb_mask;
  773. }
  774. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base() BOOST_NOEXCEPT : m_data(0), m_sign(false) {}
  775. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT
  776. : m_data(o.m_data), m_sign(o.m_sign) {}
  777. //~cpp_int_base() BOOST_NOEXCEPT {}
  778. BOOST_MP_FORCEINLINE void assign(const cpp_int_base& o) BOOST_NOEXCEPT
  779. {
  780. m_data = o.m_data;
  781. m_sign = o.m_sign;
  782. }
  783. BOOST_MP_FORCEINLINE void negate() BOOST_NOEXCEPT
  784. {
  785. m_sign = !m_sign;
  786. // Check for zero value:
  787. if(m_data == 0)
  788. {
  789. m_sign = false;
  790. }
  791. }
  792. BOOST_MP_FORCEINLINE bool isneg()const BOOST_NOEXCEPT
  793. {
  794. return m_sign;
  795. }
  796. BOOST_MP_FORCEINLINE void do_swap(cpp_int_base& o) BOOST_NOEXCEPT
  797. {
  798. std::swap(m_sign, o.m_sign);
  799. std::swap(m_data, o.m_data);
  800. }
  801. };
  802. //
  803. // Backend for unsigned fixed precision (i.e. no allocator) type which will fit entirely inside a "double_limb_type":
  804. //
  805. template <unsigned MinBits, cpp_int_check_type Checked>
  806. struct cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, true>
  807. {
  808. typedef typename trivial_limb_type<MinBits>::type local_limb_type;
  809. typedef local_limb_type* limb_pointer;
  810. typedef const local_limb_type* const_limb_pointer;
  811. private:
  812. BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(local_limb_type) * CHAR_BIT);
  813. BOOST_STATIC_CONSTANT(local_limb_type, limb_mask = limb_bits != MinBits ?
  814. static_cast<local_limb_type>(static_cast<local_limb_type>(~local_limb_type(0)) >> (limb_bits - MinBits))
  815. : static_cast<local_limb_type>(~local_limb_type(0)));
  816. local_limb_type m_data;
  817. typedef mpl::int_<Checked> checked_type;
  818. //
  819. // Interface invariants:
  820. //
  821. BOOST_STATIC_ASSERT_MSG(MinBits <= sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
  822. protected:
  823. template <class T>
  824. typename boost::disable_if_c<std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::digits <= (int)MinBits)>::type
  825. check_in_range(T val, const mpl::int_<checked>&, const boost::false_type&)
  826. {
  827. typedef typename common_type<T, local_limb_type>::type common_type;
  828. if(static_cast<common_type>(val) > limb_mask)
  829. BOOST_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent."));
  830. }
  831. template <class T>
  832. void check_in_range(T val, const mpl::int_<checked>&, const boost::true_type&)
  833. {
  834. typedef typename common_type<T, local_limb_type>::type common_type;
  835. if(static_cast<common_type>(val) > limb_mask)
  836. BOOST_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent."));
  837. if(val < 0)
  838. BOOST_THROW_EXCEPTION(std::range_error("The argument to an unsigned cpp_int constructor was negative."));
  839. }
  840. template <class T, int C, bool B>
  841. BOOST_MP_FORCEINLINE void check_in_range(T, const mpl::int_<C>&, const boost::integral_constant<bool, B>&) BOOST_NOEXCEPT {}
  842. template <class T>
  843. BOOST_MP_FORCEINLINE void check_in_range(T val) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type(), is_signed<T>())))
  844. {
  845. check_in_range(val, checked_type(), is_signed<T>());
  846. }
  847. public:
  848. //
  849. // Direct construction:
  850. //
  851. #ifdef __MSVC_RUNTIME_CHECKS
  852. template <class SI>
  853. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT
  854. : m_data(i < 0 ? (1 + ~static_cast<local_limb_type>(-i & limb_mask)) & limb_mask : static_cast<local_limb_type>(i & limb_mask)) {}
  855. template <class SI>
  856. BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
  857. : m_data(i < 0 ? 1 + ~static_cast<local_limb_type>(-i & limb_mask) : static_cast<local_limb_type>(i & limb_mask)) { check_in_range(i); }
  858. template <class UI>
  859. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT
  860. : m_data(static_cast<local_limb_type>(i & limb_mask)) {}
  861. template <class UI>
  862. BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>())))
  863. : m_data(static_cast<local_limb_type>(i & limb_mask)) { check_in_range(i); }
  864. #else
  865. template <class SI>
  866. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT
  867. : m_data(i < 0 ? (1 + ~static_cast<local_limb_type>(-i)) & limb_mask : static_cast<local_limb_type>(i) & limb_mask) {}
  868. template <class SI>
  869. BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
  870. : m_data(i < 0 ? 1 + ~static_cast<local_limb_type>(-i) : static_cast<local_limb_type>(i)) { check_in_range(i); }
  871. template <class UI>
  872. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT
  873. : m_data(static_cast<local_limb_type>(i) & limb_mask) {}
  874. template <class UI>
  875. BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>())))
  876. : m_data(static_cast<local_limb_type>(i)) { check_in_range(i); }
  877. #endif
  878. template <class F>
  879. BOOST_MP_FORCEINLINE cpp_int_base(F i, typename boost::enable_if<is_floating_point<F> >::type const* = 0) BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
  880. : m_data(static_cast<local_limb_type>(std::fabs(i)) & limb_mask)
  881. {
  882. check_in_range(i);
  883. if(i < 0)
  884. negate();
  885. }
  886. #if defined(BOOST_MP_USER_DEFINED_LITERALS)
  887. BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<>) BOOST_NOEXCEPT
  888. : m_data(static_cast<local_limb_type>(0u)) {}
  889. template <limb_type a>
  890. BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a>) BOOST_NOEXCEPT
  891. : m_data(static_cast<local_limb_type>(a)) {}
  892. template <limb_type a, limb_type b>
  893. BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a, b>) BOOST_NOEXCEPT
  894. : m_data(static_cast<local_limb_type>(a) | (static_cast<local_limb_type>(b) << bits_per_limb)) {}
  895. #endif
  896. //
  897. // Helper functions for getting at our internal data, and manipulating storage:
  898. //
  899. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR unsigned size()const BOOST_NOEXCEPT { return 1; }
  900. BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return &m_data; }
  901. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return &m_data; }
  902. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return false; }
  903. BOOST_MP_FORCEINLINE void sign(bool b) BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
  904. {
  905. if(b)
  906. negate();
  907. }
  908. BOOST_MP_FORCEINLINE void resize(unsigned, unsigned min_size)
  909. {
  910. detail::verify_new_size(2, min_size, checked_type());
  911. }
  912. BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
  913. {
  914. detail::verify_limb_mask(true, m_data, limb_mask, checked_type());
  915. m_data &= limb_mask;
  916. }
  917. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base() BOOST_NOEXCEPT : m_data(0) {}
  918. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT
  919. : m_data(o.m_data) {}
  920. //~cpp_int_base() BOOST_NOEXCEPT {}
  921. BOOST_MP_FORCEINLINE void assign(const cpp_int_base& o) BOOST_NOEXCEPT
  922. {
  923. m_data = o.m_data;
  924. }
  925. BOOST_MP_FORCEINLINE void negate() BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
  926. {
  927. if(Checked == checked)
  928. {
  929. BOOST_THROW_EXCEPTION(std::range_error("Attempt to negate an unsigned type."));
  930. }
  931. m_data = ~m_data;
  932. ++m_data;
  933. }
  934. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool isneg()const BOOST_NOEXCEPT
  935. {
  936. return false;
  937. }
  938. BOOST_MP_FORCEINLINE void do_swap(cpp_int_base& o) BOOST_NOEXCEPT
  939. {
  940. std::swap(m_data, o.m_data);
  941. }
  942. };
  943. //
  944. // Traits class, lets us know whether type T can be directly converted to the base type,
  945. // used to enable/disable constructors etc:
  946. //
  947. template <class Arg, class Base>
  948. struct is_allowed_cpp_int_base_conversion : public mpl::if_c<
  949. is_same<Arg, limb_type>::value || is_same<Arg, signed_limb_type>::value
  950. #if defined(BOOST_LITTLE_ENDIAN) && !defined(BOOST_MP_TEST_NO_LE)
  951. || is_same<Arg, double_limb_type>::value || is_same<Arg, signed_double_limb_type>::value
  952. #endif
  953. #if defined(BOOST_MP_USER_DEFINED_LITERALS)
  954. || literals::detail::is_value_pack<Arg>::value
  955. #endif
  956. || (is_trivial_cpp_int<Base>::value && is_arithmetic<Arg>::value),
  957. mpl::true_,
  958. mpl::false_
  959. >::type
  960. {};
  961. //
  962. // Now the actual backend, normalising parameters passed to the base class:
  963. //
  964. template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
  965. struct cpp_int_backend
  966. : public cpp_int_base<
  967. min_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
  968. max_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
  969. SignType,
  970. Checked,
  971. Allocator,
  972. is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value>
  973. {
  974. typedef cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> self_type;
  975. typedef cpp_int_base<
  976. min_precision<self_type>::value,
  977. max_precision<self_type>::value,
  978. SignType,
  979. Checked,
  980. Allocator,
  981. is_trivial_cpp_int<self_type>::value> base_type;
  982. typedef mpl::bool_<is_trivial_cpp_int<self_type>::value> trivial_tag;
  983. public:
  984. typedef typename mpl::if_<
  985. trivial_tag,
  986. mpl::list<
  987. signed char, short, int, long,
  988. boost::long_long_type, signed_double_limb_type>,
  989. mpl::list<signed_limb_type, signed_double_limb_type>
  990. >::type signed_types;
  991. typedef typename mpl::if_<
  992. trivial_tag,
  993. mpl::list<unsigned char, unsigned short, unsigned,
  994. unsigned long, boost::ulong_long_type, double_limb_type>,
  995. mpl::list<limb_type, double_limb_type>
  996. >::type unsigned_types;
  997. typedef typename mpl::if_<
  998. trivial_tag,
  999. mpl::list<float, double, long double>,
  1000. mpl::list<long double>
  1001. >::type float_types;
  1002. typedef mpl::int_<Checked> checked_type;
  1003. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend() BOOST_NOEXCEPT{}
  1004. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF(boost::is_void<Allocator>::value) : base_type(o) {}
  1005. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1006. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(cpp_int_backend&& o) BOOST_NOEXCEPT
  1007. : base_type(static_cast<base_type&&>(o)) {}
  1008. #endif
  1009. //
  1010. // Direct construction from arithmetic type:
  1011. //
  1012. template <class Arg>
  1013. BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(Arg i, typename boost::enable_if_c<is_allowed_cpp_int_base_conversion<Arg, base_type>::value >::type const* = 0)BOOST_MP_NOEXCEPT_IF(noexcept(base_type(std::declval<Arg>())))
  1014. : base_type(i) {}
  1015. private:
  1016. template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1017. void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, mpl::true_ const&, mpl::true_ const &)
  1018. {
  1019. // Assigning trivial type to trivial type:
  1020. this->check_in_range(*other.limbs());
  1021. *this->limbs() = static_cast<typename self_type::local_limb_type>(*other.limbs());
  1022. this->sign(other.sign());
  1023. this->normalize();
  1024. }
  1025. template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1026. void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, mpl::true_ const&, mpl::false_ const &)
  1027. {
  1028. // non-trivial to trivial narrowing conversion:
  1029. double_limb_type v = *other.limbs();
  1030. if(other.size() > 1)
  1031. {
  1032. v |= static_cast<double_limb_type>(other.limbs()[1]) << bits_per_limb;
  1033. if((Checked == checked) && (other.size() > 2))
  1034. {
  1035. BOOST_THROW_EXCEPTION(std::range_error("Assignment of a cpp_int that is out of range for the target type."));
  1036. }
  1037. }
  1038. *this = v;
  1039. this->sign(other.sign());
  1040. this->normalize();
  1041. }
  1042. template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1043. void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, mpl::false_ const&, mpl::true_ const &)
  1044. {
  1045. // trivial to non-trivial, treat the trivial argument as if it were an unsigned arithmetic type, then set the sign afterwards:
  1046. *this = static_cast<
  1047. typename boost::multiprecision::detail::canonical<
  1048. typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::local_limb_type,
  1049. cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>
  1050. >::type
  1051. >(*other.limbs());
  1052. this->sign(other.sign());
  1053. }
  1054. template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1055. void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, mpl::false_ const&, mpl::false_ const &)
  1056. {
  1057. // regular non-trivial to non-trivial assign:
  1058. this->resize(other.size(), other.size());
  1059. std::memcpy(this->limbs(), other.limbs(), (std::min)(other.size(), this->size()) * sizeof(this->limbs()[0]));
  1060. this->sign(other.sign());
  1061. this->normalize();
  1062. }
  1063. public:
  1064. template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1065. cpp_int_backend(
  1066. const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other,
  1067. typename boost::enable_if_c<is_implicit_cpp_int_conversion<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>, self_type>::value>::type* = 0)
  1068. : base_type()
  1069. {
  1070. do_assign(
  1071. other,
  1072. mpl::bool_<is_trivial_cpp_int<self_type>::value>(),
  1073. mpl::bool_<is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>());
  1074. }
  1075. template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1076. explicit cpp_int_backend(
  1077. const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other,
  1078. typename boost::disable_if_c<is_implicit_cpp_int_conversion<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>, self_type>::value>::type* = 0)
  1079. : base_type()
  1080. {
  1081. do_assign(
  1082. other,
  1083. mpl::bool_<is_trivial_cpp_int<self_type>::value>(),
  1084. mpl::bool_<is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>());
  1085. }
  1086. template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1087. cpp_int_backend& operator=(
  1088. const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other)
  1089. {
  1090. do_assign(
  1091. other,
  1092. mpl::bool_<is_trivial_cpp_int<self_type>::value>(),
  1093. mpl::bool_<is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>());
  1094. return *this;
  1095. }
  1096. #ifdef BOOST_MP_USER_DEFINED_LITERALS
  1097. BOOST_CONSTEXPR cpp_int_backend(const cpp_int_backend& a, const literals::detail::negate_tag& tag)
  1098. : base_type(static_cast<const base_type&>(a), tag){}
  1099. #endif
  1100. BOOST_MP_FORCEINLINE cpp_int_backend& operator = (const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().assign(std::declval<const cpp_int_backend&>())))
  1101. {
  1102. this->assign(o);
  1103. return *this;
  1104. }
  1105. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1106. BOOST_MP_FORCEINLINE cpp_int_backend& operator = (cpp_int_backend&& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<base_type&>() = std::declval<base_type>()))
  1107. {
  1108. *static_cast<base_type*>(this) = static_cast<base_type&&>(o);
  1109. return *this;
  1110. }
  1111. #endif
  1112. private:
  1113. template <class A>
  1114. typename boost::enable_if<is_unsigned<A> >::type do_assign_arithmetic(A val, const mpl::true_&)
  1115. BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>())))
  1116. {
  1117. this->check_in_range(val);
  1118. *this->limbs() = static_cast<typename self_type::local_limb_type>(val);
  1119. this->sign(false);
  1120. this->normalize();
  1121. }
  1122. template <class A>
  1123. typename boost::disable_if_c<is_unsigned<A>::value || !is_integral<A>::value >::type do_assign_arithmetic(A val, const mpl::true_&)
  1124. BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>())) && noexcept(std::declval<cpp_int_backend>().sign(true)))
  1125. {
  1126. this->check_in_range(val);
  1127. *this->limbs() = (val < 0) ? static_cast<typename self_type::local_limb_type>(boost::multiprecision::detail::unsigned_abs(val)) : static_cast<typename self_type::local_limb_type>(val);
  1128. this->sign(val < 0);
  1129. this->normalize();
  1130. }
  1131. template <class A>
  1132. typename boost::enable_if_c< !is_integral<A>::value>::type do_assign_arithmetic(A val, const mpl::true_&)
  1133. {
  1134. this->check_in_range(val);
  1135. *this->limbs() = (val < 0) ? static_cast<typename self_type::local_limb_type>(boost::multiprecision::detail::abs(val)) : static_cast<typename self_type::local_limb_type>(val);
  1136. this->sign(val < 0);
  1137. this->normalize();
  1138. }
  1139. BOOST_MP_FORCEINLINE void do_assign_arithmetic(limb_type i, const mpl::false_&) BOOST_NOEXCEPT
  1140. {
  1141. this->resize(1, 1);
  1142. *this->limbs() = i;
  1143. this->sign(false);
  1144. }
  1145. BOOST_MP_FORCEINLINE void do_assign_arithmetic(signed_limb_type i, const mpl::false_&) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().sign(true)))
  1146. {
  1147. this->resize(1, 1);
  1148. *this->limbs() = static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(i));
  1149. this->sign(i < 0);
  1150. }
  1151. void do_assign_arithmetic(double_limb_type i, const mpl::false_&) BOOST_NOEXCEPT
  1152. {
  1153. BOOST_STATIC_ASSERT(sizeof(i) == 2 * sizeof(limb_type));
  1154. BOOST_STATIC_ASSERT(base_type::internal_limb_count >= 2);
  1155. typename base_type::limb_pointer p = this->limbs();
  1156. #ifdef __MSVC_RUNTIME_CHECKS
  1157. *p = static_cast<limb_type>(i & ~static_cast<limb_type>(0));
  1158. #else
  1159. *p = static_cast<limb_type>(i);
  1160. #endif
  1161. p[1] = static_cast<limb_type>(i >> base_type::limb_bits);
  1162. this->resize(p[1] ? 2 : 1, p[1] ? 2 : 1);
  1163. this->sign(false);
  1164. }
  1165. void do_assign_arithmetic(signed_double_limb_type i, const mpl::false_&) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().sign(true)))
  1166. {
  1167. BOOST_STATIC_ASSERT(sizeof(i) == 2 * sizeof(limb_type));
  1168. BOOST_STATIC_ASSERT(base_type::internal_limb_count >= 2);
  1169. bool s = false;
  1170. double_limb_type ui;
  1171. if(i < 0)
  1172. s = true;
  1173. ui = static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i));
  1174. typename base_type::limb_pointer p = this->limbs();
  1175. #ifdef __MSVC_RUNTIME_CHECKS
  1176. *p = static_cast<limb_type>(ui & ~static_cast<limb_type>(0));
  1177. #else
  1178. *p = static_cast<limb_type>(ui);
  1179. #endif
  1180. p[1] = static_cast<limb_type>(ui >> base_type::limb_bits);
  1181. this->resize(p[1] ? 2 : 1, p[1] ? 2 : 1);
  1182. this->sign(s);
  1183. }
  1184. void do_assign_arithmetic(long double a, const mpl::false_&)
  1185. {
  1186. using default_ops::eval_add;
  1187. using default_ops::eval_subtract;
  1188. using std::frexp;
  1189. using std::ldexp;
  1190. using std::floor;
  1191. if(a < 0)
  1192. {
  1193. do_assign_arithmetic(-a, mpl::false_());
  1194. this->sign(true);
  1195. return;
  1196. }
  1197. if (a == 0) {
  1198. *this = static_cast<limb_type>(0u);
  1199. }
  1200. if (a == 1) {
  1201. *this = static_cast<limb_type>(1u);
  1202. }
  1203. BOOST_ASSERT(!(boost::math::isinf)(a));
  1204. BOOST_ASSERT(!(boost::math::isnan)(a));
  1205. int e;
  1206. long double f, term;
  1207. *this = static_cast<limb_type>(0u);
  1208. f = frexp(a, &e);
  1209. static const limb_type shift = std::numeric_limits<limb_type>::digits;
  1210. while(f)
  1211. {
  1212. // extract int sized bits from f:
  1213. f = ldexp(f, shift);
  1214. term = floor(f);
  1215. e -= shift;
  1216. eval_left_shift(*this, shift);
  1217. if(term > 0)
  1218. eval_add(*this, static_cast<limb_type>(term));
  1219. else
  1220. eval_subtract(*this, static_cast<limb_type>(-term));
  1221. f -= term;
  1222. }
  1223. if(e > 0)
  1224. eval_left_shift(*this, e);
  1225. else if(e < 0)
  1226. eval_right_shift(*this, -e);
  1227. }
  1228. public:
  1229. template <class Arithmetic>
  1230. BOOST_MP_FORCEINLINE typename boost::enable_if_c<!boost::multiprecision::detail::is_byte_container<Arithmetic>::value, cpp_int_backend&>::type operator = (Arithmetic val) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().do_assign_arithmetic(std::declval<Arithmetic>(), trivial_tag())))
  1231. {
  1232. do_assign_arithmetic(val, trivial_tag());
  1233. return *this;
  1234. }
  1235. private:
  1236. void do_assign_string(const char* s, const mpl::true_&)
  1237. {
  1238. std::size_t n = s ? std::strlen(s) : 0;
  1239. *this = 0;
  1240. unsigned radix = 10;
  1241. bool isneg = false;
  1242. if(n && (*s == '-'))
  1243. {
  1244. --n;
  1245. ++s;
  1246. isneg = true;
  1247. }
  1248. if(n && (*s == '0'))
  1249. {
  1250. if((n > 1) && ((s[1] == 'x') || (s[1] == 'X')))
  1251. {
  1252. radix = 16;
  1253. s +=2;
  1254. n -= 2;
  1255. }
  1256. else
  1257. {
  1258. radix = 8;
  1259. n -= 1;
  1260. }
  1261. }
  1262. if(n)
  1263. {
  1264. unsigned val;
  1265. while(*s)
  1266. {
  1267. if(*s >= '0' && *s <= '9')
  1268. val = *s - '0';
  1269. else if(*s >= 'a' && *s <= 'f')
  1270. val = 10 + *s - 'a';
  1271. else if(*s >= 'A' && *s <= 'F')
  1272. val = 10 + *s - 'A';
  1273. else
  1274. val = radix + 1;
  1275. if(val >= radix)
  1276. {
  1277. BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string."));
  1278. }
  1279. *this->limbs() = detail::checked_multiply(*this->limbs(), static_cast<typename base_type::local_limb_type>(radix), checked_type());
  1280. *this->limbs() = detail::checked_add(*this->limbs(), static_cast<typename base_type::local_limb_type>(val), checked_type());
  1281. ++s;
  1282. }
  1283. }
  1284. if(isneg)
  1285. this->negate();
  1286. }
  1287. void do_assign_string(const char* s, const mpl::false_&)
  1288. {
  1289. using default_ops::eval_multiply;
  1290. using default_ops::eval_add;
  1291. std::size_t n = s ? std::strlen(s) : 0;
  1292. *this = static_cast<limb_type>(0u);
  1293. unsigned radix = 10;
  1294. bool isneg = false;
  1295. if(n && (*s == '-'))
  1296. {
  1297. --n;
  1298. ++s;
  1299. isneg = true;
  1300. }
  1301. if(n && (*s == '0'))
  1302. {
  1303. if((n > 1) && ((s[1] == 'x') || (s[1] == 'X')))
  1304. {
  1305. radix = 16;
  1306. s +=2;
  1307. n -= 2;
  1308. }
  1309. else
  1310. {
  1311. radix = 8;
  1312. n -= 1;
  1313. }
  1314. }
  1315. //
  1316. // Exception guarantee: create the result in stack variable "result"
  1317. // then do a swap at the end. In the event of a throw, *this will
  1318. // be left unchanged.
  1319. //
  1320. cpp_int_backend result;
  1321. if(n)
  1322. {
  1323. if(radix == 16)
  1324. {
  1325. while(*s == '0') ++s;
  1326. std::size_t bitcount = 4 * std::strlen(s);
  1327. limb_type val;
  1328. std::size_t limb, shift;
  1329. if(bitcount > 4)
  1330. bitcount -= 4;
  1331. else
  1332. bitcount = 0;
  1333. std::size_t newsize = bitcount / (sizeof(limb_type) * CHAR_BIT) + 1;
  1334. result.resize(static_cast<unsigned>(newsize), static_cast<unsigned>(newsize)); // will throw if this is a checked integer that cannot be resized
  1335. std::memset(result.limbs(), 0, result.size() * sizeof(limb_type));
  1336. while(*s)
  1337. {
  1338. if(*s >= '0' && *s <= '9')
  1339. val = *s - '0';
  1340. else if(*s >= 'a' && *s <= 'f')
  1341. val = 10 + *s - 'a';
  1342. else if(*s >= 'A' && *s <= 'F')
  1343. val = 10 + *s - 'A';
  1344. else
  1345. {
  1346. BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string."));
  1347. }
  1348. limb = bitcount / (sizeof(limb_type) * CHAR_BIT);
  1349. shift = bitcount % (sizeof(limb_type) * CHAR_BIT);
  1350. val <<= shift;
  1351. if(result.size() > limb)
  1352. {
  1353. result.limbs()[limb] |= val;
  1354. }
  1355. ++s;
  1356. bitcount -= 4;
  1357. }
  1358. result.normalize();
  1359. }
  1360. else if(radix == 8)
  1361. {
  1362. while(*s == '0') ++s;
  1363. std::size_t bitcount = 3 * std::strlen(s);
  1364. limb_type val;
  1365. std::size_t limb, shift;
  1366. if(bitcount > 3)
  1367. bitcount -= 3;
  1368. else
  1369. bitcount = 0;
  1370. std::size_t newsize = bitcount / (sizeof(limb_type) * CHAR_BIT) + 1;
  1371. result.resize(static_cast<unsigned>(newsize), static_cast<unsigned>(newsize)); // will throw if this is a checked integer that cannot be resized
  1372. std::memset(result.limbs(), 0, result.size() * sizeof(limb_type));
  1373. while(*s)
  1374. {
  1375. if(*s >= '0' && *s <= '7')
  1376. val = *s - '0';
  1377. else
  1378. {
  1379. BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string."));
  1380. }
  1381. limb = bitcount / (sizeof(limb_type) * CHAR_BIT);
  1382. shift = bitcount % (sizeof(limb_type) * CHAR_BIT);
  1383. if(result.size() > limb)
  1384. {
  1385. result.limbs()[limb] |= (val << shift);
  1386. if(shift > sizeof(limb_type) * CHAR_BIT - 3)
  1387. {
  1388. // Deal with the bits in val that overflow into the next limb:
  1389. val >>= (sizeof(limb_type) * CHAR_BIT - shift);
  1390. if(val)
  1391. {
  1392. // If this is the most-significant-limb, we may need to allocate an extra one for the overflow:
  1393. if(limb + 1 == newsize)
  1394. result.resize(static_cast<unsigned>(newsize + 1), static_cast<unsigned>(newsize + 1));
  1395. if(result.size() > limb + 1)
  1396. {
  1397. result.limbs()[limb + 1] |= val;
  1398. }
  1399. }
  1400. }
  1401. }
  1402. ++s;
  1403. bitcount -= 3;
  1404. }
  1405. result.normalize();
  1406. }
  1407. else
  1408. {
  1409. // Base 10, we extract blocks of size 10^9 at a time, that way
  1410. // the number of multiplications is kept to a minimum:
  1411. limb_type block_mult = max_block_10;
  1412. while(*s)
  1413. {
  1414. limb_type block = 0;
  1415. for(unsigned i = 0; i < digits_per_block_10; ++i)
  1416. {
  1417. limb_type val;
  1418. if(*s >= '0' && *s <= '9')
  1419. val = *s - '0';
  1420. else
  1421. BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected character encountered in input."));
  1422. block *= 10;
  1423. block += val;
  1424. if(!*++s)
  1425. {
  1426. block_mult = block_multiplier(i);
  1427. break;
  1428. }
  1429. }
  1430. eval_multiply(result, block_mult);
  1431. eval_add(result, block);
  1432. }
  1433. }
  1434. }
  1435. if(isneg)
  1436. result.negate();
  1437. result.swap(*this);
  1438. }
  1439. public:
  1440. cpp_int_backend& operator = (const char* s)
  1441. {
  1442. do_assign_string(s, trivial_tag());
  1443. return *this;
  1444. }
  1445. BOOST_MP_FORCEINLINE void swap(cpp_int_backend& o) BOOST_NOEXCEPT
  1446. {
  1447. this->do_swap(o);
  1448. }
  1449. private:
  1450. std::string do_get_trivial_string(std::ios_base::fmtflags f, const mpl::false_&)const
  1451. {
  1452. typedef typename mpl::if_c<sizeof(typename base_type::local_limb_type) == 1, unsigned, typename base_type::local_limb_type>::type io_type;
  1453. if(this->sign() && (((f & std::ios_base::hex) == std::ios_base::hex) || ((f & std::ios_base::oct) == std::ios_base::oct)))
  1454. BOOST_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported."));
  1455. std::stringstream ss;
  1456. ss.flags(f & ~std::ios_base::showpos);
  1457. ss << static_cast<io_type>(*this->limbs());
  1458. std::string result;
  1459. if(this->sign())
  1460. result += '-';
  1461. else if(f & std::ios_base::showpos)
  1462. result += '+';
  1463. result += ss.str();
  1464. return result;
  1465. }
  1466. std::string do_get_trivial_string(std::ios_base::fmtflags f, const mpl::true_&)const
  1467. {
  1468. // Even though we have only one limb, we can't do IO on it :-(
  1469. int base = 10;
  1470. if((f & std::ios_base::oct) == std::ios_base::oct)
  1471. base = 8;
  1472. else if((f & std::ios_base::hex) == std::ios_base::hex)
  1473. base = 16;
  1474. std::string result;
  1475. unsigned Bits = sizeof(typename base_type::local_limb_type) * CHAR_BIT;
  1476. if(base == 8 || base == 16)
  1477. {
  1478. if(this->sign())
  1479. BOOST_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported."));
  1480. limb_type shift = base == 8 ? 3 : 4;
  1481. limb_type mask = static_cast<limb_type>((1u << shift) - 1);
  1482. typename base_type::local_limb_type v = *this->limbs();
  1483. result.assign(Bits / shift + (Bits % shift ? 1 : 0), '0');
  1484. std::string::difference_type pos = result.size() - 1;
  1485. for(unsigned i = 0; i < Bits / shift; ++i)
  1486. {
  1487. char c = '0' + static_cast<char>(v & mask);
  1488. if(c > '9')
  1489. c += 'A' - '9' - 1;
  1490. result[pos--] = c;
  1491. v >>= shift;
  1492. }
  1493. if(Bits % shift)
  1494. {
  1495. mask = static_cast<limb_type>((1u << (Bits % shift)) - 1);
  1496. char c = '0' + static_cast<char>(v & mask);
  1497. if(c > '9')
  1498. c += 'A' - '9';
  1499. result[pos] = c;
  1500. }
  1501. //
  1502. // Get rid of leading zeros:
  1503. //
  1504. std::string::size_type n = result.find_first_not_of('0');
  1505. if(!result.empty() && (n == std::string::npos))
  1506. n = result.size() - 1;
  1507. result.erase(0, n);
  1508. if(f & std::ios_base::showbase)
  1509. {
  1510. const char* pp = base == 8 ? "0" : "0x";
  1511. result.insert(static_cast<std::string::size_type>(0), pp);
  1512. }
  1513. }
  1514. else
  1515. {
  1516. result.assign(Bits / 3 + 1, '0');
  1517. std::string::difference_type pos = result.size() - 1;
  1518. typename base_type::local_limb_type v(*this->limbs());
  1519. bool neg = false;
  1520. if(this->sign())
  1521. {
  1522. neg = true;
  1523. }
  1524. while(v)
  1525. {
  1526. result[pos] = (v % 10) + '0';
  1527. --pos;
  1528. v /= 10;
  1529. }
  1530. std::string::size_type n = result.find_first_not_of('0');
  1531. result.erase(0, n);
  1532. if(result.empty())
  1533. result = "0";
  1534. if(neg)
  1535. result.insert(static_cast<std::string::size_type>(0), 1, '-');
  1536. else if(f & std::ios_base::showpos)
  1537. result.insert(static_cast<std::string::size_type>(0), 1, '+');
  1538. }
  1539. return result;
  1540. }
  1541. std::string do_get_string(std::ios_base::fmtflags f, const mpl::true_&)const
  1542. {
  1543. #ifdef BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO
  1544. return do_get_trivial_string(f, mpl::bool_<is_same<typename base_type::local_limb_type, double_limb_type>::value>());
  1545. #else
  1546. return do_get_trivial_string(f, mpl::bool_<false>());
  1547. #endif
  1548. }
  1549. std::string do_get_string(std::ios_base::fmtflags f, const mpl::false_&)const
  1550. {
  1551. using default_ops::eval_get_sign;
  1552. int base = 10;
  1553. if((f & std::ios_base::oct) == std::ios_base::oct)
  1554. base = 8;
  1555. else if((f & std::ios_base::hex) == std::ios_base::hex)
  1556. base = 16;
  1557. std::string result;
  1558. unsigned Bits = this->size() * base_type::limb_bits;
  1559. if(base == 8 || base == 16)
  1560. {
  1561. if(this->sign())
  1562. BOOST_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported."));
  1563. limb_type shift = base == 8 ? 3 : 4;
  1564. limb_type mask = static_cast<limb_type>((1u << shift) - 1);
  1565. cpp_int_backend t(*this);
  1566. result.assign(Bits / shift + ((Bits % shift) ? 1 : 0), '0');
  1567. std::string::difference_type pos = result.size() - 1;
  1568. for(unsigned i = 0; i < Bits / shift; ++i)
  1569. {
  1570. char c = '0' + static_cast<char>(t.limbs()[0] & mask);
  1571. if(c > '9')
  1572. c += 'A' - '9' - 1;
  1573. result[pos--] = c;
  1574. eval_right_shift(t, shift);
  1575. }
  1576. if(Bits % shift)
  1577. {
  1578. mask = static_cast<limb_type>((1u << (Bits % shift)) - 1);
  1579. char c = '0' + static_cast<char>(t.limbs()[0] & mask);
  1580. if(c > '9')
  1581. c += 'A' - '9';
  1582. result[pos] = c;
  1583. }
  1584. //
  1585. // Get rid of leading zeros:
  1586. //
  1587. std::string::size_type n = result.find_first_not_of('0');
  1588. if(!result.empty() && (n == std::string::npos))
  1589. n = result.size() - 1;
  1590. result.erase(0, n);
  1591. if(f & std::ios_base::showbase)
  1592. {
  1593. const char* pp = base == 8 ? "0" : "0x";
  1594. result.insert(static_cast<std::string::size_type>(0), pp);
  1595. }
  1596. }
  1597. else
  1598. {
  1599. result.assign(Bits / 3 + 1, '0');
  1600. std::string::difference_type pos = result.size() - 1;
  1601. cpp_int_backend t(*this);
  1602. cpp_int_backend r;
  1603. bool neg = false;
  1604. if(t.sign())
  1605. {
  1606. t.negate();
  1607. neg = true;
  1608. }
  1609. if(this->size() == 1)
  1610. {
  1611. result = boost::lexical_cast<std::string>(t.limbs()[0]);
  1612. }
  1613. else
  1614. {
  1615. cpp_int_backend block10;
  1616. block10 = max_block_10;
  1617. while(eval_get_sign(t) != 0)
  1618. {
  1619. cpp_int_backend t2;
  1620. divide_unsigned_helper(&t2, t, block10, r);
  1621. t = t2;
  1622. limb_type v = r.limbs()[0];
  1623. for(unsigned i = 0; i < digits_per_block_10; ++i)
  1624. {
  1625. char c = '0' + v % 10;
  1626. v /= 10;
  1627. result[pos] = c;
  1628. if(pos-- == 0)
  1629. break;
  1630. }
  1631. }
  1632. }
  1633. std::string::size_type n = result.find_first_not_of('0');
  1634. result.erase(0, n);
  1635. if(result.empty())
  1636. result = "0";
  1637. if(neg)
  1638. result.insert(static_cast<std::string::size_type>(0), 1, '-');
  1639. else if(f & std::ios_base::showpos)
  1640. result.insert(static_cast<std::string::size_type>(0), 1, '+');
  1641. }
  1642. return result;
  1643. }
  1644. public:
  1645. std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
  1646. {
  1647. return do_get_string(f, trivial_tag());
  1648. }
  1649. private:
  1650. template <class Container>
  1651. void construct_from_container(const Container& c, const mpl::false_&)
  1652. {
  1653. //
  1654. // We assume that c is a sequence of (unsigned) bytes with the most significant byte first:
  1655. //
  1656. unsigned newsize = static_cast<unsigned>(c.size() / sizeof(limb_type));
  1657. if(c.size() % sizeof(limb_type))
  1658. {
  1659. ++newsize;
  1660. }
  1661. if(newsize)
  1662. {
  1663. this->resize(newsize, newsize); // May throw
  1664. std::memset(this->limbs(), 0, this->size());
  1665. typename Container::const_iterator i(c.begin()), j(c.end());
  1666. unsigned byte_location = static_cast<unsigned>(c.size() - 1);
  1667. while(i != j)
  1668. {
  1669. unsigned limb = byte_location / sizeof(limb_type);
  1670. unsigned shift = (byte_location % sizeof(limb_type)) * CHAR_BIT;
  1671. if(this->size() > limb)
  1672. this->limbs()[limb] |= static_cast<limb_type>(static_cast<unsigned char>(*i)) << shift;
  1673. ++i;
  1674. --byte_location;
  1675. }
  1676. }
  1677. }
  1678. template <class Container>
  1679. void construct_from_container(const Container& c, const mpl::true_&)
  1680. {
  1681. //
  1682. // We assume that c is a sequence of (unsigned) bytes with the most significant byte first:
  1683. //
  1684. typedef typename base_type::local_limb_type local_limb_type;
  1685. *this->limbs() = 0;
  1686. if(c.size())
  1687. {
  1688. typename Container::const_iterator i(c.begin()), j(c.end());
  1689. unsigned byte_location = static_cast<unsigned>(c.size() - 1);
  1690. while(i != j)
  1691. {
  1692. unsigned limb = byte_location / sizeof(local_limb_type);
  1693. unsigned shift = (byte_location % sizeof(local_limb_type)) * CHAR_BIT;
  1694. if(limb == 0)
  1695. this->limbs()[0] |= static_cast<limb_type>(static_cast<unsigned char>(*i)) << shift;
  1696. ++i;
  1697. --byte_location;
  1698. }
  1699. }
  1700. }
  1701. public:
  1702. template <class Container>
  1703. cpp_int_backend(const Container& c, typename boost::enable_if_c<boost::multiprecision::detail::is_byte_container<Container>::value>::type const* = 0)
  1704. {
  1705. //
  1706. // We assume that c is a sequence of (unsigned) bytes with the most significant byte first:
  1707. //
  1708. construct_from_container(c, trivial_tag());
  1709. }
  1710. template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1711. int compare_imp(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const mpl::false_&, const mpl::false_&)const BOOST_NOEXCEPT
  1712. {
  1713. if(this->sign() != o.sign())
  1714. return this->sign() ? -1 : 1;
  1715. // Only do the compare if the same sign:
  1716. int result = compare_unsigned(o);
  1717. if(this->sign())
  1718. result = -result;
  1719. return result;
  1720. }
  1721. template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1722. int compare_imp(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const mpl::true_&, const mpl::false_&)const
  1723. {
  1724. cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> t(*this);
  1725. return t.compare(o);
  1726. }
  1727. template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1728. int compare_imp(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const mpl::false_&, const mpl::true_&)const
  1729. {
  1730. cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> t(o);
  1731. return compare(t);
  1732. }
  1733. template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1734. int compare_imp(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const mpl::true_&, const mpl::true_&)const BOOST_NOEXCEPT
  1735. {
  1736. if(this->sign())
  1737. {
  1738. if(o.sign())
  1739. {
  1740. return *this->limbs() < *o.limbs() ? 1 : (*this->limbs() > *o.limbs() ? -1 : 0);
  1741. }
  1742. else
  1743. return -1;
  1744. }
  1745. else
  1746. {
  1747. if(o.sign())
  1748. return 1;
  1749. return *this->limbs() < *o.limbs() ? -1 : (*this->limbs() > *o.limbs() ? 1 : 0);
  1750. }
  1751. }
  1752. template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1753. int compare(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o)const BOOST_NOEXCEPT
  1754. {
  1755. typedef mpl::bool_<is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value> t1;
  1756. typedef mpl::bool_<is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value> t2;
  1757. return compare_imp(o, t1(), t2());
  1758. }
  1759. template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1760. int compare_unsigned(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o)const BOOST_NOEXCEPT
  1761. {
  1762. if(this->size() != o.size())
  1763. {
  1764. return this->size() > o.size() ? 1 : -1;
  1765. }
  1766. typename base_type::const_limb_pointer pa = this->limbs();
  1767. typename base_type::const_limb_pointer pb = o.limbs();
  1768. for(int i = this->size() - 1; i >= 0; --i)
  1769. {
  1770. if(pa[i] != pb[i])
  1771. return pa[i] > pb[i] ? 1 : -1;
  1772. }
  1773. return 0;
  1774. }
  1775. template <class Arithmetic>
  1776. BOOST_MP_FORCEINLINE typename boost::enable_if<is_arithmetic<Arithmetic>, int>::type compare(Arithmetic i)const
  1777. {
  1778. // braindead version:
  1779. cpp_int_backend t;
  1780. t = i;
  1781. return compare(t);
  1782. }
  1783. };
  1784. } // namespace backends
  1785. namespace default_ops{
  1786. template <class Backend>
  1787. struct double_precision_type;
  1788. template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
  1789. struct double_precision_type<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
  1790. {
  1791. typedef typename mpl::if_c<
  1792. backends::is_fixed_precision<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
  1793. backends::cpp_int_backend<
  1794. (is_void<Allocator>::value ?
  1795. 2 * backends::max_precision<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value
  1796. : MinBits),
  1797. 2 * backends::max_precision<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
  1798. SignType,
  1799. Checked,
  1800. Allocator>,
  1801. backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>
  1802. >::type type;
  1803. };
  1804. }
  1805. template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked>
  1806. struct expression_template_default<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, void> >
  1807. {
  1808. static const expression_template_option value = et_off;
  1809. };
  1810. using boost::multiprecision::backends::cpp_int_backend;
  1811. template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
  1812. struct number_category<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> > : public mpl::int_<number_kind_integer>{};
  1813. typedef number<cpp_int_backend<> > cpp_int;
  1814. typedef rational_adaptor<cpp_int_backend<> > cpp_rational_backend;
  1815. typedef number<cpp_rational_backend> cpp_rational;
  1816. // Fixed precision unsigned types:
  1817. typedef number<cpp_int_backend<128, 128, unsigned_magnitude, unchecked, void> > uint128_t;
  1818. typedef number<cpp_int_backend<256, 256, unsigned_magnitude, unchecked, void> > uint256_t;
  1819. typedef number<cpp_int_backend<512, 512, unsigned_magnitude, unchecked, void> > uint512_t;
  1820. typedef number<cpp_int_backend<1024, 1024, unsigned_magnitude, unchecked, void> > uint1024_t;
  1821. // Fixed precision signed types:
  1822. typedef number<cpp_int_backend<128, 128, signed_magnitude, unchecked, void> > int128_t;
  1823. typedef number<cpp_int_backend<256, 256, signed_magnitude, unchecked, void> > int256_t;
  1824. typedef number<cpp_int_backend<512, 512, signed_magnitude, unchecked, void> > int512_t;
  1825. typedef number<cpp_int_backend<1024, 1024, signed_magnitude, unchecked, void> > int1024_t;
  1826. // Over again, but with checking enabled this time:
  1827. typedef number<cpp_int_backend<0, 0, signed_magnitude, checked> > checked_cpp_int;
  1828. typedef rational_adaptor<cpp_int_backend<0, 0, signed_magnitude, checked> > checked_cpp_rational_backend;
  1829. typedef number<checked_cpp_rational_backend> checked_cpp_rational;
  1830. // Fixed precision unsigned types:
  1831. typedef number<cpp_int_backend<128, 128, unsigned_magnitude, checked, void> > checked_uint128_t;
  1832. typedef number<cpp_int_backend<256, 256, unsigned_magnitude, checked, void> > checked_uint256_t;
  1833. typedef number<cpp_int_backend<512, 512, unsigned_magnitude, checked, void> > checked_uint512_t;
  1834. typedef number<cpp_int_backend<1024, 1024, unsigned_magnitude, checked, void> > checked_uint1024_t;
  1835. // Fixed precision signed types:
  1836. typedef number<cpp_int_backend<128, 128, signed_magnitude, checked, void> > checked_int128_t;
  1837. typedef number<cpp_int_backend<256, 256, signed_magnitude, checked, void> > checked_int256_t;
  1838. typedef number<cpp_int_backend<512, 512, signed_magnitude, checked, void> > checked_int512_t;
  1839. typedef number<cpp_int_backend<1024, 1024, signed_magnitude, checked, void> > checked_int1024_t;
  1840. #ifdef BOOST_NO_SFINAE_EXPR
  1841. namespace detail{
  1842. template<unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  1843. struct is_explicitly_convertible<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> > : public mpl::true_ {};
  1844. }
  1845. #endif
  1846. #ifdef _MSC_VER
  1847. #pragma warning(pop)
  1848. #endif
  1849. }} // namespaces
  1850. //
  1851. // Last of all we include the implementations of all the eval_* non member functions:
  1852. //
  1853. #include <boost/multiprecision/cpp_int/comparison.hpp>
  1854. #include <boost/multiprecision/cpp_int/add.hpp>
  1855. #include <boost/multiprecision/cpp_int/multiply.hpp>
  1856. #include <boost/multiprecision/cpp_int/divide.hpp>
  1857. #include <boost/multiprecision/cpp_int/bitwise.hpp>
  1858. #include <boost/multiprecision/cpp_int/misc.hpp>
  1859. #include <boost/multiprecision/cpp_int/limits.hpp>
  1860. #ifdef BOOST_MP_USER_DEFINED_LITERALS
  1861. #include <boost/multiprecision/cpp_int/literals.hpp>
  1862. #endif
  1863. #include <boost/multiprecision/cpp_int/serialize.hpp>
  1864. #include <boost/multiprecision/cpp_int/import_export.hpp>
  1865. #endif