mqt-core 3.3.2__cp314-cp314t-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.
- mqt/core/__init__.py +89 -0
- mqt/core/__main__.py +55 -0
- mqt/core/_commands.py +52 -0
- mqt/core/_compat/__init__.py +11 -0
- mqt/core/_compat/typing.py +29 -0
- mqt/core/_version.py +34 -0
- mqt/core/_version.pyi +12 -0
- mqt/core/bin/mqt-core-algorithms.dll +0 -0
- mqt/core/bin/mqt-core-circuit-optimizer.dll +0 -0
- mqt/core/bin/mqt-core-dd.dll +0 -0
- mqt/core/bin/mqt-core-ds.dll +0 -0
- mqt/core/bin/mqt-core-fomac.dll +0 -0
- mqt/core/bin/mqt-core-ir.dll +0 -0
- mqt/core/bin/mqt-core-na-fomac.dll +0 -0
- mqt/core/bin/mqt-core-na.dll +0 -0
- mqt/core/bin/mqt-core-qasm.dll +0 -0
- mqt/core/bin/mqt-core-qdmi-driver.dll +0 -0
- mqt/core/bin/mqt-core-qdmi-na-device.dll +0 -0
- mqt/core/bin/mqt-core-zx.dll +0 -0
- mqt/core/dd.cp314t-win_amd64.pyd +0 -0
- mqt/core/dd.pyi +1016 -0
- mqt/core/dd_evaluation.py +368 -0
- mqt/core/fomac.cp314t-win_amd64.pyd +0 -0
- mqt/core/fomac.pyi +125 -0
- mqt/core/include/mqt-core/algorithms/BernsteinVazirani.hpp +39 -0
- mqt/core/include/mqt-core/algorithms/GHZState.hpp +18 -0
- mqt/core/include/mqt-core/algorithms/Grover.hpp +33 -0
- mqt/core/include/mqt-core/algorithms/QFT.hpp +21 -0
- mqt/core/include/mqt-core/algorithms/QPE.hpp +30 -0
- mqt/core/include/mqt-core/algorithms/RandomCliffordCircuit.hpp +22 -0
- mqt/core/include/mqt-core/algorithms/StatePreparation.hpp +43 -0
- mqt/core/include/mqt-core/algorithms/WState.hpp +18 -0
- mqt/core/include/mqt-core/algorithms/mqt_core_algorithms_export.h +43 -0
- mqt/core/include/mqt-core/boost/config/abi/borland_prefix.hpp +27 -0
- mqt/core/include/mqt-core/boost/config/abi/borland_suffix.hpp +12 -0
- mqt/core/include/mqt-core/boost/config/abi/msvc_prefix.hpp +22 -0
- mqt/core/include/mqt-core/boost/config/abi/msvc_suffix.hpp +8 -0
- mqt/core/include/mqt-core/boost/config/abi_prefix.hpp +25 -0
- mqt/core/include/mqt-core/boost/config/abi_suffix.hpp +25 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx03.hpp +211 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx11.hpp +212 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx14.hpp +47 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx17.hpp +65 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx20.hpp +59 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx23.hpp +41 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx98.hpp +23 -0
- mqt/core/include/mqt-core/boost/config/auto_link.hpp +525 -0
- mqt/core/include/mqt-core/boost/config/compiler/borland.hpp +342 -0
- mqt/core/include/mqt-core/boost/config/compiler/clang.hpp +370 -0
- mqt/core/include/mqt-core/boost/config/compiler/clang_version.hpp +89 -0
- mqt/core/include/mqt-core/boost/config/compiler/codegear.hpp +389 -0
- mqt/core/include/mqt-core/boost/config/compiler/comeau.hpp +59 -0
- mqt/core/include/mqt-core/boost/config/compiler/common_edg.hpp +185 -0
- mqt/core/include/mqt-core/boost/config/compiler/compaq_cxx.hpp +19 -0
- mqt/core/include/mqt-core/boost/config/compiler/cray.hpp +446 -0
- mqt/core/include/mqt-core/boost/config/compiler/diab.hpp +26 -0
- mqt/core/include/mqt-core/boost/config/compiler/digitalmars.hpp +146 -0
- mqt/core/include/mqt-core/boost/config/compiler/gcc.hpp +386 -0
- mqt/core/include/mqt-core/boost/config/compiler/gcc_xml.hpp +115 -0
- mqt/core/include/mqt-core/boost/config/compiler/greenhills.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/compiler/hp_acc.hpp +153 -0
- mqt/core/include/mqt-core/boost/config/compiler/intel.hpp +577 -0
- mqt/core/include/mqt-core/boost/config/compiler/kai.hpp +33 -0
- mqt/core/include/mqt-core/boost/config/compiler/metrowerks.hpp +201 -0
- mqt/core/include/mqt-core/boost/config/compiler/mpw.hpp +143 -0
- mqt/core/include/mqt-core/boost/config/compiler/nvcc.hpp +64 -0
- mqt/core/include/mqt-core/boost/config/compiler/pathscale.hpp +141 -0
- mqt/core/include/mqt-core/boost/config/compiler/pgi.hpp +23 -0
- mqt/core/include/mqt-core/boost/config/compiler/sgi_mipspro.hpp +29 -0
- mqt/core/include/mqt-core/boost/config/compiler/sunpro_cc.hpp +225 -0
- mqt/core/include/mqt-core/boost/config/compiler/vacpp.hpp +189 -0
- mqt/core/include/mqt-core/boost/config/compiler/visualc.hpp +398 -0
- mqt/core/include/mqt-core/boost/config/compiler/xlcpp.hpp +303 -0
- mqt/core/include/mqt-core/boost/config/compiler/xlcpp_zos.hpp +174 -0
- mqt/core/include/mqt-core/boost/config/detail/cxx_composite.hpp +218 -0
- mqt/core/include/mqt-core/boost/config/detail/posix_features.hpp +95 -0
- mqt/core/include/mqt-core/boost/config/detail/select_compiler_config.hpp +157 -0
- mqt/core/include/mqt-core/boost/config/detail/select_platform_config.hpp +147 -0
- mqt/core/include/mqt-core/boost/config/detail/select_stdlib_config.hpp +121 -0
- mqt/core/include/mqt-core/boost/config/detail/suffix.hpp +1334 -0
- mqt/core/include/mqt-core/boost/config/header_deprecated.hpp +26 -0
- mqt/core/include/mqt-core/boost/config/helper_macros.hpp +37 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/cmath.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/complex.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/functional.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/memory.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/utility.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/platform/aix.hpp +33 -0
- mqt/core/include/mqt-core/boost/config/platform/amigaos.hpp +15 -0
- mqt/core/include/mqt-core/boost/config/platform/beos.hpp +26 -0
- mqt/core/include/mqt-core/boost/config/platform/bsd.hpp +83 -0
- mqt/core/include/mqt-core/boost/config/platform/cloudabi.hpp +18 -0
- mqt/core/include/mqt-core/boost/config/platform/cray.hpp +18 -0
- mqt/core/include/mqt-core/boost/config/platform/cygwin.hpp +71 -0
- mqt/core/include/mqt-core/boost/config/platform/haiku.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/platform/hpux.hpp +87 -0
- mqt/core/include/mqt-core/boost/config/platform/irix.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/platform/linux.hpp +106 -0
- mqt/core/include/mqt-core/boost/config/platform/macos.hpp +87 -0
- mqt/core/include/mqt-core/boost/config/platform/qnxnto.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/platform/solaris.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/platform/symbian.hpp +97 -0
- mqt/core/include/mqt-core/boost/config/platform/vms.hpp +25 -0
- mqt/core/include/mqt-core/boost/config/platform/vxworks.hpp +422 -0
- mqt/core/include/mqt-core/boost/config/platform/wasm.hpp +23 -0
- mqt/core/include/mqt-core/boost/config/platform/win32.hpp +90 -0
- mqt/core/include/mqt-core/boost/config/platform/zos.hpp +32 -0
- mqt/core/include/mqt-core/boost/config/pragma_message.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/requires_threads.hpp +92 -0
- mqt/core/include/mqt-core/boost/config/stdlib/dinkumware.hpp +324 -0
- mqt/core/include/mqt-core/boost/config/stdlib/libcomo.hpp +93 -0
- mqt/core/include/mqt-core/boost/config/stdlib/libcpp.hpp +180 -0
- mqt/core/include/mqt-core/boost/config/stdlib/libstdcpp3.hpp +482 -0
- mqt/core/include/mqt-core/boost/config/stdlib/modena.hpp +79 -0
- mqt/core/include/mqt-core/boost/config/stdlib/msl.hpp +98 -0
- mqt/core/include/mqt-core/boost/config/stdlib/roguewave.hpp +208 -0
- mqt/core/include/mqt-core/boost/config/stdlib/sgi.hpp +168 -0
- mqt/core/include/mqt-core/boost/config/stdlib/stlport.hpp +258 -0
- mqt/core/include/mqt-core/boost/config/stdlib/vacpp.hpp +74 -0
- mqt/core/include/mqt-core/boost/config/stdlib/xlcpp_zos.hpp +61 -0
- mqt/core/include/mqt-core/boost/config/user.hpp +133 -0
- mqt/core/include/mqt-core/boost/config/warning_disable.hpp +47 -0
- mqt/core/include/mqt-core/boost/config/workaround.hpp +305 -0
- mqt/core/include/mqt-core/boost/config.hpp +67 -0
- mqt/core/include/mqt-core/boost/cstdint.hpp +556 -0
- mqt/core/include/mqt-core/boost/cxx11_char_types.hpp +70 -0
- mqt/core/include/mqt-core/boost/detail/workaround.hpp +10 -0
- mqt/core/include/mqt-core/boost/limits.hpp +146 -0
- mqt/core/include/mqt-core/boost/multiprecision/complex128.hpp +24 -0
- mqt/core/include/mqt-core/boost/multiprecision/complex_adaptor.hpp +1046 -0
- mqt/core/include/mqt-core/boost/multiprecision/concepts/mp_number_archetypes.hpp +257 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float/io.hpp +698 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float/transcendental.hpp +157 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float.hpp +2297 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_complex.hpp +12 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_dec_float.hpp +3690 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/add.hpp +368 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/add_unsigned.hpp +387 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/bitwise.hpp +889 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/checked.hpp +178 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/comparison.hpp +374 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/cpp_int_config.hpp +161 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/divide.hpp +703 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/import_export.hpp +248 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/intel_intrinsics.hpp +138 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/limits.hpp +282 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/literals.hpp +295 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/misc.hpp +1457 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/multiply.hpp +848 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/serialize.hpp +211 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/value_pack.hpp +42 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int.hpp +2360 -0
- mqt/core/include/mqt-core/boost/multiprecision/debug_adaptor.hpp +760 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/assert.hpp +29 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/atomic.hpp +62 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/bitscan.hpp +317 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/check_cpp11_config.hpp +64 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/constexpr.hpp +88 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/default_ops.hpp +4052 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/digits.hpp +49 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/dynamic_array.hpp +44 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/empty_value.hpp +87 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/endian.hpp +35 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/et_ops.hpp +1831 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/float128_functions.hpp +95 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/float_string_cvt.hpp +333 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/fpclassify.hpp +101 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/functions/constants.hpp +288 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/functions/pow.hpp +905 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/functions/trig.hpp +1058 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/functions/trunc.hpp +82 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/generic_interconvert.hpp +687 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/hash.hpp +56 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/integer_ops.hpp +474 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/itos.hpp +39 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/min_max.hpp +106 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/no_et_ops.hpp +661 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/no_exceptions_support.hpp +55 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/number_base.hpp +1656 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/number_compare.hpp +848 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/precision.hpp +313 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/rebind.hpp +19 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/standalone_config.hpp +148 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/static_array.hpp +42 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/string_helpers.hpp +48 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/tables.hpp +80 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/ublas_interop.hpp +75 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/uniform_int_distribution.hpp +212 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/utype_helper.hpp +374 -0
- mqt/core/include/mqt-core/boost/multiprecision/eigen.hpp +248 -0
- mqt/core/include/mqt-core/boost/multiprecision/float128.hpp +920 -0
- mqt/core/include/mqt-core/boost/multiprecision/fwd.hpp +268 -0
- mqt/core/include/mqt-core/boost/multiprecision/gmp.hpp +4060 -0
- mqt/core/include/mqt-core/boost/multiprecision/integer.hpp +363 -0
- mqt/core/include/mqt-core/boost/multiprecision/logged_adaptor.hpp +834 -0
- mqt/core/include/mqt-core/boost/multiprecision/miller_rabin.hpp +221 -0
- mqt/core/include/mqt-core/boost/multiprecision/mpc.hpp +1721 -0
- mqt/core/include/mqt-core/boost/multiprecision/mpfi.hpp +2559 -0
- mqt/core/include/mqt-core/boost/multiprecision/mpfr.hpp +3644 -0
- mqt/core/include/mqt-core/boost/multiprecision/number.hpp +2500 -0
- mqt/core/include/mqt-core/boost/multiprecision/random.hpp +23 -0
- mqt/core/include/mqt-core/boost/multiprecision/rational_adaptor.hpp +1289 -0
- mqt/core/include/mqt-core/boost/multiprecision/tommath.hpp +1034 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/explicit_conversion.hpp +67 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/extract_exponent_type.hpp +28 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_backend.hpp +91 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_byte_container.hpp +51 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_complex.hpp +22 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_convertible_arithmetic.hpp +51 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_restricted_conversion.hpp +47 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_variable_precision.hpp +25 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/max_digits10.hpp +79 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/std_integer_traits.hpp +90 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/transcendental_reduction_type.hpp +21 -0
- mqt/core/include/mqt-core/boost/version.hpp +32 -0
- mqt/core/include/mqt-core/circuit_optimizer/CircuitOptimizer.hpp +119 -0
- mqt/core/include/mqt-core/circuit_optimizer/mqt_core_circuit_optimizer_export.h +43 -0
- mqt/core/include/mqt-core/datastructures/DirectedAcyclicGraph.hpp +117 -0
- mqt/core/include/mqt-core/datastructures/DirectedGraph.hpp +158 -0
- mqt/core/include/mqt-core/datastructures/DisjointSet.hpp +50 -0
- mqt/core/include/mqt-core/datastructures/Layer.hpp +172 -0
- mqt/core/include/mqt-core/datastructures/SymmetricMatrix.hpp +57 -0
- mqt/core/include/mqt-core/datastructures/UndirectedGraph.hpp +227 -0
- mqt/core/include/mqt-core/datastructures/mqt_core_ds_export.h +43 -0
- mqt/core/include/mqt-core/dd/Approximation.hpp +45 -0
- mqt/core/include/mqt-core/dd/CachedEdge.hpp +174 -0
- mqt/core/include/mqt-core/dd/Complex.hpp +165 -0
- mqt/core/include/mqt-core/dd/ComplexNumbers.hpp +150 -0
- mqt/core/include/mqt-core/dd/ComplexValue.hpp +184 -0
- mqt/core/include/mqt-core/dd/ComputeTable.hpp +183 -0
- mqt/core/include/mqt-core/dd/DDDefinitions.hpp +139 -0
- mqt/core/include/mqt-core/dd/DDpackageConfig.hpp +104 -0
- mqt/core/include/mqt-core/dd/DensityNoiseTable.hpp +114 -0
- mqt/core/include/mqt-core/dd/Edge.hpp +416 -0
- mqt/core/include/mqt-core/dd/Export.hpp +438 -0
- mqt/core/include/mqt-core/dd/FunctionalityConstruction.hpp +75 -0
- mqt/core/include/mqt-core/dd/GateMatrixDefinitions.hpp +43 -0
- mqt/core/include/mqt-core/dd/LinkedListBase.hpp +45 -0
- mqt/core/include/mqt-core/dd/MemoryManager.hpp +193 -0
- mqt/core/include/mqt-core/dd/Node.hpp +223 -0
- mqt/core/include/mqt-core/dd/NoiseFunctionality.hpp +144 -0
- mqt/core/include/mqt-core/dd/Operations.hpp +306 -0
- mqt/core/include/mqt-core/dd/Package.hpp +2036 -0
- mqt/core/include/mqt-core/dd/Package_fwd.hpp +22 -0
- mqt/core/include/mqt-core/dd/RealNumber.hpp +255 -0
- mqt/core/include/mqt-core/dd/RealNumberUniqueTable.hpp +217 -0
- mqt/core/include/mqt-core/dd/Simulation.hpp +98 -0
- mqt/core/include/mqt-core/dd/StateGeneration.hpp +143 -0
- mqt/core/include/mqt-core/dd/StochasticNoiseOperationTable.hpp +88 -0
- mqt/core/include/mqt-core/dd/UnaryComputeTable.hpp +121 -0
- mqt/core/include/mqt-core/dd/UniqueTable.hpp +243 -0
- mqt/core/include/mqt-core/dd/mqt_core_dd_export.h +43 -0
- mqt/core/include/mqt-core/dd/statistics/MemoryManagerStatistics.hpp +84 -0
- mqt/core/include/mqt-core/dd/statistics/PackageStatistics.hpp +55 -0
- mqt/core/include/mqt-core/dd/statistics/Statistics.hpp +48 -0
- mqt/core/include/mqt-core/dd/statistics/TableStatistics.hpp +79 -0
- mqt/core/include/mqt-core/dd/statistics/UniqueTableStatistics.hpp +31 -0
- mqt/core/include/mqt-core/fomac/FoMaC.hpp +568 -0
- mqt/core/include/mqt-core/ir/Definitions.hpp +108 -0
- mqt/core/include/mqt-core/ir/Permutation.hpp +213 -0
- mqt/core/include/mqt-core/ir/QuantumComputation.hpp +596 -0
- mqt/core/include/mqt-core/ir/Register.hpp +125 -0
- mqt/core/include/mqt-core/ir/mqt_core_ir_export.h +43 -0
- mqt/core/include/mqt-core/ir/operations/AodOperation.hpp +92 -0
- mqt/core/include/mqt-core/ir/operations/CompoundOperation.hpp +212 -0
- mqt/core/include/mqt-core/ir/operations/Control.hpp +142 -0
- mqt/core/include/mqt-core/ir/operations/Expression.hpp +847 -0
- mqt/core/include/mqt-core/ir/operations/IfElseOperation.hpp +169 -0
- mqt/core/include/mqt-core/ir/operations/NonUnitaryOperation.hpp +118 -0
- mqt/core/include/mqt-core/ir/operations/OpType.hpp +120 -0
- mqt/core/include/mqt-core/ir/operations/OpType.inc +76 -0
- mqt/core/include/mqt-core/ir/operations/Operation.hpp +247 -0
- mqt/core/include/mqt-core/ir/operations/StandardOperation.hpp +140 -0
- mqt/core/include/mqt-core/ir/operations/SymbolicOperation.hpp +144 -0
- mqt/core/include/mqt-core/mqt_na_qdmi/device.h +602 -0
- mqt/core/include/mqt-core/mqt_na_qdmi/types.h +78 -0
- mqt/core/include/mqt-core/na/NAComputation.hpp +185 -0
- mqt/core/include/mqt-core/na/device/Device.hpp +410 -0
- mqt/core/include/mqt-core/na/device/DeviceMemberInitializers.hpp +724 -0
- mqt/core/include/mqt-core/na/device/Generator.hpp +447 -0
- mqt/core/include/mqt-core/na/entities/Atom.hpp +62 -0
- mqt/core/include/mqt-core/na/entities/Location.hpp +154 -0
- mqt/core/include/mqt-core/na/entities/Zone.hpp +95 -0
- mqt/core/include/mqt-core/na/fomac/Device.hpp +169 -0
- mqt/core/include/mqt-core/na/mqt_core_na_export.h +43 -0
- mqt/core/include/mqt-core/na/operations/GlobalCZOp.hpp +38 -0
- mqt/core/include/mqt-core/na/operations/GlobalOp.hpp +58 -0
- mqt/core/include/mqt-core/na/operations/GlobalRYOp.hpp +42 -0
- mqt/core/include/mqt-core/na/operations/LoadOp.hpp +89 -0
- mqt/core/include/mqt-core/na/operations/LocalOp.hpp +56 -0
- mqt/core/include/mqt-core/na/operations/LocalRZOp.hpp +42 -0
- mqt/core/include/mqt-core/na/operations/LocalUOp.hpp +49 -0
- mqt/core/include/mqt-core/na/operations/MoveOp.hpp +66 -0
- mqt/core/include/mqt-core/na/operations/Op.hpp +62 -0
- mqt/core/include/mqt-core/na/operations/ShuttlingOp.hpp +51 -0
- mqt/core/include/mqt-core/na/operations/StoreOp.hpp +87 -0
- mqt/core/include/mqt-core/qasm3/Exception.hpp +85 -0
- mqt/core/include/mqt-core/qasm3/Gate.hpp +65 -0
- mqt/core/include/mqt-core/qasm3/Importer.hpp +192 -0
- mqt/core/include/mqt-core/qasm3/InstVisitor.hpp +145 -0
- mqt/core/include/mqt-core/qasm3/NestedEnvironment.hpp +41 -0
- mqt/core/include/mqt-core/qasm3/Parser.hpp +170 -0
- mqt/core/include/mqt-core/qasm3/Scanner.hpp +73 -0
- mqt/core/include/mqt-core/qasm3/Statement.hpp +486 -0
- mqt/core/include/mqt-core/qasm3/Statement_fwd.hpp +39 -0
- mqt/core/include/mqt-core/qasm3/StdGates.hpp +232 -0
- mqt/core/include/mqt-core/qasm3/Token.hpp +198 -0
- mqt/core/include/mqt-core/qasm3/Types.hpp +238 -0
- mqt/core/include/mqt-core/qasm3/Types_fwd.hpp +22 -0
- mqt/core/include/mqt-core/qasm3/mqt_core_qasm_export.h +43 -0
- mqt/core/include/mqt-core/qasm3/passes/CompilerPass.hpp +22 -0
- mqt/core/include/mqt-core/qasm3/passes/ConstEvalPass.hpp +102 -0
- mqt/core/include/mqt-core/qasm3/passes/TypeCheckPass.hpp +124 -0
- mqt/core/include/mqt-core/qdmi/Driver.hpp +431 -0
- mqt/core/include/mqt-core/zx/FunctionalityConstruction.hpp +125 -0
- mqt/core/include/mqt-core/zx/Rational.hpp +318 -0
- mqt/core/include/mqt-core/zx/Rules.hpp +132 -0
- mqt/core/include/mqt-core/zx/Simplify.hpp +182 -0
- mqt/core/include/mqt-core/zx/Utils.hpp +212 -0
- mqt/core/include/mqt-core/zx/ZXDefinitions.hpp +93 -0
- mqt/core/include/mqt-core/zx/ZXDiagram.hpp +480 -0
- mqt/core/include/mqt-core/zx/mqt_core_zx_export.h +43 -0
- mqt/core/include/nlohmann/adl_serializer.hpp +55 -0
- mqt/core/include/nlohmann/byte_container_with_subtype.hpp +103 -0
- mqt/core/include/nlohmann/detail/abi_macros.hpp +111 -0
- mqt/core/include/nlohmann/detail/conversions/from_json.hpp +577 -0
- mqt/core/include/nlohmann/detail/conversions/to_chars.hpp +1118 -0
- mqt/core/include/nlohmann/detail/conversions/to_json.hpp +479 -0
- mqt/core/include/nlohmann/detail/exceptions.hpp +291 -0
- mqt/core/include/nlohmann/detail/hash.hpp +129 -0
- mqt/core/include/nlohmann/detail/input/binary_reader.hpp +3068 -0
- mqt/core/include/nlohmann/detail/input/input_adapters.hpp +549 -0
- mqt/core/include/nlohmann/detail/input/json_sax.hpp +986 -0
- mqt/core/include/nlohmann/detail/input/lexer.hpp +1643 -0
- mqt/core/include/nlohmann/detail/input/parser.hpp +519 -0
- mqt/core/include/nlohmann/detail/input/position_t.hpp +37 -0
- mqt/core/include/nlohmann/detail/iterators/internal_iterator.hpp +35 -0
- mqt/core/include/nlohmann/detail/iterators/iter_impl.hpp +760 -0
- mqt/core/include/nlohmann/detail/iterators/iteration_proxy.hpp +235 -0
- mqt/core/include/nlohmann/detail/iterators/iterator_traits.hpp +61 -0
- mqt/core/include/nlohmann/detail/iterators/json_reverse_iterator.hpp +130 -0
- mqt/core/include/nlohmann/detail/iterators/primitive_iterator.hpp +132 -0
- mqt/core/include/nlohmann/detail/json_custom_base_class.hpp +39 -0
- mqt/core/include/nlohmann/detail/json_pointer.hpp +988 -0
- mqt/core/include/nlohmann/detail/json_ref.hpp +78 -0
- mqt/core/include/nlohmann/detail/macro_scope.hpp +595 -0
- mqt/core/include/nlohmann/detail/macro_unscope.hpp +46 -0
- mqt/core/include/nlohmann/detail/meta/call_std/begin.hpp +17 -0
- mqt/core/include/nlohmann/detail/meta/call_std/end.hpp +17 -0
- mqt/core/include/nlohmann/detail/meta/cpp_future.hpp +171 -0
- mqt/core/include/nlohmann/detail/meta/detected.hpp +70 -0
- mqt/core/include/nlohmann/detail/meta/identity_tag.hpp +21 -0
- mqt/core/include/nlohmann/detail/meta/is_sax.hpp +159 -0
- mqt/core/include/nlohmann/detail/meta/std_fs.hpp +29 -0
- mqt/core/include/nlohmann/detail/meta/type_traits.hpp +795 -0
- mqt/core/include/nlohmann/detail/meta/void_t.hpp +24 -0
- mqt/core/include/nlohmann/detail/output/binary_writer.hpp +1850 -0
- mqt/core/include/nlohmann/detail/output/output_adapters.hpp +147 -0
- mqt/core/include/nlohmann/detail/output/serializer.hpp +988 -0
- mqt/core/include/nlohmann/detail/string_concat.hpp +146 -0
- mqt/core/include/nlohmann/detail/string_escape.hpp +72 -0
- mqt/core/include/nlohmann/detail/string_utils.hpp +37 -0
- mqt/core/include/nlohmann/detail/value_t.hpp +118 -0
- mqt/core/include/nlohmann/json.hpp +5306 -0
- mqt/core/include/nlohmann/json_fwd.hpp +75 -0
- mqt/core/include/nlohmann/ordered_map.hpp +359 -0
- mqt/core/include/nlohmann/thirdparty/hedley/hedley.hpp +2045 -0
- mqt/core/include/nlohmann/thirdparty/hedley/hedley_undef.hpp +158 -0
- mqt/core/include/qdmi/qdmi/client.h +990 -0
- mqt/core/include/qdmi/qdmi/constants.h +1139 -0
- mqt/core/include/qdmi/qdmi/device.h +602 -0
- mqt/core/include/qdmi/qdmi/types.h +78 -0
- mqt/core/include/spdlog/async.h +99 -0
- mqt/core/include/spdlog/async_logger-inl.h +84 -0
- mqt/core/include/spdlog/async_logger.h +74 -0
- mqt/core/include/spdlog/cfg/argv.h +40 -0
- mqt/core/include/spdlog/cfg/env.h +36 -0
- mqt/core/include/spdlog/cfg/helpers-inl.h +107 -0
- mqt/core/include/spdlog/cfg/helpers.h +29 -0
- mqt/core/include/spdlog/common-inl.h +68 -0
- mqt/core/include/spdlog/common.h +406 -0
- mqt/core/include/spdlog/details/backtracer-inl.h +63 -0
- mqt/core/include/spdlog/details/backtracer.h +45 -0
- mqt/core/include/spdlog/details/circular_q.h +115 -0
- mqt/core/include/spdlog/details/console_globals.h +28 -0
- mqt/core/include/spdlog/details/file_helper-inl.h +153 -0
- mqt/core/include/spdlog/details/file_helper.h +61 -0
- mqt/core/include/spdlog/details/fmt_helper.h +141 -0
- mqt/core/include/spdlog/details/log_msg-inl.h +44 -0
- mqt/core/include/spdlog/details/log_msg.h +40 -0
- mqt/core/include/spdlog/details/log_msg_buffer-inl.h +54 -0
- mqt/core/include/spdlog/details/log_msg_buffer.h +32 -0
- mqt/core/include/spdlog/details/mpmc_blocking_q.h +177 -0
- mqt/core/include/spdlog/details/null_mutex.h +35 -0
- mqt/core/include/spdlog/details/os-inl.h +606 -0
- mqt/core/include/spdlog/details/os.h +127 -0
- mqt/core/include/spdlog/details/periodic_worker-inl.h +26 -0
- mqt/core/include/spdlog/details/periodic_worker.h +58 -0
- mqt/core/include/spdlog/details/registry-inl.h +270 -0
- mqt/core/include/spdlog/details/registry.h +131 -0
- mqt/core/include/spdlog/details/synchronous_factory.h +22 -0
- mqt/core/include/spdlog/details/tcp_client-windows.h +135 -0
- mqt/core/include/spdlog/details/tcp_client.h +127 -0
- mqt/core/include/spdlog/details/thread_pool-inl.h +126 -0
- mqt/core/include/spdlog/details/thread_pool.h +117 -0
- mqt/core/include/spdlog/details/udp_client-windows.h +98 -0
- mqt/core/include/spdlog/details/udp_client.h +81 -0
- mqt/core/include/spdlog/details/windows_include.h +11 -0
- mqt/core/include/spdlog/fmt/bin_to_hex.h +224 -0
- mqt/core/include/spdlog/fmt/bundled/args.h +220 -0
- mqt/core/include/spdlog/fmt/bundled/base.h +2989 -0
- mqt/core/include/spdlog/fmt/bundled/chrono.h +2330 -0
- mqt/core/include/spdlog/fmt/bundled/color.h +637 -0
- mqt/core/include/spdlog/fmt/bundled/compile.h +539 -0
- mqt/core/include/spdlog/fmt/bundled/core.h +5 -0
- mqt/core/include/spdlog/fmt/bundled/fmt.license.rst +27 -0
- mqt/core/include/spdlog/fmt/bundled/format-inl.h +1948 -0
- mqt/core/include/spdlog/fmt/bundled/format.h +4244 -0
- mqt/core/include/spdlog/fmt/bundled/os.h +427 -0
- mqt/core/include/spdlog/fmt/bundled/ostream.h +167 -0
- mqt/core/include/spdlog/fmt/bundled/printf.h +633 -0
- mqt/core/include/spdlog/fmt/bundled/ranges.h +850 -0
- mqt/core/include/spdlog/fmt/bundled/std.h +728 -0
- mqt/core/include/spdlog/fmt/bundled/xchar.h +369 -0
- mqt/core/include/spdlog/fmt/chrono.h +23 -0
- mqt/core/include/spdlog/fmt/compile.h +23 -0
- mqt/core/include/spdlog/fmt/fmt.h +30 -0
- mqt/core/include/spdlog/fmt/ostr.h +23 -0
- mqt/core/include/spdlog/fmt/ranges.h +23 -0
- mqt/core/include/spdlog/fmt/std.h +24 -0
- mqt/core/include/spdlog/fmt/xchar.h +23 -0
- mqt/core/include/spdlog/formatter.h +17 -0
- mqt/core/include/spdlog/fwd.h +18 -0
- mqt/core/include/spdlog/logger-inl.h +198 -0
- mqt/core/include/spdlog/logger.h +379 -0
- mqt/core/include/spdlog/mdc.h +52 -0
- mqt/core/include/spdlog/pattern_formatter-inl.h +1340 -0
- mqt/core/include/spdlog/pattern_formatter.h +118 -0
- mqt/core/include/spdlog/sinks/android_sink.h +137 -0
- mqt/core/include/spdlog/sinks/ansicolor_sink-inl.h +142 -0
- mqt/core/include/spdlog/sinks/ansicolor_sink.h +116 -0
- mqt/core/include/spdlog/sinks/base_sink-inl.h +59 -0
- mqt/core/include/spdlog/sinks/base_sink.h +51 -0
- mqt/core/include/spdlog/sinks/basic_file_sink-inl.h +48 -0
- mqt/core/include/spdlog/sinks/basic_file_sink.h +66 -0
- mqt/core/include/spdlog/sinks/callback_sink.h +56 -0
- mqt/core/include/spdlog/sinks/daily_file_sink.h +254 -0
- mqt/core/include/spdlog/sinks/dist_sink.h +81 -0
- mqt/core/include/spdlog/sinks/dup_filter_sink.h +91 -0
- mqt/core/include/spdlog/sinks/hourly_file_sink.h +193 -0
- mqt/core/include/spdlog/sinks/kafka_sink.h +119 -0
- mqt/core/include/spdlog/sinks/mongo_sink.h +108 -0
- mqt/core/include/spdlog/sinks/msvc_sink.h +68 -0
- mqt/core/include/spdlog/sinks/null_sink.h +41 -0
- mqt/core/include/spdlog/sinks/ostream_sink.h +43 -0
- mqt/core/include/spdlog/sinks/qt_sinks.h +304 -0
- mqt/core/include/spdlog/sinks/ringbuffer_sink.h +67 -0
- mqt/core/include/spdlog/sinks/rotating_file_sink-inl.h +179 -0
- mqt/core/include/spdlog/sinks/rotating_file_sink.h +93 -0
- mqt/core/include/spdlog/sinks/sink-inl.h +22 -0
- mqt/core/include/spdlog/sinks/sink.h +34 -0
- mqt/core/include/spdlog/sinks/stdout_color_sinks-inl.h +38 -0
- mqt/core/include/spdlog/sinks/stdout_color_sinks.h +49 -0
- mqt/core/include/spdlog/sinks/stdout_sinks-inl.h +127 -0
- mqt/core/include/spdlog/sinks/stdout_sinks.h +84 -0
- mqt/core/include/spdlog/sinks/syslog_sink.h +104 -0
- mqt/core/include/spdlog/sinks/systemd_sink.h +121 -0
- mqt/core/include/spdlog/sinks/tcp_sink.h +75 -0
- mqt/core/include/spdlog/sinks/udp_sink.h +69 -0
- mqt/core/include/spdlog/sinks/win_eventlog_sink.h +260 -0
- mqt/core/include/spdlog/sinks/wincolor_sink-inl.h +172 -0
- mqt/core/include/spdlog/sinks/wincolor_sink.h +82 -0
- mqt/core/include/spdlog/spdlog-inl.h +96 -0
- mqt/core/include/spdlog/spdlog.h +357 -0
- mqt/core/include/spdlog/stopwatch.h +66 -0
- mqt/core/include/spdlog/tweakme.h +148 -0
- mqt/core/include/spdlog/version.h +11 -0
- mqt/core/ir/__init__.pyi +2078 -0
- mqt/core/ir/operations.pyi +1011 -0
- mqt/core/ir/registers.pyi +91 -0
- mqt/core/ir/symbolic.pyi +177 -0
- mqt/core/ir.cp314t-win_amd64.pyd +0 -0
- mqt/core/lib/mqt-core-algorithms.lib +0 -0
- mqt/core/lib/mqt-core-circuit-optimizer.lib +0 -0
- mqt/core/lib/mqt-core-dd.lib +0 -0
- mqt/core/lib/mqt-core-ds.lib +0 -0
- mqt/core/lib/mqt-core-fomac.lib +0 -0
- mqt/core/lib/mqt-core-ir.lib +0 -0
- mqt/core/lib/mqt-core-na-fomac.lib +0 -0
- mqt/core/lib/mqt-core-na.lib +0 -0
- mqt/core/lib/mqt-core-qasm.lib +0 -0
- mqt/core/lib/mqt-core-qdmi-driver.lib +0 -0
- mqt/core/lib/mqt-core-qdmi-na-device-gen.lib +0 -0
- mqt/core/lib/mqt-core-qdmi-na-device.lib +0 -0
- mqt/core/lib/mqt-core-zx.lib +0 -0
- mqt/core/lib/pkgconfig/spdlog.pc +13 -0
- mqt/core/lib/spdlog.lib +0 -0
- mqt/core/na/__init__.py +12 -0
- mqt/core/na/fomac.cp314t-win_amd64.pyd +0 -0
- mqt/core/na/fomac.pyi +117 -0
- mqt/core/nlohmann_json.natvis +278 -0
- mqt/core/plugins/__init__.py +9 -0
- mqt/core/plugins/qiskit/__init__.py +19 -0
- mqt/core/plugins/qiskit/mqt_to_qiskit.py +420 -0
- mqt/core/plugins/qiskit/qiskit_to_mqt.py +562 -0
- mqt/core/py.typed +2 -0
- mqt/core/share/cmake/mqt-core/AddMQTPythonBinding.cmake +55 -0
- mqt/core/share/cmake/mqt-core/Cache.cmake +33 -0
- mqt/core/share/cmake/mqt-core/FindGMP.cmake +103 -0
- mqt/core/share/cmake/mqt-core/PackageAddTest.cmake +46 -0
- mqt/core/share/cmake/mqt-core/PreventInSourceBuilds.cmake +25 -0
- mqt/core/share/cmake/mqt-core/StandardProjectSettings.cmake +87 -0
- mqt/core/share/cmake/mqt-core/mqt-core-config-version.cmake +85 -0
- mqt/core/share/cmake/mqt-core/mqt-core-config.cmake +52 -0
- mqt/core/share/cmake/mqt-core/mqt-core-targets-release.cmake +141 -0
- mqt/core/share/cmake/mqt-core/mqt-core-targets.cmake +445 -0
- mqt/core/share/cmake/nlohmann_json/nlohmann_jsonConfig.cmake +15 -0
- mqt/core/share/cmake/nlohmann_json/nlohmann_jsonConfigVersion.cmake +20 -0
- mqt/core/share/cmake/nlohmann_json/nlohmann_jsonTargets.cmake +110 -0
- mqt/core/share/cmake/qdmi/Cache.cmake +44 -0
- mqt/core/share/cmake/qdmi/PrefixHandling.cmake +78 -0
- mqt/core/share/cmake/qdmi/prefix_defs.txt +26 -0
- mqt/core/share/cmake/qdmi/qdmi-config-version.cmake +85 -0
- mqt/core/share/cmake/qdmi/qdmi-config.cmake +42 -0
- mqt/core/share/cmake/qdmi/qdmi-targets.cmake +129 -0
- mqt/core/share/cmake/spdlog/spdlogConfig.cmake +44 -0
- mqt/core/share/cmake/spdlog/spdlogConfigTargets-release.cmake +19 -0
- mqt/core/share/cmake/spdlog/spdlogConfigTargets.cmake +121 -0
- mqt/core/share/cmake/spdlog/spdlogConfigVersion.cmake +65 -0
- mqt/core/share/pkgconfig/nlohmann_json.pc +7 -0
- mqt_core-3.3.2.dist-info/DELVEWHEEL +2 -0
- mqt_core-3.3.2.dist-info/METADATA +210 -0
- mqt_core-3.3.2.dist-info/RECORD +537 -0
- mqt_core-3.3.2.dist-info/WHEEL +5 -0
- mqt_core-3.3.2.dist-info/entry_points.txt +4 -0
- mqt_core-3.3.2.dist-info/licenses/LICENSE.md +22 -0
- mqt_core.libs/msvcp140.dll +0 -0
|
@@ -0,0 +1,848 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright 2012-20 John Maddock.
|
|
3
|
+
// Copyright 2019-20 Christopher Kormanyos.
|
|
4
|
+
// Copyright 2019-20 Madhur Chauhan.
|
|
5
|
+
// Distributed under the Boost Software License, Version 1.0.
|
|
6
|
+
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
|
|
7
|
+
//
|
|
8
|
+
// Comparison operators for cpp_int_backend:
|
|
9
|
+
//
|
|
10
|
+
#ifndef BOOST_MP_CPP_INT_MULTIPLY_HPP
|
|
11
|
+
#define BOOST_MP_CPP_INT_MULTIPLY_HPP
|
|
12
|
+
|
|
13
|
+
#include <limits>
|
|
14
|
+
#include <boost/multiprecision/detail/standalone_config.hpp>
|
|
15
|
+
#include <boost/multiprecision/detail/endian.hpp>
|
|
16
|
+
#include <boost/multiprecision/detail/assert.hpp>
|
|
17
|
+
#include <boost/multiprecision/integer.hpp>
|
|
18
|
+
|
|
19
|
+
namespace boost { namespace multiprecision { namespace backends {
|
|
20
|
+
|
|
21
|
+
#ifdef BOOST_MSVC
|
|
22
|
+
#pragma warning(push)
|
|
23
|
+
#pragma warning(disable : 4127) // conditional expression is constant
|
|
24
|
+
#endif
|
|
25
|
+
//
|
|
26
|
+
// Multiplication by a single limb:
|
|
27
|
+
//
|
|
28
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
29
|
+
inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type
|
|
30
|
+
eval_multiply(
|
|
31
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
32
|
+
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
|
|
33
|
+
const limb_type& val) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
|
|
34
|
+
{
|
|
35
|
+
if (!val)
|
|
36
|
+
{
|
|
37
|
+
result = static_cast<limb_type>(0);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if ((void*)&a != (void*)&result)
|
|
41
|
+
result.resize(a.size(), a.size());
|
|
42
|
+
double_limb_type carry = 0;
|
|
43
|
+
typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer p = result.limbs();
|
|
44
|
+
typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pe = result.limbs() + result.size();
|
|
45
|
+
typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer pa = a.limbs();
|
|
46
|
+
while (p != pe)
|
|
47
|
+
{
|
|
48
|
+
carry += static_cast<double_limb_type>(*pa) * static_cast<double_limb_type>(val);
|
|
49
|
+
#ifdef __MSVC_RUNTIME_CHECKS
|
|
50
|
+
*p = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
|
|
51
|
+
#else
|
|
52
|
+
*p = static_cast<limb_type>(carry);
|
|
53
|
+
#endif
|
|
54
|
+
carry >>= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
|
|
55
|
+
++p, ++pa;
|
|
56
|
+
}
|
|
57
|
+
if (carry)
|
|
58
|
+
{
|
|
59
|
+
std::size_t i = result.size();
|
|
60
|
+
result.resize(i + 1, i + 1);
|
|
61
|
+
if (result.size() > i)
|
|
62
|
+
result.limbs()[i] = static_cast<limb_type>(carry);
|
|
63
|
+
}
|
|
64
|
+
result.sign(a.sign());
|
|
65
|
+
if (is_fixed_precision<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)
|
|
66
|
+
result.normalize();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
//
|
|
70
|
+
// resize_for_carry forces a resize of the underlying buffer only if a previous request
|
|
71
|
+
// for "required" elements could possibly have failed, *and* we have checking enabled.
|
|
72
|
+
// This will cause an overflow error inside resize():
|
|
73
|
+
//
|
|
74
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
|
|
75
|
+
inline BOOST_MP_CXX14_CONSTEXPR void resize_for_carry(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& /*result*/, std::size_t /*required*/) {}
|
|
76
|
+
|
|
77
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, class Allocator1>
|
|
78
|
+
inline BOOST_MP_CXX14_CONSTEXPR void resize_for_carry(cpp_int_backend<MinBits1, MaxBits1, SignType1, checked, Allocator1>& result, std::size_t required)
|
|
79
|
+
{
|
|
80
|
+
if (result.size() < required)
|
|
81
|
+
result.resize(required, required);
|
|
82
|
+
}
|
|
83
|
+
//
|
|
84
|
+
// Minimum number of limbs required for Karatsuba to be worthwhile:
|
|
85
|
+
//
|
|
86
|
+
#ifdef BOOST_MP_KARATSUBA_CUTOFF
|
|
87
|
+
const size_t karatsuba_cutoff = BOOST_MP_KARATSUBA_CUTOFF;
|
|
88
|
+
#else
|
|
89
|
+
const size_t karatsuba_cutoff = 40;
|
|
90
|
+
#endif
|
|
91
|
+
//
|
|
92
|
+
// Core (recursive) Karatsuba multiplication, all the storage required is allocated upfront and
|
|
93
|
+
// passed down the stack in this routine. Note that all the cpp_int_backend's must be the same type
|
|
94
|
+
// and full variable precision. Karatsuba really doesn't play nice with fixed-size integers. If necessary
|
|
95
|
+
// fixed precision integers will get aliased as variable-precision types before this is called.
|
|
96
|
+
//
|
|
97
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator>
|
|
98
|
+
inline void multiply_karatsuba(
|
|
99
|
+
cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& result,
|
|
100
|
+
const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a,
|
|
101
|
+
const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& b,
|
|
102
|
+
typename cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>::scoped_shared_storage& storage)
|
|
103
|
+
{
|
|
104
|
+
using cpp_int_type = cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>;
|
|
105
|
+
|
|
106
|
+
std::size_t as = a.size();
|
|
107
|
+
std::size_t bs = b.size();
|
|
108
|
+
//
|
|
109
|
+
// Termination condition: if either argument is smaller than karatsuba_cutoff
|
|
110
|
+
// then schoolboy multiplication will be faster:
|
|
111
|
+
//
|
|
112
|
+
if ((as < karatsuba_cutoff) || (bs < karatsuba_cutoff))
|
|
113
|
+
{
|
|
114
|
+
eval_multiply(result, a, b);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
//
|
|
118
|
+
// Partitioning size: split the larger of a and b into 2 halves
|
|
119
|
+
//
|
|
120
|
+
std::size_t n = (as > bs ? as : bs) / 2 + 1;
|
|
121
|
+
//
|
|
122
|
+
// Partition a and b into high and low parts.
|
|
123
|
+
// ie write a, b as a = a_h * 2^n + a_l, b = b_h * 2^n + b_l
|
|
124
|
+
//
|
|
125
|
+
// We could copy the high and low parts into new variables, but we'll
|
|
126
|
+
// use aliasing to reference the internal limbs of a and b. There is one wart here:
|
|
127
|
+
// if a and b are mismatched in size, then n may be larger than the smaller
|
|
128
|
+
// of a and b. In that situation the high part is zero, and we have no limbs
|
|
129
|
+
// to alias, so instead alias a local variable.
|
|
130
|
+
// This raises 2 questions:
|
|
131
|
+
// * Is this the best way to partition a and b?
|
|
132
|
+
// * Since we have one high part zero, the arithmetic simplifies considerably,
|
|
133
|
+
// so should we have a special routine for this?
|
|
134
|
+
//
|
|
135
|
+
std::size_t sz = (std::min)(as, n);
|
|
136
|
+
const cpp_int_type a_l(a.limbs(), 0, sz);
|
|
137
|
+
|
|
138
|
+
sz = (std::min)(bs, n);
|
|
139
|
+
const cpp_int_type b_l(b.limbs(), 0, sz);
|
|
140
|
+
|
|
141
|
+
limb_type zero = 0;
|
|
142
|
+
const cpp_int_type a_h(as > n ? a.limbs() + n : &zero, 0, as > n ? as - n : 1);
|
|
143
|
+
const cpp_int_type b_h(bs > n ? b.limbs() + n : &zero, 0, bs > n ? bs - n : 1);
|
|
144
|
+
//
|
|
145
|
+
// The basis for the Karatsuba algorithm is as follows:
|
|
146
|
+
//
|
|
147
|
+
// let x = a_h * b_ h
|
|
148
|
+
// y = a_l * b_l
|
|
149
|
+
// z = (a_h + a_l)*(b_h + b_l) - x - y
|
|
150
|
+
// and therefore a * b = x * (2 ^ (2 * n))+ z * (2 ^ n) + y
|
|
151
|
+
//
|
|
152
|
+
// Begin by allocating our temporaries, these alias the memory already allocated in the shared storage:
|
|
153
|
+
//
|
|
154
|
+
cpp_int_type t1(storage, 2 * n + 2);
|
|
155
|
+
cpp_int_type t2(storage, n + 1);
|
|
156
|
+
cpp_int_type t3(storage, n + 1);
|
|
157
|
+
//
|
|
158
|
+
// Now we want:
|
|
159
|
+
//
|
|
160
|
+
// result = | a_h*b_h | a_l*b_l |
|
|
161
|
+
// (bits) <-- 2*n -->
|
|
162
|
+
//
|
|
163
|
+
// We create aliases for the low and high parts of result, and multiply directly into them:
|
|
164
|
+
//
|
|
165
|
+
cpp_int_type result_low(result.limbs(), 0, 2 * n);
|
|
166
|
+
cpp_int_type result_high(result.limbs(), 2 * n, result.size() - 2 * n);
|
|
167
|
+
//
|
|
168
|
+
// low part of result is a_l * b_l:
|
|
169
|
+
//
|
|
170
|
+
multiply_karatsuba(result_low, a_l, b_l, storage);
|
|
171
|
+
//
|
|
172
|
+
// We haven't zeroed out memory in result, so set to zero any unused limbs,
|
|
173
|
+
// if a_l and b_l have mostly random bits then nothing happens here, but if
|
|
174
|
+
// one is zero or nearly so, then a memset might be faster... it's not clear
|
|
175
|
+
// that it's worth the extra logic though (and is darn hard to measure
|
|
176
|
+
// what the "average" case is).
|
|
177
|
+
//
|
|
178
|
+
for (std::size_t i = result_low.size(); i < 2 * n; ++i)
|
|
179
|
+
result.limbs()[i] = 0;
|
|
180
|
+
//
|
|
181
|
+
// Set the high part of result to a_h * b_h:
|
|
182
|
+
//
|
|
183
|
+
multiply_karatsuba(result_high, a_h, b_h, storage);
|
|
184
|
+
for (std::size_t i = result_high.size() + 2 * n; i < result.size(); ++i)
|
|
185
|
+
result.limbs()[i] = 0;
|
|
186
|
+
//
|
|
187
|
+
// Now calculate (a_h+a_l)*(b_h+b_l):
|
|
188
|
+
//
|
|
189
|
+
add_unsigned(t2, a_l, a_h);
|
|
190
|
+
add_unsigned(t3, b_l, b_h);
|
|
191
|
+
multiply_karatsuba(t1, t2, t3, storage); // t1 = (a_h+a_l)*(b_h+b_l)
|
|
192
|
+
//
|
|
193
|
+
// There is now a slight deviation from Karatsuba, we want to subtract
|
|
194
|
+
// a_l*b_l + a_h*b_h from t1, but rather than use an addition and a subtraction
|
|
195
|
+
// plus one temporary, we'll use 2 subtractions. On the minus side, a subtraction
|
|
196
|
+
// is on average slightly slower than an addition, but we save a temporary (ie memory)
|
|
197
|
+
// and also hammer the same piece of memory over and over rather than 2 disparate
|
|
198
|
+
// memory regions. Overall it seems to be a slight win.
|
|
199
|
+
//
|
|
200
|
+
subtract_unsigned(t1, t1, result_high);
|
|
201
|
+
subtract_unsigned(t1, t1, result_low);
|
|
202
|
+
//
|
|
203
|
+
// The final step is to left shift t1 by n bits and add to the result.
|
|
204
|
+
// Rather than do an actual left shift, we can simply alias the result
|
|
205
|
+
// and add to the alias:
|
|
206
|
+
//
|
|
207
|
+
cpp_int_type result_alias(result.limbs(), n, result.size() - n);
|
|
208
|
+
add_unsigned(result_alias, result_alias, t1);
|
|
209
|
+
//
|
|
210
|
+
// Free up storage for use by sister branches to this one:
|
|
211
|
+
//
|
|
212
|
+
storage.deallocate(t1.capacity() + t2.capacity() + t3.capacity());
|
|
213
|
+
|
|
214
|
+
result.normalize();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
inline std::size_t karatsuba_storage_size(std::size_t s)
|
|
218
|
+
{
|
|
219
|
+
//
|
|
220
|
+
// This estimates how much memory we will need based on
|
|
221
|
+
// s-limb multiplication. In an ideal world the number of limbs
|
|
222
|
+
// would halve with each recursion, and our storage requirements
|
|
223
|
+
// would be 4s in the limit, and rather less in practice since
|
|
224
|
+
// we bail out long before we reach one limb. In the real world
|
|
225
|
+
// we don't quite halve s in each recursion, so this is an heuristic
|
|
226
|
+
// which over-estimates how much we need. We could compute an exact
|
|
227
|
+
// value, but it would be rather time consuming.
|
|
228
|
+
//
|
|
229
|
+
return 5 * s;
|
|
230
|
+
}
|
|
231
|
+
//
|
|
232
|
+
// There are 2 entry point routines for Karatsuba multiplication:
|
|
233
|
+
// one for variable precision types, and one for fixed precision types.
|
|
234
|
+
// These are responsible for allocating all the storage required for the recursive
|
|
235
|
+
// routines above, and are always at the outermost level.
|
|
236
|
+
//
|
|
237
|
+
// Normal variable precision case comes first:
|
|
238
|
+
//
|
|
239
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
|
|
240
|
+
inline typename std::enable_if<!is_fixed_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value>::type
|
|
241
|
+
setup_karatsuba(
|
|
242
|
+
cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& result,
|
|
243
|
+
const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& a,
|
|
244
|
+
const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& b)
|
|
245
|
+
{
|
|
246
|
+
std::size_t as = a.size();
|
|
247
|
+
std::size_t bs = b.size();
|
|
248
|
+
std::size_t s = as > bs ? as : bs;
|
|
249
|
+
std::size_t storage_size = karatsuba_storage_size(s);
|
|
250
|
+
if (storage_size < 300)
|
|
251
|
+
{
|
|
252
|
+
//
|
|
253
|
+
// Special case: if we don't need too much memory, we can use stack based storage
|
|
254
|
+
// and save a call to the allocator, this allows us to use Karatsuba multiply
|
|
255
|
+
// at lower limb counts than would otherwise be possible:
|
|
256
|
+
//
|
|
257
|
+
limb_type limbs[300];
|
|
258
|
+
typename cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>::scoped_shared_storage storage(limbs, storage_size);
|
|
259
|
+
multiply_karatsuba(result, a, b, storage);
|
|
260
|
+
}
|
|
261
|
+
else
|
|
262
|
+
{
|
|
263
|
+
typename cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>::scoped_shared_storage storage(result.allocator(), storage_size);
|
|
264
|
+
multiply_karatsuba(result, a, b, storage);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
|
|
269
|
+
inline typename std::enable_if<is_fixed_precision<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_fixed_precision<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value || is_fixed_precision<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value>::type
|
|
270
|
+
setup_karatsuba(
|
|
271
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
272
|
+
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
|
|
273
|
+
const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b)
|
|
274
|
+
{
|
|
275
|
+
//
|
|
276
|
+
// Now comes the fixed precision case.
|
|
277
|
+
// In fact Karatsuba doesn't really work with fixed precision since the logic
|
|
278
|
+
// requires that we calculate all the bits of the result (especially in the
|
|
279
|
+
// temporaries used internally). So... we'll convert all the arguments
|
|
280
|
+
// to variable precision types by aliasing them, this also
|
|
281
|
+
// reduce the number of template instantations:
|
|
282
|
+
//
|
|
283
|
+
using variable_precision_type = cpp_int_backend<0, 0, signed_magnitude, unchecked, std::allocator<limb_type> >;
|
|
284
|
+
variable_precision_type a_t(a.limbs(), 0, a.size()), b_t(b.limbs(), 0, b.size());
|
|
285
|
+
std::size_t as = a.size();
|
|
286
|
+
std::size_t bs = b.size();
|
|
287
|
+
std::size_t s = as > bs ? as : bs;
|
|
288
|
+
std::size_t sz = as + bs;
|
|
289
|
+
std::size_t storage_size = karatsuba_storage_size(s);
|
|
290
|
+
|
|
291
|
+
if (!is_fixed_precision<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || (sz * sizeof(limb_type) * CHAR_BIT <= MaxBits1))
|
|
292
|
+
{
|
|
293
|
+
// Result is large enough for all the bits of the result, so we can use aliasing:
|
|
294
|
+
result.resize(sz, sz);
|
|
295
|
+
variable_precision_type t(result.limbs(), 0, result.size());
|
|
296
|
+
typename variable_precision_type::scoped_shared_storage storage(t.allocator(), storage_size);
|
|
297
|
+
multiply_karatsuba(t, a_t, b_t, storage);
|
|
298
|
+
result.resize(t.size(), t.size());
|
|
299
|
+
}
|
|
300
|
+
else
|
|
301
|
+
{
|
|
302
|
+
//
|
|
303
|
+
// Not enough bit in result for the answer, so we must use a temporary
|
|
304
|
+
// and then truncate (ie modular arithmetic):
|
|
305
|
+
//
|
|
306
|
+
typename variable_precision_type::scoped_shared_storage storage(variable_precision_type::allocator_type(), sz + storage_size);
|
|
307
|
+
variable_precision_type t(storage, sz);
|
|
308
|
+
multiply_karatsuba(t, a_t, b_t, storage);
|
|
309
|
+
//
|
|
310
|
+
// If there is truncation, and result is a checked type then this will throw:
|
|
311
|
+
//
|
|
312
|
+
result = t;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
|
|
316
|
+
inline typename std::enable_if<!is_fixed_precision<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_fixed_precision<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_fixed_precision<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value>::type
|
|
317
|
+
setup_karatsuba(
|
|
318
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
319
|
+
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
|
|
320
|
+
const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b)
|
|
321
|
+
{
|
|
322
|
+
//
|
|
323
|
+
// Variable precision, mixed arguments, just alias and forward:
|
|
324
|
+
//
|
|
325
|
+
using variable_precision_type = cpp_int_backend<0, 0, signed_magnitude, unchecked, std::allocator<limb_type> >;
|
|
326
|
+
variable_precision_type a_t(a.limbs(), 0, a.size()), b_t(b.limbs(), 0, b.size());
|
|
327
|
+
std::size_t as = a.size();
|
|
328
|
+
std::size_t bs = b.size();
|
|
329
|
+
std::size_t s = as > bs ? as : bs;
|
|
330
|
+
std::size_t sz = as + bs;
|
|
331
|
+
std::size_t storage_size = karatsuba_storage_size(s);
|
|
332
|
+
|
|
333
|
+
result.resize(sz, sz);
|
|
334
|
+
variable_precision_type t(result.limbs(), 0, result.size());
|
|
335
|
+
typename variable_precision_type::scoped_shared_storage storage(t.allocator(), storage_size);
|
|
336
|
+
multiply_karatsuba(t, a_t, b_t, storage);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
|
|
340
|
+
inline BOOST_MP_CXX14_CONSTEXPR void
|
|
341
|
+
eval_multiply_comba(
|
|
342
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
343
|
+
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
|
|
344
|
+
const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
|
|
345
|
+
{
|
|
346
|
+
//
|
|
347
|
+
// see PR #182
|
|
348
|
+
// Comba Multiplier - based on Paul Comba's
|
|
349
|
+
// Exponentiation cryptosystems on the IBM PC, 1990
|
|
350
|
+
//
|
|
351
|
+
std::ptrdiff_t as = a.size(),
|
|
352
|
+
bs = b.size(),
|
|
353
|
+
rs = result.size();
|
|
354
|
+
typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pr = result.limbs();
|
|
355
|
+
|
|
356
|
+
double_limb_type carry = 0,
|
|
357
|
+
temp = 0;
|
|
358
|
+
limb_type overflow = 0;
|
|
359
|
+
const std::size_t limb_bits = sizeof(limb_type) * CHAR_BIT;
|
|
360
|
+
const bool must_throw = rs < as + bs - 1;
|
|
361
|
+
for (std::ptrdiff_t r = 0, lim = (std::min)(rs, as + bs - 1); r < lim; ++r, overflow = 0)
|
|
362
|
+
{
|
|
363
|
+
std::ptrdiff_t i = r >= as ? as - 1 : r,
|
|
364
|
+
j = r - i,
|
|
365
|
+
k = i < bs - j ? i + 1 : bs - j; // min(i+1, bs-j);
|
|
366
|
+
|
|
367
|
+
typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer pa = a.limbs() + i;
|
|
368
|
+
typename cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>::const_limb_pointer pb = b.limbs() + j;
|
|
369
|
+
|
|
370
|
+
temp = carry;
|
|
371
|
+
carry += static_cast<double_limb_type>(*(pa)) * (*(pb));
|
|
372
|
+
overflow += carry < temp;
|
|
373
|
+
for (--k; k; k--)
|
|
374
|
+
{
|
|
375
|
+
temp = carry;
|
|
376
|
+
carry += static_cast<double_limb_type>(*(--pa)) * (*(++pb));
|
|
377
|
+
overflow += carry < temp;
|
|
378
|
+
}
|
|
379
|
+
*(pr++) = static_cast<limb_type>(carry);
|
|
380
|
+
carry = (static_cast<double_limb_type>(overflow) << limb_bits) | (carry >> limb_bits);
|
|
381
|
+
}
|
|
382
|
+
if (carry || must_throw)
|
|
383
|
+
{
|
|
384
|
+
resize_for_carry(result, as + bs);
|
|
385
|
+
if (static_cast<int>(result.size()) >= as + bs)
|
|
386
|
+
*pr = static_cast<limb_type>(carry);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
|
|
390
|
+
inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value>::type
|
|
391
|
+
eval_multiply(
|
|
392
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
393
|
+
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
|
|
394
|
+
const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b)
|
|
395
|
+
noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
|
|
396
|
+
&& (karatsuba_cutoff * sizeof(limb_type) * CHAR_BIT > MaxBits1)
|
|
397
|
+
&& (karatsuba_cutoff * sizeof(limb_type)* CHAR_BIT > MaxBits2)
|
|
398
|
+
&& (karatsuba_cutoff * sizeof(limb_type)* CHAR_BIT > MaxBits3)))
|
|
399
|
+
{
|
|
400
|
+
// Uses simple (O(n^2)) multiplication when the limbs are less
|
|
401
|
+
// otherwise switches to karatsuba algorithm based on experimental value (~40 limbs)
|
|
402
|
+
//
|
|
403
|
+
// Trivial cases first:
|
|
404
|
+
//
|
|
405
|
+
std::size_t as = a.size();
|
|
406
|
+
std::size_t bs = b.size();
|
|
407
|
+
typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer pa = a.limbs();
|
|
408
|
+
typename cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>::const_limb_pointer pb = b.limbs();
|
|
409
|
+
if (as == 1)
|
|
410
|
+
{
|
|
411
|
+
bool s = b.sign() != a.sign();
|
|
412
|
+
if (bs == 1)
|
|
413
|
+
{
|
|
414
|
+
result = static_cast<double_limb_type>(*pa) * static_cast<double_limb_type>(*pb);
|
|
415
|
+
}
|
|
416
|
+
else
|
|
417
|
+
{
|
|
418
|
+
limb_type l = *pa;
|
|
419
|
+
eval_multiply(result, b, l);
|
|
420
|
+
}
|
|
421
|
+
result.sign(s);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
if (bs == 1)
|
|
425
|
+
{
|
|
426
|
+
bool s = b.sign() != a.sign();
|
|
427
|
+
limb_type l = *pb;
|
|
428
|
+
eval_multiply(result, a, l);
|
|
429
|
+
result.sign(s);
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if ((void*)&result == (void*)&a)
|
|
434
|
+
{
|
|
435
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(a);
|
|
436
|
+
eval_multiply(result, t, b);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
if ((void*)&result == (void*)&b)
|
|
440
|
+
{
|
|
441
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(b);
|
|
442
|
+
eval_multiply(result, a, t);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
constexpr double_limb_type limb_max = static_cast<double_limb_type>(~static_cast<limb_type>(0u));
|
|
447
|
+
constexpr double_limb_type double_limb_max = static_cast<double_limb_type>(~static_cast<double_limb_type>(0u));
|
|
448
|
+
|
|
449
|
+
result.resize(as + bs, as + bs - 1);
|
|
450
|
+
#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
|
|
451
|
+
if (!BOOST_MP_IS_CONST_EVALUATED(as) && (as >= karatsuba_cutoff && bs >= karatsuba_cutoff))
|
|
452
|
+
#else
|
|
453
|
+
if (as >= karatsuba_cutoff && bs >= karatsuba_cutoff)
|
|
454
|
+
#endif
|
|
455
|
+
{
|
|
456
|
+
setup_karatsuba(result, a, b);
|
|
457
|
+
//
|
|
458
|
+
// Set the sign of the result:
|
|
459
|
+
//
|
|
460
|
+
result.sign(a.sign() != b.sign());
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pr = result.limbs();
|
|
464
|
+
static_assert(double_limb_max - 2 * limb_max >= limb_max * limb_max, "failed limb size sanity check");
|
|
465
|
+
|
|
466
|
+
#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
|
|
467
|
+
if (BOOST_MP_IS_CONST_EVALUATED(as))
|
|
468
|
+
{
|
|
469
|
+
for (std::size_t i = 0; i < result.size(); ++i)
|
|
470
|
+
pr[i] = 0;
|
|
471
|
+
}
|
|
472
|
+
else
|
|
473
|
+
#endif
|
|
474
|
+
std::memset(pr, 0, result.size() * sizeof(limb_type));
|
|
475
|
+
|
|
476
|
+
#if defined(BOOST_MP_COMBA)
|
|
477
|
+
//
|
|
478
|
+
// Comba Multiplier might not be efficient because of less efficient assembly
|
|
479
|
+
// by the compiler as of 09/01/2020 (DD/MM/YY). See PR #182
|
|
480
|
+
// Till then this will lay dormant :(
|
|
481
|
+
//
|
|
482
|
+
eval_multiply_comba(result, a, b);
|
|
483
|
+
#else
|
|
484
|
+
|
|
485
|
+
double_limb_type carry = 0;
|
|
486
|
+
for (std::size_t i = 0; i < as; ++i)
|
|
487
|
+
{
|
|
488
|
+
BOOST_MP_ASSERT(result.size() > i);
|
|
489
|
+
std::size_t inner_limit = !is_fixed_precision<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value ? bs : (std::min)(result.size() - i, bs);
|
|
490
|
+
std::size_t j = 0;
|
|
491
|
+
for (; j < inner_limit; ++j)
|
|
492
|
+
{
|
|
493
|
+
BOOST_MP_ASSERT(i + j < result.size());
|
|
494
|
+
#if (!defined(__GLIBCXX__) && !defined(__GLIBCPP__)) || !BOOST_WORKAROUND(BOOST_GCC_VERSION, <= 50100)
|
|
495
|
+
BOOST_MP_ASSERT(!std::numeric_limits<double_limb_type>::is_specialized || ((std::numeric_limits<double_limb_type>::max)() - carry >
|
|
496
|
+
static_cast<double_limb_type>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value) * static_cast<double_limb_type>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value)));
|
|
497
|
+
#endif
|
|
498
|
+
carry += static_cast<double_limb_type>(pa[i]) * static_cast<double_limb_type>(pb[j]);
|
|
499
|
+
BOOST_MP_ASSERT(!std::numeric_limits<double_limb_type>::is_specialized || ((std::numeric_limits<double_limb_type>::max)() - carry >= pr[i + j]));
|
|
500
|
+
carry += pr[i + j];
|
|
501
|
+
#ifdef __MSVC_RUNTIME_CHECKS
|
|
502
|
+
pr[i + j] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
|
|
503
|
+
#else
|
|
504
|
+
pr[i + j] = static_cast<limb_type>(carry);
|
|
505
|
+
#endif
|
|
506
|
+
carry >>= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
|
|
507
|
+
BOOST_MP_ASSERT(carry <= (cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value));
|
|
508
|
+
}
|
|
509
|
+
if (carry)
|
|
510
|
+
{
|
|
511
|
+
resize_for_carry(result, i + j + 1); // May throw if checking is enabled
|
|
512
|
+
if (i + j < result.size())
|
|
513
|
+
#ifdef __MSVC_RUNTIME_CHECKS
|
|
514
|
+
pr[i + j] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
|
|
515
|
+
#else
|
|
516
|
+
pr[i + j] = static_cast<limb_type>(carry);
|
|
517
|
+
#endif
|
|
518
|
+
}
|
|
519
|
+
carry = 0;
|
|
520
|
+
}
|
|
521
|
+
#endif // ifdef(BOOST_MP_COMBA) ends
|
|
522
|
+
|
|
523
|
+
result.normalize();
|
|
524
|
+
//
|
|
525
|
+
// Set the sign of the result:
|
|
526
|
+
//
|
|
527
|
+
result.sign(a.sign() != b.sign());
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
531
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type
|
|
532
|
+
eval_multiply(
|
|
533
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
534
|
+
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a)
|
|
535
|
+
noexcept((noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>&>()))))
|
|
536
|
+
{
|
|
537
|
+
eval_multiply(result, result, a);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
|
|
541
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
|
|
542
|
+
eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& val)
|
|
543
|
+
noexcept((noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const limb_type&>()))))
|
|
544
|
+
{
|
|
545
|
+
eval_multiply(result, result, val);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
549
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type
|
|
550
|
+
eval_multiply(
|
|
551
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
552
|
+
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
|
|
553
|
+
const double_limb_type& val)
|
|
554
|
+
noexcept(
|
|
555
|
+
(noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>&>(), std::declval<const limb_type&>())))
|
|
556
|
+
&& (noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>())))
|
|
557
|
+
)
|
|
558
|
+
{
|
|
559
|
+
if (val <= (std::numeric_limits<limb_type>::max)())
|
|
560
|
+
{
|
|
561
|
+
eval_multiply(result, a, static_cast<limb_type>(val));
|
|
562
|
+
}
|
|
563
|
+
else
|
|
564
|
+
{
|
|
565
|
+
#if BOOST_MP_ENDIAN_LITTLE_BYTE && !defined(BOOST_MP_TEST_NO_LE)
|
|
566
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(val);
|
|
567
|
+
#else
|
|
568
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t;
|
|
569
|
+
t = val;
|
|
570
|
+
#endif
|
|
571
|
+
eval_multiply(result, a, t);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
|
|
576
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
|
|
577
|
+
eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const double_limb_type& val)
|
|
578
|
+
noexcept((noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const double_limb_type&>()))))
|
|
579
|
+
{
|
|
580
|
+
eval_multiply(result, result, val);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
584
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type
|
|
585
|
+
eval_multiply(
|
|
586
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
587
|
+
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
|
|
588
|
+
const signed_limb_type& val)
|
|
589
|
+
noexcept((noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>&>(), std::declval<const limb_type&>()))))
|
|
590
|
+
{
|
|
591
|
+
if (val > 0)
|
|
592
|
+
eval_multiply(result, a, static_cast<limb_type>(val));
|
|
593
|
+
else
|
|
594
|
+
{
|
|
595
|
+
eval_multiply(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(val)));
|
|
596
|
+
result.negate();
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
|
|
601
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
|
|
602
|
+
eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_limb_type& val)
|
|
603
|
+
noexcept((noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const limb_type&>()))))
|
|
604
|
+
{
|
|
605
|
+
eval_multiply(result, result, val);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
609
|
+
inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type
|
|
610
|
+
eval_multiply(
|
|
611
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
612
|
+
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
|
|
613
|
+
const signed_double_limb_type& val)
|
|
614
|
+
noexcept(
|
|
615
|
+
(noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>&>(), std::declval<const limb_type&>())))
|
|
616
|
+
&& (noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>())))
|
|
617
|
+
)
|
|
618
|
+
{
|
|
619
|
+
if (val > 0)
|
|
620
|
+
{
|
|
621
|
+
if (val <= (std::numeric_limits<limb_type>::max)())
|
|
622
|
+
{
|
|
623
|
+
eval_multiply(result, a, static_cast<limb_type>(val));
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
else if (val >= -static_cast<signed_double_limb_type>((std::numeric_limits<limb_type>::max)()))
|
|
628
|
+
{
|
|
629
|
+
eval_multiply(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(val)));
|
|
630
|
+
result.negate();
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
#if BOOST_MP_ENDIAN_LITTLE_BYTE && !defined(BOOST_MP_TEST_NO_LE)
|
|
634
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(val);
|
|
635
|
+
#else
|
|
636
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t;
|
|
637
|
+
t = val;
|
|
638
|
+
#endif
|
|
639
|
+
eval_multiply(result, a, t);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
|
|
643
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
|
|
644
|
+
eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_double_limb_type& val)
|
|
645
|
+
noexcept(
|
|
646
|
+
(noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const limb_type&>())))
|
|
647
|
+
&& (noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>())))
|
|
648
|
+
)
|
|
649
|
+
{
|
|
650
|
+
eval_multiply(result, result, val);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
//
|
|
654
|
+
// Now over again for trivial cpp_int's:
|
|
655
|
+
//
|
|
656
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
|
|
657
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
|
|
658
|
+
is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)>::type
|
|
659
|
+
eval_multiply(
|
|
660
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
661
|
+
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
|
|
662
|
+
{
|
|
663
|
+
*result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
|
|
664
|
+
result.sign(result.sign() != o.sign());
|
|
665
|
+
result.normalize();
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
|
|
669
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
|
|
670
|
+
is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
|
|
671
|
+
eval_multiply(
|
|
672
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
673
|
+
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
|
|
674
|
+
{
|
|
675
|
+
*result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
|
|
676
|
+
result.normalize();
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
|
|
680
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
|
|
681
|
+
is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)>::type
|
|
682
|
+
eval_multiply(
|
|
683
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
684
|
+
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a,
|
|
685
|
+
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
|
|
686
|
+
{
|
|
687
|
+
*result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
|
|
688
|
+
result.sign(a.sign() != b.sign());
|
|
689
|
+
result.normalize();
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
|
|
693
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
|
|
694
|
+
is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
|
|
695
|
+
eval_multiply(
|
|
696
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
697
|
+
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a,
|
|
698
|
+
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
|
|
699
|
+
{
|
|
700
|
+
*result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
|
|
701
|
+
result.normalize();
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
//
|
|
705
|
+
// Special routines for multiplying two integers to obtain a multiprecision result:
|
|
706
|
+
//
|
|
707
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
|
|
708
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
|
|
709
|
+
!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
|
|
710
|
+
eval_multiply(
|
|
711
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
712
|
+
signed_double_limb_type a, signed_double_limb_type b)
|
|
713
|
+
{
|
|
714
|
+
constexpr signed_double_limb_type mask = static_cast<signed_double_limb_type>(~static_cast<limb_type>(0));
|
|
715
|
+
constexpr std::size_t limb_bits = static_cast<std::size_t>(sizeof(limb_type) * CHAR_BIT);
|
|
716
|
+
|
|
717
|
+
bool s = false;
|
|
718
|
+
if (a < 0)
|
|
719
|
+
{
|
|
720
|
+
a = -a;
|
|
721
|
+
s = true;
|
|
722
|
+
}
|
|
723
|
+
if (b < 0)
|
|
724
|
+
{
|
|
725
|
+
b = -b;
|
|
726
|
+
s = !s;
|
|
727
|
+
}
|
|
728
|
+
double_limb_type w = a & mask;
|
|
729
|
+
double_limb_type x = static_cast<double_limb_type>(a >> limb_bits);
|
|
730
|
+
double_limb_type y = b & mask;
|
|
731
|
+
double_limb_type z = static_cast<double_limb_type>(b >> limb_bits);
|
|
732
|
+
|
|
733
|
+
result.resize(4, 4);
|
|
734
|
+
limb_type* pr = result.limbs();
|
|
735
|
+
|
|
736
|
+
double_limb_type carry = w * y;
|
|
737
|
+
#ifdef __MSVC_RUNTIME_CHECKS
|
|
738
|
+
pr[0] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
|
|
739
|
+
carry >>= limb_bits;
|
|
740
|
+
carry += w * z + x * y;
|
|
741
|
+
pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
|
|
742
|
+
carry >>= limb_bits;
|
|
743
|
+
carry += x * z;
|
|
744
|
+
pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
|
|
745
|
+
pr[3] = static_cast<limb_type>(carry >> limb_bits);
|
|
746
|
+
#else
|
|
747
|
+
pr[0] = static_cast<limb_type>(carry);
|
|
748
|
+
carry >>= limb_bits;
|
|
749
|
+
carry += w * z + x * y;
|
|
750
|
+
pr[1] = static_cast<limb_type>(carry);
|
|
751
|
+
carry >>= limb_bits;
|
|
752
|
+
carry += x * z;
|
|
753
|
+
pr[2] = static_cast<limb_type>(carry);
|
|
754
|
+
pr[3] = static_cast<limb_type>(carry >> limb_bits);
|
|
755
|
+
#endif
|
|
756
|
+
result.sign(s);
|
|
757
|
+
result.normalize();
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
|
|
761
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
|
|
762
|
+
!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
|
|
763
|
+
eval_multiply(
|
|
764
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
765
|
+
double_limb_type a, double_limb_type b)
|
|
766
|
+
{
|
|
767
|
+
constexpr signed_double_limb_type mask = static_cast<signed_double_limb_type>(~static_cast<limb_type>(0));
|
|
768
|
+
constexpr std::size_t limb_bits = static_cast<std::size_t>(sizeof(limb_type) * CHAR_BIT);
|
|
769
|
+
|
|
770
|
+
double_limb_type w = a & mask;
|
|
771
|
+
double_limb_type x = a >> limb_bits;
|
|
772
|
+
double_limb_type y = b & mask;
|
|
773
|
+
double_limb_type z = b >> limb_bits;
|
|
774
|
+
|
|
775
|
+
result.resize(4, 4);
|
|
776
|
+
limb_type* pr = result.limbs();
|
|
777
|
+
|
|
778
|
+
double_limb_type carry = w * y;
|
|
779
|
+
#ifdef __MSVC_RUNTIME_CHECKS
|
|
780
|
+
pr[0] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
|
|
781
|
+
carry >>= limb_bits;
|
|
782
|
+
carry += w * z;
|
|
783
|
+
pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
|
|
784
|
+
carry >>= limb_bits;
|
|
785
|
+
pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
|
|
786
|
+
carry = x * y + pr[1];
|
|
787
|
+
pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
|
|
788
|
+
carry >>= limb_bits;
|
|
789
|
+
carry += pr[2] + x * z;
|
|
790
|
+
pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
|
|
791
|
+
pr[3] = static_cast<limb_type>(carry >> limb_bits);
|
|
792
|
+
#else
|
|
793
|
+
pr[0] = static_cast<limb_type>(carry);
|
|
794
|
+
carry >>= limb_bits;
|
|
795
|
+
carry += w * z;
|
|
796
|
+
pr[1] = static_cast<limb_type>(carry);
|
|
797
|
+
carry >>= limb_bits;
|
|
798
|
+
pr[2] = static_cast<limb_type>(carry);
|
|
799
|
+
carry = x * y + pr[1];
|
|
800
|
+
pr[1] = static_cast<limb_type>(carry);
|
|
801
|
+
carry >>= limb_bits;
|
|
802
|
+
carry += pr[2] + x * z;
|
|
803
|
+
pr[2] = static_cast<limb_type>(carry);
|
|
804
|
+
pr[3] = static_cast<limb_type>(carry >> limb_bits);
|
|
805
|
+
#endif
|
|
806
|
+
result.sign(false);
|
|
807
|
+
result.normalize();
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1,
|
|
811
|
+
std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
812
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
|
|
813
|
+
!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type
|
|
814
|
+
eval_multiply(
|
|
815
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
816
|
+
cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> const& a,
|
|
817
|
+
cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> const& b)
|
|
818
|
+
{
|
|
819
|
+
using canonical_type = typename boost::multiprecision::detail::canonical<typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::local_limb_type, cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::type;
|
|
820
|
+
eval_multiply(result, static_cast<canonical_type>(*a.limbs()), static_cast<canonical_type>(*b.limbs()));
|
|
821
|
+
result.sign(a.sign() != b.sign());
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class SI>
|
|
825
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (sizeof(SI) <= sizeof(signed_double_limb_type) / 2)>::type
|
|
826
|
+
eval_multiply(
|
|
827
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
828
|
+
SI a, SI b)
|
|
829
|
+
{
|
|
830
|
+
result = static_cast<signed_double_limb_type>(a) * static_cast<signed_double_limb_type>(b);
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class UI>
|
|
834
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (sizeof(UI) <= sizeof(signed_double_limb_type) / 2)>::type
|
|
835
|
+
eval_multiply(
|
|
836
|
+
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
|
|
837
|
+
UI a, UI b)
|
|
838
|
+
{
|
|
839
|
+
result = static_cast<double_limb_type>(a) * static_cast<double_limb_type>(b);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
#ifdef BOOST_MSVC
|
|
843
|
+
#pragma warning(pop)
|
|
844
|
+
#endif
|
|
845
|
+
|
|
846
|
+
}}} // namespace boost::multiprecision::backends
|
|
847
|
+
|
|
848
|
+
#endif
|