mqt-core 3.3.2__cp313-cp313t-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (537) hide show
  1. mqt/core/__init__.py +89 -0
  2. mqt/core/__main__.py +55 -0
  3. mqt/core/_commands.py +52 -0
  4. mqt/core/_compat/__init__.py +11 -0
  5. mqt/core/_compat/typing.py +29 -0
  6. mqt/core/_version.py +34 -0
  7. mqt/core/_version.pyi +12 -0
  8. mqt/core/bin/mqt-core-algorithms.dll +0 -0
  9. mqt/core/bin/mqt-core-circuit-optimizer.dll +0 -0
  10. mqt/core/bin/mqt-core-dd.dll +0 -0
  11. mqt/core/bin/mqt-core-ds.dll +0 -0
  12. mqt/core/bin/mqt-core-fomac.dll +0 -0
  13. mqt/core/bin/mqt-core-ir.dll +0 -0
  14. mqt/core/bin/mqt-core-na-fomac.dll +0 -0
  15. mqt/core/bin/mqt-core-na.dll +0 -0
  16. mqt/core/bin/mqt-core-qasm.dll +0 -0
  17. mqt/core/bin/mqt-core-qdmi-driver.dll +0 -0
  18. mqt/core/bin/mqt-core-qdmi-na-device.dll +0 -0
  19. mqt/core/bin/mqt-core-zx.dll +0 -0
  20. mqt/core/dd.cp313t-win_amd64.pyd +0 -0
  21. mqt/core/dd.pyi +1016 -0
  22. mqt/core/dd_evaluation.py +368 -0
  23. mqt/core/fomac.cp313t-win_amd64.pyd +0 -0
  24. mqt/core/fomac.pyi +125 -0
  25. mqt/core/include/mqt-core/algorithms/BernsteinVazirani.hpp +39 -0
  26. mqt/core/include/mqt-core/algorithms/GHZState.hpp +18 -0
  27. mqt/core/include/mqt-core/algorithms/Grover.hpp +33 -0
  28. mqt/core/include/mqt-core/algorithms/QFT.hpp +21 -0
  29. mqt/core/include/mqt-core/algorithms/QPE.hpp +30 -0
  30. mqt/core/include/mqt-core/algorithms/RandomCliffordCircuit.hpp +22 -0
  31. mqt/core/include/mqt-core/algorithms/StatePreparation.hpp +43 -0
  32. mqt/core/include/mqt-core/algorithms/WState.hpp +18 -0
  33. mqt/core/include/mqt-core/algorithms/mqt_core_algorithms_export.h +43 -0
  34. mqt/core/include/mqt-core/boost/config/abi/borland_prefix.hpp +27 -0
  35. mqt/core/include/mqt-core/boost/config/abi/borland_suffix.hpp +12 -0
  36. mqt/core/include/mqt-core/boost/config/abi/msvc_prefix.hpp +22 -0
  37. mqt/core/include/mqt-core/boost/config/abi/msvc_suffix.hpp +8 -0
  38. mqt/core/include/mqt-core/boost/config/abi_prefix.hpp +25 -0
  39. mqt/core/include/mqt-core/boost/config/abi_suffix.hpp +25 -0
  40. mqt/core/include/mqt-core/boost/config/assert_cxx03.hpp +211 -0
  41. mqt/core/include/mqt-core/boost/config/assert_cxx11.hpp +212 -0
  42. mqt/core/include/mqt-core/boost/config/assert_cxx14.hpp +47 -0
  43. mqt/core/include/mqt-core/boost/config/assert_cxx17.hpp +65 -0
  44. mqt/core/include/mqt-core/boost/config/assert_cxx20.hpp +59 -0
  45. mqt/core/include/mqt-core/boost/config/assert_cxx23.hpp +41 -0
  46. mqt/core/include/mqt-core/boost/config/assert_cxx98.hpp +23 -0
  47. mqt/core/include/mqt-core/boost/config/auto_link.hpp +525 -0
  48. mqt/core/include/mqt-core/boost/config/compiler/borland.hpp +342 -0
  49. mqt/core/include/mqt-core/boost/config/compiler/clang.hpp +370 -0
  50. mqt/core/include/mqt-core/boost/config/compiler/clang_version.hpp +89 -0
  51. mqt/core/include/mqt-core/boost/config/compiler/codegear.hpp +389 -0
  52. mqt/core/include/mqt-core/boost/config/compiler/comeau.hpp +59 -0
  53. mqt/core/include/mqt-core/boost/config/compiler/common_edg.hpp +185 -0
  54. mqt/core/include/mqt-core/boost/config/compiler/compaq_cxx.hpp +19 -0
  55. mqt/core/include/mqt-core/boost/config/compiler/cray.hpp +446 -0
  56. mqt/core/include/mqt-core/boost/config/compiler/diab.hpp +26 -0
  57. mqt/core/include/mqt-core/boost/config/compiler/digitalmars.hpp +146 -0
  58. mqt/core/include/mqt-core/boost/config/compiler/gcc.hpp +386 -0
  59. mqt/core/include/mqt-core/boost/config/compiler/gcc_xml.hpp +115 -0
  60. mqt/core/include/mqt-core/boost/config/compiler/greenhills.hpp +28 -0
  61. mqt/core/include/mqt-core/boost/config/compiler/hp_acc.hpp +153 -0
  62. mqt/core/include/mqt-core/boost/config/compiler/intel.hpp +577 -0
  63. mqt/core/include/mqt-core/boost/config/compiler/kai.hpp +33 -0
  64. mqt/core/include/mqt-core/boost/config/compiler/metrowerks.hpp +201 -0
  65. mqt/core/include/mqt-core/boost/config/compiler/mpw.hpp +143 -0
  66. mqt/core/include/mqt-core/boost/config/compiler/nvcc.hpp +64 -0
  67. mqt/core/include/mqt-core/boost/config/compiler/pathscale.hpp +141 -0
  68. mqt/core/include/mqt-core/boost/config/compiler/pgi.hpp +23 -0
  69. mqt/core/include/mqt-core/boost/config/compiler/sgi_mipspro.hpp +29 -0
  70. mqt/core/include/mqt-core/boost/config/compiler/sunpro_cc.hpp +225 -0
  71. mqt/core/include/mqt-core/boost/config/compiler/vacpp.hpp +189 -0
  72. mqt/core/include/mqt-core/boost/config/compiler/visualc.hpp +398 -0
  73. mqt/core/include/mqt-core/boost/config/compiler/xlcpp.hpp +303 -0
  74. mqt/core/include/mqt-core/boost/config/compiler/xlcpp_zos.hpp +174 -0
  75. mqt/core/include/mqt-core/boost/config/detail/cxx_composite.hpp +218 -0
  76. mqt/core/include/mqt-core/boost/config/detail/posix_features.hpp +95 -0
  77. mqt/core/include/mqt-core/boost/config/detail/select_compiler_config.hpp +157 -0
  78. mqt/core/include/mqt-core/boost/config/detail/select_platform_config.hpp +147 -0
  79. mqt/core/include/mqt-core/boost/config/detail/select_stdlib_config.hpp +121 -0
  80. mqt/core/include/mqt-core/boost/config/detail/suffix.hpp +1334 -0
  81. mqt/core/include/mqt-core/boost/config/header_deprecated.hpp +26 -0
  82. mqt/core/include/mqt-core/boost/config/helper_macros.hpp +37 -0
  83. mqt/core/include/mqt-core/boost/config/no_tr1/cmath.hpp +28 -0
  84. mqt/core/include/mqt-core/boost/config/no_tr1/complex.hpp +28 -0
  85. mqt/core/include/mqt-core/boost/config/no_tr1/functional.hpp +28 -0
  86. mqt/core/include/mqt-core/boost/config/no_tr1/memory.hpp +28 -0
  87. mqt/core/include/mqt-core/boost/config/no_tr1/utility.hpp +28 -0
  88. mqt/core/include/mqt-core/boost/config/platform/aix.hpp +33 -0
  89. mqt/core/include/mqt-core/boost/config/platform/amigaos.hpp +15 -0
  90. mqt/core/include/mqt-core/boost/config/platform/beos.hpp +26 -0
  91. mqt/core/include/mqt-core/boost/config/platform/bsd.hpp +83 -0
  92. mqt/core/include/mqt-core/boost/config/platform/cloudabi.hpp +18 -0
  93. mqt/core/include/mqt-core/boost/config/platform/cray.hpp +18 -0
  94. mqt/core/include/mqt-core/boost/config/platform/cygwin.hpp +71 -0
  95. mqt/core/include/mqt-core/boost/config/platform/haiku.hpp +31 -0
  96. mqt/core/include/mqt-core/boost/config/platform/hpux.hpp +87 -0
  97. mqt/core/include/mqt-core/boost/config/platform/irix.hpp +31 -0
  98. mqt/core/include/mqt-core/boost/config/platform/linux.hpp +106 -0
  99. mqt/core/include/mqt-core/boost/config/platform/macos.hpp +87 -0
  100. mqt/core/include/mqt-core/boost/config/platform/qnxnto.hpp +31 -0
  101. mqt/core/include/mqt-core/boost/config/platform/solaris.hpp +31 -0
  102. mqt/core/include/mqt-core/boost/config/platform/symbian.hpp +97 -0
  103. mqt/core/include/mqt-core/boost/config/platform/vms.hpp +25 -0
  104. mqt/core/include/mqt-core/boost/config/platform/vxworks.hpp +422 -0
  105. mqt/core/include/mqt-core/boost/config/platform/wasm.hpp +23 -0
  106. mqt/core/include/mqt-core/boost/config/platform/win32.hpp +90 -0
  107. mqt/core/include/mqt-core/boost/config/platform/zos.hpp +32 -0
  108. mqt/core/include/mqt-core/boost/config/pragma_message.hpp +31 -0
  109. mqt/core/include/mqt-core/boost/config/requires_threads.hpp +92 -0
  110. mqt/core/include/mqt-core/boost/config/stdlib/dinkumware.hpp +324 -0
  111. mqt/core/include/mqt-core/boost/config/stdlib/libcomo.hpp +93 -0
  112. mqt/core/include/mqt-core/boost/config/stdlib/libcpp.hpp +180 -0
  113. mqt/core/include/mqt-core/boost/config/stdlib/libstdcpp3.hpp +482 -0
  114. mqt/core/include/mqt-core/boost/config/stdlib/modena.hpp +79 -0
  115. mqt/core/include/mqt-core/boost/config/stdlib/msl.hpp +98 -0
  116. mqt/core/include/mqt-core/boost/config/stdlib/roguewave.hpp +208 -0
  117. mqt/core/include/mqt-core/boost/config/stdlib/sgi.hpp +168 -0
  118. mqt/core/include/mqt-core/boost/config/stdlib/stlport.hpp +258 -0
  119. mqt/core/include/mqt-core/boost/config/stdlib/vacpp.hpp +74 -0
  120. mqt/core/include/mqt-core/boost/config/stdlib/xlcpp_zos.hpp +61 -0
  121. mqt/core/include/mqt-core/boost/config/user.hpp +133 -0
  122. mqt/core/include/mqt-core/boost/config/warning_disable.hpp +47 -0
  123. mqt/core/include/mqt-core/boost/config/workaround.hpp +305 -0
  124. mqt/core/include/mqt-core/boost/config.hpp +67 -0
  125. mqt/core/include/mqt-core/boost/cstdint.hpp +556 -0
  126. mqt/core/include/mqt-core/boost/cxx11_char_types.hpp +70 -0
  127. mqt/core/include/mqt-core/boost/detail/workaround.hpp +10 -0
  128. mqt/core/include/mqt-core/boost/limits.hpp +146 -0
  129. mqt/core/include/mqt-core/boost/multiprecision/complex128.hpp +24 -0
  130. mqt/core/include/mqt-core/boost/multiprecision/complex_adaptor.hpp +1046 -0
  131. mqt/core/include/mqt-core/boost/multiprecision/concepts/mp_number_archetypes.hpp +257 -0
  132. mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float/io.hpp +698 -0
  133. mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float/transcendental.hpp +157 -0
  134. mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float.hpp +2297 -0
  135. mqt/core/include/mqt-core/boost/multiprecision/cpp_complex.hpp +12 -0
  136. mqt/core/include/mqt-core/boost/multiprecision/cpp_dec_float.hpp +3690 -0
  137. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/add.hpp +368 -0
  138. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/add_unsigned.hpp +387 -0
  139. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/bitwise.hpp +889 -0
  140. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/checked.hpp +178 -0
  141. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/comparison.hpp +374 -0
  142. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/cpp_int_config.hpp +161 -0
  143. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/divide.hpp +703 -0
  144. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/import_export.hpp +248 -0
  145. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/intel_intrinsics.hpp +138 -0
  146. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/limits.hpp +282 -0
  147. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/literals.hpp +295 -0
  148. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/misc.hpp +1457 -0
  149. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/multiply.hpp +848 -0
  150. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/serialize.hpp +211 -0
  151. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/value_pack.hpp +42 -0
  152. mqt/core/include/mqt-core/boost/multiprecision/cpp_int.hpp +2360 -0
  153. mqt/core/include/mqt-core/boost/multiprecision/debug_adaptor.hpp +760 -0
  154. mqt/core/include/mqt-core/boost/multiprecision/detail/assert.hpp +29 -0
  155. mqt/core/include/mqt-core/boost/multiprecision/detail/atomic.hpp +62 -0
  156. mqt/core/include/mqt-core/boost/multiprecision/detail/bitscan.hpp +317 -0
  157. mqt/core/include/mqt-core/boost/multiprecision/detail/check_cpp11_config.hpp +64 -0
  158. mqt/core/include/mqt-core/boost/multiprecision/detail/constexpr.hpp +88 -0
  159. mqt/core/include/mqt-core/boost/multiprecision/detail/default_ops.hpp +4052 -0
  160. mqt/core/include/mqt-core/boost/multiprecision/detail/digits.hpp +49 -0
  161. mqt/core/include/mqt-core/boost/multiprecision/detail/dynamic_array.hpp +44 -0
  162. mqt/core/include/mqt-core/boost/multiprecision/detail/empty_value.hpp +87 -0
  163. mqt/core/include/mqt-core/boost/multiprecision/detail/endian.hpp +35 -0
  164. mqt/core/include/mqt-core/boost/multiprecision/detail/et_ops.hpp +1831 -0
  165. mqt/core/include/mqt-core/boost/multiprecision/detail/float128_functions.hpp +95 -0
  166. mqt/core/include/mqt-core/boost/multiprecision/detail/float_string_cvt.hpp +333 -0
  167. mqt/core/include/mqt-core/boost/multiprecision/detail/fpclassify.hpp +101 -0
  168. mqt/core/include/mqt-core/boost/multiprecision/detail/functions/constants.hpp +288 -0
  169. mqt/core/include/mqt-core/boost/multiprecision/detail/functions/pow.hpp +905 -0
  170. mqt/core/include/mqt-core/boost/multiprecision/detail/functions/trig.hpp +1058 -0
  171. mqt/core/include/mqt-core/boost/multiprecision/detail/functions/trunc.hpp +82 -0
  172. mqt/core/include/mqt-core/boost/multiprecision/detail/generic_interconvert.hpp +687 -0
  173. mqt/core/include/mqt-core/boost/multiprecision/detail/hash.hpp +56 -0
  174. mqt/core/include/mqt-core/boost/multiprecision/detail/integer_ops.hpp +474 -0
  175. mqt/core/include/mqt-core/boost/multiprecision/detail/itos.hpp +39 -0
  176. mqt/core/include/mqt-core/boost/multiprecision/detail/min_max.hpp +106 -0
  177. mqt/core/include/mqt-core/boost/multiprecision/detail/no_et_ops.hpp +661 -0
  178. mqt/core/include/mqt-core/boost/multiprecision/detail/no_exceptions_support.hpp +55 -0
  179. mqt/core/include/mqt-core/boost/multiprecision/detail/number_base.hpp +1656 -0
  180. mqt/core/include/mqt-core/boost/multiprecision/detail/number_compare.hpp +848 -0
  181. mqt/core/include/mqt-core/boost/multiprecision/detail/precision.hpp +313 -0
  182. mqt/core/include/mqt-core/boost/multiprecision/detail/rebind.hpp +19 -0
  183. mqt/core/include/mqt-core/boost/multiprecision/detail/standalone_config.hpp +148 -0
  184. mqt/core/include/mqt-core/boost/multiprecision/detail/static_array.hpp +42 -0
  185. mqt/core/include/mqt-core/boost/multiprecision/detail/string_helpers.hpp +48 -0
  186. mqt/core/include/mqt-core/boost/multiprecision/detail/tables.hpp +80 -0
  187. mqt/core/include/mqt-core/boost/multiprecision/detail/ublas_interop.hpp +75 -0
  188. mqt/core/include/mqt-core/boost/multiprecision/detail/uniform_int_distribution.hpp +212 -0
  189. mqt/core/include/mqt-core/boost/multiprecision/detail/utype_helper.hpp +374 -0
  190. mqt/core/include/mqt-core/boost/multiprecision/eigen.hpp +248 -0
  191. mqt/core/include/mqt-core/boost/multiprecision/float128.hpp +920 -0
  192. mqt/core/include/mqt-core/boost/multiprecision/fwd.hpp +268 -0
  193. mqt/core/include/mqt-core/boost/multiprecision/gmp.hpp +4060 -0
  194. mqt/core/include/mqt-core/boost/multiprecision/integer.hpp +363 -0
  195. mqt/core/include/mqt-core/boost/multiprecision/logged_adaptor.hpp +834 -0
  196. mqt/core/include/mqt-core/boost/multiprecision/miller_rabin.hpp +221 -0
  197. mqt/core/include/mqt-core/boost/multiprecision/mpc.hpp +1721 -0
  198. mqt/core/include/mqt-core/boost/multiprecision/mpfi.hpp +2559 -0
  199. mqt/core/include/mqt-core/boost/multiprecision/mpfr.hpp +3644 -0
  200. mqt/core/include/mqt-core/boost/multiprecision/number.hpp +2500 -0
  201. mqt/core/include/mqt-core/boost/multiprecision/random.hpp +23 -0
  202. mqt/core/include/mqt-core/boost/multiprecision/rational_adaptor.hpp +1289 -0
  203. mqt/core/include/mqt-core/boost/multiprecision/tommath.hpp +1034 -0
  204. mqt/core/include/mqt-core/boost/multiprecision/traits/explicit_conversion.hpp +67 -0
  205. mqt/core/include/mqt-core/boost/multiprecision/traits/extract_exponent_type.hpp +28 -0
  206. mqt/core/include/mqt-core/boost/multiprecision/traits/is_backend.hpp +91 -0
  207. mqt/core/include/mqt-core/boost/multiprecision/traits/is_byte_container.hpp +51 -0
  208. mqt/core/include/mqt-core/boost/multiprecision/traits/is_complex.hpp +22 -0
  209. mqt/core/include/mqt-core/boost/multiprecision/traits/is_convertible_arithmetic.hpp +51 -0
  210. mqt/core/include/mqt-core/boost/multiprecision/traits/is_restricted_conversion.hpp +47 -0
  211. mqt/core/include/mqt-core/boost/multiprecision/traits/is_variable_precision.hpp +25 -0
  212. mqt/core/include/mqt-core/boost/multiprecision/traits/max_digits10.hpp +79 -0
  213. mqt/core/include/mqt-core/boost/multiprecision/traits/std_integer_traits.hpp +90 -0
  214. mqt/core/include/mqt-core/boost/multiprecision/traits/transcendental_reduction_type.hpp +21 -0
  215. mqt/core/include/mqt-core/boost/version.hpp +32 -0
  216. mqt/core/include/mqt-core/circuit_optimizer/CircuitOptimizer.hpp +119 -0
  217. mqt/core/include/mqt-core/circuit_optimizer/mqt_core_circuit_optimizer_export.h +43 -0
  218. mqt/core/include/mqt-core/datastructures/DirectedAcyclicGraph.hpp +117 -0
  219. mqt/core/include/mqt-core/datastructures/DirectedGraph.hpp +158 -0
  220. mqt/core/include/mqt-core/datastructures/DisjointSet.hpp +50 -0
  221. mqt/core/include/mqt-core/datastructures/Layer.hpp +172 -0
  222. mqt/core/include/mqt-core/datastructures/SymmetricMatrix.hpp +57 -0
  223. mqt/core/include/mqt-core/datastructures/UndirectedGraph.hpp +227 -0
  224. mqt/core/include/mqt-core/datastructures/mqt_core_ds_export.h +43 -0
  225. mqt/core/include/mqt-core/dd/Approximation.hpp +45 -0
  226. mqt/core/include/mqt-core/dd/CachedEdge.hpp +174 -0
  227. mqt/core/include/mqt-core/dd/Complex.hpp +165 -0
  228. mqt/core/include/mqt-core/dd/ComplexNumbers.hpp +150 -0
  229. mqt/core/include/mqt-core/dd/ComplexValue.hpp +184 -0
  230. mqt/core/include/mqt-core/dd/ComputeTable.hpp +183 -0
  231. mqt/core/include/mqt-core/dd/DDDefinitions.hpp +139 -0
  232. mqt/core/include/mqt-core/dd/DDpackageConfig.hpp +104 -0
  233. mqt/core/include/mqt-core/dd/DensityNoiseTable.hpp +114 -0
  234. mqt/core/include/mqt-core/dd/Edge.hpp +416 -0
  235. mqt/core/include/mqt-core/dd/Export.hpp +438 -0
  236. mqt/core/include/mqt-core/dd/FunctionalityConstruction.hpp +75 -0
  237. mqt/core/include/mqt-core/dd/GateMatrixDefinitions.hpp +43 -0
  238. mqt/core/include/mqt-core/dd/LinkedListBase.hpp +45 -0
  239. mqt/core/include/mqt-core/dd/MemoryManager.hpp +193 -0
  240. mqt/core/include/mqt-core/dd/Node.hpp +223 -0
  241. mqt/core/include/mqt-core/dd/NoiseFunctionality.hpp +144 -0
  242. mqt/core/include/mqt-core/dd/Operations.hpp +306 -0
  243. mqt/core/include/mqt-core/dd/Package.hpp +2036 -0
  244. mqt/core/include/mqt-core/dd/Package_fwd.hpp +22 -0
  245. mqt/core/include/mqt-core/dd/RealNumber.hpp +255 -0
  246. mqt/core/include/mqt-core/dd/RealNumberUniqueTable.hpp +217 -0
  247. mqt/core/include/mqt-core/dd/Simulation.hpp +98 -0
  248. mqt/core/include/mqt-core/dd/StateGeneration.hpp +143 -0
  249. mqt/core/include/mqt-core/dd/StochasticNoiseOperationTable.hpp +88 -0
  250. mqt/core/include/mqt-core/dd/UnaryComputeTable.hpp +121 -0
  251. mqt/core/include/mqt-core/dd/UniqueTable.hpp +243 -0
  252. mqt/core/include/mqt-core/dd/mqt_core_dd_export.h +43 -0
  253. mqt/core/include/mqt-core/dd/statistics/MemoryManagerStatistics.hpp +84 -0
  254. mqt/core/include/mqt-core/dd/statistics/PackageStatistics.hpp +55 -0
  255. mqt/core/include/mqt-core/dd/statistics/Statistics.hpp +48 -0
  256. mqt/core/include/mqt-core/dd/statistics/TableStatistics.hpp +79 -0
  257. mqt/core/include/mqt-core/dd/statistics/UniqueTableStatistics.hpp +31 -0
  258. mqt/core/include/mqt-core/fomac/FoMaC.hpp +568 -0
  259. mqt/core/include/mqt-core/ir/Definitions.hpp +108 -0
  260. mqt/core/include/mqt-core/ir/Permutation.hpp +213 -0
  261. mqt/core/include/mqt-core/ir/QuantumComputation.hpp +596 -0
  262. mqt/core/include/mqt-core/ir/Register.hpp +125 -0
  263. mqt/core/include/mqt-core/ir/mqt_core_ir_export.h +43 -0
  264. mqt/core/include/mqt-core/ir/operations/AodOperation.hpp +92 -0
  265. mqt/core/include/mqt-core/ir/operations/CompoundOperation.hpp +212 -0
  266. mqt/core/include/mqt-core/ir/operations/Control.hpp +142 -0
  267. mqt/core/include/mqt-core/ir/operations/Expression.hpp +847 -0
  268. mqt/core/include/mqt-core/ir/operations/IfElseOperation.hpp +169 -0
  269. mqt/core/include/mqt-core/ir/operations/NonUnitaryOperation.hpp +118 -0
  270. mqt/core/include/mqt-core/ir/operations/OpType.hpp +120 -0
  271. mqt/core/include/mqt-core/ir/operations/OpType.inc +76 -0
  272. mqt/core/include/mqt-core/ir/operations/Operation.hpp +247 -0
  273. mqt/core/include/mqt-core/ir/operations/StandardOperation.hpp +140 -0
  274. mqt/core/include/mqt-core/ir/operations/SymbolicOperation.hpp +144 -0
  275. mqt/core/include/mqt-core/mqt_na_qdmi/device.h +602 -0
  276. mqt/core/include/mqt-core/mqt_na_qdmi/types.h +78 -0
  277. mqt/core/include/mqt-core/na/NAComputation.hpp +185 -0
  278. mqt/core/include/mqt-core/na/device/Device.hpp +410 -0
  279. mqt/core/include/mqt-core/na/device/DeviceMemberInitializers.hpp +724 -0
  280. mqt/core/include/mqt-core/na/device/Generator.hpp +447 -0
  281. mqt/core/include/mqt-core/na/entities/Atom.hpp +62 -0
  282. mqt/core/include/mqt-core/na/entities/Location.hpp +154 -0
  283. mqt/core/include/mqt-core/na/entities/Zone.hpp +95 -0
  284. mqt/core/include/mqt-core/na/fomac/Device.hpp +169 -0
  285. mqt/core/include/mqt-core/na/mqt_core_na_export.h +43 -0
  286. mqt/core/include/mqt-core/na/operations/GlobalCZOp.hpp +38 -0
  287. mqt/core/include/mqt-core/na/operations/GlobalOp.hpp +58 -0
  288. mqt/core/include/mqt-core/na/operations/GlobalRYOp.hpp +42 -0
  289. mqt/core/include/mqt-core/na/operations/LoadOp.hpp +89 -0
  290. mqt/core/include/mqt-core/na/operations/LocalOp.hpp +56 -0
  291. mqt/core/include/mqt-core/na/operations/LocalRZOp.hpp +42 -0
  292. mqt/core/include/mqt-core/na/operations/LocalUOp.hpp +49 -0
  293. mqt/core/include/mqt-core/na/operations/MoveOp.hpp +66 -0
  294. mqt/core/include/mqt-core/na/operations/Op.hpp +62 -0
  295. mqt/core/include/mqt-core/na/operations/ShuttlingOp.hpp +51 -0
  296. mqt/core/include/mqt-core/na/operations/StoreOp.hpp +87 -0
  297. mqt/core/include/mqt-core/qasm3/Exception.hpp +85 -0
  298. mqt/core/include/mqt-core/qasm3/Gate.hpp +65 -0
  299. mqt/core/include/mqt-core/qasm3/Importer.hpp +192 -0
  300. mqt/core/include/mqt-core/qasm3/InstVisitor.hpp +145 -0
  301. mqt/core/include/mqt-core/qasm3/NestedEnvironment.hpp +41 -0
  302. mqt/core/include/mqt-core/qasm3/Parser.hpp +170 -0
  303. mqt/core/include/mqt-core/qasm3/Scanner.hpp +73 -0
  304. mqt/core/include/mqt-core/qasm3/Statement.hpp +486 -0
  305. mqt/core/include/mqt-core/qasm3/Statement_fwd.hpp +39 -0
  306. mqt/core/include/mqt-core/qasm3/StdGates.hpp +232 -0
  307. mqt/core/include/mqt-core/qasm3/Token.hpp +198 -0
  308. mqt/core/include/mqt-core/qasm3/Types.hpp +238 -0
  309. mqt/core/include/mqt-core/qasm3/Types_fwd.hpp +22 -0
  310. mqt/core/include/mqt-core/qasm3/mqt_core_qasm_export.h +43 -0
  311. mqt/core/include/mqt-core/qasm3/passes/CompilerPass.hpp +22 -0
  312. mqt/core/include/mqt-core/qasm3/passes/ConstEvalPass.hpp +102 -0
  313. mqt/core/include/mqt-core/qasm3/passes/TypeCheckPass.hpp +124 -0
  314. mqt/core/include/mqt-core/qdmi/Driver.hpp +431 -0
  315. mqt/core/include/mqt-core/zx/FunctionalityConstruction.hpp +125 -0
  316. mqt/core/include/mqt-core/zx/Rational.hpp +318 -0
  317. mqt/core/include/mqt-core/zx/Rules.hpp +132 -0
  318. mqt/core/include/mqt-core/zx/Simplify.hpp +182 -0
  319. mqt/core/include/mqt-core/zx/Utils.hpp +212 -0
  320. mqt/core/include/mqt-core/zx/ZXDefinitions.hpp +93 -0
  321. mqt/core/include/mqt-core/zx/ZXDiagram.hpp +480 -0
  322. mqt/core/include/mqt-core/zx/mqt_core_zx_export.h +43 -0
  323. mqt/core/include/nlohmann/adl_serializer.hpp +55 -0
  324. mqt/core/include/nlohmann/byte_container_with_subtype.hpp +103 -0
  325. mqt/core/include/nlohmann/detail/abi_macros.hpp +111 -0
  326. mqt/core/include/nlohmann/detail/conversions/from_json.hpp +577 -0
  327. mqt/core/include/nlohmann/detail/conversions/to_chars.hpp +1118 -0
  328. mqt/core/include/nlohmann/detail/conversions/to_json.hpp +479 -0
  329. mqt/core/include/nlohmann/detail/exceptions.hpp +291 -0
  330. mqt/core/include/nlohmann/detail/hash.hpp +129 -0
  331. mqt/core/include/nlohmann/detail/input/binary_reader.hpp +3068 -0
  332. mqt/core/include/nlohmann/detail/input/input_adapters.hpp +549 -0
  333. mqt/core/include/nlohmann/detail/input/json_sax.hpp +986 -0
  334. mqt/core/include/nlohmann/detail/input/lexer.hpp +1643 -0
  335. mqt/core/include/nlohmann/detail/input/parser.hpp +519 -0
  336. mqt/core/include/nlohmann/detail/input/position_t.hpp +37 -0
  337. mqt/core/include/nlohmann/detail/iterators/internal_iterator.hpp +35 -0
  338. mqt/core/include/nlohmann/detail/iterators/iter_impl.hpp +760 -0
  339. mqt/core/include/nlohmann/detail/iterators/iteration_proxy.hpp +235 -0
  340. mqt/core/include/nlohmann/detail/iterators/iterator_traits.hpp +61 -0
  341. mqt/core/include/nlohmann/detail/iterators/json_reverse_iterator.hpp +130 -0
  342. mqt/core/include/nlohmann/detail/iterators/primitive_iterator.hpp +132 -0
  343. mqt/core/include/nlohmann/detail/json_custom_base_class.hpp +39 -0
  344. mqt/core/include/nlohmann/detail/json_pointer.hpp +988 -0
  345. mqt/core/include/nlohmann/detail/json_ref.hpp +78 -0
  346. mqt/core/include/nlohmann/detail/macro_scope.hpp +595 -0
  347. mqt/core/include/nlohmann/detail/macro_unscope.hpp +46 -0
  348. mqt/core/include/nlohmann/detail/meta/call_std/begin.hpp +17 -0
  349. mqt/core/include/nlohmann/detail/meta/call_std/end.hpp +17 -0
  350. mqt/core/include/nlohmann/detail/meta/cpp_future.hpp +171 -0
  351. mqt/core/include/nlohmann/detail/meta/detected.hpp +70 -0
  352. mqt/core/include/nlohmann/detail/meta/identity_tag.hpp +21 -0
  353. mqt/core/include/nlohmann/detail/meta/is_sax.hpp +159 -0
  354. mqt/core/include/nlohmann/detail/meta/std_fs.hpp +29 -0
  355. mqt/core/include/nlohmann/detail/meta/type_traits.hpp +795 -0
  356. mqt/core/include/nlohmann/detail/meta/void_t.hpp +24 -0
  357. mqt/core/include/nlohmann/detail/output/binary_writer.hpp +1850 -0
  358. mqt/core/include/nlohmann/detail/output/output_adapters.hpp +147 -0
  359. mqt/core/include/nlohmann/detail/output/serializer.hpp +988 -0
  360. mqt/core/include/nlohmann/detail/string_concat.hpp +146 -0
  361. mqt/core/include/nlohmann/detail/string_escape.hpp +72 -0
  362. mqt/core/include/nlohmann/detail/string_utils.hpp +37 -0
  363. mqt/core/include/nlohmann/detail/value_t.hpp +118 -0
  364. mqt/core/include/nlohmann/json.hpp +5306 -0
  365. mqt/core/include/nlohmann/json_fwd.hpp +75 -0
  366. mqt/core/include/nlohmann/ordered_map.hpp +359 -0
  367. mqt/core/include/nlohmann/thirdparty/hedley/hedley.hpp +2045 -0
  368. mqt/core/include/nlohmann/thirdparty/hedley/hedley_undef.hpp +158 -0
  369. mqt/core/include/qdmi/qdmi/client.h +990 -0
  370. mqt/core/include/qdmi/qdmi/constants.h +1139 -0
  371. mqt/core/include/qdmi/qdmi/device.h +602 -0
  372. mqt/core/include/qdmi/qdmi/types.h +78 -0
  373. mqt/core/include/spdlog/async.h +99 -0
  374. mqt/core/include/spdlog/async_logger-inl.h +84 -0
  375. mqt/core/include/spdlog/async_logger.h +74 -0
  376. mqt/core/include/spdlog/cfg/argv.h +40 -0
  377. mqt/core/include/spdlog/cfg/env.h +36 -0
  378. mqt/core/include/spdlog/cfg/helpers-inl.h +107 -0
  379. mqt/core/include/spdlog/cfg/helpers.h +29 -0
  380. mqt/core/include/spdlog/common-inl.h +68 -0
  381. mqt/core/include/spdlog/common.h +406 -0
  382. mqt/core/include/spdlog/details/backtracer-inl.h +63 -0
  383. mqt/core/include/spdlog/details/backtracer.h +45 -0
  384. mqt/core/include/spdlog/details/circular_q.h +115 -0
  385. mqt/core/include/spdlog/details/console_globals.h +28 -0
  386. mqt/core/include/spdlog/details/file_helper-inl.h +153 -0
  387. mqt/core/include/spdlog/details/file_helper.h +61 -0
  388. mqt/core/include/spdlog/details/fmt_helper.h +141 -0
  389. mqt/core/include/spdlog/details/log_msg-inl.h +44 -0
  390. mqt/core/include/spdlog/details/log_msg.h +40 -0
  391. mqt/core/include/spdlog/details/log_msg_buffer-inl.h +54 -0
  392. mqt/core/include/spdlog/details/log_msg_buffer.h +32 -0
  393. mqt/core/include/spdlog/details/mpmc_blocking_q.h +177 -0
  394. mqt/core/include/spdlog/details/null_mutex.h +35 -0
  395. mqt/core/include/spdlog/details/os-inl.h +606 -0
  396. mqt/core/include/spdlog/details/os.h +127 -0
  397. mqt/core/include/spdlog/details/periodic_worker-inl.h +26 -0
  398. mqt/core/include/spdlog/details/periodic_worker.h +58 -0
  399. mqt/core/include/spdlog/details/registry-inl.h +270 -0
  400. mqt/core/include/spdlog/details/registry.h +131 -0
  401. mqt/core/include/spdlog/details/synchronous_factory.h +22 -0
  402. mqt/core/include/spdlog/details/tcp_client-windows.h +135 -0
  403. mqt/core/include/spdlog/details/tcp_client.h +127 -0
  404. mqt/core/include/spdlog/details/thread_pool-inl.h +126 -0
  405. mqt/core/include/spdlog/details/thread_pool.h +117 -0
  406. mqt/core/include/spdlog/details/udp_client-windows.h +98 -0
  407. mqt/core/include/spdlog/details/udp_client.h +81 -0
  408. mqt/core/include/spdlog/details/windows_include.h +11 -0
  409. mqt/core/include/spdlog/fmt/bin_to_hex.h +224 -0
  410. mqt/core/include/spdlog/fmt/bundled/args.h +220 -0
  411. mqt/core/include/spdlog/fmt/bundled/base.h +2989 -0
  412. mqt/core/include/spdlog/fmt/bundled/chrono.h +2330 -0
  413. mqt/core/include/spdlog/fmt/bundled/color.h +637 -0
  414. mqt/core/include/spdlog/fmt/bundled/compile.h +539 -0
  415. mqt/core/include/spdlog/fmt/bundled/core.h +5 -0
  416. mqt/core/include/spdlog/fmt/bundled/fmt.license.rst +27 -0
  417. mqt/core/include/spdlog/fmt/bundled/format-inl.h +1948 -0
  418. mqt/core/include/spdlog/fmt/bundled/format.h +4244 -0
  419. mqt/core/include/spdlog/fmt/bundled/os.h +427 -0
  420. mqt/core/include/spdlog/fmt/bundled/ostream.h +167 -0
  421. mqt/core/include/spdlog/fmt/bundled/printf.h +633 -0
  422. mqt/core/include/spdlog/fmt/bundled/ranges.h +850 -0
  423. mqt/core/include/spdlog/fmt/bundled/std.h +728 -0
  424. mqt/core/include/spdlog/fmt/bundled/xchar.h +369 -0
  425. mqt/core/include/spdlog/fmt/chrono.h +23 -0
  426. mqt/core/include/spdlog/fmt/compile.h +23 -0
  427. mqt/core/include/spdlog/fmt/fmt.h +30 -0
  428. mqt/core/include/spdlog/fmt/ostr.h +23 -0
  429. mqt/core/include/spdlog/fmt/ranges.h +23 -0
  430. mqt/core/include/spdlog/fmt/std.h +24 -0
  431. mqt/core/include/spdlog/fmt/xchar.h +23 -0
  432. mqt/core/include/spdlog/formatter.h +17 -0
  433. mqt/core/include/spdlog/fwd.h +18 -0
  434. mqt/core/include/spdlog/logger-inl.h +198 -0
  435. mqt/core/include/spdlog/logger.h +379 -0
  436. mqt/core/include/spdlog/mdc.h +52 -0
  437. mqt/core/include/spdlog/pattern_formatter-inl.h +1340 -0
  438. mqt/core/include/spdlog/pattern_formatter.h +118 -0
  439. mqt/core/include/spdlog/sinks/android_sink.h +137 -0
  440. mqt/core/include/spdlog/sinks/ansicolor_sink-inl.h +142 -0
  441. mqt/core/include/spdlog/sinks/ansicolor_sink.h +116 -0
  442. mqt/core/include/spdlog/sinks/base_sink-inl.h +59 -0
  443. mqt/core/include/spdlog/sinks/base_sink.h +51 -0
  444. mqt/core/include/spdlog/sinks/basic_file_sink-inl.h +48 -0
  445. mqt/core/include/spdlog/sinks/basic_file_sink.h +66 -0
  446. mqt/core/include/spdlog/sinks/callback_sink.h +56 -0
  447. mqt/core/include/spdlog/sinks/daily_file_sink.h +254 -0
  448. mqt/core/include/spdlog/sinks/dist_sink.h +81 -0
  449. mqt/core/include/spdlog/sinks/dup_filter_sink.h +91 -0
  450. mqt/core/include/spdlog/sinks/hourly_file_sink.h +193 -0
  451. mqt/core/include/spdlog/sinks/kafka_sink.h +119 -0
  452. mqt/core/include/spdlog/sinks/mongo_sink.h +108 -0
  453. mqt/core/include/spdlog/sinks/msvc_sink.h +68 -0
  454. mqt/core/include/spdlog/sinks/null_sink.h +41 -0
  455. mqt/core/include/spdlog/sinks/ostream_sink.h +43 -0
  456. mqt/core/include/spdlog/sinks/qt_sinks.h +304 -0
  457. mqt/core/include/spdlog/sinks/ringbuffer_sink.h +67 -0
  458. mqt/core/include/spdlog/sinks/rotating_file_sink-inl.h +179 -0
  459. mqt/core/include/spdlog/sinks/rotating_file_sink.h +93 -0
  460. mqt/core/include/spdlog/sinks/sink-inl.h +22 -0
  461. mqt/core/include/spdlog/sinks/sink.h +34 -0
  462. mqt/core/include/spdlog/sinks/stdout_color_sinks-inl.h +38 -0
  463. mqt/core/include/spdlog/sinks/stdout_color_sinks.h +49 -0
  464. mqt/core/include/spdlog/sinks/stdout_sinks-inl.h +127 -0
  465. mqt/core/include/spdlog/sinks/stdout_sinks.h +84 -0
  466. mqt/core/include/spdlog/sinks/syslog_sink.h +104 -0
  467. mqt/core/include/spdlog/sinks/systemd_sink.h +121 -0
  468. mqt/core/include/spdlog/sinks/tcp_sink.h +75 -0
  469. mqt/core/include/spdlog/sinks/udp_sink.h +69 -0
  470. mqt/core/include/spdlog/sinks/win_eventlog_sink.h +260 -0
  471. mqt/core/include/spdlog/sinks/wincolor_sink-inl.h +172 -0
  472. mqt/core/include/spdlog/sinks/wincolor_sink.h +82 -0
  473. mqt/core/include/spdlog/spdlog-inl.h +96 -0
  474. mqt/core/include/spdlog/spdlog.h +357 -0
  475. mqt/core/include/spdlog/stopwatch.h +66 -0
  476. mqt/core/include/spdlog/tweakme.h +148 -0
  477. mqt/core/include/spdlog/version.h +11 -0
  478. mqt/core/ir/__init__.pyi +2078 -0
  479. mqt/core/ir/operations.pyi +1011 -0
  480. mqt/core/ir/registers.pyi +91 -0
  481. mqt/core/ir/symbolic.pyi +177 -0
  482. mqt/core/ir.cp313t-win_amd64.pyd +0 -0
  483. mqt/core/lib/mqt-core-algorithms.lib +0 -0
  484. mqt/core/lib/mqt-core-circuit-optimizer.lib +0 -0
  485. mqt/core/lib/mqt-core-dd.lib +0 -0
  486. mqt/core/lib/mqt-core-ds.lib +0 -0
  487. mqt/core/lib/mqt-core-fomac.lib +0 -0
  488. mqt/core/lib/mqt-core-ir.lib +0 -0
  489. mqt/core/lib/mqt-core-na-fomac.lib +0 -0
  490. mqt/core/lib/mqt-core-na.lib +0 -0
  491. mqt/core/lib/mqt-core-qasm.lib +0 -0
  492. mqt/core/lib/mqt-core-qdmi-driver.lib +0 -0
  493. mqt/core/lib/mqt-core-qdmi-na-device-gen.lib +0 -0
  494. mqt/core/lib/mqt-core-qdmi-na-device.lib +0 -0
  495. mqt/core/lib/mqt-core-zx.lib +0 -0
  496. mqt/core/lib/pkgconfig/spdlog.pc +13 -0
  497. mqt/core/lib/spdlog.lib +0 -0
  498. mqt/core/na/__init__.py +12 -0
  499. mqt/core/na/fomac.cp313t-win_amd64.pyd +0 -0
  500. mqt/core/na/fomac.pyi +117 -0
  501. mqt/core/nlohmann_json.natvis +278 -0
  502. mqt/core/plugins/__init__.py +9 -0
  503. mqt/core/plugins/qiskit/__init__.py +19 -0
  504. mqt/core/plugins/qiskit/mqt_to_qiskit.py +420 -0
  505. mqt/core/plugins/qiskit/qiskit_to_mqt.py +562 -0
  506. mqt/core/py.typed +2 -0
  507. mqt/core/share/cmake/mqt-core/AddMQTPythonBinding.cmake +55 -0
  508. mqt/core/share/cmake/mqt-core/Cache.cmake +33 -0
  509. mqt/core/share/cmake/mqt-core/FindGMP.cmake +103 -0
  510. mqt/core/share/cmake/mqt-core/PackageAddTest.cmake +46 -0
  511. mqt/core/share/cmake/mqt-core/PreventInSourceBuilds.cmake +25 -0
  512. mqt/core/share/cmake/mqt-core/StandardProjectSettings.cmake +87 -0
  513. mqt/core/share/cmake/mqt-core/mqt-core-config-version.cmake +85 -0
  514. mqt/core/share/cmake/mqt-core/mqt-core-config.cmake +52 -0
  515. mqt/core/share/cmake/mqt-core/mqt-core-targets-release.cmake +141 -0
  516. mqt/core/share/cmake/mqt-core/mqt-core-targets.cmake +445 -0
  517. mqt/core/share/cmake/nlohmann_json/nlohmann_jsonConfig.cmake +15 -0
  518. mqt/core/share/cmake/nlohmann_json/nlohmann_jsonConfigVersion.cmake +20 -0
  519. mqt/core/share/cmake/nlohmann_json/nlohmann_jsonTargets.cmake +110 -0
  520. mqt/core/share/cmake/qdmi/Cache.cmake +44 -0
  521. mqt/core/share/cmake/qdmi/PrefixHandling.cmake +78 -0
  522. mqt/core/share/cmake/qdmi/prefix_defs.txt +26 -0
  523. mqt/core/share/cmake/qdmi/qdmi-config-version.cmake +85 -0
  524. mqt/core/share/cmake/qdmi/qdmi-config.cmake +42 -0
  525. mqt/core/share/cmake/qdmi/qdmi-targets.cmake +129 -0
  526. mqt/core/share/cmake/spdlog/spdlogConfig.cmake +44 -0
  527. mqt/core/share/cmake/spdlog/spdlogConfigTargets-release.cmake +19 -0
  528. mqt/core/share/cmake/spdlog/spdlogConfigTargets.cmake +121 -0
  529. mqt/core/share/cmake/spdlog/spdlogConfigVersion.cmake +65 -0
  530. mqt/core/share/pkgconfig/nlohmann_json.pc +7 -0
  531. mqt_core-3.3.2.dist-info/DELVEWHEEL +2 -0
  532. mqt_core-3.3.2.dist-info/METADATA +210 -0
  533. mqt_core-3.3.2.dist-info/RECORD +537 -0
  534. mqt_core-3.3.2.dist-info/WHEEL +5 -0
  535. mqt_core-3.3.2.dist-info/entry_points.txt +4 -0
  536. mqt_core-3.3.2.dist-info/licenses/LICENSE.md +22 -0
  537. mqt_core.libs/msvcp140.dll +0 -0
@@ -0,0 +1,1289 @@
1
+ ///////////////////////////////////////////////////////////////
2
+ // Copyright 2020 John Maddock. Distributed under the Boost
3
+ // Software License, Version 1.0. (See accompanying file
4
+ // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
5
+
6
+ #ifndef BOOST_MP_RATIONAL_ADAPTOR_HPP
7
+ #define BOOST_MP_RATIONAL_ADAPTOR_HPP
8
+
9
+ #include <boost/multiprecision/number.hpp>
10
+ #include <boost/multiprecision/detail/hash.hpp>
11
+ #include <boost/multiprecision/detail/float128_functions.hpp>
12
+ #include <boost/multiprecision/detail/no_exceptions_support.hpp>
13
+
14
+ namespace boost {
15
+ namespace multiprecision {
16
+ namespace backends {
17
+
18
+ template <class Backend>
19
+ struct rational_adaptor
20
+ {
21
+ //
22
+ // Each backend need to declare 3 type lists which declare the types
23
+ // with which this can interoperate. These lists must at least contain
24
+ // the widest type in each category - so "long long" must be the final
25
+ // type in the signed_types list for example. Any narrower types if not
26
+ // present in the list will get promoted to the next wider type that is
27
+ // in the list whenever mixed arithmetic involving that type is encountered.
28
+ //
29
+ typedef typename Backend::signed_types signed_types;
30
+ typedef typename Backend::unsigned_types unsigned_types;
31
+ typedef typename Backend::float_types float_types;
32
+
33
+ typedef typename std::tuple_element<0, unsigned_types>::type ui_type;
34
+
35
+ static Backend get_one()
36
+ {
37
+ Backend t;
38
+ t = static_cast<ui_type>(1);
39
+ return t;
40
+ }
41
+ static Backend get_zero()
42
+ {
43
+ Backend t;
44
+ t = static_cast<ui_type>(0);
45
+ return t;
46
+ }
47
+
48
+ static const Backend& one()
49
+ {
50
+ static const Backend result(get_one());
51
+ return result;
52
+ }
53
+ static const Backend& zero()
54
+ {
55
+ static const Backend result(get_zero());
56
+ return result;
57
+ }
58
+
59
+ void normalize()
60
+ {
61
+ using default_ops::eval_gcd;
62
+ using default_ops::eval_eq;
63
+ using default_ops::eval_divide;
64
+ using default_ops::eval_get_sign;
65
+
66
+ int s = eval_get_sign(m_denom);
67
+
68
+ if(s == 0)
69
+ {
70
+ BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero"));
71
+ }
72
+ else if (s < 0)
73
+ {
74
+ m_num.negate();
75
+ m_denom.negate();
76
+ }
77
+
78
+ Backend g, t;
79
+ eval_gcd(g, m_num, m_denom);
80
+ if (!eval_eq(g, one()))
81
+ {
82
+ eval_divide(t, m_num, g);
83
+ m_num.swap(t);
84
+ eval_divide(t, m_denom, g);
85
+ m_denom = std::move(t);
86
+ }
87
+ }
88
+
89
+ // We must have a default constructor:
90
+ rational_adaptor()
91
+ : m_num(zero()), m_denom(one()) {}
92
+
93
+ rational_adaptor(const rational_adaptor& o) : m_num(o.m_num), m_denom(o.m_denom) {}
94
+ rational_adaptor(rational_adaptor&& o) = default;
95
+
96
+ // Optional constructors, we can make this type slightly more efficient
97
+ // by providing constructors from any type we can handle natively.
98
+ // These will also cause number<> to be implicitly constructible
99
+ // from these types unless we make such constructors explicit.
100
+ //
101
+ template <class Arithmetic>
102
+ rational_adaptor(const Arithmetic& val, typename std::enable_if<std::is_constructible<Backend, Arithmetic>::value && !std::is_floating_point<Arithmetic>::value>::type const* = nullptr)
103
+ : m_num(val), m_denom(one()) {}
104
+
105
+ //
106
+ // Pass-through 2-arg construction of components:
107
+ //
108
+ template <class T, class U>
109
+ rational_adaptor(const T& a, const U& b, typename std::enable_if<std::is_constructible<Backend, T const&>::value && std::is_constructible<Backend, U const&>::value>::type const* = nullptr)
110
+ : m_num(a), m_denom(b)
111
+ {
112
+ normalize();
113
+ }
114
+ template <class T, class U>
115
+ rational_adaptor(T&& a, const U& b, typename std::enable_if<std::is_constructible<Backend, T>::value && std::is_constructible<Backend, U>::value>::type const* = nullptr)
116
+ : m_num(static_cast<T&&>(a)), m_denom(b)
117
+ {
118
+ normalize();
119
+ }
120
+ template <class T, class U>
121
+ rational_adaptor(T&& a, U&& b, typename std::enable_if<std::is_constructible<Backend, T>::value && std::is_constructible<Backend, U>::value>::type const* = nullptr)
122
+ : m_num(static_cast<T&&>(a)), m_denom(static_cast<U&&>(b))
123
+ {
124
+ normalize();
125
+ }
126
+ template <class T, class U>
127
+ rational_adaptor(const T& a, U&& b, typename std::enable_if<std::is_constructible<Backend, T>::value && std::is_constructible<Backend, U>::value>::type const* = nullptr)
128
+ : m_num(a), m_denom(static_cast<U&&>(b))
129
+ {
130
+ normalize();
131
+ }
132
+ //
133
+ // In the absense of converting constructors, operator= takes the strain.
134
+ // In addition to the usual suspects, there must be one operator= for each type
135
+ // listed in signed_types, unsigned_types, and float_types plus a string constructor.
136
+ //
137
+ rational_adaptor& operator=(const rational_adaptor& o) = default;
138
+ rational_adaptor& operator=(rational_adaptor&& o) = default;
139
+ template <class Arithmetic>
140
+ inline typename std::enable_if<!std::is_floating_point<Arithmetic>::value, rational_adaptor&>::type operator=(const Arithmetic& i)
141
+ {
142
+ m_num = i;
143
+ m_denom = one();
144
+ return *this;
145
+ }
146
+ rational_adaptor& operator=(const char* s)
147
+ {
148
+ using default_ops::eval_eq;
149
+
150
+ std::string s1;
151
+ multiprecision::number<Backend> v1, v2;
152
+ char c;
153
+ bool have_hex = false;
154
+ const char* p = s; // saved for later
155
+
156
+ while ((0 != (c = *s)) && (c == 'x' || c == 'X' || c == '-' || c == '+' || (c >= '0' && c <= '9') || (have_hex && (c >= 'a' && c <= 'f')) || (have_hex && (c >= 'A' && c <= 'F'))))
157
+ {
158
+ if (c == 'x' || c == 'X')
159
+ have_hex = true;
160
+ s1.append(1, c);
161
+ ++s;
162
+ }
163
+ v1.assign(s1);
164
+ s1.erase();
165
+ if (c == '/')
166
+ {
167
+ ++s;
168
+ while ((0 != (c = *s)) && (c == 'x' || c == 'X' || c == '-' || c == '+' || (c >= '0' && c <= '9') || (have_hex && (c >= 'a' && c <= 'f')) || (have_hex && (c >= 'A' && c <= 'F'))))
169
+ {
170
+ if (c == 'x' || c == 'X')
171
+ have_hex = true;
172
+ s1.append(1, c);
173
+ ++s;
174
+ }
175
+ v2.assign(s1);
176
+ }
177
+ else
178
+ v2 = 1;
179
+ if (*s)
180
+ {
181
+ BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("Could not parse the string \"") + p + std::string("\" as a valid rational number.")));
182
+ }
183
+ multiprecision::number<Backend> gcd;
184
+ eval_gcd(gcd.backend(), v1.backend(), v2.backend());
185
+ if (!eval_eq(gcd.backend(), one()))
186
+ {
187
+ v1 /= gcd;
188
+ v2 /= gcd;
189
+ }
190
+ num() = std::move(std::move(v1).backend());
191
+ denom() = std::move(std::move(v2).backend());
192
+ return *this;
193
+ }
194
+ template <class Float>
195
+ typename std::enable_if<std::is_floating_point<Float>::value, rational_adaptor&>::type operator=(Float i)
196
+ {
197
+ using default_ops::eval_eq;
198
+ BOOST_MP_FLOAT128_USING using std::floor; using std::frexp; using std::ldexp;
199
+
200
+ int e;
201
+ Float f = frexp(i, &e);
202
+ #ifdef BOOST_HAS_FLOAT128
203
+ f = ldexp(f, std::is_same<float128_type, Float>::value ? 113 : std::numeric_limits<Float>::digits);
204
+ e -= std::is_same<float128_type, Float>::value ? 113 : std::numeric_limits<Float>::digits;
205
+ #else
206
+ f = ldexp(f, std::numeric_limits<Float>::digits);
207
+ e -= std::numeric_limits<Float>::digits;
208
+ #endif
209
+ number<Backend> num(f);
210
+ number<Backend> denom(1u);
211
+ if (e > 0)
212
+ {
213
+ num <<= e;
214
+ }
215
+ else if (e < 0)
216
+ {
217
+ denom <<= -e;
218
+ }
219
+ number<Backend> gcd;
220
+ eval_gcd(gcd.backend(), num.backend(), denom.backend());
221
+ if (!eval_eq(gcd.backend(), one()))
222
+ {
223
+ num /= gcd;
224
+ denom /= gcd;
225
+ }
226
+ this->num() = std::move(std::move(num).backend());
227
+ this->denom() = std::move(std::move(denom).backend());
228
+ return *this;
229
+ }
230
+
231
+ void swap(rational_adaptor& o)
232
+ {
233
+ m_num.swap(o.m_num);
234
+ m_denom.swap(o.m_denom);
235
+ }
236
+ std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
237
+ {
238
+ using default_ops::eval_eq;
239
+ //
240
+ // We format the string ourselves so we can match what GMP's mpq type does:
241
+ //
242
+ std::string result = num().str(digits, f);
243
+ if (!eval_eq(denom(), one()))
244
+ {
245
+ result.append(1, '/');
246
+ result.append(denom().str(digits, f));
247
+ }
248
+ return result;
249
+ }
250
+ void negate()
251
+ {
252
+ m_num.negate();
253
+ }
254
+ int compare(const rational_adaptor& o) const
255
+ {
256
+ std::ptrdiff_t s1 = eval_get_sign(*this);
257
+ std::ptrdiff_t s2 = eval_get_sign(o);
258
+ if (s1 != s2)
259
+ {
260
+ return s1 < s2 ? -1 : 1;
261
+ }
262
+ else if (s1 == 0)
263
+ return 0; // both zero.
264
+
265
+ bool neg = false;
266
+ if (s1 >= 0)
267
+ {
268
+ s1 = eval_msb(num()) + eval_msb(o.denom());
269
+ s2 = eval_msb(o.num()) + eval_msb(denom());
270
+ }
271
+ else
272
+ {
273
+ Backend t(num());
274
+ t.negate();
275
+ s1 = eval_msb(t) + eval_msb(o.denom());
276
+ t = o.num();
277
+ t.negate();
278
+ s2 = eval_msb(t) + eval_msb(denom());
279
+ neg = true;
280
+ }
281
+ s1 -= s2;
282
+ if (s1 < -1)
283
+ return neg ? 1 : -1;
284
+ else if (s1 > 1)
285
+ return neg ? -1 : 1;
286
+
287
+ Backend t1, t2;
288
+ eval_multiply(t1, num(), o.denom());
289
+ eval_multiply(t2, o.num(), denom());
290
+ return t1.compare(t2);
291
+ }
292
+ //
293
+ // Comparison with arithmetic types, default just constructs a temporary:
294
+ //
295
+ template <class A>
296
+ typename std::enable_if<boost::multiprecision::detail::is_arithmetic<A>::value, int>::type compare(A i) const
297
+ {
298
+ rational_adaptor t;
299
+ t = i; // Note: construct directly from i if supported.
300
+ return compare(t);
301
+ }
302
+
303
+ Backend& num() { return m_num; }
304
+ const Backend& num()const { return m_num; }
305
+ Backend& denom() { return m_denom; }
306
+ const Backend& denom()const { return m_denom; }
307
+
308
+ #ifndef BOOST_MP_STANDALONE
309
+ template <class Archive>
310
+ void serialize(Archive& ar, const std::integral_constant<bool, true>&)
311
+ {
312
+ // Saving
313
+ number<Backend> n(num()), d(denom());
314
+ ar& boost::make_nvp("numerator", n);
315
+ ar& boost::make_nvp("denominator", d);
316
+ }
317
+ template <class Archive>
318
+ void serialize(Archive& ar, const std::integral_constant<bool, false>&)
319
+ {
320
+ // Loading
321
+ number<Backend> n, d;
322
+ ar& boost::make_nvp("numerator", n);
323
+ ar& boost::make_nvp("denominator", d);
324
+ num() = n.backend();
325
+ denom() = d.backend();
326
+ }
327
+ template <class Archive>
328
+ void serialize(Archive& ar, const unsigned int /*version*/)
329
+ {
330
+ using tag = typename Archive::is_saving;
331
+ using saving_tag = std::integral_constant<bool, tag::value>;
332
+ serialize(ar, saving_tag());
333
+ }
334
+ #endif // BOOST_MP_STANDALONE
335
+
336
+ private:
337
+ Backend m_num, m_denom;
338
+ };
339
+
340
+ //
341
+ // Helpers:
342
+ //
343
+ template <class T>
344
+ inline constexpr typename std::enable_if<std::numeric_limits<T>::is_specialized && !std::numeric_limits<T>::is_signed, bool>::type
345
+ is_minus_one(const T&)
346
+ {
347
+ return false;
348
+ }
349
+ template <class T>
350
+ inline constexpr typename std::enable_if<!std::numeric_limits<T>::is_specialized || std::numeric_limits<T>::is_signed, bool>::type
351
+ is_minus_one(const T& val)
352
+ {
353
+ return val == -1;
354
+ }
355
+
356
+ //
357
+ // Required non-members:
358
+ //
359
+ template <class Backend>
360
+ inline void eval_add(rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b)
361
+ {
362
+ eval_add_subtract_imp(a, a, b, true);
363
+ }
364
+ template <class Backend>
365
+ inline void eval_subtract(rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b)
366
+ {
367
+ eval_add_subtract_imp(a, a, b, false);
368
+ }
369
+
370
+ template <class Backend>
371
+ inline void eval_multiply(rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b)
372
+ {
373
+ eval_multiply_imp(a, a, b.num(), b.denom());
374
+ }
375
+
376
+ template <class Backend>
377
+ void eval_divide(rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b)
378
+ {
379
+ using default_ops::eval_divide;
380
+ rational_adaptor<Backend> t;
381
+ eval_divide(t, a, b);
382
+ a = std::move(t);
383
+ }
384
+ //
385
+ // Conversions:
386
+ //
387
+ template <class R, class IntBackend>
388
+ inline typename std::enable_if<number_category<R>::value == number_kind_floating_point>::type eval_convert_to(R* result, const rational_adaptor<IntBackend>& backend)
389
+ {
390
+ //
391
+ // The generic conversion is as good as anything we can write here:
392
+ //
393
+ ::boost::multiprecision::detail::generic_convert_rational_to_float(*result, backend);
394
+ }
395
+
396
+ template <class R, class IntBackend>
397
+ inline typename std::enable_if<(number_category<R>::value != number_kind_integer) && (number_category<R>::value != number_kind_floating_point) && !std::is_enum<R>::value>::type eval_convert_to(R* result, const rational_adaptor<IntBackend>& backend)
398
+ {
399
+ using default_ops::eval_convert_to;
400
+ R d;
401
+ eval_convert_to(result, backend.num());
402
+ eval_convert_to(&d, backend.denom());
403
+ *result /= d;
404
+ }
405
+
406
+ template <class R, class Backend>
407
+ inline typename std::enable_if<number_category<R>::value == number_kind_integer>::type eval_convert_to(R* result, const rational_adaptor<Backend>& backend)
408
+ {
409
+ using default_ops::eval_divide;
410
+ using default_ops::eval_convert_to;
411
+ Backend t;
412
+ eval_divide(t, backend.num(), backend.denom());
413
+ eval_convert_to(result, t);
414
+ }
415
+
416
+ //
417
+ // Hashing support, not strictly required, but it is used in our tests:
418
+ //
419
+ template <class Backend>
420
+ inline std::size_t hash_value(const rational_adaptor<Backend>& arg)
421
+ {
422
+ std::size_t result = hash_value(arg.num());
423
+ std::size_t result2 = hash_value(arg.denom());
424
+ boost::multiprecision::detail::hash_combine(result, result2);
425
+ return result;
426
+ }
427
+ //
428
+ // assign_components:
429
+ //
430
+ template <class Backend>
431
+ void assign_components(rational_adaptor<Backend>& result, Backend const& a, Backend const& b)
432
+ {
433
+ using default_ops::eval_gcd;
434
+ using default_ops::eval_divide;
435
+ using default_ops::eval_eq;
436
+ using default_ops::eval_is_zero;
437
+ using default_ops::eval_get_sign;
438
+
439
+ if (eval_is_zero(b))
440
+ {
441
+ BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero"));
442
+ }
443
+ Backend g;
444
+ eval_gcd(g, a, b);
445
+ if (eval_eq(g, rational_adaptor<Backend>::one()))
446
+ {
447
+ result.num() = a;
448
+ result.denom() = b;
449
+ }
450
+ else
451
+ {
452
+ eval_divide(result.num(), a, g);
453
+ eval_divide(result.denom(), b, g);
454
+ }
455
+ if (eval_get_sign(result.denom()) < 0)
456
+ {
457
+ result.num().negate();
458
+ result.denom().negate();
459
+ }
460
+ }
461
+ //
462
+ // Again for arithmetic types, overload for whatever arithmetic types are directly supported:
463
+ //
464
+ template <class Backend, class Arithmetic1, class Arithmetic2>
465
+ inline void assign_components(rational_adaptor<Backend>& result, const Arithmetic1& a, typename std::enable_if<std::is_arithmetic<Arithmetic1>::value && std::is_arithmetic<Arithmetic2>::value, const Arithmetic2&>::type b)
466
+ {
467
+ using default_ops::eval_gcd;
468
+ using default_ops::eval_divide;
469
+ using default_ops::eval_eq;
470
+
471
+ if (b == 0)
472
+ {
473
+ BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero"));
474
+ }
475
+
476
+ Backend g;
477
+ result.num() = a;
478
+ eval_gcd(g, result.num(), b);
479
+ if (eval_eq(g, rational_adaptor<Backend>::one()))
480
+ {
481
+ result.denom() = b;
482
+ }
483
+ else
484
+ {
485
+ eval_divide(result.num(), g);
486
+ eval_divide(result.denom(), b, g);
487
+ }
488
+ if (eval_get_sign(result.denom()) < 0)
489
+ {
490
+ result.num().negate();
491
+ result.denom().negate();
492
+ }
493
+ }
494
+ template <class Backend, class Arithmetic1, class Arithmetic2>
495
+ inline void assign_components(rational_adaptor<Backend>& result, const Arithmetic1& a, typename std::enable_if<!std::is_arithmetic<Arithmetic1>::value || !std::is_arithmetic<Arithmetic2>::value, const Arithmetic2&>::type b)
496
+ {
497
+ using default_ops::eval_gcd;
498
+ using default_ops::eval_divide;
499
+ using default_ops::eval_eq;
500
+
501
+ Backend g;
502
+ result.num() = a;
503
+ result.denom() = b;
504
+
505
+ if (eval_get_sign(result.denom()) == 0)
506
+ {
507
+ BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero"));
508
+ }
509
+
510
+ eval_gcd(g, result.num(), result.denom());
511
+ if (!eval_eq(g, rational_adaptor<Backend>::one()))
512
+ {
513
+ eval_divide(result.num(), g);
514
+ eval_divide(result.denom(), g);
515
+ }
516
+ if (eval_get_sign(result.denom()) < 0)
517
+ {
518
+ result.num().negate();
519
+ result.denom().negate();
520
+ }
521
+ }
522
+ //
523
+ // Optional comparison operators:
524
+ //
525
+ template <class Backend>
526
+ inline bool eval_is_zero(const rational_adaptor<Backend>& arg)
527
+ {
528
+ using default_ops::eval_is_zero;
529
+ return eval_is_zero(arg.num());
530
+ }
531
+
532
+ template <class Backend>
533
+ inline int eval_get_sign(const rational_adaptor<Backend>& arg)
534
+ {
535
+ using default_ops::eval_get_sign;
536
+ return eval_get_sign(arg.num());
537
+ }
538
+
539
+ template <class Backend>
540
+ inline bool eval_eq(const rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b)
541
+ {
542
+ using default_ops::eval_eq;
543
+ return eval_eq(a.num(), b.num()) && eval_eq(a.denom(), b.denom());
544
+ }
545
+
546
+ template <class Backend, class Arithmetic>
547
+ inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value&& std::is_integral<Arithmetic>::value, bool>::type
548
+ eval_eq(const rational_adaptor<Backend>& a, Arithmetic b)
549
+ {
550
+ using default_ops::eval_eq;
551
+ return eval_eq(a.denom(), rational_adaptor<Backend>::one()) && eval_eq(a.num(), b);
552
+ }
553
+
554
+ template <class Backend, class Arithmetic>
555
+ inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value&& std::is_integral<Arithmetic>::value, bool>::type
556
+ eval_eq(Arithmetic b, const rational_adaptor<Backend>& a)
557
+ {
558
+ using default_ops::eval_eq;
559
+ return eval_eq(a.denom(), rational_adaptor<Backend>::one()) && eval_eq(a.num(), b);
560
+ }
561
+
562
+ //
563
+ // Arithmetic operations, starting with addition:
564
+ //
565
+ template <class Backend, class Arithmetic>
566
+ void eval_add_subtract_imp(rational_adaptor<Backend>& result, const Arithmetic& arg, bool isaddition)
567
+ {
568
+ using default_ops::eval_multiply;
569
+ using default_ops::eval_divide;
570
+ using default_ops::eval_add;
571
+ using default_ops::eval_gcd;
572
+ Backend t;
573
+ eval_multiply(t, result.denom(), arg);
574
+ if (isaddition)
575
+ eval_add(result.num(), t);
576
+ else
577
+ eval_subtract(result.num(), t);
578
+ //
579
+ // There is no need to re-normalize here, we have
580
+ // (a + bm) / b
581
+ // and gcd(a + bm, b) = gcd(a, b) = 1
582
+ //
583
+ /*
584
+ eval_gcd(t, result.num(), result.denom());
585
+ if (!eval_eq(t, rational_adaptor<Backend>::one()) != 0)
586
+ {
587
+ Backend t2;
588
+ eval_divide(t2, result.num(), t);
589
+ t2.swap(result.num());
590
+ eval_divide(t2, result.denom(), t);
591
+ t2.swap(result.denom());
592
+ }
593
+ */
594
+ }
595
+
596
+ template <class Backend, class Arithmetic>
597
+ inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type
598
+ eval_add(rational_adaptor<Backend>& result, const Arithmetic& arg)
599
+ {
600
+ eval_add_subtract_imp(result, arg, true);
601
+ }
602
+
603
+ template <class Backend, class Arithmetic>
604
+ inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type
605
+ eval_subtract(rational_adaptor<Backend>& result, const Arithmetic& arg)
606
+ {
607
+ eval_add_subtract_imp(result, arg, false);
608
+ }
609
+
610
+ template <class Backend>
611
+ void eval_add_subtract_imp(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b, bool isaddition)
612
+ {
613
+ using default_ops::eval_eq;
614
+ using default_ops::eval_multiply;
615
+ using default_ops::eval_divide;
616
+ using default_ops::eval_add;
617
+ using default_ops::eval_subtract;
618
+ //
619
+ // Let a = an/ad
620
+ // b = bn/bd
621
+ // g = gcd(ad, bd)
622
+ // result = rn/rd
623
+ //
624
+ // Then:
625
+ // rn = an * (bd/g) + bn * (ad/g)
626
+ // rd = ad * (bd/g)
627
+ // = (ad/g) * (bd/g) * g
628
+ //
629
+ // And the whole thing can then be rescaled by
630
+ // gcd(rn, g)
631
+ //
632
+ Backend gcd, t1, t2, t3, t4;
633
+ //
634
+ // Begin by getting the gcd of the 2 denominators:
635
+ //
636
+ eval_gcd(gcd, a.denom(), b.denom());
637
+ //
638
+ // Do we have gcd > 1:
639
+ //
640
+ if (!eval_eq(gcd, rational_adaptor<Backend>::one()))
641
+ {
642
+ //
643
+ // Scale the denominators by gcd, and put the results in t1 and t2:
644
+ //
645
+ eval_divide(t1, b.denom(), gcd);
646
+ eval_divide(t2, a.denom(), gcd);
647
+ //
648
+ // multiply the numerators by the scale denominators and put the results in t3, t4:
649
+ //
650
+ eval_multiply(t3, a.num(), t1);
651
+ eval_multiply(t4, b.num(), t2);
652
+ //
653
+ // Add them up:
654
+ //
655
+ if (isaddition)
656
+ eval_add(t3, t4);
657
+ else
658
+ eval_subtract(t3, t4);
659
+ //
660
+ // Get the gcd of gcd and our numerator (t3):
661
+ //
662
+ eval_gcd(t4, t3, gcd);
663
+ if (eval_eq(t4, rational_adaptor<Backend>::one()))
664
+ {
665
+ result.num() = t3;
666
+ eval_multiply(result.denom(), t1, a.denom());
667
+ }
668
+ else
669
+ {
670
+ //
671
+ // Uncommon case where gcd is not 1, divide the numerator
672
+ // and the denominator terms by the new gcd. Note we perform division
673
+ // on the existing gcd value as this is the smallest of the 3 denominator
674
+ // terms we'll be multiplying together, so there's a good chance it's a
675
+ // single limb value already:
676
+ //
677
+ eval_divide(result.num(), t3, t4);
678
+ eval_divide(t3, gcd, t4);
679
+ eval_multiply(t4, t1, t2);
680
+ eval_multiply(result.denom(), t4, t3);
681
+ }
682
+ }
683
+ else
684
+ {
685
+ //
686
+ // Most common case (approx 60%) where gcd is one:
687
+ //
688
+ eval_multiply(t1, a.num(), b.denom());
689
+ eval_multiply(t2, a.denom(), b.num());
690
+ if (isaddition)
691
+ eval_add(result.num(), t1, t2);
692
+ else
693
+ eval_subtract(result.num(), t1, t2);
694
+ eval_multiply(result.denom(), a.denom(), b.denom());
695
+ }
696
+ }
697
+
698
+
699
+ template <class Backend>
700
+ inline void eval_add(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b)
701
+ {
702
+ eval_add_subtract_imp(result, a, b, true);
703
+ }
704
+ template <class Backend>
705
+ inline void eval_subtract(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b)
706
+ {
707
+ eval_add_subtract_imp(result, a, b, false);
708
+ }
709
+
710
+ template <class Backend, class Arithmetic>
711
+ void eval_add_subtract_imp(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const Arithmetic& b, bool isaddition)
712
+ {
713
+ using default_ops::eval_add;
714
+ using default_ops::eval_subtract;
715
+ using default_ops::eval_multiply;
716
+
717
+ if (&result == &a)
718
+ return eval_add_subtract_imp(result, b, isaddition);
719
+
720
+ eval_multiply(result.num(), a.denom(), b);
721
+ if (isaddition)
722
+ eval_add(result.num(), a.num());
723
+ else
724
+ BOOST_IF_CONSTEXPR(std::numeric_limits<Backend>::is_signed == false)
725
+ {
726
+ Backend t;
727
+ eval_subtract(t, a.num(), result.num());
728
+ result.num() = std::move(t);
729
+ }
730
+ else
731
+ {
732
+ eval_subtract(result.num(), a.num());
733
+ result.negate();
734
+ }
735
+ result.denom() = a.denom();
736
+ //
737
+ // There is no need to re-normalize here, we have
738
+ // (a + bm) / b
739
+ // and gcd(a + bm, b) = gcd(a, b) = 1
740
+ //
741
+ }
742
+ template <class Backend, class Arithmetic>
743
+ inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type
744
+ eval_add(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const Arithmetic& b)
745
+ {
746
+ eval_add_subtract_imp(result, a, b, true);
747
+ }
748
+ template <class Backend, class Arithmetic>
749
+ inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type
750
+ eval_subtract(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const Arithmetic& b)
751
+ {
752
+ eval_add_subtract_imp(result, a, b, false);
753
+ }
754
+
755
+ //
756
+ // Multiplication:
757
+ //
758
+ template <class Backend>
759
+ void eval_multiply_imp(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const Backend& b_num, const Backend& b_denom)
760
+ {
761
+ using default_ops::eval_multiply;
762
+ using default_ops::eval_divide;
763
+ using default_ops::eval_gcd;
764
+ using default_ops::eval_get_sign;
765
+ using default_ops::eval_eq;
766
+
767
+ Backend gcd_left, gcd_right, t1, t2;
768
+ eval_gcd(gcd_left, a.num(), b_denom);
769
+ eval_gcd(gcd_right, b_num, a.denom());
770
+ //
771
+ // Unit gcd's are the most likely case:
772
+ //
773
+ bool b_left = eval_eq(gcd_left, rational_adaptor<Backend>::one());
774
+ bool b_right = eval_eq(gcd_right, rational_adaptor<Backend>::one());
775
+
776
+ if (b_left && b_right)
777
+ {
778
+ eval_multiply(result.num(), a.num(), b_num);
779
+ eval_multiply(result.denom(), a.denom(), b_denom);
780
+ }
781
+ else if (b_left)
782
+ {
783
+ eval_divide(t2, b_num, gcd_right);
784
+ eval_multiply(result.num(), a.num(), t2);
785
+ eval_divide(t1, a.denom(), gcd_right);
786
+ eval_multiply(result.denom(), t1, b_denom);
787
+ }
788
+ else if (b_right)
789
+ {
790
+ eval_divide(t1, a.num(), gcd_left);
791
+ eval_multiply(result.num(), t1, b_num);
792
+ eval_divide(t2, b_denom, gcd_left);
793
+ eval_multiply(result.denom(), a.denom(), t2);
794
+ }
795
+ else
796
+ {
797
+ eval_divide(t1, a.num(), gcd_left);
798
+ eval_divide(t2, b_num, gcd_right);
799
+ eval_multiply(result.num(), t1, t2);
800
+ eval_divide(t1, a.denom(), gcd_right);
801
+ eval_divide(t2, b_denom, gcd_left);
802
+ eval_multiply(result.denom(), t1, t2);
803
+ }
804
+ //
805
+ // We may have b_denom negative if this is actually division, if so just correct things now:
806
+ //
807
+ if (eval_get_sign(b_denom) < 0)
808
+ {
809
+ result.num().negate();
810
+ result.denom().negate();
811
+ }
812
+ }
813
+
814
+ template <class Backend>
815
+ void eval_multiply(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b)
816
+ {
817
+ using default_ops::eval_multiply;
818
+
819
+ if (&a == &b)
820
+ {
821
+ // squaring, gcd's are 1:
822
+ eval_multiply(result.num(), a.num(), b.num());
823
+ eval_multiply(result.denom(), a.denom(), b.denom());
824
+ return;
825
+ }
826
+ eval_multiply_imp(result, a, b.num(), b.denom());
827
+ }
828
+
829
+ template <class Backend, class Arithmetic>
830
+ void eval_multiply_imp(Backend& result_num, Backend& result_denom, Arithmetic arg)
831
+ {
832
+ if (arg == 0)
833
+ {
834
+ result_num = rational_adaptor<Backend>::zero();
835
+ result_denom = rational_adaptor<Backend>::one();
836
+ return;
837
+ }
838
+ else if (arg == 1)
839
+ return;
840
+
841
+ using default_ops::eval_multiply;
842
+ using default_ops::eval_divide;
843
+ using default_ops::eval_gcd;
844
+ using default_ops::eval_convert_to;
845
+
846
+ Backend gcd, t;
847
+ Arithmetic integer_gcd;
848
+ eval_gcd(gcd, result_denom, arg);
849
+ eval_convert_to(&integer_gcd, gcd);
850
+ arg /= integer_gcd;
851
+ if (boost::multiprecision::detail::unsigned_abs(arg) > 1)
852
+ {
853
+ eval_multiply(t, result_num, arg);
854
+ result_num = std::move(t);
855
+ }
856
+ else if (is_minus_one(arg))
857
+ result_num.negate();
858
+ if (integer_gcd > 1)
859
+ {
860
+ eval_divide(t, result_denom, integer_gcd);
861
+ result_denom = std::move(t);
862
+ }
863
+ }
864
+ template <class Backend>
865
+ void eval_multiply_imp(Backend& result_num, Backend& result_denom, Backend arg)
866
+ {
867
+ using default_ops::eval_multiply;
868
+ using default_ops::eval_divide;
869
+ using default_ops::eval_gcd;
870
+ using default_ops::eval_convert_to;
871
+ using default_ops::eval_is_zero;
872
+ using default_ops::eval_eq;
873
+ using default_ops::eval_get_sign;
874
+
875
+ if (eval_is_zero(arg))
876
+ {
877
+ result_num = rational_adaptor<Backend>::zero();
878
+ result_denom = rational_adaptor<Backend>::one();
879
+ return;
880
+ }
881
+ else if (eval_eq(arg, rational_adaptor<Backend>::one()))
882
+ return;
883
+
884
+ Backend gcd, t;
885
+ eval_gcd(gcd, result_denom, arg);
886
+ if (!eval_eq(gcd, rational_adaptor<Backend>::one()))
887
+ {
888
+ eval_divide(t, arg, gcd);
889
+ arg = t;
890
+ }
891
+ else
892
+ t = arg;
893
+ if (eval_get_sign(arg) < 0)
894
+ t.negate();
895
+
896
+ if (!eval_eq(t, rational_adaptor<Backend>::one()))
897
+ {
898
+ eval_multiply(t, result_num, arg);
899
+ result_num = std::move(t);
900
+ }
901
+ else if (eval_get_sign(arg) < 0)
902
+ result_num.negate();
903
+ if (!eval_eq(gcd, rational_adaptor<Backend>::one()))
904
+ {
905
+ eval_divide(t, result_denom, gcd);
906
+ result_denom = std::move(t);
907
+ }
908
+ }
909
+
910
+ template <class Backend, class Arithmetic>
911
+ inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type
912
+ eval_multiply(rational_adaptor<Backend>& result, const Arithmetic& arg)
913
+ {
914
+ eval_multiply_imp(result.num(), result.denom(), arg);
915
+ }
916
+
917
+ template <class Backend, class Arithmetic>
918
+ typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && std::is_integral<Arithmetic>::value>::type
919
+ eval_multiply_imp(rational_adaptor<Backend>& result, const Backend& a_num, const Backend& a_denom, Arithmetic b)
920
+ {
921
+ if (b == 0)
922
+ {
923
+ result.num() = rational_adaptor<Backend>::zero();
924
+ result.denom() = rational_adaptor<Backend>::one();
925
+ return;
926
+ }
927
+ else if (b == 1)
928
+ {
929
+ result.num() = a_num;
930
+ result.denom() = a_denom;
931
+ return;
932
+ }
933
+
934
+ using default_ops::eval_multiply;
935
+ using default_ops::eval_divide;
936
+ using default_ops::eval_gcd;
937
+ using default_ops::eval_convert_to;
938
+
939
+ Backend gcd;
940
+ Arithmetic integer_gcd;
941
+ eval_gcd(gcd, a_denom, b);
942
+ eval_convert_to(&integer_gcd, gcd);
943
+ b /= integer_gcd;
944
+ if (boost::multiprecision::detail::unsigned_abs(b) > 1)
945
+ eval_multiply(result.num(), a_num, b);
946
+ else if (is_minus_one(b))
947
+ {
948
+ result.num() = a_num;
949
+ result.num().negate();
950
+ }
951
+ else
952
+ result.num() = a_num;
953
+ if (integer_gcd > 1)
954
+ eval_divide(result.denom(), a_denom, integer_gcd);
955
+ else
956
+ result.denom() = a_denom;
957
+ }
958
+ template <class Backend>
959
+ inline void eval_multiply_imp(rational_adaptor<Backend>& result, const Backend& a_num, const Backend& a_denom, const Backend& b)
960
+ {
961
+ result.num() = a_num;
962
+ result.denom() = a_denom;
963
+ eval_multiply_imp(result.num(), result.denom(), b);
964
+ }
965
+
966
+ template <class Backend, class Arithmetic>
967
+ inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type
968
+ eval_multiply(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const Arithmetic& b)
969
+ {
970
+ if (&result == &a)
971
+ return eval_multiply(result, b);
972
+
973
+ eval_multiply_imp(result, a.num(), a.denom(), b);
974
+ }
975
+
976
+ template <class Backend, class Arithmetic>
977
+ inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type
978
+ eval_multiply(rational_adaptor<Backend>& result, const Arithmetic& b, const rational_adaptor<Backend>& a)
979
+ {
980
+ return eval_multiply(result, a, b);
981
+ }
982
+
983
+ //
984
+ // Division:
985
+ //
986
+ template <class Backend>
987
+ inline void eval_divide(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b)
988
+ {
989
+ using default_ops::eval_multiply;
990
+ using default_ops::eval_get_sign;
991
+
992
+ if (eval_get_sign(b.num()) == 0)
993
+ {
994
+ BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero"));
995
+ return;
996
+ }
997
+ if (&a == &b)
998
+ {
999
+ // Huh? Really?
1000
+ result.num() = result.denom() = rational_adaptor<Backend>::one();
1001
+ return;
1002
+ }
1003
+ if (&result == &b)
1004
+ {
1005
+ rational_adaptor<Backend> t(b);
1006
+ return eval_divide(result, a, t);
1007
+ }
1008
+ eval_multiply_imp(result, a, b.denom(), b.num());
1009
+ }
1010
+
1011
+ template <class Backend, class Arithmetic>
1012
+ inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type
1013
+ eval_divide(rational_adaptor<Backend>& result, const Arithmetic& b, const rational_adaptor<Backend>& a)
1014
+ {
1015
+ using default_ops::eval_get_sign;
1016
+
1017
+ if (eval_get_sign(a.num()) == 0)
1018
+ {
1019
+ BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero"));
1020
+ return;
1021
+ }
1022
+ if (&a == &result)
1023
+ {
1024
+ eval_multiply_imp(result.denom(), result.num(), b);
1025
+ result.num().swap(result.denom());
1026
+ }
1027
+ else
1028
+ eval_multiply_imp(result, a.denom(), a.num(), b);
1029
+
1030
+ if (eval_get_sign(result.denom()) < 0)
1031
+ {
1032
+ result.num().negate();
1033
+ result.denom().negate();
1034
+ }
1035
+ }
1036
+
1037
+ template <class Backend, class Arithmetic>
1038
+ typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && std::is_integral<Arithmetic>::value>::type
1039
+ eval_divide(rational_adaptor<Backend>& result, Arithmetic arg)
1040
+ {
1041
+ if (arg == 0)
1042
+ {
1043
+ BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero"));
1044
+ return;
1045
+ }
1046
+ else if (arg == 1)
1047
+ return;
1048
+ else if (is_minus_one(arg))
1049
+ {
1050
+ result.negate();
1051
+ return;
1052
+ }
1053
+ if (eval_get_sign(result) == 0)
1054
+ {
1055
+ return;
1056
+ }
1057
+
1058
+
1059
+ using default_ops::eval_multiply;
1060
+ using default_ops::eval_gcd;
1061
+ using default_ops::eval_convert_to;
1062
+ using default_ops::eval_divide;
1063
+
1064
+ Backend gcd, t;
1065
+ Arithmetic integer_gcd;
1066
+ eval_gcd(gcd, result.num(), arg);
1067
+ eval_convert_to(&integer_gcd, gcd);
1068
+ arg /= integer_gcd;
1069
+
1070
+ eval_multiply(t, result.denom(), boost::multiprecision::detail::unsigned_abs(arg));
1071
+ result.denom() = std::move(t);
1072
+ if (arg < 0)
1073
+ {
1074
+ result.num().negate();
1075
+ }
1076
+ if (integer_gcd > 1)
1077
+ {
1078
+ eval_divide(t, result.num(), integer_gcd);
1079
+ result.num() = std::move(t);
1080
+ }
1081
+ }
1082
+ template <class Backend>
1083
+ void eval_divide(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, Backend arg)
1084
+ {
1085
+ using default_ops::eval_multiply;
1086
+ using default_ops::eval_gcd;
1087
+ using default_ops::eval_convert_to;
1088
+ using default_ops::eval_divide;
1089
+ using default_ops::eval_is_zero;
1090
+ using default_ops::eval_eq;
1091
+ using default_ops::eval_get_sign;
1092
+
1093
+ if (eval_is_zero(arg))
1094
+ {
1095
+ BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero"));
1096
+ return;
1097
+ }
1098
+ else if (eval_eq(a, rational_adaptor<Backend>::one()) || (eval_get_sign(a) == 0))
1099
+ {
1100
+ if (&result != &a)
1101
+ result = a;
1102
+ result.denom() = arg;
1103
+ return;
1104
+ }
1105
+
1106
+ Backend gcd, u_arg, t;
1107
+ eval_gcd(gcd, a.num(), arg);
1108
+ bool has_unit_gcd = eval_eq(gcd, rational_adaptor<Backend>::one());
1109
+ if (!has_unit_gcd)
1110
+ {
1111
+ eval_divide(u_arg, arg, gcd);
1112
+ arg = u_arg;
1113
+ }
1114
+ else
1115
+ u_arg = arg;
1116
+ if (eval_get_sign(u_arg) < 0)
1117
+ u_arg.negate();
1118
+
1119
+ eval_multiply(t, a.denom(), u_arg);
1120
+ result.denom() = std::move(t);
1121
+
1122
+ if (!has_unit_gcd)
1123
+ {
1124
+ eval_divide(t, a.num(), gcd);
1125
+ result.num() = std::move(t);
1126
+ }
1127
+ else if (&result != &a)
1128
+ result.num() = a.num();
1129
+
1130
+ if (eval_get_sign(arg) < 0)
1131
+ {
1132
+ result.num().negate();
1133
+ }
1134
+ }
1135
+ template <class Backend>
1136
+ void eval_divide(rational_adaptor<Backend>& result, const Backend& arg)
1137
+ {
1138
+ eval_divide(result, result, arg);
1139
+ }
1140
+
1141
+ template <class Backend, class Arithmetic>
1142
+ typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && std::is_integral<Arithmetic>::value>::type
1143
+ eval_divide(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, Arithmetic arg)
1144
+ {
1145
+ if (&result == &a)
1146
+ return eval_divide(result, arg);
1147
+ if (arg == 0)
1148
+ {
1149
+ BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero"));
1150
+ return;
1151
+ }
1152
+ else if (arg == 1)
1153
+ {
1154
+ result = a;
1155
+ return;
1156
+ }
1157
+ else if (is_minus_one(arg))
1158
+ {
1159
+ result = a;
1160
+ result.num().negate();
1161
+ return;
1162
+ }
1163
+
1164
+ if (eval_get_sign(a) == 0)
1165
+ {
1166
+ result = a;
1167
+ return;
1168
+ }
1169
+
1170
+ using default_ops::eval_multiply;
1171
+ using default_ops::eval_divide;
1172
+ using default_ops::eval_gcd;
1173
+ using default_ops::eval_convert_to;
1174
+
1175
+ Backend gcd;
1176
+ Arithmetic integer_gcd;
1177
+ eval_gcd(gcd, a.num(), arg);
1178
+ eval_convert_to(&integer_gcd, gcd);
1179
+ arg /= integer_gcd;
1180
+ eval_multiply(result.denom(), a.denom(), boost::multiprecision::detail::unsigned_abs(arg));
1181
+
1182
+ if (integer_gcd > 1)
1183
+ {
1184
+ eval_divide(result.num(), a.num(), integer_gcd);
1185
+ }
1186
+ else
1187
+ result.num() = a.num();
1188
+ if (arg < 0)
1189
+ {
1190
+ result.num().negate();
1191
+ }
1192
+ }
1193
+
1194
+ //
1195
+ // Increment and decrement:
1196
+ //
1197
+ template <class Backend>
1198
+ inline void eval_increment(rational_adaptor<Backend>& arg)
1199
+ {
1200
+ using default_ops::eval_add;
1201
+ eval_add(arg.num(), arg.denom());
1202
+ }
1203
+ template <class Backend>
1204
+ inline void eval_decrement(rational_adaptor<Backend>& arg)
1205
+ {
1206
+ using default_ops::eval_subtract;
1207
+ eval_subtract(arg.num(), arg.denom());
1208
+ }
1209
+
1210
+ //
1211
+ // abs:
1212
+ //
1213
+ template <class Backend>
1214
+ inline void eval_abs(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& arg)
1215
+ {
1216
+ using default_ops::eval_abs;
1217
+ eval_abs(result.num(), arg.num());
1218
+ result.denom() = arg.denom();
1219
+ }
1220
+
1221
+ } // namespace backends
1222
+
1223
+ //
1224
+ // Define a category for this number type, one of:
1225
+ //
1226
+ // number_kind_integer
1227
+ // number_kind_floating_point
1228
+ // number_kind_rational
1229
+ // number_kind_fixed_point
1230
+ // number_kind_complex
1231
+ //
1232
+ template<class Backend>
1233
+ struct number_category<rational_adaptor<Backend> > : public std::integral_constant<int, number_kind_rational>
1234
+ {};
1235
+
1236
+ template <class Backend, expression_template_option ExpressionTemplates>
1237
+ struct component_type<number<rational_adaptor<Backend>, ExpressionTemplates> >
1238
+ {
1239
+ typedef number<Backend, ExpressionTemplates> type;
1240
+ };
1241
+
1242
+ template <class IntBackend, expression_template_option ET>
1243
+ inline number<IntBackend, ET> numerator(const number<rational_adaptor<IntBackend>, ET>& val)
1244
+ {
1245
+ return val.backend().num();
1246
+ }
1247
+ template <class IntBackend, expression_template_option ET>
1248
+ inline number<IntBackend, ET> denominator(const number<rational_adaptor<IntBackend>, ET>& val)
1249
+ {
1250
+ return val.backend().denom();
1251
+ }
1252
+
1253
+ template <class Backend>
1254
+ struct is_unsigned_number<rational_adaptor<Backend> > : public is_unsigned_number<Backend>
1255
+ {};
1256
+
1257
+
1258
+ }} // namespace boost::multiprecision
1259
+
1260
+ namespace std {
1261
+
1262
+ template <class IntBackend, boost::multiprecision::expression_template_option ExpressionTemplates>
1263
+ class numeric_limits<boost::multiprecision::number<boost::multiprecision::rational_adaptor<IntBackend>, ExpressionTemplates> > : public std::numeric_limits<boost::multiprecision::number<IntBackend, ExpressionTemplates> >
1264
+ {
1265
+ using base_type = std::numeric_limits<boost::multiprecision::number<IntBackend> >;
1266
+ using number_type = boost::multiprecision::number<boost::multiprecision::rational_adaptor<IntBackend> >;
1267
+
1268
+ public:
1269
+ static constexpr bool is_integer = false;
1270
+ static constexpr bool is_exact = true;
1271
+ static constexpr number_type(min)() { return (base_type::min)(); }
1272
+ static constexpr number_type(max)() { return (base_type::max)(); }
1273
+ static constexpr number_type lowest() { return -(max)(); }
1274
+ static constexpr number_type epsilon() { return base_type::epsilon(); }
1275
+ static constexpr number_type round_error() { return epsilon() / 2; }
1276
+ static constexpr number_type infinity() { return base_type::infinity(); }
1277
+ static constexpr number_type quiet_NaN() { return base_type::quiet_NaN(); }
1278
+ static constexpr number_type signaling_NaN() { return base_type::signaling_NaN(); }
1279
+ static constexpr number_type denorm_min() { return base_type::denorm_min(); }
1280
+ };
1281
+
1282
+ template <class IntBackend, boost::multiprecision::expression_template_option ExpressionTemplates>
1283
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::rational_adaptor<IntBackend>, ExpressionTemplates> >::is_integer;
1284
+ template <class IntBackend, boost::multiprecision::expression_template_option ExpressionTemplates>
1285
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::rational_adaptor<IntBackend>, ExpressionTemplates> >::is_exact;
1286
+
1287
+ } // namespace std
1288
+
1289
+ #endif