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,2360 @@
|
|
|
1
|
+
////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright 2012 - 2022 John Maddock.
|
|
3
|
+
// Copyright 2022 Christopher Kormanyos.
|
|
4
|
+
// Distributed under the Boost Software License,
|
|
5
|
+
// Version 1.0. (See accompanying file LICENSE_1_0.txt
|
|
6
|
+
// or copy at https://www.boost.org/LICENSE_1_0.txt)
|
|
7
|
+
|
|
8
|
+
#ifndef BOOST_MP_CPP_INT_HPP
|
|
9
|
+
#define BOOST_MP_CPP_INT_HPP
|
|
10
|
+
|
|
11
|
+
#include <cstdint>
|
|
12
|
+
#include <cstring>
|
|
13
|
+
#include <iostream>
|
|
14
|
+
#include <iomanip>
|
|
15
|
+
#include <type_traits>
|
|
16
|
+
#include <string>
|
|
17
|
+
#include <boost/multiprecision/detail/standalone_config.hpp>
|
|
18
|
+
#include <boost/multiprecision/detail/endian.hpp>
|
|
19
|
+
#include <boost/multiprecision/number.hpp>
|
|
20
|
+
#include <boost/multiprecision/detail/integer_ops.hpp>
|
|
21
|
+
#include <boost/multiprecision/detail/rebind.hpp>
|
|
22
|
+
#include <boost/multiprecision/cpp_int/cpp_int_config.hpp>
|
|
23
|
+
#include <boost/multiprecision/rational_adaptor.hpp>
|
|
24
|
+
#include <boost/multiprecision/traits/is_byte_container.hpp>
|
|
25
|
+
#include <boost/multiprecision/cpp_int/checked.hpp>
|
|
26
|
+
#include <boost/multiprecision/detail/constexpr.hpp>
|
|
27
|
+
#include <boost/multiprecision/detail/float128_functions.hpp>
|
|
28
|
+
#include <boost/multiprecision/cpp_int/value_pack.hpp>
|
|
29
|
+
#include <boost/multiprecision/detail/empty_value.hpp>
|
|
30
|
+
#include <boost/multiprecision/detail/no_exceptions_support.hpp>
|
|
31
|
+
#include <boost/multiprecision/detail/assert.hpp>
|
|
32
|
+
#include <boost/multiprecision/detail/fpclassify.hpp>
|
|
33
|
+
|
|
34
|
+
namespace boost {
|
|
35
|
+
namespace multiprecision {
|
|
36
|
+
|
|
37
|
+
#ifdef BOOST_MSVC
|
|
38
|
+
#pragma warning(push)
|
|
39
|
+
#pragma warning(disable : 4307) // integral constant overflow (oveflow is in a branch not taken when it would overflow)
|
|
40
|
+
#pragma warning(disable : 4127) // conditional expression is constant
|
|
41
|
+
#pragma warning(disable : 4702) // Unreachable code (reachability depends on template params)
|
|
42
|
+
#endif
|
|
43
|
+
#if defined(__GNUC__) && !defined(__clang__)
|
|
44
|
+
// see https://github.com/boostorg/multiprecision/issues/413
|
|
45
|
+
// and https://github.com/boostorg/multiprecision/issues/431
|
|
46
|
+
#pragma GCC diagnostic push
|
|
47
|
+
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
|
48
|
+
#endif
|
|
49
|
+
|
|
50
|
+
namespace detail {
|
|
51
|
+
|
|
52
|
+
template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
|
|
53
|
+
struct is_byte_container<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> > : public std::false_type
|
|
54
|
+
{};
|
|
55
|
+
|
|
56
|
+
} // namespace detail
|
|
57
|
+
|
|
58
|
+
namespace backends {
|
|
59
|
+
|
|
60
|
+
namespace detail {
|
|
61
|
+
template <std::size_t Value1, std::size_t Value2>
|
|
62
|
+
struct static_unsigned_max
|
|
63
|
+
{
|
|
64
|
+
static constexpr std::size_t value = (Value1 > Value2) ? Value1 : Value2;
|
|
65
|
+
};
|
|
66
|
+
} // Namespace detail
|
|
67
|
+
|
|
68
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, bool trivial = false>
|
|
69
|
+
struct cpp_int_base;
|
|
70
|
+
//
|
|
71
|
+
// Traits class determines the maximum and minimum precision values:
|
|
72
|
+
//
|
|
73
|
+
template <class T>
|
|
74
|
+
struct max_precision;
|
|
75
|
+
|
|
76
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
|
|
77
|
+
struct max_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
|
|
78
|
+
{
|
|
79
|
+
static constexpr std::size_t value = std::is_void<Allocator>::value ? detail::static_unsigned_max<MinBits, MaxBits>::value
|
|
80
|
+
: (((MaxBits >= MinBits) && MaxBits) ? MaxBits : SIZE_MAX);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
template <class T>
|
|
84
|
+
struct min_precision;
|
|
85
|
+
|
|
86
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
|
|
87
|
+
struct min_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
|
|
88
|
+
{
|
|
89
|
+
static constexpr std::size_t value = (std::is_void<Allocator>::value ? detail::static_unsigned_max<MinBits, MaxBits>::value : MinBits);
|
|
90
|
+
};
|
|
91
|
+
//
|
|
92
|
+
// Traits class determines whether the number of bits precision requested could fit in a native type,
|
|
93
|
+
// we call this a "trivial" cpp_int:
|
|
94
|
+
//
|
|
95
|
+
template <class T>
|
|
96
|
+
struct is_trivial_cpp_int
|
|
97
|
+
{
|
|
98
|
+
static constexpr bool value = false;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
|
|
102
|
+
struct is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
|
|
103
|
+
{
|
|
104
|
+
using self = cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>;
|
|
105
|
+
static constexpr bool value = std::is_void<Allocator>::value && (max_precision<self>::value <= (sizeof(double_limb_type) * CHAR_BIT) - (SignType == signed_packed ? 1 : 0));
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
|
|
109
|
+
struct is_trivial_cpp_int<cpp_int_base<MinBits, MaxBits, SignType, Checked, Allocator, true> >
|
|
110
|
+
{
|
|
111
|
+
static constexpr bool value = true;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
} // namespace backends
|
|
115
|
+
//
|
|
116
|
+
// Traits class to determine whether a cpp_int_backend is signed or not:
|
|
117
|
+
//
|
|
118
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
|
|
119
|
+
struct is_unsigned_number<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
|
|
120
|
+
: public std::integral_constant<bool, (SignType == unsigned_magnitude) || (SignType == unsigned_packed)>
|
|
121
|
+
{};
|
|
122
|
+
|
|
123
|
+
namespace backends {
|
|
124
|
+
//
|
|
125
|
+
// Traits class determines whether T should be implicitly convertible to U, or
|
|
126
|
+
// whether the constructor should be made explicit. The latter happens if we
|
|
127
|
+
// are losing the sign, or have fewer digits precision in the target type:
|
|
128
|
+
//
|
|
129
|
+
template <class T, class U>
|
|
130
|
+
struct is_implicit_cpp_int_conversion;
|
|
131
|
+
|
|
132
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
133
|
+
struct is_implicit_cpp_int_conversion<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >
|
|
134
|
+
{
|
|
135
|
+
using t1 = cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>;
|
|
136
|
+
using t2 = cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>;
|
|
137
|
+
static constexpr bool value =
|
|
138
|
+
(is_signed_number<t2>::value || !is_signed_number<t1>::value) && (max_precision<t1>::value <= max_precision<t2>::value);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
//
|
|
142
|
+
// Traits class to determine whether operations on a cpp_int may throw:
|
|
143
|
+
//
|
|
144
|
+
template <class T>
|
|
145
|
+
struct is_non_throwing_cpp_int : public std::integral_constant<bool, false>
|
|
146
|
+
{};
|
|
147
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType>
|
|
148
|
+
struct is_non_throwing_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, unchecked, void> > : public std::integral_constant<bool, true>
|
|
149
|
+
{};
|
|
150
|
+
|
|
151
|
+
//
|
|
152
|
+
// Traits class, determines whether the cpp_int is fixed precision or not:
|
|
153
|
+
//
|
|
154
|
+
template <class T>
|
|
155
|
+
struct is_fixed_precision;
|
|
156
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
|
|
157
|
+
struct is_fixed_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
|
|
158
|
+
: public std::integral_constant<bool, max_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value != SIZE_MAX>
|
|
159
|
+
{};
|
|
160
|
+
|
|
161
|
+
namespace detail {
|
|
162
|
+
|
|
163
|
+
inline BOOST_MP_CXX14_CONSTEXPR void verify_new_size(std::size_t new_size, std::size_t min_size, const std::integral_constant<int, checked>&)
|
|
164
|
+
{
|
|
165
|
+
if (new_size < min_size)
|
|
166
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Unable to allocate sufficient storage for the value of the result: value overflows the maximum allowable magnitude."));
|
|
167
|
+
}
|
|
168
|
+
inline BOOST_MP_CXX14_CONSTEXPR void verify_new_size(std::size_t /*new_size*/, std::size_t /*min_size*/, const std::integral_constant<int, unchecked>&) {}
|
|
169
|
+
|
|
170
|
+
template <class U>
|
|
171
|
+
inline BOOST_MP_CXX14_CONSTEXPR void verify_limb_mask(bool b, U limb, U mask, const std::integral_constant<int, checked>&)
|
|
172
|
+
{
|
|
173
|
+
// When we mask out "limb" with "mask", do we loose bits? If so it's an overflow error:
|
|
174
|
+
if (b && (limb & ~mask))
|
|
175
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Overflow in cpp_int arithmetic: there is insufficient precision in the target type to hold all of the bits of the result."));
|
|
176
|
+
}
|
|
177
|
+
template <class U>
|
|
178
|
+
inline BOOST_MP_CXX14_CONSTEXPR void verify_limb_mask(bool /*b*/, U /*limb*/, U /*mask*/, const std::integral_constant<int, unchecked>&) {}
|
|
179
|
+
|
|
180
|
+
} // namespace detail
|
|
181
|
+
|
|
182
|
+
//
|
|
183
|
+
// Now define the various data layouts that are possible as partial specializations of the base class,
|
|
184
|
+
// starting with the default arbitrary precision signed integer type:
|
|
185
|
+
//
|
|
186
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator>
|
|
187
|
+
struct cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>
|
|
188
|
+
: private boost::multiprecision::detail::empty_value<typename detail::rebind<limb_type, Allocator>::type>
|
|
189
|
+
{
|
|
190
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, bool trivial2>
|
|
191
|
+
friend struct cpp_int_base;
|
|
192
|
+
|
|
193
|
+
using allocator_type = typename detail::rebind<limb_type, Allocator>::type;
|
|
194
|
+
using limb_pointer = typename std::allocator_traits<allocator_type>::pointer ;
|
|
195
|
+
using const_limb_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
|
|
196
|
+
using checked_type = std::integral_constant<int, Checked>;
|
|
197
|
+
|
|
198
|
+
//
|
|
199
|
+
// Interface invariants:
|
|
200
|
+
//
|
|
201
|
+
static_assert(!std::is_void<Allocator>::value, "Allocator must not be void here");
|
|
202
|
+
|
|
203
|
+
using base_type = boost::multiprecision::detail::empty_value<allocator_type>;
|
|
204
|
+
|
|
205
|
+
private:
|
|
206
|
+
struct limb_data
|
|
207
|
+
{
|
|
208
|
+
std::size_t capacity;
|
|
209
|
+
limb_pointer data;
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
public:
|
|
213
|
+
static constexpr std::size_t limb_bits = sizeof(limb_type) * CHAR_BIT;
|
|
214
|
+
static constexpr limb_type max_limb_value = ~static_cast<limb_type>(0u);
|
|
215
|
+
static constexpr limb_type sign_bit_mask = static_cast<limb_type>(1u) << (limb_bits - 1);
|
|
216
|
+
static constexpr std::size_t internal_limb_count =
|
|
217
|
+
MinBits
|
|
218
|
+
? (MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0))
|
|
219
|
+
: (sizeof(limb_data) / sizeof(limb_type)) > 1 ? (sizeof(limb_data) / sizeof(limb_type)) : 2;
|
|
220
|
+
private:
|
|
221
|
+
union data_type
|
|
222
|
+
{
|
|
223
|
+
limb_data ld;
|
|
224
|
+
limb_type la[internal_limb_count];
|
|
225
|
+
limb_type first;
|
|
226
|
+
double_limb_type double_first;
|
|
227
|
+
|
|
228
|
+
constexpr data_type() noexcept : first(0) {}
|
|
229
|
+
constexpr data_type(limb_type i) noexcept : first(i) {}
|
|
230
|
+
constexpr data_type(signed_limb_type i) noexcept : first(static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(i))) {}
|
|
231
|
+
#if BOOST_MP_ENDIAN_LITTLE_BYTE
|
|
232
|
+
constexpr data_type(double_limb_type i) noexcept : double_first(i)
|
|
233
|
+
{}
|
|
234
|
+
constexpr data_type(signed_double_limb_type i) noexcept : double_first(static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i))) {}
|
|
235
|
+
#endif
|
|
236
|
+
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !(defined(BOOST_MSVC) && (BOOST_MSVC < 1900))
|
|
237
|
+
constexpr data_type(limb_type* limbs, std::size_t len) noexcept : ld{ len, limbs }
|
|
238
|
+
{}
|
|
239
|
+
#else
|
|
240
|
+
constexpr data_type(limb_type* limbs, std::size_t len) noexcept
|
|
241
|
+
{
|
|
242
|
+
ld.capacity = len;
|
|
243
|
+
ld.data = limbs;
|
|
244
|
+
}
|
|
245
|
+
#endif
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
data_type m_data;
|
|
249
|
+
std::size_t m_limbs;
|
|
250
|
+
bool m_sign, m_internal, m_alias;
|
|
251
|
+
|
|
252
|
+
public:
|
|
253
|
+
//
|
|
254
|
+
// Direct construction:
|
|
255
|
+
//
|
|
256
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(limb_type i) noexcept
|
|
257
|
+
: m_data(i),
|
|
258
|
+
m_limbs(1),
|
|
259
|
+
m_sign(false),
|
|
260
|
+
m_internal(true),
|
|
261
|
+
m_alias(false) {}
|
|
262
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(signed_limb_type i) noexcept
|
|
263
|
+
: m_data(i),
|
|
264
|
+
m_limbs(1),
|
|
265
|
+
m_sign(i < 0),
|
|
266
|
+
m_internal(true),
|
|
267
|
+
m_alias(false) {}
|
|
268
|
+
#if BOOST_MP_ENDIAN_LITTLE_BYTE && !defined(BOOST_MP_TEST_NO_LE)
|
|
269
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(double_limb_type i) noexcept
|
|
270
|
+
: m_data(i),
|
|
271
|
+
m_limbs(i > max_limb_value ? 2 : 1),
|
|
272
|
+
m_sign(false),
|
|
273
|
+
m_internal(true),
|
|
274
|
+
m_alias(false)
|
|
275
|
+
{}
|
|
276
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(signed_double_limb_type i) noexcept
|
|
277
|
+
: m_data(i),
|
|
278
|
+
m_limbs(i < 0 ? (static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) > static_cast<double_limb_type>(max_limb_value) ? 2 : 1) : (i > max_limb_value ? 2 : 1)),
|
|
279
|
+
m_sign(i < 0),
|
|
280
|
+
m_internal(true),
|
|
281
|
+
m_alias(false) {}
|
|
282
|
+
#endif
|
|
283
|
+
//
|
|
284
|
+
// Aliasing constructor aliases data:
|
|
285
|
+
//
|
|
286
|
+
struct scoped_shared_storage : private boost::multiprecision::detail::empty_value<allocator_type>
|
|
287
|
+
{
|
|
288
|
+
private:
|
|
289
|
+
limb_type* data;
|
|
290
|
+
std::size_t capacity;
|
|
291
|
+
std::size_t allocated;
|
|
292
|
+
bool is_alias;
|
|
293
|
+
allocator_type& allocator() noexcept { return boost::multiprecision::detail::empty_value<allocator_type>::get(); }
|
|
294
|
+
|
|
295
|
+
public:
|
|
296
|
+
scoped_shared_storage(const allocator_type& a, std::size_t len)
|
|
297
|
+
: boost::multiprecision::detail::empty_value<allocator_type>(boost::multiprecision::detail::empty_init_t(), a), capacity(len), allocated(0), is_alias(false)
|
|
298
|
+
{
|
|
299
|
+
data = allocator().allocate(len);
|
|
300
|
+
}
|
|
301
|
+
scoped_shared_storage(const cpp_int_base& i, std::size_t len)
|
|
302
|
+
: boost::multiprecision::detail::empty_value<allocator_type>(boost::multiprecision::detail::empty_init_t(), i.allocator()), capacity(len), allocated(0), is_alias(false)
|
|
303
|
+
{
|
|
304
|
+
data = allocator().allocate(len);
|
|
305
|
+
}
|
|
306
|
+
scoped_shared_storage(limb_type* limbs, std::size_t n) : data(limbs), capacity(n), allocated(0), is_alias(true) {}
|
|
307
|
+
~scoped_shared_storage()
|
|
308
|
+
{
|
|
309
|
+
if(!is_alias)
|
|
310
|
+
allocator().deallocate(data, capacity);
|
|
311
|
+
}
|
|
312
|
+
limb_type* allocate(std::size_t n) noexcept
|
|
313
|
+
{
|
|
314
|
+
limb_type* result = data + allocated;
|
|
315
|
+
allocated += n;
|
|
316
|
+
BOOST_MP_ASSERT(allocated <= capacity);
|
|
317
|
+
return result;
|
|
318
|
+
}
|
|
319
|
+
void deallocate(std::size_t n)
|
|
320
|
+
{
|
|
321
|
+
BOOST_MP_ASSERT(n <= allocated);
|
|
322
|
+
allocated -= n;
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
explicit constexpr cpp_int_base(limb_type* data, std::size_t offset, std::size_t len) noexcept
|
|
326
|
+
: m_data(data + offset, len),
|
|
327
|
+
m_limbs(len),
|
|
328
|
+
m_sign(false),
|
|
329
|
+
m_internal(false),
|
|
330
|
+
m_alias(true) {}
|
|
331
|
+
// This next constructor is for constructing const objects from const limb_type*'s only.
|
|
332
|
+
// Unfortunately we appear to have no way to assert that within the language, and the const_cast
|
|
333
|
+
// is a side effect of that :(
|
|
334
|
+
explicit constexpr cpp_int_base(const limb_type* data, std::size_t offset, std::size_t len) noexcept
|
|
335
|
+
: m_data(const_cast<limb_type*>(data) + offset, len),
|
|
336
|
+
m_limbs(len),
|
|
337
|
+
m_sign(false),
|
|
338
|
+
m_internal(false),
|
|
339
|
+
m_alias(true) {}
|
|
340
|
+
explicit cpp_int_base(scoped_shared_storage& data, std::size_t len) noexcept
|
|
341
|
+
: m_data(data.allocate(len), len),
|
|
342
|
+
m_limbs(len),
|
|
343
|
+
m_sign(false),
|
|
344
|
+
m_internal(false),
|
|
345
|
+
m_alias(true) {}
|
|
346
|
+
//
|
|
347
|
+
// Helper functions for getting at our internal data, and manipulating storage:
|
|
348
|
+
//
|
|
349
|
+
BOOST_MP_FORCEINLINE allocator_type& allocator() noexcept { return base_type::get(); }
|
|
350
|
+
BOOST_MP_FORCEINLINE const allocator_type& allocator() const noexcept { return base_type::get(); }
|
|
351
|
+
BOOST_MP_FORCEINLINE std::size_t size() const noexcept { return m_limbs; }
|
|
352
|
+
BOOST_MP_FORCEINLINE limb_pointer limbs() noexcept { return m_internal ? m_data.la : m_data.ld.data; }
|
|
353
|
+
BOOST_MP_FORCEINLINE const_limb_pointer limbs() const noexcept { return m_internal ? m_data.la : m_data.ld.data; }
|
|
354
|
+
BOOST_MP_FORCEINLINE std::size_t capacity() const noexcept { return m_internal ? internal_limb_count : m_data.ld.capacity; }
|
|
355
|
+
BOOST_MP_FORCEINLINE bool sign() const noexcept { return m_sign; }
|
|
356
|
+
void sign(bool b) noexcept
|
|
357
|
+
{
|
|
358
|
+
m_sign = b;
|
|
359
|
+
// Check for zero value:
|
|
360
|
+
if (m_sign && (m_limbs == 1))
|
|
361
|
+
{
|
|
362
|
+
if (limbs()[0] == 0)
|
|
363
|
+
m_sign = false;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
void resize(std::size_t new_size, std::size_t min_size)
|
|
367
|
+
{
|
|
368
|
+
constexpr std::size_t max_limbs = MaxBits / (CHAR_BIT * sizeof(limb_type)) + ((MaxBits % (CHAR_BIT * sizeof(limb_type))) ? 1 : 0);
|
|
369
|
+
// We never resize beyond MaxSize:
|
|
370
|
+
if (new_size > max_limbs)
|
|
371
|
+
new_size = max_limbs;
|
|
372
|
+
detail::verify_new_size(new_size, min_size, checked_type());
|
|
373
|
+
// See if we have enough capacity already:
|
|
374
|
+
std::size_t cap = capacity();
|
|
375
|
+
if (new_size > cap)
|
|
376
|
+
{
|
|
377
|
+
// We must not be an alias, memory allocation here defeats the whole point of aliasing:
|
|
378
|
+
BOOST_MP_ASSERT(!m_alias);
|
|
379
|
+
// Allocate a new buffer and copy everything over:
|
|
380
|
+
cap = (std::min)((std::max)(cap * 4, new_size), max_limbs);
|
|
381
|
+
limb_pointer pl = allocator().allocate(cap);
|
|
382
|
+
std::memcpy(pl, limbs(), size() * sizeof(limbs()[0]));
|
|
383
|
+
if (!m_internal && !m_alias)
|
|
384
|
+
allocator().deallocate(limbs(), capacity());
|
|
385
|
+
else
|
|
386
|
+
m_internal = false;
|
|
387
|
+
m_limbs = new_size;
|
|
388
|
+
m_data.ld.capacity = cap;
|
|
389
|
+
m_data.ld.data = pl;
|
|
390
|
+
}
|
|
391
|
+
else
|
|
392
|
+
{
|
|
393
|
+
m_limbs = new_size;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
BOOST_MP_FORCEINLINE void normalize() noexcept
|
|
397
|
+
{
|
|
398
|
+
limb_pointer p = limbs();
|
|
399
|
+
while ((m_limbs - 1) && !p[m_limbs - 1])
|
|
400
|
+
--m_limbs;
|
|
401
|
+
}
|
|
402
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base() noexcept : m_data(), m_limbs(1), m_sign(false), m_internal(true), m_alias(false){}
|
|
403
|
+
BOOST_MP_FORCEINLINE cpp_int_base(const cpp_int_base& o) : base_type(o), m_limbs(o.m_alias ? o.m_limbs : 0), m_sign(o.m_sign), m_internal(o.m_alias ? false : true), m_alias(o.m_alias)
|
|
404
|
+
{
|
|
405
|
+
if (m_alias)
|
|
406
|
+
{
|
|
407
|
+
m_data.ld = o.m_data.ld;
|
|
408
|
+
}
|
|
409
|
+
else
|
|
410
|
+
{
|
|
411
|
+
resize(o.size(), o.size());
|
|
412
|
+
std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0]));
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
// rvalue copy:
|
|
416
|
+
cpp_int_base(cpp_int_base&& o)
|
|
417
|
+
: base_type(static_cast<base_type&&>(o)), m_limbs(o.m_limbs), m_sign(o.m_sign), m_internal(o.m_internal), m_alias(o.m_alias)
|
|
418
|
+
{
|
|
419
|
+
if (m_internal)
|
|
420
|
+
{
|
|
421
|
+
std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0]));
|
|
422
|
+
}
|
|
423
|
+
else
|
|
424
|
+
{
|
|
425
|
+
m_data.ld = o.m_data.ld;
|
|
426
|
+
o.m_limbs = 0;
|
|
427
|
+
o.m_internal = true;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
cpp_int_base& operator=(cpp_int_base&& o) noexcept
|
|
431
|
+
{
|
|
432
|
+
if (!m_internal && !m_alias)
|
|
433
|
+
allocator().deallocate(m_data.ld.data, m_data.ld.capacity);
|
|
434
|
+
*static_cast<base_type*>(this) = static_cast<base_type&&>(o);
|
|
435
|
+
m_limbs = o.m_limbs;
|
|
436
|
+
m_sign = o.m_sign;
|
|
437
|
+
m_internal = o.m_internal;
|
|
438
|
+
m_alias = o.m_alias;
|
|
439
|
+
if (m_internal)
|
|
440
|
+
{
|
|
441
|
+
std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0]));
|
|
442
|
+
}
|
|
443
|
+
else
|
|
444
|
+
{
|
|
445
|
+
m_data.ld = o.m_data.ld;
|
|
446
|
+
o.m_limbs = 0;
|
|
447
|
+
o.m_internal = true;
|
|
448
|
+
}
|
|
449
|
+
return *this;
|
|
450
|
+
}
|
|
451
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_int_check_type Checked2>
|
|
452
|
+
cpp_int_base& operator=(cpp_int_base<MinBits2, MaxBits2, signed_magnitude, Checked2, Allocator>&& o) noexcept
|
|
453
|
+
{
|
|
454
|
+
if(o.m_internal)
|
|
455
|
+
{
|
|
456
|
+
m_sign = o.m_sign;
|
|
457
|
+
this->resize(o.size(), o.size());
|
|
458
|
+
std::memcpy(this->limbs(), o.limbs(), o.size() * sizeof(*(o.limbs())));
|
|
459
|
+
return *this;
|
|
460
|
+
}
|
|
461
|
+
if (!m_internal && !m_alias)
|
|
462
|
+
allocator().deallocate(m_data.ld.data, m_data.ld.capacity);
|
|
463
|
+
*static_cast<base_type*>(this) = static_cast<typename cpp_int_base<MinBits2, MaxBits2, signed_magnitude, Checked2, Allocator>::base_type&&>(o);
|
|
464
|
+
m_limbs = o.m_limbs;
|
|
465
|
+
m_sign = o.m_sign;
|
|
466
|
+
m_internal = o.m_internal;
|
|
467
|
+
m_alias = o.m_alias;
|
|
468
|
+
m_data.ld.capacity = o.m_data.ld.capacity;
|
|
469
|
+
m_data.ld.data = o.limbs();
|
|
470
|
+
o.m_limbs = 0;
|
|
471
|
+
o.m_internal = true;
|
|
472
|
+
return *this;
|
|
473
|
+
}
|
|
474
|
+
BOOST_MP_FORCEINLINE ~cpp_int_base() noexcept
|
|
475
|
+
{
|
|
476
|
+
if (!m_internal && !m_alias)
|
|
477
|
+
allocator().deallocate(limbs(), capacity());
|
|
478
|
+
}
|
|
479
|
+
void assign(const cpp_int_base& o)
|
|
480
|
+
{
|
|
481
|
+
if (this != &o)
|
|
482
|
+
{
|
|
483
|
+
static_cast<base_type&>(*this) = static_cast<const base_type&>(o);
|
|
484
|
+
m_limbs = 0;
|
|
485
|
+
resize(o.size(), o.size());
|
|
486
|
+
std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0]));
|
|
487
|
+
m_sign = o.m_sign;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
BOOST_MP_FORCEINLINE void negate() noexcept
|
|
491
|
+
{
|
|
492
|
+
m_sign = !m_sign;
|
|
493
|
+
// Check for zero value:
|
|
494
|
+
if (m_sign && (m_limbs == 1))
|
|
495
|
+
{
|
|
496
|
+
if (limbs()[0] == 0)
|
|
497
|
+
m_sign = false;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
BOOST_MP_FORCEINLINE bool isneg() const noexcept
|
|
501
|
+
{
|
|
502
|
+
return m_sign;
|
|
503
|
+
}
|
|
504
|
+
BOOST_MP_FORCEINLINE void do_swap(cpp_int_base& o) noexcept
|
|
505
|
+
{
|
|
506
|
+
std::swap(m_data, o.m_data);
|
|
507
|
+
std::swap(m_sign, o.m_sign);
|
|
508
|
+
std::swap(m_internal, o.m_internal);
|
|
509
|
+
std::swap(m_limbs, o.m_limbs);
|
|
510
|
+
std::swap(m_alias, o.m_alias);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
protected:
|
|
514
|
+
template <class A>
|
|
515
|
+
void check_in_range(const A&) noexcept {}
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator>
|
|
519
|
+
constexpr std::size_t cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::limb_bits;
|
|
520
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator>
|
|
521
|
+
constexpr limb_type cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::max_limb_value;
|
|
522
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator>
|
|
523
|
+
constexpr limb_type cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::sign_bit_mask;
|
|
524
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator>
|
|
525
|
+
constexpr std::size_t cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::internal_limb_count;
|
|
526
|
+
|
|
527
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator>
|
|
528
|
+
struct cpp_int_base<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator, false>
|
|
529
|
+
: private boost::multiprecision::detail::empty_value<typename detail::rebind<limb_type, Allocator>::type>
|
|
530
|
+
{
|
|
531
|
+
//
|
|
532
|
+
// There is currently no support for unsigned arbitrary precision arithmetic, largely
|
|
533
|
+
// because it's not clear what subtraction should do:
|
|
534
|
+
//
|
|
535
|
+
static_assert(((sizeof(Allocator) == 0) && !std::is_void<Allocator>::value), "There is curently no support for unsigned arbitrary precision integers.");
|
|
536
|
+
};
|
|
537
|
+
//
|
|
538
|
+
// Fixed precision (i.e. no allocator), signed-magnitude type with limb-usage count:
|
|
539
|
+
//
|
|
540
|
+
template <std::size_t MinBits, cpp_int_check_type Checked>
|
|
541
|
+
struct cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>
|
|
542
|
+
{
|
|
543
|
+
using limb_pointer = limb_type* ;
|
|
544
|
+
using const_limb_pointer = const limb_type* ;
|
|
545
|
+
using checked_type = std::integral_constant<int, Checked>;
|
|
546
|
+
|
|
547
|
+
struct scoped_shared_storage
|
|
548
|
+
{
|
|
549
|
+
BOOST_MP_CXX14_CONSTEXPR scoped_shared_storage(const cpp_int_base&, std::size_t) {}
|
|
550
|
+
BOOST_MP_CXX14_CONSTEXPR void deallocate(std::size_t) {}
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
//
|
|
554
|
+
// Interface invariants:
|
|
555
|
+
//
|
|
556
|
+
static_assert(MinBits > sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
|
|
557
|
+
|
|
558
|
+
public:
|
|
559
|
+
static constexpr std::size_t limb_bits = sizeof(limb_type) * CHAR_BIT;
|
|
560
|
+
static constexpr limb_type max_limb_value = ~static_cast<limb_type>(0u);
|
|
561
|
+
static constexpr limb_type sign_bit_mask = static_cast<limb_type>(1u) << (limb_bits - 1);
|
|
562
|
+
static constexpr std::size_t internal_limb_count = MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0);
|
|
563
|
+
static constexpr limb_type upper_limb_mask = (MinBits % limb_bits) ? (limb_type(1) << (MinBits % limb_bits)) - 1 : (~limb_type(0));
|
|
564
|
+
static_assert(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs");
|
|
565
|
+
|
|
566
|
+
private:
|
|
567
|
+
union data_type
|
|
568
|
+
{
|
|
569
|
+
limb_type m_data[internal_limb_count];
|
|
570
|
+
limb_type m_first_limb;
|
|
571
|
+
double_limb_type m_double_first_limb;
|
|
572
|
+
|
|
573
|
+
constexpr data_type()
|
|
574
|
+
: m_data{0}
|
|
575
|
+
{}
|
|
576
|
+
constexpr data_type(limb_type i)
|
|
577
|
+
: m_data{i}
|
|
578
|
+
{}
|
|
579
|
+
#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
|
|
580
|
+
constexpr data_type(limb_type i, limb_type j) : m_data{i, j}
|
|
581
|
+
{}
|
|
582
|
+
#endif
|
|
583
|
+
constexpr data_type(double_limb_type i) : m_double_first_limb(i)
|
|
584
|
+
{
|
|
585
|
+
#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
|
|
586
|
+
if (BOOST_MP_IS_CONST_EVALUATED(m_double_first_limb))
|
|
587
|
+
{
|
|
588
|
+
data_type t(static_cast<limb_type>(i & max_limb_value), static_cast<limb_type>(i >> limb_bits));
|
|
589
|
+
*this = t;
|
|
590
|
+
}
|
|
591
|
+
#endif
|
|
592
|
+
}
|
|
593
|
+
template <limb_type... VALUES>
|
|
594
|
+
constexpr data_type(literals::detail::value_pack<VALUES...>) : m_data{VALUES...}
|
|
595
|
+
{}
|
|
596
|
+
} m_wrapper;
|
|
597
|
+
std::uint16_t m_limbs;
|
|
598
|
+
bool m_sign;
|
|
599
|
+
|
|
600
|
+
public:
|
|
601
|
+
//
|
|
602
|
+
// Direct construction:
|
|
603
|
+
//
|
|
604
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(limb_type i) noexcept
|
|
605
|
+
: m_wrapper(i),
|
|
606
|
+
m_limbs(1),
|
|
607
|
+
m_sign(false) {}
|
|
608
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(signed_limb_type i) noexcept
|
|
609
|
+
: m_wrapper(limb_type(i < 0 ? static_cast<limb_type>(-static_cast<signed_double_limb_type>(i)) : i)),
|
|
610
|
+
m_limbs(1),
|
|
611
|
+
m_sign(i < 0) {}
|
|
612
|
+
#if BOOST_MP_ENDIAN_LITTLE_BYTE && !defined(BOOST_MP_TEST_NO_LE)
|
|
613
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(double_limb_type i) noexcept
|
|
614
|
+
: m_wrapper(i),
|
|
615
|
+
m_limbs(i > max_limb_value ? 2 : 1),
|
|
616
|
+
m_sign(false)
|
|
617
|
+
{}
|
|
618
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(signed_double_limb_type i) noexcept
|
|
619
|
+
: m_wrapper(double_limb_type(i < 0 ? static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) : i)),
|
|
620
|
+
m_limbs(i < 0 ? (static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)),
|
|
621
|
+
m_sign(i < 0) {}
|
|
622
|
+
#endif
|
|
623
|
+
template <limb_type... VALUES>
|
|
624
|
+
constexpr cpp_int_base(literals::detail::value_pack<VALUES...> i)
|
|
625
|
+
: m_wrapper(i), m_limbs(sizeof...(VALUES)), m_sign(false)
|
|
626
|
+
{}
|
|
627
|
+
constexpr cpp_int_base(literals::detail::value_pack<> i)
|
|
628
|
+
: m_wrapper(i), m_limbs(1), m_sign(false) {}
|
|
629
|
+
constexpr cpp_int_base(const cpp_int_base& a, const literals::detail::negate_tag&)
|
|
630
|
+
: m_wrapper(a.m_wrapper), m_limbs(a.m_limbs), m_sign((a.m_limbs == 1) && (*a.limbs() == 0) ? false : !a.m_sign) {}
|
|
631
|
+
explicit constexpr cpp_int_base(scoped_shared_storage&, std::size_t) noexcept : m_wrapper(), m_limbs(0), m_sign(false)
|
|
632
|
+
{}
|
|
633
|
+
//
|
|
634
|
+
// These are deprecated in C++20 unless we make them explicit:
|
|
635
|
+
//
|
|
636
|
+
BOOST_MP_CXX14_CONSTEXPR cpp_int_base& operator=(const cpp_int_base&) = default;
|
|
637
|
+
//
|
|
638
|
+
// Helper functions for getting at our internal data, and manipulating storage:
|
|
639
|
+
//
|
|
640
|
+
BOOST_MP_FORCEINLINE constexpr std::size_t size() const noexcept { return m_limbs; }
|
|
641
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR limb_pointer limbs() noexcept { return m_wrapper.m_data; }
|
|
642
|
+
BOOST_MP_FORCEINLINE constexpr const_limb_pointer limbs() const noexcept { return m_wrapper.m_data; }
|
|
643
|
+
BOOST_MP_FORCEINLINE constexpr bool sign() const noexcept { return m_sign; }
|
|
644
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void sign(bool b) noexcept
|
|
645
|
+
{
|
|
646
|
+
m_sign = b;
|
|
647
|
+
// Check for zero value:
|
|
648
|
+
if (m_sign && (m_limbs == 1))
|
|
649
|
+
{
|
|
650
|
+
if (limbs()[0] == 0)
|
|
651
|
+
m_sign = false;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void resize(std::size_t new_size, std::size_t min_size) noexcept((Checked == unchecked))
|
|
655
|
+
{
|
|
656
|
+
m_limbs = static_cast<std::uint16_t>((std::min)(new_size, internal_limb_count));
|
|
657
|
+
detail::verify_new_size(m_limbs, min_size, checked_type());
|
|
658
|
+
}
|
|
659
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void normalize() noexcept((Checked == unchecked))
|
|
660
|
+
{
|
|
661
|
+
limb_pointer p = limbs();
|
|
662
|
+
detail::verify_limb_mask(m_limbs == internal_limb_count, p[m_limbs - 1], upper_limb_mask, checked_type());
|
|
663
|
+
p[internal_limb_count - 1] &= upper_limb_mask;
|
|
664
|
+
while ((m_limbs - 1) && !p[m_limbs - 1])
|
|
665
|
+
--m_limbs;
|
|
666
|
+
if ((m_limbs == 1) && (!*p))
|
|
667
|
+
m_sign = false; // zero is always unsigned
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base() noexcept : m_wrapper(limb_type(0u)), m_limbs(1), m_sign(false) {}
|
|
671
|
+
// Not defaulted, it breaks constexpr support in the Intel compiler for some reason:
|
|
672
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(const cpp_int_base& o) noexcept
|
|
673
|
+
: m_wrapper(o.m_wrapper),
|
|
674
|
+
m_limbs(o.m_limbs),
|
|
675
|
+
m_sign(o.m_sign) {}
|
|
676
|
+
// Defaulted functions:
|
|
677
|
+
//~cpp_int_base() noexcept {}
|
|
678
|
+
|
|
679
|
+
void BOOST_MP_CXX14_CONSTEXPR assign(const cpp_int_base& o) noexcept
|
|
680
|
+
{
|
|
681
|
+
if (this != &o)
|
|
682
|
+
{
|
|
683
|
+
m_limbs = o.m_limbs;
|
|
684
|
+
#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
|
|
685
|
+
if (BOOST_MP_IS_CONST_EVALUATED(m_limbs))
|
|
686
|
+
{
|
|
687
|
+
for (std::size_t i = 0; i < m_limbs; ++i)
|
|
688
|
+
limbs()[i] = o.limbs()[i];
|
|
689
|
+
}
|
|
690
|
+
else
|
|
691
|
+
#endif
|
|
692
|
+
std::memcpy(limbs(), o.limbs(), o.size() * sizeof(o.limbs()[0]));
|
|
693
|
+
m_sign = o.m_sign;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void negate() noexcept
|
|
697
|
+
{
|
|
698
|
+
m_sign = !m_sign;
|
|
699
|
+
// Check for zero value:
|
|
700
|
+
if (m_sign && (m_limbs == 1))
|
|
701
|
+
{
|
|
702
|
+
if (limbs()[0] == 0)
|
|
703
|
+
m_sign = false;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR bool isneg() const noexcept
|
|
707
|
+
{
|
|
708
|
+
return m_sign;
|
|
709
|
+
}
|
|
710
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void do_swap(cpp_int_base& o) noexcept
|
|
711
|
+
{
|
|
712
|
+
for (std::size_t i = 0; i < (std::max)(size(), o.size()); ++i)
|
|
713
|
+
std_constexpr::swap(m_wrapper.m_data[i], o.m_wrapper.m_data[i]);
|
|
714
|
+
std_constexpr::swap(m_sign, o.m_sign);
|
|
715
|
+
std_constexpr::swap(m_limbs, o.m_limbs);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
protected:
|
|
719
|
+
template <class A>
|
|
720
|
+
BOOST_MP_CXX14_CONSTEXPR void check_in_range(const A&) noexcept {}
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
template <std::size_t MinBits, cpp_int_check_type Checked>
|
|
724
|
+
constexpr std::size_t cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::limb_bits;
|
|
725
|
+
template <std::size_t MinBits, cpp_int_check_type Checked>
|
|
726
|
+
constexpr limb_type cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::max_limb_value;
|
|
727
|
+
template <std::size_t MinBits, cpp_int_check_type Checked>
|
|
728
|
+
constexpr limb_type cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::sign_bit_mask;
|
|
729
|
+
template <std::size_t MinBits, cpp_int_check_type Checked>
|
|
730
|
+
constexpr std::size_t cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::internal_limb_count;
|
|
731
|
+
//
|
|
732
|
+
// Fixed precision (i.e. no allocator), unsigned type with limb-usage count:
|
|
733
|
+
//
|
|
734
|
+
template <std::size_t MinBits, cpp_int_check_type Checked>
|
|
735
|
+
struct cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>
|
|
736
|
+
{
|
|
737
|
+
using limb_pointer = limb_type* ;
|
|
738
|
+
using const_limb_pointer = const limb_type* ;
|
|
739
|
+
using checked_type = std::integral_constant<int, Checked>;
|
|
740
|
+
|
|
741
|
+
struct scoped_shared_storage
|
|
742
|
+
{
|
|
743
|
+
BOOST_MP_CXX14_CONSTEXPR scoped_shared_storage(const cpp_int_base&, std::size_t) {}
|
|
744
|
+
BOOST_MP_CXX14_CONSTEXPR void deallocate(std::size_t) {}
|
|
745
|
+
};
|
|
746
|
+
//
|
|
747
|
+
// Interface invariants:
|
|
748
|
+
//
|
|
749
|
+
static_assert(MinBits > sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
|
|
750
|
+
|
|
751
|
+
public:
|
|
752
|
+
static constexpr std::size_t limb_bits = sizeof(limb_type) * CHAR_BIT;
|
|
753
|
+
static constexpr limb_type max_limb_value = ~static_cast<limb_type>(0u);
|
|
754
|
+
static constexpr limb_type sign_bit_mask = static_cast<limb_type>(1u) << (limb_bits - 1);
|
|
755
|
+
static constexpr std::size_t internal_limb_count = MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0);
|
|
756
|
+
static constexpr limb_type upper_limb_mask = (MinBits % limb_bits) ? (limb_type(1) << (MinBits % limb_bits)) - 1 : (~limb_type(0));
|
|
757
|
+
static_assert(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs");
|
|
758
|
+
|
|
759
|
+
private:
|
|
760
|
+
union data_type
|
|
761
|
+
{
|
|
762
|
+
limb_type m_data[internal_limb_count];
|
|
763
|
+
limb_type m_first_limb;
|
|
764
|
+
double_limb_type m_double_first_limb;
|
|
765
|
+
|
|
766
|
+
constexpr data_type()
|
|
767
|
+
: m_data{0}
|
|
768
|
+
{}
|
|
769
|
+
constexpr data_type(limb_type i)
|
|
770
|
+
: m_data{i}
|
|
771
|
+
{}
|
|
772
|
+
#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
|
|
773
|
+
constexpr data_type(limb_type i, limb_type j) : m_data{i, j}
|
|
774
|
+
{}
|
|
775
|
+
#endif
|
|
776
|
+
constexpr data_type(double_limb_type i) : m_double_first_limb(i)
|
|
777
|
+
{
|
|
778
|
+
#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
|
|
779
|
+
if (BOOST_MP_IS_CONST_EVALUATED(m_double_first_limb))
|
|
780
|
+
{
|
|
781
|
+
data_type t(static_cast<limb_type>(i & max_limb_value), static_cast<limb_type>(i >> limb_bits));
|
|
782
|
+
*this = t;
|
|
783
|
+
}
|
|
784
|
+
#endif
|
|
785
|
+
}
|
|
786
|
+
template <limb_type... VALUES>
|
|
787
|
+
constexpr data_type(literals::detail::value_pack<VALUES...>) : m_data{VALUES...}
|
|
788
|
+
{}
|
|
789
|
+
} m_wrapper;
|
|
790
|
+
std::size_t m_limbs;
|
|
791
|
+
|
|
792
|
+
public:
|
|
793
|
+
//
|
|
794
|
+
// Direct construction:
|
|
795
|
+
//
|
|
796
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(limb_type i) noexcept
|
|
797
|
+
: m_wrapper(i),
|
|
798
|
+
m_limbs(1) {}
|
|
799
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(signed_limb_type i) noexcept((Checked == unchecked))
|
|
800
|
+
: m_wrapper(static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(i))),
|
|
801
|
+
m_limbs(1)
|
|
802
|
+
{
|
|
803
|
+
if (i < 0)
|
|
804
|
+
negate();
|
|
805
|
+
}
|
|
806
|
+
#if BOOST_MP_ENDIAN_LITTLE_BYTE && !defined(BOOST_MP_TEST_NO_LE)
|
|
807
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(double_limb_type i) noexcept
|
|
808
|
+
: m_wrapper(i),
|
|
809
|
+
m_limbs(i > max_limb_value ? 2 : 1)
|
|
810
|
+
{}
|
|
811
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(signed_double_limb_type i) noexcept((Checked == unchecked))
|
|
812
|
+
: m_wrapper(double_limb_type(i < 0 ? static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) : i)),
|
|
813
|
+
m_limbs(i < 0 ? (static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1))
|
|
814
|
+
{
|
|
815
|
+
if (i < 0)
|
|
816
|
+
negate();
|
|
817
|
+
}
|
|
818
|
+
#endif
|
|
819
|
+
template <limb_type... VALUES>
|
|
820
|
+
constexpr cpp_int_base(literals::detail::value_pack<VALUES...> i)
|
|
821
|
+
: m_wrapper(i), m_limbs(sizeof...(VALUES))
|
|
822
|
+
{}
|
|
823
|
+
constexpr cpp_int_base(literals::detail::value_pack<>)
|
|
824
|
+
: m_wrapper(static_cast<limb_type>(0u)), m_limbs(1) {}
|
|
825
|
+
explicit constexpr cpp_int_base(scoped_shared_storage&, std::size_t) noexcept : m_wrapper(), m_limbs(1)
|
|
826
|
+
{}
|
|
827
|
+
//
|
|
828
|
+
// Helper functions for getting at our internal data, and manipulating storage:
|
|
829
|
+
//
|
|
830
|
+
BOOST_MP_FORCEINLINE constexpr std::size_t size() const noexcept { return m_limbs; }
|
|
831
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR limb_pointer limbs() noexcept { return m_wrapper.m_data; }
|
|
832
|
+
BOOST_MP_FORCEINLINE constexpr const_limb_pointer limbs() const noexcept { return m_wrapper.m_data; }
|
|
833
|
+
BOOST_MP_FORCEINLINE constexpr bool sign() const noexcept { return false; }
|
|
834
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void sign(bool b) noexcept((Checked == unchecked))
|
|
835
|
+
{
|
|
836
|
+
if (b)
|
|
837
|
+
negate();
|
|
838
|
+
}
|
|
839
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void resize(std::size_t new_size, std::size_t min_size) noexcept((Checked == unchecked))
|
|
840
|
+
{
|
|
841
|
+
m_limbs = (std::min)(new_size, internal_limb_count);
|
|
842
|
+
detail::verify_new_size(m_limbs, min_size, checked_type());
|
|
843
|
+
}
|
|
844
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void normalize() noexcept((Checked == unchecked))
|
|
845
|
+
{
|
|
846
|
+
limb_pointer p = limbs();
|
|
847
|
+
|
|
848
|
+
limb_type c = p[internal_limb_count - 1];
|
|
849
|
+
bool full_limbs = m_limbs == internal_limb_count;
|
|
850
|
+
|
|
851
|
+
p[internal_limb_count - 1] &= upper_limb_mask;
|
|
852
|
+
while ((m_limbs - 1) && !p[m_limbs - 1])
|
|
853
|
+
--m_limbs;
|
|
854
|
+
//
|
|
855
|
+
// Verification at the end, so that we're in a valid state if we throw:
|
|
856
|
+
//
|
|
857
|
+
detail::verify_limb_mask(full_limbs, c, upper_limb_mask, checked_type());
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base() noexcept
|
|
861
|
+
: m_wrapper(limb_type(0u)),
|
|
862
|
+
m_limbs(1) {}
|
|
863
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(const cpp_int_base& o) noexcept
|
|
864
|
+
: m_wrapper(o.m_wrapper),
|
|
865
|
+
m_limbs(o.m_limbs) {}
|
|
866
|
+
// Defaulted functions:
|
|
867
|
+
//~cpp_int_base() noexcept {}
|
|
868
|
+
//
|
|
869
|
+
// These are deprecated in C++20 unless we make them explicit:
|
|
870
|
+
//
|
|
871
|
+
BOOST_MP_CXX14_CONSTEXPR cpp_int_base& operator=(const cpp_int_base&) = default;
|
|
872
|
+
|
|
873
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void assign(const cpp_int_base& o) noexcept
|
|
874
|
+
{
|
|
875
|
+
if (this != &o)
|
|
876
|
+
{
|
|
877
|
+
m_limbs = o.m_limbs;
|
|
878
|
+
#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
|
|
879
|
+
if (BOOST_MP_IS_CONST_EVALUATED(m_limbs))
|
|
880
|
+
{
|
|
881
|
+
for (std::size_t i = 0; i < m_limbs; ++i)
|
|
882
|
+
limbs()[i] = o.limbs()[i];
|
|
883
|
+
}
|
|
884
|
+
else
|
|
885
|
+
#endif
|
|
886
|
+
std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0]));
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
private:
|
|
891
|
+
void check_negate(const std::integral_constant<int, checked>&)
|
|
892
|
+
{
|
|
893
|
+
BOOST_MP_THROW_EXCEPTION(std::range_error("Attempt to negate an unsigned number."));
|
|
894
|
+
}
|
|
895
|
+
BOOST_MP_CXX14_CONSTEXPR void check_negate(const std::integral_constant<int, unchecked>&) {}
|
|
896
|
+
|
|
897
|
+
public:
|
|
898
|
+
BOOST_MP_CXX14_CONSTEXPR void negate() noexcept((Checked == unchecked))
|
|
899
|
+
{
|
|
900
|
+
// Not so much a negate as a complement - this gets called when subtraction
|
|
901
|
+
// would result in a "negative" number:
|
|
902
|
+
if ((m_limbs == 1) && (m_wrapper.m_data[0] == 0))
|
|
903
|
+
return; // negating zero is always zero, and always OK.
|
|
904
|
+
check_negate(checked_type());
|
|
905
|
+
std::size_t i = m_limbs;
|
|
906
|
+
for (; i < internal_limb_count; ++i)
|
|
907
|
+
m_wrapper.m_data[i] = 0;
|
|
908
|
+
m_limbs = internal_limb_count;
|
|
909
|
+
for (i = 0; i < internal_limb_count; ++i)
|
|
910
|
+
m_wrapper.m_data[i] = ~m_wrapper.m_data[i];
|
|
911
|
+
normalize();
|
|
912
|
+
eval_increment(static_cast<cpp_int_backend<MinBits, MinBits, unsigned_magnitude, Checked, void>&>(*this));
|
|
913
|
+
}
|
|
914
|
+
BOOST_MP_FORCEINLINE constexpr bool isneg() const noexcept
|
|
915
|
+
{
|
|
916
|
+
return false;
|
|
917
|
+
}
|
|
918
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void do_swap(cpp_int_base& o) noexcept
|
|
919
|
+
{
|
|
920
|
+
for (std::size_t i = 0; i < (std::max)(size(), o.size()); ++i)
|
|
921
|
+
std_constexpr::swap(m_wrapper.m_data[i], o.m_wrapper.m_data[i]);
|
|
922
|
+
std_constexpr::swap(m_limbs, o.m_limbs);
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
protected:
|
|
926
|
+
template <class A>
|
|
927
|
+
BOOST_MP_CXX14_CONSTEXPR void check_in_range(const A&) noexcept {}
|
|
928
|
+
};
|
|
929
|
+
|
|
930
|
+
template <std::size_t MinBits, cpp_int_check_type Checked>
|
|
931
|
+
constexpr std::size_t cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::limb_bits;
|
|
932
|
+
template <std::size_t MinBits, cpp_int_check_type Checked>
|
|
933
|
+
constexpr limb_type cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::max_limb_value;
|
|
934
|
+
template <std::size_t MinBits, cpp_int_check_type Checked>
|
|
935
|
+
constexpr limb_type cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::sign_bit_mask;
|
|
936
|
+
template <std::size_t MinBits, cpp_int_check_type Checked>
|
|
937
|
+
constexpr std::size_t cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::internal_limb_count;
|
|
938
|
+
//
|
|
939
|
+
// Traits classes to figure out a native type with N bits, these vary from boost::uint_t<N> only
|
|
940
|
+
// because some platforms have native integer types longer than long long, "really long long" anyone??
|
|
941
|
+
//
|
|
942
|
+
template <unsigned N, bool s>
|
|
943
|
+
struct trivial_limb_type_imp
|
|
944
|
+
{
|
|
945
|
+
using type = double_limb_type;
|
|
946
|
+
};
|
|
947
|
+
|
|
948
|
+
template <unsigned N>
|
|
949
|
+
struct trivial_limb_type_imp<N, true>
|
|
950
|
+
{
|
|
951
|
+
using type = typename boost::multiprecision::detail::uint_t<N>::least;
|
|
952
|
+
};
|
|
953
|
+
|
|
954
|
+
template <unsigned N>
|
|
955
|
+
struct trivial_limb_type : public trivial_limb_type_imp<N, N <= sizeof(long long) * CHAR_BIT>
|
|
956
|
+
{};
|
|
957
|
+
//
|
|
958
|
+
// Backend for fixed precision signed-magnitude type which will fit entirely inside a "double_limb_type":
|
|
959
|
+
//
|
|
960
|
+
template <std::size_t MinBits, cpp_int_check_type Checked>
|
|
961
|
+
struct cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, true>
|
|
962
|
+
{
|
|
963
|
+
using local_limb_type = typename trivial_limb_type<static_cast<unsigned>(MinBits)>::type;
|
|
964
|
+
using limb_pointer = local_limb_type*;
|
|
965
|
+
using const_limb_pointer = const local_limb_type*;
|
|
966
|
+
using checked_type = std::integral_constant<int, Checked>;
|
|
967
|
+
|
|
968
|
+
struct scoped_shared_storage
|
|
969
|
+
{
|
|
970
|
+
BOOST_MP_CXX14_CONSTEXPR scoped_shared_storage(const cpp_int_base&, std::size_t) {}
|
|
971
|
+
BOOST_MP_CXX14_CONSTEXPR void deallocate(std::size_t) {}
|
|
972
|
+
};
|
|
973
|
+
|
|
974
|
+
protected:
|
|
975
|
+
static constexpr std::size_t limb_bits = sizeof(local_limb_type) * CHAR_BIT;
|
|
976
|
+
static constexpr local_limb_type limb_mask = (MinBits < limb_bits) ? local_limb_type((local_limb_type(~local_limb_type(0))) >> (limb_bits - MinBits)) : local_limb_type(~local_limb_type(0));
|
|
977
|
+
|
|
978
|
+
private:
|
|
979
|
+
local_limb_type m_data;
|
|
980
|
+
bool m_sign;
|
|
981
|
+
|
|
982
|
+
//
|
|
983
|
+
// Interface invariants:
|
|
984
|
+
//
|
|
985
|
+
static_assert(MinBits <= sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
|
|
986
|
+
|
|
987
|
+
protected:
|
|
988
|
+
template <class T>
|
|
989
|
+
BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(!boost::multiprecision::detail::is_integral<T>::value || (std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::digits <= static_cast<int>(MinBits))))>::type
|
|
990
|
+
check_in_range(T val, const std::integral_constant<int, checked>&)
|
|
991
|
+
{
|
|
992
|
+
using common_type = typename std::common_type<typename boost::multiprecision::detail::make_unsigned<T>::type, local_limb_type>::type;
|
|
993
|
+
|
|
994
|
+
if (static_cast<common_type>(boost::multiprecision::detail::unsigned_abs(val)) > static_cast<common_type>(limb_mask))
|
|
995
|
+
BOOST_MP_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent."));
|
|
996
|
+
}
|
|
997
|
+
template <class T>
|
|
998
|
+
BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(boost::multiprecision::detail::is_integral<T>::value || (std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::digits <= static_cast<int>(MinBits))))>::type
|
|
999
|
+
check_in_range(T val, const std::integral_constant<int, checked>&)
|
|
1000
|
+
{
|
|
1001
|
+
using std::abs;
|
|
1002
|
+
using common_type = typename std::common_type<T, local_limb_type>::type;
|
|
1003
|
+
|
|
1004
|
+
if (static_cast<common_type>(abs(val)) > static_cast<common_type>(limb_mask))
|
|
1005
|
+
BOOST_MP_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent."));
|
|
1006
|
+
}
|
|
1007
|
+
template <class T, int C>
|
|
1008
|
+
BOOST_MP_CXX14_CONSTEXPR void check_in_range(T, const std::integral_constant<int, C>&) noexcept {}
|
|
1009
|
+
|
|
1010
|
+
template <class T>
|
|
1011
|
+
BOOST_MP_CXX14_CONSTEXPR void check_in_range(T val) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type())))
|
|
1012
|
+
{
|
|
1013
|
+
check_in_range(val, checked_type());
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
public:
|
|
1017
|
+
//
|
|
1018
|
+
// Direct construction:
|
|
1019
|
+
//
|
|
1020
|
+
template <class SI>
|
|
1021
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(SI i, typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (Checked == unchecked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
|
|
1022
|
+
: m_data(i < 0 ? static_cast<local_limb_type>(static_cast<typename boost::multiprecision::detail::make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask) : static_cast<local_limb_type>(i & limb_mask)), m_sign(i < 0) {}
|
|
1023
|
+
template <class SI>
|
|
1024
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(SI i, typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (Checked == checked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
|
|
1025
|
+
: m_data(i < 0 ? (static_cast<local_limb_type>(static_cast<typename boost::multiprecision::detail::make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask)) : static_cast<local_limb_type>(i & limb_mask)), m_sign(i < 0)
|
|
1026
|
+
{
|
|
1027
|
+
check_in_range(i);
|
|
1028
|
+
}
|
|
1029
|
+
template <class UI>
|
|
1030
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(UI i, typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (Checked == unchecked)>::type const* = nullptr) noexcept
|
|
1031
|
+
: m_data(static_cast<local_limb_type>(i) & limb_mask),
|
|
1032
|
+
m_sign(false) {}
|
|
1033
|
+
template <class UI>
|
|
1034
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(UI i, typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (Checked == checked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>())))
|
|
1035
|
+
: m_data(static_cast<local_limb_type>(i) & limb_mask), m_sign(false) { check_in_range(i); }
|
|
1036
|
+
#if !(defined(__clang__) && defined(__MINGW32__))
|
|
1037
|
+
template <class F>
|
|
1038
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(F i, typename std::enable_if<std::is_floating_point<F>::value && (Checked == unchecked)>::type const* = nullptr) noexcept
|
|
1039
|
+
: m_data(static_cast<local_limb_type>(i < 0 ? -i : i) & limb_mask),
|
|
1040
|
+
m_sign(i < 0) {}
|
|
1041
|
+
template <class F>
|
|
1042
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(F i, typename std::enable_if<std::is_floating_point<F>::value && (Checked == checked)>::type const* = nullptr)
|
|
1043
|
+
: m_data(static_cast<local_limb_type>(i < 0 ? -i : i) & limb_mask), m_sign(i < 0) { check_in_range(i); }
|
|
1044
|
+
#else
|
|
1045
|
+
//
|
|
1046
|
+
// conversion from float to __int128 is broken on clang/mingw,
|
|
1047
|
+
// see: https://bugs.llvm.org/show_bug.cgi?id=48940
|
|
1048
|
+
// Since no floating point type has more than 64 bits of
|
|
1049
|
+
// precision, we can simply cast to an intermediate type to
|
|
1050
|
+
// solve the issue:
|
|
1051
|
+
//
|
|
1052
|
+
template <class F>
|
|
1053
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(F i, typename std::enable_if<std::is_floating_point<F>::value && (Checked == unchecked)>::type const* = nullptr) noexcept
|
|
1054
|
+
: m_data(static_cast<local_limb_type>(static_cast<std::uint64_t>(i < 0 ? -i : i)) & limb_mask),
|
|
1055
|
+
m_sign(i < 0) {}
|
|
1056
|
+
template <class F>
|
|
1057
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(F i, typename std::enable_if<std::is_floating_point<F>::value && (Checked == checked)>::type const* = nullptr)
|
|
1058
|
+
: m_data(static_cast<local_limb_type>(static_cast<std::uint64_t>(i < 0 ? -i : i)) & limb_mask), m_sign(i < 0) { check_in_range(i); }
|
|
1059
|
+
#endif
|
|
1060
|
+
|
|
1061
|
+
constexpr cpp_int_base(literals::detail::value_pack<>) noexcept
|
|
1062
|
+
: m_data(static_cast<local_limb_type>(0u)),
|
|
1063
|
+
m_sign(false)
|
|
1064
|
+
{}
|
|
1065
|
+
template <limb_type a>
|
|
1066
|
+
constexpr cpp_int_base(literals::detail::value_pack<a>) noexcept
|
|
1067
|
+
: m_data(static_cast<local_limb_type>(a)),
|
|
1068
|
+
m_sign(false) {}
|
|
1069
|
+
template <limb_type a, limb_type b>
|
|
1070
|
+
constexpr cpp_int_base(literals::detail::value_pack<a, b>) noexcept
|
|
1071
|
+
: m_data(static_cast<local_limb_type>(a) | (static_cast<local_limb_type>(b) << bits_per_limb)),
|
|
1072
|
+
m_sign(false) {}
|
|
1073
|
+
constexpr cpp_int_base(const cpp_int_base& a, const literals::detail::negate_tag&) noexcept
|
|
1074
|
+
: m_data(a.m_data),
|
|
1075
|
+
m_sign(a.m_data ? !a.m_sign : false) {}
|
|
1076
|
+
//
|
|
1077
|
+
// These are deprecated in C++20 unless we make them explicit:
|
|
1078
|
+
//
|
|
1079
|
+
BOOST_MP_CXX14_CONSTEXPR cpp_int_base& operator=(const cpp_int_base&) = default;
|
|
1080
|
+
|
|
1081
|
+
explicit constexpr cpp_int_base(scoped_shared_storage&, std::size_t) noexcept : m_data(0), m_sign(false)
|
|
1082
|
+
{}
|
|
1083
|
+
//
|
|
1084
|
+
// Helper functions for getting at our internal data, and manipulating storage:
|
|
1085
|
+
//
|
|
1086
|
+
BOOST_MP_FORCEINLINE constexpr std::size_t size() const noexcept { return 1; }
|
|
1087
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR limb_pointer limbs() noexcept { return &m_data; }
|
|
1088
|
+
BOOST_MP_FORCEINLINE constexpr const_limb_pointer limbs() const noexcept { return &m_data; }
|
|
1089
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR bool sign() const noexcept { return m_sign; }
|
|
1090
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void sign(bool b) noexcept
|
|
1091
|
+
{
|
|
1092
|
+
m_sign = b;
|
|
1093
|
+
// Check for zero value:
|
|
1094
|
+
if (m_sign && !m_data)
|
|
1095
|
+
{
|
|
1096
|
+
m_sign = false;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void resize(std::size_t /* new_size */, std::size_t min_size)
|
|
1100
|
+
{
|
|
1101
|
+
detail::verify_new_size(2, min_size, checked_type());
|
|
1102
|
+
}
|
|
1103
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void normalize() noexcept((Checked == unchecked))
|
|
1104
|
+
{
|
|
1105
|
+
if (!m_data)
|
|
1106
|
+
m_sign = false; // zero is always unsigned
|
|
1107
|
+
detail::verify_limb_mask(true, m_data, limb_mask, checked_type());
|
|
1108
|
+
m_data &= limb_mask;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base() noexcept : m_data(0), m_sign(false) {}
|
|
1112
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(const cpp_int_base& o) noexcept
|
|
1113
|
+
: m_data(o.m_data),
|
|
1114
|
+
m_sign(o.m_sign) {}
|
|
1115
|
+
//~cpp_int_base() noexcept {}
|
|
1116
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void assign(const cpp_int_base& o) noexcept
|
|
1117
|
+
{
|
|
1118
|
+
m_data = o.m_data;
|
|
1119
|
+
m_sign = o.m_sign;
|
|
1120
|
+
}
|
|
1121
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void negate() noexcept
|
|
1122
|
+
{
|
|
1123
|
+
m_sign = !m_sign;
|
|
1124
|
+
// Check for zero value:
|
|
1125
|
+
if (m_data == 0)
|
|
1126
|
+
{
|
|
1127
|
+
m_sign = false;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR bool isneg() const noexcept
|
|
1131
|
+
{
|
|
1132
|
+
return m_sign;
|
|
1133
|
+
}
|
|
1134
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void do_swap(cpp_int_base& o) noexcept
|
|
1135
|
+
{
|
|
1136
|
+
std_constexpr::swap(m_sign, o.m_sign);
|
|
1137
|
+
std_constexpr::swap(m_data, o.m_data);
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
//
|
|
1141
|
+
// Backend for unsigned fixed precision (i.e. no allocator) type which will fit entirely inside a "double_limb_type":
|
|
1142
|
+
//
|
|
1143
|
+
template <std::size_t MinBits, cpp_int_check_type Checked>
|
|
1144
|
+
struct cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, true>
|
|
1145
|
+
{
|
|
1146
|
+
using local_limb_type = typename trivial_limb_type<static_cast<unsigned>(MinBits)>::type;
|
|
1147
|
+
using limb_pointer = local_limb_type* ;
|
|
1148
|
+
using const_limb_pointer = const local_limb_type* ;
|
|
1149
|
+
|
|
1150
|
+
struct scoped_shared_storage
|
|
1151
|
+
{
|
|
1152
|
+
BOOST_MP_CXX14_CONSTEXPR scoped_shared_storage(const cpp_int_base&, std::size_t) {}
|
|
1153
|
+
BOOST_MP_CXX14_CONSTEXPR void deallocate(std::size_t) {}
|
|
1154
|
+
};
|
|
1155
|
+
|
|
1156
|
+
private:
|
|
1157
|
+
static constexpr std::size_t limb_bits = sizeof(local_limb_type) * CHAR_BIT;
|
|
1158
|
+
static constexpr local_limb_type limb_mask = limb_bits != MinBits ? static_cast<local_limb_type>(static_cast<local_limb_type>(~local_limb_type(0)) >> (limb_bits - MinBits))
|
|
1159
|
+
: static_cast<local_limb_type>(~local_limb_type(0));
|
|
1160
|
+
|
|
1161
|
+
local_limb_type m_data;
|
|
1162
|
+
|
|
1163
|
+
using checked_type = std::integral_constant<int, Checked>;
|
|
1164
|
+
|
|
1165
|
+
//
|
|
1166
|
+
// Interface invariants:
|
|
1167
|
+
//
|
|
1168
|
+
static_assert(MinBits <= sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
|
|
1169
|
+
|
|
1170
|
+
protected:
|
|
1171
|
+
template <class T>
|
|
1172
|
+
BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< !(std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::digits <= static_cast<int>(MinBits)))>::type
|
|
1173
|
+
check_in_range(T val, const std::integral_constant<int, checked>&, const std::integral_constant<bool, false>&)
|
|
1174
|
+
{
|
|
1175
|
+
using common_type = typename std::common_type<T, local_limb_type>::type;
|
|
1176
|
+
|
|
1177
|
+
if (static_cast<common_type>(val) > limb_mask)
|
|
1178
|
+
BOOST_MP_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent."));
|
|
1179
|
+
}
|
|
1180
|
+
template <class T>
|
|
1181
|
+
BOOST_MP_CXX14_CONSTEXPR void check_in_range(T val, const std::integral_constant<int, checked>&, const std::integral_constant<bool, true>&)
|
|
1182
|
+
{
|
|
1183
|
+
using common_type = typename std::common_type<T, local_limb_type>::type;
|
|
1184
|
+
|
|
1185
|
+
if (static_cast<common_type>(val) > static_cast<common_type>(limb_mask))
|
|
1186
|
+
BOOST_MP_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent."));
|
|
1187
|
+
if (val < 0)
|
|
1188
|
+
BOOST_MP_THROW_EXCEPTION(std::range_error("The argument to an unsigned cpp_int constructor was negative."));
|
|
1189
|
+
}
|
|
1190
|
+
template <class T, int C, bool B>
|
|
1191
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void check_in_range(T, const std::integral_constant<int, C>&, const std::integral_constant<bool, B>&) noexcept {}
|
|
1192
|
+
|
|
1193
|
+
template <class T>
|
|
1194
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void check_in_range(T val) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type(), boost::multiprecision::detail::is_signed<T>())))
|
|
1195
|
+
{
|
|
1196
|
+
check_in_range(val, checked_type(), boost::multiprecision::detail::is_signed<T>());
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
public:
|
|
1200
|
+
//
|
|
1201
|
+
// Direct construction:
|
|
1202
|
+
//
|
|
1203
|
+
#ifdef __MSVC_RUNTIME_CHECKS
|
|
1204
|
+
template <class SI>
|
|
1205
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(SI i, typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (Checked == unchecked)>::type const* = nullptr) noexcept
|
|
1206
|
+
: m_data(i < 0 ? (1 + ~static_cast<local_limb_type>(-i & limb_mask)) & limb_mask : static_cast<local_limb_type>(i & limb_mask))
|
|
1207
|
+
{}
|
|
1208
|
+
template <class SI>
|
|
1209
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(SI i, typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (Checked == checked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
|
|
1210
|
+
: m_data(i < 0 ? 1 + ~static_cast<local_limb_type>(-i & limb_mask) : static_cast<local_limb_type>(i & limb_mask)) { check_in_range(i); }
|
|
1211
|
+
template <class UI>
|
|
1212
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(UI i, typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (Checked == unchecked)>::type const* = nullptr) noexcept
|
|
1213
|
+
: m_data(static_cast<local_limb_type>(i& limb_mask)) {}
|
|
1214
|
+
template <class UI>
|
|
1215
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(UI i, typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (Checked == checked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>())))
|
|
1216
|
+
: m_data(static_cast<local_limb_type>(i & limb_mask)) { check_in_range(i); }
|
|
1217
|
+
#else
|
|
1218
|
+
template <class SI>
|
|
1219
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(SI i, typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (Checked == unchecked)>::type const* = nullptr) noexcept
|
|
1220
|
+
: m_data(i < 0 ? (1 + ~static_cast<local_limb_type>(-i)) & limb_mask : static_cast<local_limb_type>(i) & limb_mask)
|
|
1221
|
+
{}
|
|
1222
|
+
template <class SI>
|
|
1223
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(SI i, typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (Checked == checked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
|
|
1224
|
+
: m_data(i < 0 ? 1 + ~static_cast<local_limb_type>(-i) : static_cast<local_limb_type>(i)) { check_in_range(i); }
|
|
1225
|
+
template <class UI>
|
|
1226
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(UI i, typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (Checked == unchecked)>::type const* = nullptr) noexcept
|
|
1227
|
+
: m_data(static_cast<local_limb_type>(i) & limb_mask) {}
|
|
1228
|
+
template <class UI>
|
|
1229
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(UI i, typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (Checked == checked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>())))
|
|
1230
|
+
: m_data(static_cast<local_limb_type>(i)) { check_in_range(i); }
|
|
1231
|
+
#endif
|
|
1232
|
+
template <class F>
|
|
1233
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(F i, typename std::enable_if<std::is_floating_point<F>::value >::type const* = nullptr) noexcept((Checked == unchecked))
|
|
1234
|
+
: m_data(static_cast<local_limb_type>(i < 0 ? -i : i) & limb_mask)
|
|
1235
|
+
{
|
|
1236
|
+
check_in_range(i);
|
|
1237
|
+
if (i < 0)
|
|
1238
|
+
negate();
|
|
1239
|
+
}
|
|
1240
|
+
constexpr cpp_int_base(literals::detail::value_pack<>) noexcept
|
|
1241
|
+
: m_data(static_cast<local_limb_type>(0u))
|
|
1242
|
+
{}
|
|
1243
|
+
template <limb_type a>
|
|
1244
|
+
constexpr cpp_int_base(literals::detail::value_pack<a>) noexcept
|
|
1245
|
+
: m_data(static_cast<local_limb_type>(a)) {}
|
|
1246
|
+
template <limb_type a, limb_type b>
|
|
1247
|
+
constexpr cpp_int_base(literals::detail::value_pack<a, b>) noexcept
|
|
1248
|
+
: m_data(static_cast<local_limb_type>(a) | (static_cast<local_limb_type>(b) << bits_per_limb)) {}
|
|
1249
|
+
//
|
|
1250
|
+
// These are deprecated in C++20 unless we make them explicit:
|
|
1251
|
+
//
|
|
1252
|
+
BOOST_MP_CXX14_CONSTEXPR cpp_int_base& operator=(const cpp_int_base&) = default;
|
|
1253
|
+
|
|
1254
|
+
explicit constexpr cpp_int_base(scoped_shared_storage&, std::size_t) noexcept : m_data(0)
|
|
1255
|
+
{}
|
|
1256
|
+
//
|
|
1257
|
+
// Helper functions for getting at our internal data, and manipulating storage:
|
|
1258
|
+
//
|
|
1259
|
+
BOOST_MP_FORCEINLINE constexpr std::size_t size() const noexcept { return 1; }
|
|
1260
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR limb_pointer limbs() noexcept { return &m_data; }
|
|
1261
|
+
BOOST_MP_FORCEINLINE constexpr const_limb_pointer limbs() const noexcept { return &m_data; }
|
|
1262
|
+
BOOST_MP_FORCEINLINE constexpr bool sign() const noexcept { return false; }
|
|
1263
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void sign(bool b) noexcept((Checked == unchecked))
|
|
1264
|
+
{
|
|
1265
|
+
if (b)
|
|
1266
|
+
negate();
|
|
1267
|
+
}
|
|
1268
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void resize(unsigned, std::size_t min_size)
|
|
1269
|
+
{
|
|
1270
|
+
detail::verify_new_size(2, min_size, checked_type());
|
|
1271
|
+
}
|
|
1272
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void normalize() noexcept((Checked == unchecked))
|
|
1273
|
+
{
|
|
1274
|
+
local_limb_type c = m_data;
|
|
1275
|
+
m_data &= limb_mask;
|
|
1276
|
+
//
|
|
1277
|
+
// Verification has to come afterwards, otherwise we can leave
|
|
1278
|
+
// ourselves in an invalid state:
|
|
1279
|
+
//
|
|
1280
|
+
detail::verify_limb_mask(true, c, limb_mask, checked_type());
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base() noexcept : m_data(0) {}
|
|
1284
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_base(const cpp_int_base& o) noexcept
|
|
1285
|
+
: m_data(o.m_data) {}
|
|
1286
|
+
//~cpp_int_base() noexcept {}
|
|
1287
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void assign(const cpp_int_base& o) noexcept
|
|
1288
|
+
{
|
|
1289
|
+
m_data = o.m_data;
|
|
1290
|
+
}
|
|
1291
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void negate()
|
|
1292
|
+
#if !defined(BOOST_NO_CXX17_IF_CONSTEXPR)
|
|
1293
|
+
noexcept((Checked == unchecked))
|
|
1294
|
+
#endif
|
|
1295
|
+
{
|
|
1296
|
+
BOOST_IF_CONSTEXPR(Checked == checked)
|
|
1297
|
+
{
|
|
1298
|
+
BOOST_MP_THROW_EXCEPTION(std::range_error("Attempt to negate an unsigned type."));
|
|
1299
|
+
}
|
|
1300
|
+
m_data = ~m_data;
|
|
1301
|
+
++m_data;
|
|
1302
|
+
}
|
|
1303
|
+
BOOST_MP_FORCEINLINE constexpr bool isneg() const noexcept
|
|
1304
|
+
{
|
|
1305
|
+
return false;
|
|
1306
|
+
}
|
|
1307
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void do_swap(cpp_int_base& o) noexcept
|
|
1308
|
+
{
|
|
1309
|
+
std_constexpr::swap(m_data, o.m_data);
|
|
1310
|
+
}
|
|
1311
|
+
};
|
|
1312
|
+
//
|
|
1313
|
+
// Traits class, lets us know whether type T can be directly converted to the base type,
|
|
1314
|
+
// used to enable/disable constructors etc:
|
|
1315
|
+
//
|
|
1316
|
+
template <class Arg, class Base>
|
|
1317
|
+
struct is_allowed_cpp_int_base_conversion : public std::conditional<
|
|
1318
|
+
std::is_same<Arg, limb_type>::value || std::is_same<Arg, signed_limb_type>::value
|
|
1319
|
+
#if BOOST_MP_ENDIAN_LITTLE_BYTE && !defined(BOOST_MP_TEST_NO_LE)
|
|
1320
|
+
|| std::is_same<Arg, double_limb_type>::value || std::is_same<Arg, signed_double_limb_type>::value
|
|
1321
|
+
#endif
|
|
1322
|
+
|| literals::detail::is_value_pack<Arg>::value || (is_trivial_cpp_int<Base>::value && boost::multiprecision::detail::is_arithmetic<Arg>::value),
|
|
1323
|
+
std::integral_constant<bool, true>,
|
|
1324
|
+
std::integral_constant<bool, false>>::type
|
|
1325
|
+
{};
|
|
1326
|
+
//
|
|
1327
|
+
// Now the actual backend, normalising parameters passed to the base class:
|
|
1328
|
+
//
|
|
1329
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
|
|
1330
|
+
struct cpp_int_backend
|
|
1331
|
+
: public cpp_int_base<
|
|
1332
|
+
min_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
|
|
1333
|
+
max_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
|
|
1334
|
+
SignType,
|
|
1335
|
+
Checked,
|
|
1336
|
+
Allocator,
|
|
1337
|
+
is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value>
|
|
1338
|
+
{
|
|
1339
|
+
using self_type = cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>;
|
|
1340
|
+
using base_type = cpp_int_base<
|
|
1341
|
+
min_precision<self_type>::value,
|
|
1342
|
+
max_precision<self_type>::value,
|
|
1343
|
+
SignType,
|
|
1344
|
+
Checked,
|
|
1345
|
+
Allocator,
|
|
1346
|
+
is_trivial_cpp_int<self_type>::value>;
|
|
1347
|
+
using trivial_tag = std::integral_constant<bool, is_trivial_cpp_int<self_type>::value>;
|
|
1348
|
+
|
|
1349
|
+
public:
|
|
1350
|
+
using signed_types = typename std::conditional<
|
|
1351
|
+
is_trivial_cpp_int<self_type>::value,
|
|
1352
|
+
std::tuple<
|
|
1353
|
+
signed char, short, int, long,
|
|
1354
|
+
long long, signed_double_limb_type>,
|
|
1355
|
+
std::tuple<signed_limb_type, signed_double_limb_type> >::type;
|
|
1356
|
+
using unsigned_types = typename std::conditional<
|
|
1357
|
+
is_trivial_cpp_int<self_type>::value,
|
|
1358
|
+
std::tuple<unsigned char, unsigned short, unsigned,
|
|
1359
|
+
unsigned long, unsigned long long, double_limb_type>,
|
|
1360
|
+
std::tuple<limb_type, double_limb_type> >::type;
|
|
1361
|
+
using float_types = typename std::conditional<
|
|
1362
|
+
is_trivial_cpp_int<self_type>::value,
|
|
1363
|
+
std::tuple<float, double, long double>,
|
|
1364
|
+
std::tuple<long double> >::type;
|
|
1365
|
+
using checked_type = std::integral_constant<int, Checked> ;
|
|
1366
|
+
|
|
1367
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_backend() noexcept {}
|
|
1368
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_backend(const cpp_int_backend& o) noexcept(std::is_void<Allocator>::value) : base_type(o) {}
|
|
1369
|
+
// rvalue copy:
|
|
1370
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_backend(cpp_int_backend&& o) noexcept
|
|
1371
|
+
: base_type(static_cast<base_type&&>(o))
|
|
1372
|
+
{}
|
|
1373
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2>
|
|
1374
|
+
BOOST_MP_FORCEINLINE BOOST_CXX14_CONSTEXPR cpp_int_backend(cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2>&& o, typename std::enable_if<is_implicit_cpp_int_conversion<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2>, self_type>::value>::type* = nullptr) noexcept
|
|
1375
|
+
{
|
|
1376
|
+
*this = static_cast<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2>&&>(o);
|
|
1377
|
+
}
|
|
1378
|
+
//
|
|
1379
|
+
// Direct construction from arithmetic type:
|
|
1380
|
+
//
|
|
1381
|
+
template <class Arg>
|
|
1382
|
+
BOOST_MP_FORCEINLINE constexpr cpp_int_backend(Arg i, typename std::enable_if<is_allowed_cpp_int_base_conversion<Arg, base_type>::value>::type const* = nullptr) noexcept(noexcept(base_type(std::declval<Arg>())))
|
|
1383
|
+
: base_type(i) {}
|
|
1384
|
+
//
|
|
1385
|
+
// Aliasing constructor: the result will alias the memory referenced, unless
|
|
1386
|
+
// we have fixed precision and storage, in which case we copy the memory:
|
|
1387
|
+
//
|
|
1388
|
+
explicit constexpr cpp_int_backend(limb_type* data, std::size_t offset, std::size_t len) noexcept
|
|
1389
|
+
: base_type(data, offset, len) {}
|
|
1390
|
+
explicit cpp_int_backend(const limb_type* data, std::size_t offset, std::size_t len) noexcept
|
|
1391
|
+
: base_type(data, offset, len) { this->normalize(); }
|
|
1392
|
+
explicit constexpr cpp_int_backend(typename base_type::scoped_shared_storage& data, std::size_t len) noexcept
|
|
1393
|
+
: base_type(data, len) {}
|
|
1394
|
+
|
|
1395
|
+
private:
|
|
1396
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
1397
|
+
BOOST_MP_CXX14_CONSTEXPR void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, std::true_type const&, std::true_type const&)
|
|
1398
|
+
{
|
|
1399
|
+
// Assigning trivial type to trivial type:
|
|
1400
|
+
this->check_in_range(*other.limbs());
|
|
1401
|
+
*this->limbs() = static_cast<typename self_type::local_limb_type>(*other.limbs());
|
|
1402
|
+
this->sign(other.sign());
|
|
1403
|
+
this->normalize();
|
|
1404
|
+
}
|
|
1405
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
1406
|
+
BOOST_MP_CXX14_CONSTEXPR void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, std::true_type const&, std::false_type const&)
|
|
1407
|
+
{
|
|
1408
|
+
// non-trivial to trivial narrowing conversion:
|
|
1409
|
+
double_limb_type v = *other.limbs();
|
|
1410
|
+
if (other.size() > 1)
|
|
1411
|
+
{
|
|
1412
|
+
v |= static_cast<double_limb_type>(other.limbs()[1]) << bits_per_limb;
|
|
1413
|
+
BOOST_IF_CONSTEXPR(Checked == checked)
|
|
1414
|
+
{
|
|
1415
|
+
if (other.size() > 2)
|
|
1416
|
+
{
|
|
1417
|
+
BOOST_MP_THROW_EXCEPTION(std::range_error("Assignment of a cpp_int that is out of range for the target type."));
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
*this = v;
|
|
1422
|
+
this->sign(other.sign());
|
|
1423
|
+
this->normalize();
|
|
1424
|
+
}
|
|
1425
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
1426
|
+
BOOST_MP_CXX14_CONSTEXPR void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, std::false_type const&, std::true_type const&)
|
|
1427
|
+
{
|
|
1428
|
+
// trivial to non-trivial, treat the trivial argument as if it were an unsigned arithmetic type, then set the sign afterwards:
|
|
1429
|
+
*this = static_cast<
|
|
1430
|
+
typename boost::multiprecision::detail::canonical<
|
|
1431
|
+
typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::local_limb_type,
|
|
1432
|
+
cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::type>(*other.limbs());
|
|
1433
|
+
this->sign(other.sign());
|
|
1434
|
+
}
|
|
1435
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
1436
|
+
BOOST_MP_CXX14_CONSTEXPR void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, std::false_type const&, std::false_type const&)
|
|
1437
|
+
{
|
|
1438
|
+
// regular non-trivial to non-trivial assign:
|
|
1439
|
+
this->resize(other.size(), other.size());
|
|
1440
|
+
|
|
1441
|
+
#if !defined(BOOST_MP_HAS_IS_CONSTANT_EVALUATED) && !defined(BOOST_MP_HAS_BUILTIN_IS_CONSTANT_EVALUATED) && !defined(BOOST_NO_CXX14_CONSTEXPR)
|
|
1442
|
+
std::size_t count = (std::min)(other.size(), this->size());
|
|
1443
|
+
for (std::size_t i = 0; i < count; ++i)
|
|
1444
|
+
this->limbs()[i] = other.limbs()[i];
|
|
1445
|
+
#else
|
|
1446
|
+
#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
|
|
1447
|
+
if (BOOST_MP_IS_CONST_EVALUATED(other.size()))
|
|
1448
|
+
{
|
|
1449
|
+
std::size_t count = (std::min)(other.size(), this->size());
|
|
1450
|
+
for (std::size_t i = 0; i < count; ++i)
|
|
1451
|
+
this->limbs()[i] = other.limbs()[i];
|
|
1452
|
+
}
|
|
1453
|
+
else
|
|
1454
|
+
#endif
|
|
1455
|
+
{
|
|
1456
|
+
static_assert(sizeof(other.limbs()[0]) == sizeof(this->limbs()[0]), "This method requires equal limb sizes");
|
|
1457
|
+
std::memcpy(this->limbs(), other.limbs(), (std::min)(other.size() * sizeof(other.limbs()[0]), this->size() * sizeof(this->limbs()[0])));
|
|
1458
|
+
}
|
|
1459
|
+
#endif
|
|
1460
|
+
this->sign(other.sign());
|
|
1461
|
+
this->normalize();
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
public:
|
|
1465
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
1466
|
+
BOOST_MP_CXX14_CONSTEXPR cpp_int_backend(
|
|
1467
|
+
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other,
|
|
1468
|
+
typename std::enable_if<is_implicit_cpp_int_conversion<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>, self_type>::value>::type* = nullptr)
|
|
1469
|
+
: base_type()
|
|
1470
|
+
{
|
|
1471
|
+
do_assign(
|
|
1472
|
+
other,
|
|
1473
|
+
std::integral_constant<bool, is_trivial_cpp_int<self_type>::value>(),
|
|
1474
|
+
std::integral_constant<bool, is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>());
|
|
1475
|
+
}
|
|
1476
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
1477
|
+
explicit BOOST_MP_CXX14_CONSTEXPR cpp_int_backend(
|
|
1478
|
+
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other,
|
|
1479
|
+
typename std::enable_if< !(is_implicit_cpp_int_conversion<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>, self_type>::value)>::type* = nullptr)
|
|
1480
|
+
: base_type()
|
|
1481
|
+
{
|
|
1482
|
+
do_assign(
|
|
1483
|
+
other,
|
|
1484
|
+
std::integral_constant<bool, is_trivial_cpp_int<self_type>::value>(),
|
|
1485
|
+
std::integral_constant<bool, is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>());
|
|
1486
|
+
}
|
|
1487
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
1488
|
+
BOOST_MP_CXX14_CONSTEXPR cpp_int_backend& operator=(
|
|
1489
|
+
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other)
|
|
1490
|
+
{
|
|
1491
|
+
do_assign(
|
|
1492
|
+
other,
|
|
1493
|
+
std::integral_constant<bool, is_trivial_cpp_int<self_type>::value>(),
|
|
1494
|
+
std::integral_constant<bool, is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>());
|
|
1495
|
+
return *this;
|
|
1496
|
+
}
|
|
1497
|
+
constexpr cpp_int_backend(const cpp_int_backend& a, const literals::detail::negate_tag& tag)
|
|
1498
|
+
: base_type(static_cast<const base_type&>(a), tag)
|
|
1499
|
+
{}
|
|
1500
|
+
|
|
1501
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_backend& operator=(const cpp_int_backend& o) noexcept(noexcept(std::declval<cpp_int_backend>().assign(std::declval<const cpp_int_backend&>())))
|
|
1502
|
+
{
|
|
1503
|
+
this->assign(o);
|
|
1504
|
+
return *this;
|
|
1505
|
+
}
|
|
1506
|
+
// rvalue copy:
|
|
1507
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_backend& operator=(cpp_int_backend&& o) noexcept(noexcept(std::declval<base_type&>() = std::declval<base_type>()))
|
|
1508
|
+
{
|
|
1509
|
+
*static_cast<base_type*>(this) = static_cast<base_type&&>(o);
|
|
1510
|
+
return *this;
|
|
1511
|
+
}
|
|
1512
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2>
|
|
1513
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<((MaxBits2 <= MaxBits) || (MaxBits == 0)) && !std::is_void<Allocator>::value, cpp_int_backend&>::type operator=(cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator>&& o) noexcept
|
|
1514
|
+
{
|
|
1515
|
+
*static_cast<base_type*>(this) = static_cast<typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2>::base_type&&>(o);
|
|
1516
|
+
return *this;
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
template <class A>
|
|
1520
|
+
BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
|
|
1521
|
+
boost::multiprecision::detail::is_unsigned<A>::value
|
|
1522
|
+
&& trivial_tag::value, cpp_int_backend&>::type
|
|
1523
|
+
operator=(const A& val)
|
|
1524
|
+
noexcept(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>())))
|
|
1525
|
+
{
|
|
1526
|
+
this->check_in_range(val);
|
|
1527
|
+
*this->limbs() = static_cast<typename self_type::local_limb_type>(val);
|
|
1528
|
+
this->sign(false);
|
|
1529
|
+
this->normalize();
|
|
1530
|
+
return *this;
|
|
1531
|
+
}
|
|
1532
|
+
template <class A>
|
|
1533
|
+
BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
|
|
1534
|
+
!(boost::multiprecision::detail::is_unsigned<A>::value || !boost::multiprecision::detail::is_integral<A>::value)
|
|
1535
|
+
&& trivial_tag::value, cpp_int_backend&>::type
|
|
1536
|
+
operator=(const A& val)
|
|
1537
|
+
noexcept(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>())) && noexcept(std::declval<cpp_int_backend>().sign(true)))
|
|
1538
|
+
{
|
|
1539
|
+
this->check_in_range(val);
|
|
1540
|
+
*this->limbs() = (val < 0) ? static_cast<typename self_type::local_limb_type>(boost::multiprecision::detail::unsigned_abs(val)) : static_cast<typename self_type::local_limb_type>(val);
|
|
1541
|
+
this->sign(val < 0);
|
|
1542
|
+
this->normalize();
|
|
1543
|
+
return *this;
|
|
1544
|
+
}
|
|
1545
|
+
template <class A>
|
|
1546
|
+
BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
|
|
1547
|
+
std::is_convertible<A, limb_type>::value
|
|
1548
|
+
&& !boost::multiprecision::detail::is_integral<A>::value
|
|
1549
|
+
&& trivial_tag::value, cpp_int_backend&>::type
|
|
1550
|
+
operator=(const A& val)
|
|
1551
|
+
{
|
|
1552
|
+
this->check_in_range(val);
|
|
1553
|
+
*this->limbs() = (val < 0) ? static_cast<typename self_type::local_limb_type>(boost::multiprecision::detail::abs(val)) : static_cast<typename self_type::local_limb_type>(val);
|
|
1554
|
+
this->sign(val < 0);
|
|
1555
|
+
this->normalize();
|
|
1556
|
+
return *this;
|
|
1557
|
+
}
|
|
1558
|
+
template <class A>
|
|
1559
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
|
|
1560
|
+
std::is_same<A, limb_type>::value && !trivial_tag::value, cpp_int_backend&>::type
|
|
1561
|
+
operator=(A i) noexcept
|
|
1562
|
+
{
|
|
1563
|
+
this->resize(1, 1);
|
|
1564
|
+
*this->limbs() = i;
|
|
1565
|
+
this->sign(false);
|
|
1566
|
+
return *this;
|
|
1567
|
+
}
|
|
1568
|
+
template <class A>
|
|
1569
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if <
|
|
1570
|
+
std::is_same<A, signed_limb_type>::value && !trivial_tag::value, cpp_int_backend&>::type
|
|
1571
|
+
operator=(A i) noexcept(noexcept(std::declval<cpp_int_backend>().sign(true)))
|
|
1572
|
+
{
|
|
1573
|
+
this->resize(1, 1);
|
|
1574
|
+
*this->limbs() = static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(i));
|
|
1575
|
+
this->sign(i < 0);
|
|
1576
|
+
return *this;
|
|
1577
|
+
}
|
|
1578
|
+
template <class A>
|
|
1579
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if <
|
|
1580
|
+
std::is_same<A, double_limb_type>::value && !trivial_tag::value, cpp_int_backend&>::type
|
|
1581
|
+
operator=(A i) noexcept
|
|
1582
|
+
{
|
|
1583
|
+
static_assert(sizeof(i) == 2 * sizeof(limb_type), "Failed integer size check");
|
|
1584
|
+
static_assert(base_type::internal_limb_count >= 2, "Failed internal limb count");
|
|
1585
|
+
typename base_type::limb_pointer p = this->limbs();
|
|
1586
|
+
#ifdef __MSVC_RUNTIME_CHECKS
|
|
1587
|
+
*p = static_cast<limb_type>(i & ~static_cast<limb_type>(0));
|
|
1588
|
+
#else
|
|
1589
|
+
*p = static_cast<limb_type>(i);
|
|
1590
|
+
#endif
|
|
1591
|
+
p[1] = static_cast<limb_type>(i >> base_type::limb_bits);
|
|
1592
|
+
this->resize(p[1] ? 2 : 1, p[1] ? 2 : 1);
|
|
1593
|
+
this->sign(false);
|
|
1594
|
+
return *this;
|
|
1595
|
+
}
|
|
1596
|
+
template <class A>
|
|
1597
|
+
BOOST_MP_CXX14_CONSTEXPR typename std::enable_if <
|
|
1598
|
+
std::is_same<A, signed_double_limb_type>::value && !trivial_tag::value, cpp_int_backend&>::type
|
|
1599
|
+
operator=(A i) noexcept(noexcept(std::declval<cpp_int_backend>().sign(true)))
|
|
1600
|
+
{
|
|
1601
|
+
static_assert(sizeof(i) == 2 * sizeof(limb_type), "double limb type size check failed");
|
|
1602
|
+
static_assert(base_type::internal_limb_count >= 2, "Failed internal limb count check");
|
|
1603
|
+
bool s = false;
|
|
1604
|
+
if (i < 0)
|
|
1605
|
+
s = true;
|
|
1606
|
+
double_limb_type ui = static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i));
|
|
1607
|
+
typename base_type::limb_pointer p = this->limbs();
|
|
1608
|
+
#ifdef __MSVC_RUNTIME_CHECKS
|
|
1609
|
+
*p = static_cast<limb_type>(ui & ~static_cast<limb_type>(0));
|
|
1610
|
+
#else
|
|
1611
|
+
*p = static_cast<limb_type>(ui);
|
|
1612
|
+
#endif
|
|
1613
|
+
p[1] = static_cast<limb_type>(ui >> base_type::limb_bits);
|
|
1614
|
+
this->resize(p[1] ? 2 : 1, p[1] ? 2 : 1);
|
|
1615
|
+
this->sign(s);
|
|
1616
|
+
return *this;
|
|
1617
|
+
}
|
|
1618
|
+
private:
|
|
1619
|
+
template <class F>
|
|
1620
|
+
BOOST_MP_CXX14_CONSTEXPR void do_assign_float(F a)
|
|
1621
|
+
{
|
|
1622
|
+
using default_ops::eval_add;
|
|
1623
|
+
using default_ops::eval_subtract;
|
|
1624
|
+
BOOST_MP_FLOAT128_USING using std::floor; using std::frexp; using std::ldexp;
|
|
1625
|
+
|
|
1626
|
+
if (a < 0)
|
|
1627
|
+
{
|
|
1628
|
+
do_assign_float(-a);
|
|
1629
|
+
this->sign(true);
|
|
1630
|
+
return;
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1633
|
+
if (a == 0)
|
|
1634
|
+
{
|
|
1635
|
+
*this = static_cast<limb_type>(0u);
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
if (a == 1)
|
|
1639
|
+
{
|
|
1640
|
+
*this = static_cast<limb_type>(1u);
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
if (!BOOST_MP_ISFINITE(a))
|
|
1644
|
+
{
|
|
1645
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Cannot convert a non-finite number to an integer."));
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
int e = 0;
|
|
1649
|
+
F f(0), term(0);
|
|
1650
|
+
*this = static_cast<limb_type>(0u);
|
|
1651
|
+
|
|
1652
|
+
f = frexp(a, &e);
|
|
1653
|
+
|
|
1654
|
+
#if !(defined(__clang__) && (__clang_major__ <= 7))
|
|
1655
|
+
constexpr limb_type shift = std::numeric_limits<limb_type>::digits;
|
|
1656
|
+
#else
|
|
1657
|
+
// clang 7 has an issue converting long double to unsigned long long in
|
|
1658
|
+
// release mode (bits get dropped, conversion appears to go via float)
|
|
1659
|
+
// Never extract more than double bits at a time:
|
|
1660
|
+
constexpr limb_type shift = std::numeric_limits<limb_type>::digits > std::numeric_limits<double>::digits
|
|
1661
|
+
? std::numeric_limits<double>::digits : std::numeric_limits<limb_type>::digits;
|
|
1662
|
+
#endif
|
|
1663
|
+
|
|
1664
|
+
while (f != static_cast<F>(0.0f))
|
|
1665
|
+
{
|
|
1666
|
+
// extract int sized bits from f:
|
|
1667
|
+
f = ldexp(f, shift);
|
|
1668
|
+
term = floor(f);
|
|
1669
|
+
e = e - static_cast<int>(shift);
|
|
1670
|
+
eval_left_shift(*this, shift);
|
|
1671
|
+
#if !(defined(__clang__) && (__clang_major__ <= 7))
|
|
1672
|
+
if (term > 0)
|
|
1673
|
+
eval_add(*this, static_cast<limb_type>(term));
|
|
1674
|
+
else
|
|
1675
|
+
eval_subtract(*this, static_cast<limb_type>(-term));
|
|
1676
|
+
#else
|
|
1677
|
+
// clang 7 requires extra cast to double to avoid buggy code generation:
|
|
1678
|
+
if (term > 0)
|
|
1679
|
+
eval_add(*this, static_cast<limb_type>(static_cast<double>(term)));
|
|
1680
|
+
else
|
|
1681
|
+
eval_subtract(*this, static_cast<limb_type>(static_cast<double>(-term)));
|
|
1682
|
+
#endif
|
|
1683
|
+
f -= term;
|
|
1684
|
+
}
|
|
1685
|
+
if (e > 0)
|
|
1686
|
+
eval_left_shift(*this, static_cast<unsigned int>(e));
|
|
1687
|
+
else if (e < 0)
|
|
1688
|
+
eval_right_shift(*this, static_cast<unsigned int>(-e));
|
|
1689
|
+
}
|
|
1690
|
+
public:
|
|
1691
|
+
template <class A>
|
|
1692
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if <
|
|
1693
|
+
std::is_floating_point<A>::value && !trivial_tag::value, cpp_int_backend&>::type
|
|
1694
|
+
operator=(A a)
|
|
1695
|
+
{
|
|
1696
|
+
do_assign_float(a);
|
|
1697
|
+
return *this;
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
private:
|
|
1701
|
+
void do_assign_string(const char* s, const std::integral_constant<bool, true>&)
|
|
1702
|
+
{
|
|
1703
|
+
std::size_t n = s ? std::strlen(s) : 0;
|
|
1704
|
+
*this = 0;
|
|
1705
|
+
unsigned radix = 10;
|
|
1706
|
+
bool isneg = false;
|
|
1707
|
+
if (n && (*s == '-'))
|
|
1708
|
+
{
|
|
1709
|
+
--n;
|
|
1710
|
+
++s;
|
|
1711
|
+
isneg = true;
|
|
1712
|
+
}
|
|
1713
|
+
if (n && (*s == '0'))
|
|
1714
|
+
{
|
|
1715
|
+
if ((n > 1) && ((s[1] == 'x') || (s[1] == 'X')))
|
|
1716
|
+
{
|
|
1717
|
+
radix = 16;
|
|
1718
|
+
s += 2;
|
|
1719
|
+
n -= 2;
|
|
1720
|
+
}
|
|
1721
|
+
else
|
|
1722
|
+
{
|
|
1723
|
+
radix = 8;
|
|
1724
|
+
n -= 1;
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
if (n)
|
|
1728
|
+
{
|
|
1729
|
+
unsigned val;
|
|
1730
|
+
while (*s)
|
|
1731
|
+
{
|
|
1732
|
+
if (*s >= '0' && *s <= '9')
|
|
1733
|
+
val = static_cast<unsigned>(*s - '0');
|
|
1734
|
+
else if (*s >= 'a' && *s <= 'f')
|
|
1735
|
+
val = 10u + static_cast<unsigned>(*s - 'a');
|
|
1736
|
+
else if (*s >= 'A' && *s <= 'F')
|
|
1737
|
+
val = 10u + static_cast<unsigned>(*s - 'A');
|
|
1738
|
+
else
|
|
1739
|
+
val = radix + 1u;
|
|
1740
|
+
if (val >= radix)
|
|
1741
|
+
{
|
|
1742
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string."));
|
|
1743
|
+
}
|
|
1744
|
+
*this->limbs() = detail::checked_multiply(*this->limbs(), static_cast<typename base_type::local_limb_type>(radix), checked_type());
|
|
1745
|
+
*this->limbs() = detail::checked_add(*this->limbs(), static_cast<typename base_type::local_limb_type>(val), checked_type());
|
|
1746
|
+
++s;
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
if (isneg)
|
|
1750
|
+
this->negate();
|
|
1751
|
+
}
|
|
1752
|
+
void do_assign_string(const char* s, const std::integral_constant<bool, false>&)
|
|
1753
|
+
{
|
|
1754
|
+
using default_ops::eval_add;
|
|
1755
|
+
using default_ops::eval_multiply;
|
|
1756
|
+
std::size_t n = s ? std::strlen(s) : 0;
|
|
1757
|
+
*this = static_cast<limb_type>(0u);
|
|
1758
|
+
unsigned radix = 10;
|
|
1759
|
+
bool isneg = false;
|
|
1760
|
+
if (n && (*s == '-'))
|
|
1761
|
+
{
|
|
1762
|
+
--n;
|
|
1763
|
+
++s;
|
|
1764
|
+
isneg = true;
|
|
1765
|
+
}
|
|
1766
|
+
if (n && (*s == '0'))
|
|
1767
|
+
{
|
|
1768
|
+
if ((n > 1) && ((s[1] == 'x') || (s[1] == 'X')))
|
|
1769
|
+
{
|
|
1770
|
+
radix = 16;
|
|
1771
|
+
s += 2;
|
|
1772
|
+
n -= 2;
|
|
1773
|
+
}
|
|
1774
|
+
else
|
|
1775
|
+
{
|
|
1776
|
+
radix = 8;
|
|
1777
|
+
n -= 1;
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
//
|
|
1781
|
+
// Exception guarantee: create the result in stack variable "result"
|
|
1782
|
+
// then do a swap at the end. In the event of a throw, *this will
|
|
1783
|
+
// be left unchanged.
|
|
1784
|
+
//
|
|
1785
|
+
cpp_int_backend result;
|
|
1786
|
+
if (n)
|
|
1787
|
+
{
|
|
1788
|
+
if (radix == 16)
|
|
1789
|
+
{
|
|
1790
|
+
while (*s == '0')
|
|
1791
|
+
++s;
|
|
1792
|
+
std::size_t bitcount = 4 * std::strlen(s);
|
|
1793
|
+
limb_type val;
|
|
1794
|
+
std::size_t limb, shift;
|
|
1795
|
+
if (bitcount > 4)
|
|
1796
|
+
bitcount -= 4;
|
|
1797
|
+
else
|
|
1798
|
+
bitcount = 0;
|
|
1799
|
+
std::size_t newsize = bitcount / (sizeof(limb_type) * CHAR_BIT) + 1;
|
|
1800
|
+
result.resize(static_cast<unsigned>(newsize), static_cast<unsigned>(newsize)); // will throw if this is a checked integer that cannot be resized
|
|
1801
|
+
std::memset(result.limbs(), 0, result.size() * sizeof(limb_type));
|
|
1802
|
+
while (*s)
|
|
1803
|
+
{
|
|
1804
|
+
if (*s >= '0' && *s <= '9')
|
|
1805
|
+
val = static_cast<unsigned>(*s - '0');
|
|
1806
|
+
else if (*s >= 'a' && *s <= 'f')
|
|
1807
|
+
val = 10u + static_cast<unsigned>(*s - 'a');
|
|
1808
|
+
else if (*s >= 'A' && *s <= 'F')
|
|
1809
|
+
val = 10u + static_cast<unsigned>(*s - 'A');
|
|
1810
|
+
else
|
|
1811
|
+
{
|
|
1812
|
+
#if defined(BOOST_NO_EXCEPTIONS)
|
|
1813
|
+
val = static_cast<unsigned>('0');
|
|
1814
|
+
#endif
|
|
1815
|
+
|
|
1816
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string."));
|
|
1817
|
+
}
|
|
1818
|
+
limb = bitcount / (sizeof(limb_type) * CHAR_BIT);
|
|
1819
|
+
shift = bitcount % (sizeof(limb_type) * CHAR_BIT);
|
|
1820
|
+
val <<= shift;
|
|
1821
|
+
if (result.size() > limb)
|
|
1822
|
+
{
|
|
1823
|
+
result.limbs()[limb] |= val;
|
|
1824
|
+
}
|
|
1825
|
+
++s;
|
|
1826
|
+
bitcount -= 4;
|
|
1827
|
+
}
|
|
1828
|
+
result.normalize();
|
|
1829
|
+
}
|
|
1830
|
+
else if (radix == 8)
|
|
1831
|
+
{
|
|
1832
|
+
while (*s == '0')
|
|
1833
|
+
++s;
|
|
1834
|
+
std::size_t bitcount = 3 * std::strlen(s);
|
|
1835
|
+
limb_type val;
|
|
1836
|
+
std::size_t limb, shift;
|
|
1837
|
+
if (bitcount > 3)
|
|
1838
|
+
bitcount -= 3;
|
|
1839
|
+
else
|
|
1840
|
+
bitcount = 0;
|
|
1841
|
+
std::size_t newsize = bitcount / (sizeof(limb_type) * CHAR_BIT) + 1;
|
|
1842
|
+
result.resize(static_cast<unsigned>(newsize), static_cast<unsigned>(newsize)); // will throw if this is a checked integer that cannot be resized
|
|
1843
|
+
std::memset(result.limbs(), 0, result.size() * sizeof(limb_type));
|
|
1844
|
+
while (*s)
|
|
1845
|
+
{
|
|
1846
|
+
if (*s >= '0' && *s <= '7')
|
|
1847
|
+
val = static_cast<unsigned>(*s - '0');
|
|
1848
|
+
else
|
|
1849
|
+
{
|
|
1850
|
+
#if defined(BOOST_NO_EXCEPTIONS)
|
|
1851
|
+
val = static_cast<unsigned>('0');
|
|
1852
|
+
#endif
|
|
1853
|
+
|
|
1854
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string."));
|
|
1855
|
+
}
|
|
1856
|
+
limb = bitcount / (sizeof(limb_type) * CHAR_BIT);
|
|
1857
|
+
shift = bitcount % (sizeof(limb_type) * CHAR_BIT);
|
|
1858
|
+
if (result.size() > limb)
|
|
1859
|
+
{
|
|
1860
|
+
result.limbs()[limb] |= (val << shift);
|
|
1861
|
+
if (shift > sizeof(limb_type) * CHAR_BIT - 3)
|
|
1862
|
+
{
|
|
1863
|
+
// Deal with the bits in val that overflow into the next limb:
|
|
1864
|
+
val >>= (sizeof(limb_type) * CHAR_BIT - shift);
|
|
1865
|
+
if (val)
|
|
1866
|
+
{
|
|
1867
|
+
// If this is the most-significant-limb, we may need to allocate an extra one for the overflow:
|
|
1868
|
+
if (limb + 1 == newsize)
|
|
1869
|
+
{
|
|
1870
|
+
result.resize(static_cast<unsigned>(newsize + 1), static_cast<unsigned>(newsize + 1));
|
|
1871
|
+
result.limbs()[limb + 1] = 0;
|
|
1872
|
+
}
|
|
1873
|
+
if (result.size() > limb + 1)
|
|
1874
|
+
{
|
|
1875
|
+
result.limbs()[limb + 1] |= val;
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
++s;
|
|
1881
|
+
bitcount -= 3;
|
|
1882
|
+
}
|
|
1883
|
+
result.normalize();
|
|
1884
|
+
}
|
|
1885
|
+
else
|
|
1886
|
+
{
|
|
1887
|
+
// Base 10, we extract blocks of size 10^9 at a time, that way
|
|
1888
|
+
// the number of multiplications is kept to a minimum:
|
|
1889
|
+
limb_type block_mult = max_block_10;
|
|
1890
|
+
while (*s)
|
|
1891
|
+
{
|
|
1892
|
+
limb_type block = 0;
|
|
1893
|
+
for (unsigned i = 0; i < digits_per_block_10; ++i)
|
|
1894
|
+
{
|
|
1895
|
+
limb_type val;
|
|
1896
|
+
if (*s >= '0' && *s <= '9')
|
|
1897
|
+
val = static_cast<limb_type>(*s - '0');
|
|
1898
|
+
else
|
|
1899
|
+
{
|
|
1900
|
+
#if defined(BOOST_NO_EXCEPTIONS)
|
|
1901
|
+
val = static_cast<unsigned>('0');
|
|
1902
|
+
#endif
|
|
1903
|
+
|
|
1904
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Unexpected character encountered in input."));
|
|
1905
|
+
}
|
|
1906
|
+
block *= 10;
|
|
1907
|
+
block += val;
|
|
1908
|
+
if (!*++s)
|
|
1909
|
+
{
|
|
1910
|
+
block_mult = block_multiplier(i);
|
|
1911
|
+
break;
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
eval_multiply(result, block_mult);
|
|
1915
|
+
eval_add(result, block);
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
if (isneg)
|
|
1920
|
+
result.negate();
|
|
1921
|
+
result.swap(*this);
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
public:
|
|
1925
|
+
cpp_int_backend& operator=(const char* s)
|
|
1926
|
+
{
|
|
1927
|
+
do_assign_string(s, trivial_tag());
|
|
1928
|
+
return *this;
|
|
1929
|
+
}
|
|
1930
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void swap(cpp_int_backend& o) noexcept
|
|
1931
|
+
{
|
|
1932
|
+
this->do_swap(o);
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
private:
|
|
1936
|
+
std::string do_get_trivial_string(std::ios_base::fmtflags f, const std::integral_constant<bool, false>&) const
|
|
1937
|
+
{
|
|
1938
|
+
using io_type = typename std::conditional<sizeof(typename base_type::local_limb_type) == 1, unsigned, typename base_type::local_limb_type>::type;
|
|
1939
|
+
if (this->sign() && (((f & std::ios_base::hex) == std::ios_base::hex) || ((f & std::ios_base::oct) == std::ios_base::oct)))
|
|
1940
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported."));
|
|
1941
|
+
std::stringstream ss;
|
|
1942
|
+
ss.flags(f & ~std::ios_base::showpos);
|
|
1943
|
+
ss << static_cast<io_type>(*this->limbs());
|
|
1944
|
+
std::string result;
|
|
1945
|
+
if (this->sign())
|
|
1946
|
+
result += '-';
|
|
1947
|
+
else if (f & std::ios_base::showpos)
|
|
1948
|
+
result += '+';
|
|
1949
|
+
result += ss.str();
|
|
1950
|
+
return result;
|
|
1951
|
+
}
|
|
1952
|
+
std::string do_get_trivial_string(std::ios_base::fmtflags f, const std::integral_constant<bool, true>&) const
|
|
1953
|
+
{
|
|
1954
|
+
// Even though we have only one limb, we can't do IO on it :-(
|
|
1955
|
+
int base = 10;
|
|
1956
|
+
if ((f & std::ios_base::oct) == std::ios_base::oct)
|
|
1957
|
+
base = 8;
|
|
1958
|
+
else if ((f & std::ios_base::hex) == std::ios_base::hex)
|
|
1959
|
+
base = 16;
|
|
1960
|
+
std::string result;
|
|
1961
|
+
|
|
1962
|
+
std::size_t Bits = sizeof(typename base_type::local_limb_type) * CHAR_BIT;
|
|
1963
|
+
|
|
1964
|
+
if (base == 8 || base == 16)
|
|
1965
|
+
{
|
|
1966
|
+
if (this->sign())
|
|
1967
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported."));
|
|
1968
|
+
limb_type shift = base == 8 ? 3 : 4;
|
|
1969
|
+
limb_type mask = static_cast<limb_type>((1u << shift) - 1);
|
|
1970
|
+
typename base_type::local_limb_type v = *this->limbs();
|
|
1971
|
+
result.assign(Bits / shift + (Bits % shift ? 1 : 0), '0');
|
|
1972
|
+
std::string::difference_type pos = static_cast<std::string::difference_type>(result.size() - 1u);
|
|
1973
|
+
char letter_a = f & std::ios_base::uppercase ? 'A' : 'a';
|
|
1974
|
+
for (std::size_t i = 0; i < Bits / shift; ++i)
|
|
1975
|
+
{
|
|
1976
|
+
char c = static_cast<char>('0' + static_cast<char>(v & mask));
|
|
1977
|
+
if (c > '9')
|
|
1978
|
+
c = static_cast<char>(c + letter_a - '9' - 1);
|
|
1979
|
+
result[static_cast<std::size_t>(pos)] = c;
|
|
1980
|
+
--pos;
|
|
1981
|
+
v >>= shift;
|
|
1982
|
+
}
|
|
1983
|
+
if (Bits % shift)
|
|
1984
|
+
{
|
|
1985
|
+
mask = static_cast<limb_type>((1u << (Bits % shift)) - 1);
|
|
1986
|
+
char c = static_cast<char>('0' + static_cast<char>(v & mask));
|
|
1987
|
+
if (c > '9')
|
|
1988
|
+
c = static_cast<char>(c + letter_a - '9');
|
|
1989
|
+
result[static_cast<std::size_t>(pos)] = c;
|
|
1990
|
+
}
|
|
1991
|
+
//
|
|
1992
|
+
// Get rid of leading zeros:
|
|
1993
|
+
//
|
|
1994
|
+
std::string::size_type n = result.find_first_not_of('0');
|
|
1995
|
+
if (!result.empty() && (n == std::string::npos))
|
|
1996
|
+
n = result.size() - 1;
|
|
1997
|
+
result.erase(0, n);
|
|
1998
|
+
if (f & std::ios_base::showbase)
|
|
1999
|
+
{
|
|
2000
|
+
const char* pp = base == 8 ? "0" : (f & std::ios_base::uppercase) ? "0X" : "0x";
|
|
2001
|
+
result.insert(static_cast<std::string::size_type>(0), pp);
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
else
|
|
2005
|
+
{
|
|
2006
|
+
result.assign(Bits / 3 + 1, '0');
|
|
2007
|
+
std::string::difference_type pos = static_cast<std::string::difference_type>(result.size() - 1u);
|
|
2008
|
+
typename base_type::local_limb_type v(*this->limbs());
|
|
2009
|
+
bool neg = false;
|
|
2010
|
+
if (this->sign())
|
|
2011
|
+
{
|
|
2012
|
+
neg = true;
|
|
2013
|
+
}
|
|
2014
|
+
while (v)
|
|
2015
|
+
{
|
|
2016
|
+
result[static_cast<std::string::size_type>(pos)] = static_cast<char>(static_cast<char>(v % 10) + '0');
|
|
2017
|
+
--pos;
|
|
2018
|
+
v /= 10;
|
|
2019
|
+
}
|
|
2020
|
+
std::string::size_type n = result.find_first_not_of('0');
|
|
2021
|
+
result.erase(0, n);
|
|
2022
|
+
if (result.empty())
|
|
2023
|
+
result = "0";
|
|
2024
|
+
if (neg)
|
|
2025
|
+
result.insert(static_cast<std::string::size_type>(0), 1, '-');
|
|
2026
|
+
else if (f & std::ios_base::showpos)
|
|
2027
|
+
result.insert(static_cast<std::string::size_type>(0), 1, '+');
|
|
2028
|
+
}
|
|
2029
|
+
return result;
|
|
2030
|
+
}
|
|
2031
|
+
std::string do_get_string(std::ios_base::fmtflags f, const std::integral_constant<bool, true>&) const
|
|
2032
|
+
{
|
|
2033
|
+
#ifdef BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO
|
|
2034
|
+
return do_get_trivial_string(f, std::integral_constant<bool, std::is_same<typename base_type::local_limb_type, double_limb_type>::value>());
|
|
2035
|
+
#else
|
|
2036
|
+
return do_get_trivial_string(f, std::integral_constant<bool, false>());
|
|
2037
|
+
#endif
|
|
2038
|
+
}
|
|
2039
|
+
std::string do_get_string(std::ios_base::fmtflags f, const std::integral_constant<bool, false>&) const
|
|
2040
|
+
{
|
|
2041
|
+
using default_ops::eval_get_sign;
|
|
2042
|
+
int base = 10;
|
|
2043
|
+
if ((f & std::ios_base::oct) == std::ios_base::oct)
|
|
2044
|
+
base = 8;
|
|
2045
|
+
else if ((f & std::ios_base::hex) == std::ios_base::hex)
|
|
2046
|
+
base = 16;
|
|
2047
|
+
std::string result;
|
|
2048
|
+
|
|
2049
|
+
std::size_t Bits = this->size() * base_type::limb_bits;
|
|
2050
|
+
|
|
2051
|
+
if (base == 8 || base == 16)
|
|
2052
|
+
{
|
|
2053
|
+
if (this->sign())
|
|
2054
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported."));
|
|
2055
|
+
limb_type shift = base == 8 ? 3 : 4;
|
|
2056
|
+
limb_type mask = static_cast<limb_type>((1u << shift) - 1);
|
|
2057
|
+
cpp_int_backend t(*this);
|
|
2058
|
+
result.assign(Bits / shift + ((Bits % shift) ? 1 : 0), '0');
|
|
2059
|
+
std::string::difference_type pos = static_cast<std::string::difference_type>(result.size() - 1u);
|
|
2060
|
+
char letter_a = f & std::ios_base::uppercase ? 'A' : 'a';
|
|
2061
|
+
for (std::size_t i = 0; i < Bits / shift; ++i)
|
|
2062
|
+
{
|
|
2063
|
+
char c = static_cast<char>('0' + static_cast<char>(t.limbs()[0] & mask));
|
|
2064
|
+
if (c > '9')
|
|
2065
|
+
c = static_cast<char>(c + letter_a - '9' - 1);
|
|
2066
|
+
result[static_cast<std::size_t>(pos)] = c;
|
|
2067
|
+
--pos;
|
|
2068
|
+
eval_right_shift(t, shift);
|
|
2069
|
+
}
|
|
2070
|
+
if (Bits % shift)
|
|
2071
|
+
{
|
|
2072
|
+
mask = static_cast<limb_type>((1u << (Bits % shift)) - 1);
|
|
2073
|
+
char c = static_cast<char>('0' + static_cast<char>(t.limbs()[0] & mask));
|
|
2074
|
+
if (c > '9')
|
|
2075
|
+
c = static_cast<char>(c + letter_a - '9');
|
|
2076
|
+
result[static_cast<std::size_t>(pos)] = c;
|
|
2077
|
+
}
|
|
2078
|
+
//
|
|
2079
|
+
// Get rid of leading zeros:
|
|
2080
|
+
//
|
|
2081
|
+
std::string::size_type n = result.find_first_not_of('0');
|
|
2082
|
+
if (!result.empty() && (n == std::string::npos))
|
|
2083
|
+
n = result.size() - 1;
|
|
2084
|
+
result.erase(0, n);
|
|
2085
|
+
if (f & std::ios_base::showbase)
|
|
2086
|
+
{
|
|
2087
|
+
const char* pp = base == 8 ? "0" : (f & std::ios_base::uppercase) ? "0X" : "0x";
|
|
2088
|
+
result.insert(static_cast<std::string::size_type>(0), pp);
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
else
|
|
2092
|
+
{
|
|
2093
|
+
result.assign(Bits / 3 + 1, '0');
|
|
2094
|
+
std::string::difference_type pos = static_cast<std::string::difference_type>(result.size() - 1u);
|
|
2095
|
+
cpp_int_backend t(*this);
|
|
2096
|
+
cpp_int_backend r;
|
|
2097
|
+
bool neg = false;
|
|
2098
|
+
if (t.sign())
|
|
2099
|
+
{
|
|
2100
|
+
t.negate();
|
|
2101
|
+
neg = true;
|
|
2102
|
+
}
|
|
2103
|
+
if (this->size() == 1)
|
|
2104
|
+
{
|
|
2105
|
+
result = std::to_string(t.limbs()[0]);
|
|
2106
|
+
}
|
|
2107
|
+
else
|
|
2108
|
+
{
|
|
2109
|
+
cpp_int_backend block10;
|
|
2110
|
+
block10 = max_block_10;
|
|
2111
|
+
while (eval_get_sign(t) != 0)
|
|
2112
|
+
{
|
|
2113
|
+
cpp_int_backend t2;
|
|
2114
|
+
divide_unsigned_helper(&t2, t, block10, r);
|
|
2115
|
+
t = t2;
|
|
2116
|
+
limb_type v = r.limbs()[0];
|
|
2117
|
+
for (std::size_t i = 0; i < digits_per_block_10; ++i)
|
|
2118
|
+
{
|
|
2119
|
+
char c = static_cast<char>('0' + static_cast<char>(v % 10));
|
|
2120
|
+
v /= 10;
|
|
2121
|
+
result[static_cast<std::size_t>(pos)] = c;
|
|
2122
|
+
if (pos-- == 0u)
|
|
2123
|
+
break;
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
std::string::size_type n = result.find_first_not_of('0');
|
|
2128
|
+
result.erase(0, n);
|
|
2129
|
+
if (result.empty())
|
|
2130
|
+
result = std::string(static_cast<std::size_t>(1u), '0');
|
|
2131
|
+
if (neg)
|
|
2132
|
+
result.insert(static_cast<std::string::size_type>(0), 1, '-');
|
|
2133
|
+
else if (f & std::ios_base::showpos)
|
|
2134
|
+
result.insert(static_cast<std::string::size_type>(0), 1, '+');
|
|
2135
|
+
}
|
|
2136
|
+
return result;
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
public:
|
|
2140
|
+
std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f) const
|
|
2141
|
+
{
|
|
2142
|
+
return do_get_string(f, trivial_tag());
|
|
2143
|
+
}
|
|
2144
|
+
|
|
2145
|
+
private:
|
|
2146
|
+
template <class Container>
|
|
2147
|
+
void construct_from_container(const Container& c, const std::integral_constant<bool, false>&)
|
|
2148
|
+
{
|
|
2149
|
+
//
|
|
2150
|
+
// We assume that c is a sequence of (unsigned) bytes with the most significant byte first:
|
|
2151
|
+
//
|
|
2152
|
+
std::size_t newsize = static_cast<unsigned>(c.size() / sizeof(limb_type));
|
|
2153
|
+
if (c.size() % sizeof(limb_type))
|
|
2154
|
+
{
|
|
2155
|
+
++newsize;
|
|
2156
|
+
}
|
|
2157
|
+
if (newsize)
|
|
2158
|
+
{
|
|
2159
|
+
this->resize(newsize, newsize); // May throw
|
|
2160
|
+
std::memset(this->limbs(), 0, this->size());
|
|
2161
|
+
typename Container::const_iterator i(c.begin()), j(c.end());
|
|
2162
|
+
std::size_t byte_location = static_cast<unsigned>(c.size() - 1);
|
|
2163
|
+
while (i != j)
|
|
2164
|
+
{
|
|
2165
|
+
std::size_t limb = byte_location / sizeof(limb_type);
|
|
2166
|
+
std::size_t shift = (byte_location % sizeof(limb_type)) * CHAR_BIT;
|
|
2167
|
+
if (this->size() > limb)
|
|
2168
|
+
this->limbs()[limb] |= static_cast<limb_type>(static_cast<unsigned char>(*i)) << shift;
|
|
2169
|
+
++i;
|
|
2170
|
+
--byte_location;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
template <class Container>
|
|
2175
|
+
BOOST_MP_CXX14_CONSTEXPR void construct_from_container(const Container& c, const std::integral_constant<bool, true>&)
|
|
2176
|
+
{
|
|
2177
|
+
//
|
|
2178
|
+
// We assume that c is a sequence of (unsigned) bytes with the most significant byte first:
|
|
2179
|
+
//
|
|
2180
|
+
using local_limb_type = typename base_type::local_limb_type;
|
|
2181
|
+
*this->limbs() = 0;
|
|
2182
|
+
if (c.size())
|
|
2183
|
+
{
|
|
2184
|
+
typename Container::const_iterator i(c.begin()), j(c.end());
|
|
2185
|
+
std::size_t byte_location = static_cast<unsigned>(c.size() - 1);
|
|
2186
|
+
while (i != j)
|
|
2187
|
+
{
|
|
2188
|
+
std::size_t limb = byte_location / sizeof(local_limb_type);
|
|
2189
|
+
std::size_t shift = (byte_location % sizeof(local_limb_type)) * CHAR_BIT;
|
|
2190
|
+
if (limb == 0)
|
|
2191
|
+
this->limbs()[0] |= static_cast<limb_type>(static_cast<unsigned char>(*i)) << shift;
|
|
2192
|
+
++i;
|
|
2193
|
+
--byte_location;
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
public:
|
|
2199
|
+
template <class Container>
|
|
2200
|
+
BOOST_MP_CXX14_CONSTEXPR cpp_int_backend(const Container& c, typename std::enable_if<boost::multiprecision::detail::is_byte_container<Container>::value>::type const* = nullptr)
|
|
2201
|
+
{
|
|
2202
|
+
//
|
|
2203
|
+
// We assume that c is a sequence of (unsigned) bytes with the most significant byte first:
|
|
2204
|
+
//
|
|
2205
|
+
construct_from_container(c, trivial_tag());
|
|
2206
|
+
}
|
|
2207
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
2208
|
+
BOOST_MP_CXX14_CONSTEXPR int compare_imp(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const std::integral_constant<bool, false>&, const std::integral_constant<bool, false>&) const noexcept
|
|
2209
|
+
{
|
|
2210
|
+
if (this->sign() != o.sign())
|
|
2211
|
+
return this->sign() ? -1 : 1;
|
|
2212
|
+
|
|
2213
|
+
// Only do the compare if the same sign:
|
|
2214
|
+
int result = compare_unsigned(o);
|
|
2215
|
+
|
|
2216
|
+
if (this->sign())
|
|
2217
|
+
result = -result;
|
|
2218
|
+
return result;
|
|
2219
|
+
}
|
|
2220
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
2221
|
+
BOOST_MP_CXX14_CONSTEXPR int compare_imp(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const std::integral_constant<bool, true>&, const std::integral_constant<bool, false>&) const
|
|
2222
|
+
{
|
|
2223
|
+
cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> t(*this);
|
|
2224
|
+
return t.compare(o);
|
|
2225
|
+
}
|
|
2226
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
2227
|
+
BOOST_MP_CXX14_CONSTEXPR int compare_imp(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const std::integral_constant<bool, false>&, const std::integral_constant<bool, true>&) const
|
|
2228
|
+
{
|
|
2229
|
+
cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> t(o);
|
|
2230
|
+
return compare(t);
|
|
2231
|
+
}
|
|
2232
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
2233
|
+
BOOST_MP_CXX14_CONSTEXPR int compare_imp(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const std::integral_constant<bool, true>&, const std::integral_constant<bool, true>&) const noexcept
|
|
2234
|
+
{
|
|
2235
|
+
if (this->sign())
|
|
2236
|
+
{
|
|
2237
|
+
if (o.sign())
|
|
2238
|
+
{
|
|
2239
|
+
return *this->limbs() < *o.limbs() ? 1 : (*this->limbs() > *o.limbs() ? -1 : 0);
|
|
2240
|
+
}
|
|
2241
|
+
else
|
|
2242
|
+
return -1;
|
|
2243
|
+
}
|
|
2244
|
+
else
|
|
2245
|
+
{
|
|
2246
|
+
if (o.sign())
|
|
2247
|
+
return 1;
|
|
2248
|
+
return *this->limbs() < *o.limbs() ? -1 : (*this->limbs() > *o.limbs() ? 1 : 0);
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
2252
|
+
BOOST_MP_CXX14_CONSTEXPR int compare(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) const noexcept
|
|
2253
|
+
{
|
|
2254
|
+
using t1 = std::integral_constant<bool, is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value> ;
|
|
2255
|
+
using t2 = std::integral_constant<bool, is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>;
|
|
2256
|
+
return compare_imp(o, t1(), t2());
|
|
2257
|
+
}
|
|
2258
|
+
template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
2259
|
+
BOOST_MP_CXX14_CONSTEXPR int compare_unsigned(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) const noexcept
|
|
2260
|
+
{
|
|
2261
|
+
if (this->size() != o.size())
|
|
2262
|
+
{
|
|
2263
|
+
return this->size() > o.size() ? 1 : -1;
|
|
2264
|
+
}
|
|
2265
|
+
typename base_type::const_limb_pointer pa = this->limbs();
|
|
2266
|
+
typename base_type::const_limb_pointer pb = o.limbs();
|
|
2267
|
+
for (std::ptrdiff_t i = static_cast<std::ptrdiff_t>(static_cast<std::ptrdiff_t>(this->size()) - 1); i >= 0; --i)
|
|
2268
|
+
{
|
|
2269
|
+
if (pa[i] != pb[i])
|
|
2270
|
+
return pa[i] > pb[i] ? 1 : -1;
|
|
2271
|
+
}
|
|
2272
|
+
return 0;
|
|
2273
|
+
}
|
|
2274
|
+
template <class Arithmetic>
|
|
2275
|
+
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_arithmetic<Arithmetic>::value, int>::type compare(Arithmetic i) const
|
|
2276
|
+
{
|
|
2277
|
+
// braindead version:
|
|
2278
|
+
cpp_int_backend t;
|
|
2279
|
+
t = i;
|
|
2280
|
+
return compare(t);
|
|
2281
|
+
}
|
|
2282
|
+
};
|
|
2283
|
+
|
|
2284
|
+
} // namespace backends
|
|
2285
|
+
|
|
2286
|
+
namespace default_ops {
|
|
2287
|
+
|
|
2288
|
+
template <class Backend>
|
|
2289
|
+
struct double_precision_type;
|
|
2290
|
+
|
|
2291
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
|
|
2292
|
+
struct double_precision_type<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
|
|
2293
|
+
{
|
|
2294
|
+
using type = typename std::conditional<
|
|
2295
|
+
backends::is_fixed_precision<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
|
|
2296
|
+
backends::cpp_int_backend<
|
|
2297
|
+
(std::is_void<Allocator>::value ? 2 * backends::max_precision<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value
|
|
2298
|
+
: MinBits),
|
|
2299
|
+
2 * backends::max_precision<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
|
|
2300
|
+
SignType,
|
|
2301
|
+
Checked,
|
|
2302
|
+
Allocator>,
|
|
2303
|
+
backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::type;
|
|
2304
|
+
};
|
|
2305
|
+
|
|
2306
|
+
} // namespace default_ops
|
|
2307
|
+
|
|
2308
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
|
|
2309
|
+
struct is_equivalent_number_type<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, backends::cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >
|
|
2310
|
+
: public std::integral_constant<bool, std::numeric_limits<number<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, et_on> >::digits == std::numeric_limits<number<backends::cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>, et_on> >::digits>{};
|
|
2311
|
+
|
|
2312
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
|
|
2313
|
+
struct number_category<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> > : public std::integral_constant<int, number_kind_integer>
|
|
2314
|
+
{};
|
|
2315
|
+
|
|
2316
|
+
#ifdef BOOST_HAS_INT128
|
|
2317
|
+
|
|
2318
|
+
namespace detail {
|
|
2319
|
+
|
|
2320
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
|
|
2321
|
+
struct is_convertible_arithmetic<int128_type, backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
|
|
2322
|
+
{
|
|
2323
|
+
static constexpr bool value = true;
|
|
2324
|
+
};
|
|
2325
|
+
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
|
|
2326
|
+
struct is_convertible_arithmetic<uint128_type, backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
|
|
2327
|
+
{
|
|
2328
|
+
static constexpr bool value = true;
|
|
2329
|
+
};
|
|
2330
|
+
|
|
2331
|
+
}
|
|
2332
|
+
|
|
2333
|
+
#endif
|
|
2334
|
+
|
|
2335
|
+
#if defined(__GNUC__) && !defined(__clang__)
|
|
2336
|
+
// see https://github.com/boostorg/multiprecision/issues/413
|
|
2337
|
+
// and https://github.com/boostorg/multiprecision/issues/431
|
|
2338
|
+
#pragma GCC diagnostic pop
|
|
2339
|
+
#endif
|
|
2340
|
+
#ifdef BOOST_MSVC
|
|
2341
|
+
#pragma warning(pop)
|
|
2342
|
+
#endif
|
|
2343
|
+
|
|
2344
|
+
}} // namespace boost::multiprecision
|
|
2345
|
+
|
|
2346
|
+
//
|
|
2347
|
+
// Last of all we include the implementations of all the eval_* non member functions:
|
|
2348
|
+
//
|
|
2349
|
+
#include <boost/multiprecision/cpp_int/limits.hpp>
|
|
2350
|
+
#include <boost/multiprecision/cpp_int/comparison.hpp>
|
|
2351
|
+
#include <boost/multiprecision/cpp_int/add.hpp>
|
|
2352
|
+
#include <boost/multiprecision/cpp_int/multiply.hpp>
|
|
2353
|
+
#include <boost/multiprecision/cpp_int/divide.hpp>
|
|
2354
|
+
#include <boost/multiprecision/cpp_int/bitwise.hpp>
|
|
2355
|
+
#include <boost/multiprecision/cpp_int/misc.hpp>
|
|
2356
|
+
#include <boost/multiprecision/cpp_int/literals.hpp>
|
|
2357
|
+
#include <boost/multiprecision/cpp_int/serialize.hpp>
|
|
2358
|
+
#include <boost/multiprecision/cpp_int/import_export.hpp>
|
|
2359
|
+
|
|
2360
|
+
#endif
|