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.
Files changed (537) hide show
  1. mqt/core/__init__.py +89 -0
  2. mqt/core/__main__.py +55 -0
  3. mqt/core/_commands.py +52 -0
  4. mqt/core/_compat/__init__.py +11 -0
  5. mqt/core/_compat/typing.py +29 -0
  6. mqt/core/_version.py +34 -0
  7. mqt/core/_version.pyi +12 -0
  8. mqt/core/bin/mqt-core-algorithms.dll +0 -0
  9. mqt/core/bin/mqt-core-circuit-optimizer.dll +0 -0
  10. mqt/core/bin/mqt-core-dd.dll +0 -0
  11. mqt/core/bin/mqt-core-ds.dll +0 -0
  12. mqt/core/bin/mqt-core-fomac.dll +0 -0
  13. mqt/core/bin/mqt-core-ir.dll +0 -0
  14. mqt/core/bin/mqt-core-na-fomac.dll +0 -0
  15. mqt/core/bin/mqt-core-na.dll +0 -0
  16. mqt/core/bin/mqt-core-qasm.dll +0 -0
  17. mqt/core/bin/mqt-core-qdmi-driver.dll +0 -0
  18. mqt/core/bin/mqt-core-qdmi-na-device.dll +0 -0
  19. mqt/core/bin/mqt-core-zx.dll +0 -0
  20. mqt/core/dd.cp314t-win_amd64.pyd +0 -0
  21. mqt/core/dd.pyi +1016 -0
  22. mqt/core/dd_evaluation.py +368 -0
  23. mqt/core/fomac.cp314t-win_amd64.pyd +0 -0
  24. mqt/core/fomac.pyi +125 -0
  25. mqt/core/include/mqt-core/algorithms/BernsteinVazirani.hpp +39 -0
  26. mqt/core/include/mqt-core/algorithms/GHZState.hpp +18 -0
  27. mqt/core/include/mqt-core/algorithms/Grover.hpp +33 -0
  28. mqt/core/include/mqt-core/algorithms/QFT.hpp +21 -0
  29. mqt/core/include/mqt-core/algorithms/QPE.hpp +30 -0
  30. mqt/core/include/mqt-core/algorithms/RandomCliffordCircuit.hpp +22 -0
  31. mqt/core/include/mqt-core/algorithms/StatePreparation.hpp +43 -0
  32. mqt/core/include/mqt-core/algorithms/WState.hpp +18 -0
  33. mqt/core/include/mqt-core/algorithms/mqt_core_algorithms_export.h +43 -0
  34. mqt/core/include/mqt-core/boost/config/abi/borland_prefix.hpp +27 -0
  35. mqt/core/include/mqt-core/boost/config/abi/borland_suffix.hpp +12 -0
  36. mqt/core/include/mqt-core/boost/config/abi/msvc_prefix.hpp +22 -0
  37. mqt/core/include/mqt-core/boost/config/abi/msvc_suffix.hpp +8 -0
  38. mqt/core/include/mqt-core/boost/config/abi_prefix.hpp +25 -0
  39. mqt/core/include/mqt-core/boost/config/abi_suffix.hpp +25 -0
  40. mqt/core/include/mqt-core/boost/config/assert_cxx03.hpp +211 -0
  41. mqt/core/include/mqt-core/boost/config/assert_cxx11.hpp +212 -0
  42. mqt/core/include/mqt-core/boost/config/assert_cxx14.hpp +47 -0
  43. mqt/core/include/mqt-core/boost/config/assert_cxx17.hpp +65 -0
  44. mqt/core/include/mqt-core/boost/config/assert_cxx20.hpp +59 -0
  45. mqt/core/include/mqt-core/boost/config/assert_cxx23.hpp +41 -0
  46. mqt/core/include/mqt-core/boost/config/assert_cxx98.hpp +23 -0
  47. mqt/core/include/mqt-core/boost/config/auto_link.hpp +525 -0
  48. mqt/core/include/mqt-core/boost/config/compiler/borland.hpp +342 -0
  49. mqt/core/include/mqt-core/boost/config/compiler/clang.hpp +370 -0
  50. mqt/core/include/mqt-core/boost/config/compiler/clang_version.hpp +89 -0
  51. mqt/core/include/mqt-core/boost/config/compiler/codegear.hpp +389 -0
  52. mqt/core/include/mqt-core/boost/config/compiler/comeau.hpp +59 -0
  53. mqt/core/include/mqt-core/boost/config/compiler/common_edg.hpp +185 -0
  54. mqt/core/include/mqt-core/boost/config/compiler/compaq_cxx.hpp +19 -0
  55. mqt/core/include/mqt-core/boost/config/compiler/cray.hpp +446 -0
  56. mqt/core/include/mqt-core/boost/config/compiler/diab.hpp +26 -0
  57. mqt/core/include/mqt-core/boost/config/compiler/digitalmars.hpp +146 -0
  58. mqt/core/include/mqt-core/boost/config/compiler/gcc.hpp +386 -0
  59. mqt/core/include/mqt-core/boost/config/compiler/gcc_xml.hpp +115 -0
  60. mqt/core/include/mqt-core/boost/config/compiler/greenhills.hpp +28 -0
  61. mqt/core/include/mqt-core/boost/config/compiler/hp_acc.hpp +153 -0
  62. mqt/core/include/mqt-core/boost/config/compiler/intel.hpp +577 -0
  63. mqt/core/include/mqt-core/boost/config/compiler/kai.hpp +33 -0
  64. mqt/core/include/mqt-core/boost/config/compiler/metrowerks.hpp +201 -0
  65. mqt/core/include/mqt-core/boost/config/compiler/mpw.hpp +143 -0
  66. mqt/core/include/mqt-core/boost/config/compiler/nvcc.hpp +64 -0
  67. mqt/core/include/mqt-core/boost/config/compiler/pathscale.hpp +141 -0
  68. mqt/core/include/mqt-core/boost/config/compiler/pgi.hpp +23 -0
  69. mqt/core/include/mqt-core/boost/config/compiler/sgi_mipspro.hpp +29 -0
  70. mqt/core/include/mqt-core/boost/config/compiler/sunpro_cc.hpp +225 -0
  71. mqt/core/include/mqt-core/boost/config/compiler/vacpp.hpp +189 -0
  72. mqt/core/include/mqt-core/boost/config/compiler/visualc.hpp +398 -0
  73. mqt/core/include/mqt-core/boost/config/compiler/xlcpp.hpp +303 -0
  74. mqt/core/include/mqt-core/boost/config/compiler/xlcpp_zos.hpp +174 -0
  75. mqt/core/include/mqt-core/boost/config/detail/cxx_composite.hpp +218 -0
  76. mqt/core/include/mqt-core/boost/config/detail/posix_features.hpp +95 -0
  77. mqt/core/include/mqt-core/boost/config/detail/select_compiler_config.hpp +157 -0
  78. mqt/core/include/mqt-core/boost/config/detail/select_platform_config.hpp +147 -0
  79. mqt/core/include/mqt-core/boost/config/detail/select_stdlib_config.hpp +121 -0
  80. mqt/core/include/mqt-core/boost/config/detail/suffix.hpp +1334 -0
  81. mqt/core/include/mqt-core/boost/config/header_deprecated.hpp +26 -0
  82. mqt/core/include/mqt-core/boost/config/helper_macros.hpp +37 -0
  83. mqt/core/include/mqt-core/boost/config/no_tr1/cmath.hpp +28 -0
  84. mqt/core/include/mqt-core/boost/config/no_tr1/complex.hpp +28 -0
  85. mqt/core/include/mqt-core/boost/config/no_tr1/functional.hpp +28 -0
  86. mqt/core/include/mqt-core/boost/config/no_tr1/memory.hpp +28 -0
  87. mqt/core/include/mqt-core/boost/config/no_tr1/utility.hpp +28 -0
  88. mqt/core/include/mqt-core/boost/config/platform/aix.hpp +33 -0
  89. mqt/core/include/mqt-core/boost/config/platform/amigaos.hpp +15 -0
  90. mqt/core/include/mqt-core/boost/config/platform/beos.hpp +26 -0
  91. mqt/core/include/mqt-core/boost/config/platform/bsd.hpp +83 -0
  92. mqt/core/include/mqt-core/boost/config/platform/cloudabi.hpp +18 -0
  93. mqt/core/include/mqt-core/boost/config/platform/cray.hpp +18 -0
  94. mqt/core/include/mqt-core/boost/config/platform/cygwin.hpp +71 -0
  95. mqt/core/include/mqt-core/boost/config/platform/haiku.hpp +31 -0
  96. mqt/core/include/mqt-core/boost/config/platform/hpux.hpp +87 -0
  97. mqt/core/include/mqt-core/boost/config/platform/irix.hpp +31 -0
  98. mqt/core/include/mqt-core/boost/config/platform/linux.hpp +106 -0
  99. mqt/core/include/mqt-core/boost/config/platform/macos.hpp +87 -0
  100. mqt/core/include/mqt-core/boost/config/platform/qnxnto.hpp +31 -0
  101. mqt/core/include/mqt-core/boost/config/platform/solaris.hpp +31 -0
  102. mqt/core/include/mqt-core/boost/config/platform/symbian.hpp +97 -0
  103. mqt/core/include/mqt-core/boost/config/platform/vms.hpp +25 -0
  104. mqt/core/include/mqt-core/boost/config/platform/vxworks.hpp +422 -0
  105. mqt/core/include/mqt-core/boost/config/platform/wasm.hpp +23 -0
  106. mqt/core/include/mqt-core/boost/config/platform/win32.hpp +90 -0
  107. mqt/core/include/mqt-core/boost/config/platform/zos.hpp +32 -0
  108. mqt/core/include/mqt-core/boost/config/pragma_message.hpp +31 -0
  109. mqt/core/include/mqt-core/boost/config/requires_threads.hpp +92 -0
  110. mqt/core/include/mqt-core/boost/config/stdlib/dinkumware.hpp +324 -0
  111. mqt/core/include/mqt-core/boost/config/stdlib/libcomo.hpp +93 -0
  112. mqt/core/include/mqt-core/boost/config/stdlib/libcpp.hpp +180 -0
  113. mqt/core/include/mqt-core/boost/config/stdlib/libstdcpp3.hpp +482 -0
  114. mqt/core/include/mqt-core/boost/config/stdlib/modena.hpp +79 -0
  115. mqt/core/include/mqt-core/boost/config/stdlib/msl.hpp +98 -0
  116. mqt/core/include/mqt-core/boost/config/stdlib/roguewave.hpp +208 -0
  117. mqt/core/include/mqt-core/boost/config/stdlib/sgi.hpp +168 -0
  118. mqt/core/include/mqt-core/boost/config/stdlib/stlport.hpp +258 -0
  119. mqt/core/include/mqt-core/boost/config/stdlib/vacpp.hpp +74 -0
  120. mqt/core/include/mqt-core/boost/config/stdlib/xlcpp_zos.hpp +61 -0
  121. mqt/core/include/mqt-core/boost/config/user.hpp +133 -0
  122. mqt/core/include/mqt-core/boost/config/warning_disable.hpp +47 -0
  123. mqt/core/include/mqt-core/boost/config/workaround.hpp +305 -0
  124. mqt/core/include/mqt-core/boost/config.hpp +67 -0
  125. mqt/core/include/mqt-core/boost/cstdint.hpp +556 -0
  126. mqt/core/include/mqt-core/boost/cxx11_char_types.hpp +70 -0
  127. mqt/core/include/mqt-core/boost/detail/workaround.hpp +10 -0
  128. mqt/core/include/mqt-core/boost/limits.hpp +146 -0
  129. mqt/core/include/mqt-core/boost/multiprecision/complex128.hpp +24 -0
  130. mqt/core/include/mqt-core/boost/multiprecision/complex_adaptor.hpp +1046 -0
  131. mqt/core/include/mqt-core/boost/multiprecision/concepts/mp_number_archetypes.hpp +257 -0
  132. mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float/io.hpp +698 -0
  133. mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float/transcendental.hpp +157 -0
  134. mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float.hpp +2297 -0
  135. mqt/core/include/mqt-core/boost/multiprecision/cpp_complex.hpp +12 -0
  136. mqt/core/include/mqt-core/boost/multiprecision/cpp_dec_float.hpp +3690 -0
  137. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/add.hpp +368 -0
  138. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/add_unsigned.hpp +387 -0
  139. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/bitwise.hpp +889 -0
  140. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/checked.hpp +178 -0
  141. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/comparison.hpp +374 -0
  142. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/cpp_int_config.hpp +161 -0
  143. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/divide.hpp +703 -0
  144. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/import_export.hpp +248 -0
  145. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/intel_intrinsics.hpp +138 -0
  146. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/limits.hpp +282 -0
  147. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/literals.hpp +295 -0
  148. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/misc.hpp +1457 -0
  149. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/multiply.hpp +848 -0
  150. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/serialize.hpp +211 -0
  151. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/value_pack.hpp +42 -0
  152. mqt/core/include/mqt-core/boost/multiprecision/cpp_int.hpp +2360 -0
  153. mqt/core/include/mqt-core/boost/multiprecision/debug_adaptor.hpp +760 -0
  154. mqt/core/include/mqt-core/boost/multiprecision/detail/assert.hpp +29 -0
  155. mqt/core/include/mqt-core/boost/multiprecision/detail/atomic.hpp +62 -0
  156. mqt/core/include/mqt-core/boost/multiprecision/detail/bitscan.hpp +317 -0
  157. mqt/core/include/mqt-core/boost/multiprecision/detail/check_cpp11_config.hpp +64 -0
  158. mqt/core/include/mqt-core/boost/multiprecision/detail/constexpr.hpp +88 -0
  159. mqt/core/include/mqt-core/boost/multiprecision/detail/default_ops.hpp +4052 -0
  160. mqt/core/include/mqt-core/boost/multiprecision/detail/digits.hpp +49 -0
  161. mqt/core/include/mqt-core/boost/multiprecision/detail/dynamic_array.hpp +44 -0
  162. mqt/core/include/mqt-core/boost/multiprecision/detail/empty_value.hpp +87 -0
  163. mqt/core/include/mqt-core/boost/multiprecision/detail/endian.hpp +35 -0
  164. mqt/core/include/mqt-core/boost/multiprecision/detail/et_ops.hpp +1831 -0
  165. mqt/core/include/mqt-core/boost/multiprecision/detail/float128_functions.hpp +95 -0
  166. mqt/core/include/mqt-core/boost/multiprecision/detail/float_string_cvt.hpp +333 -0
  167. mqt/core/include/mqt-core/boost/multiprecision/detail/fpclassify.hpp +101 -0
  168. mqt/core/include/mqt-core/boost/multiprecision/detail/functions/constants.hpp +288 -0
  169. mqt/core/include/mqt-core/boost/multiprecision/detail/functions/pow.hpp +905 -0
  170. mqt/core/include/mqt-core/boost/multiprecision/detail/functions/trig.hpp +1058 -0
  171. mqt/core/include/mqt-core/boost/multiprecision/detail/functions/trunc.hpp +82 -0
  172. mqt/core/include/mqt-core/boost/multiprecision/detail/generic_interconvert.hpp +687 -0
  173. mqt/core/include/mqt-core/boost/multiprecision/detail/hash.hpp +56 -0
  174. mqt/core/include/mqt-core/boost/multiprecision/detail/integer_ops.hpp +474 -0
  175. mqt/core/include/mqt-core/boost/multiprecision/detail/itos.hpp +39 -0
  176. mqt/core/include/mqt-core/boost/multiprecision/detail/min_max.hpp +106 -0
  177. mqt/core/include/mqt-core/boost/multiprecision/detail/no_et_ops.hpp +661 -0
  178. mqt/core/include/mqt-core/boost/multiprecision/detail/no_exceptions_support.hpp +55 -0
  179. mqt/core/include/mqt-core/boost/multiprecision/detail/number_base.hpp +1656 -0
  180. mqt/core/include/mqt-core/boost/multiprecision/detail/number_compare.hpp +848 -0
  181. mqt/core/include/mqt-core/boost/multiprecision/detail/precision.hpp +313 -0
  182. mqt/core/include/mqt-core/boost/multiprecision/detail/rebind.hpp +19 -0
  183. mqt/core/include/mqt-core/boost/multiprecision/detail/standalone_config.hpp +148 -0
  184. mqt/core/include/mqt-core/boost/multiprecision/detail/static_array.hpp +42 -0
  185. mqt/core/include/mqt-core/boost/multiprecision/detail/string_helpers.hpp +48 -0
  186. mqt/core/include/mqt-core/boost/multiprecision/detail/tables.hpp +80 -0
  187. mqt/core/include/mqt-core/boost/multiprecision/detail/ublas_interop.hpp +75 -0
  188. mqt/core/include/mqt-core/boost/multiprecision/detail/uniform_int_distribution.hpp +212 -0
  189. mqt/core/include/mqt-core/boost/multiprecision/detail/utype_helper.hpp +374 -0
  190. mqt/core/include/mqt-core/boost/multiprecision/eigen.hpp +248 -0
  191. mqt/core/include/mqt-core/boost/multiprecision/float128.hpp +920 -0
  192. mqt/core/include/mqt-core/boost/multiprecision/fwd.hpp +268 -0
  193. mqt/core/include/mqt-core/boost/multiprecision/gmp.hpp +4060 -0
  194. mqt/core/include/mqt-core/boost/multiprecision/integer.hpp +363 -0
  195. mqt/core/include/mqt-core/boost/multiprecision/logged_adaptor.hpp +834 -0
  196. mqt/core/include/mqt-core/boost/multiprecision/miller_rabin.hpp +221 -0
  197. mqt/core/include/mqt-core/boost/multiprecision/mpc.hpp +1721 -0
  198. mqt/core/include/mqt-core/boost/multiprecision/mpfi.hpp +2559 -0
  199. mqt/core/include/mqt-core/boost/multiprecision/mpfr.hpp +3644 -0
  200. mqt/core/include/mqt-core/boost/multiprecision/number.hpp +2500 -0
  201. mqt/core/include/mqt-core/boost/multiprecision/random.hpp +23 -0
  202. mqt/core/include/mqt-core/boost/multiprecision/rational_adaptor.hpp +1289 -0
  203. mqt/core/include/mqt-core/boost/multiprecision/tommath.hpp +1034 -0
  204. mqt/core/include/mqt-core/boost/multiprecision/traits/explicit_conversion.hpp +67 -0
  205. mqt/core/include/mqt-core/boost/multiprecision/traits/extract_exponent_type.hpp +28 -0
  206. mqt/core/include/mqt-core/boost/multiprecision/traits/is_backend.hpp +91 -0
  207. mqt/core/include/mqt-core/boost/multiprecision/traits/is_byte_container.hpp +51 -0
  208. mqt/core/include/mqt-core/boost/multiprecision/traits/is_complex.hpp +22 -0
  209. mqt/core/include/mqt-core/boost/multiprecision/traits/is_convertible_arithmetic.hpp +51 -0
  210. mqt/core/include/mqt-core/boost/multiprecision/traits/is_restricted_conversion.hpp +47 -0
  211. mqt/core/include/mqt-core/boost/multiprecision/traits/is_variable_precision.hpp +25 -0
  212. mqt/core/include/mqt-core/boost/multiprecision/traits/max_digits10.hpp +79 -0
  213. mqt/core/include/mqt-core/boost/multiprecision/traits/std_integer_traits.hpp +90 -0
  214. mqt/core/include/mqt-core/boost/multiprecision/traits/transcendental_reduction_type.hpp +21 -0
  215. mqt/core/include/mqt-core/boost/version.hpp +32 -0
  216. mqt/core/include/mqt-core/circuit_optimizer/CircuitOptimizer.hpp +119 -0
  217. mqt/core/include/mqt-core/circuit_optimizer/mqt_core_circuit_optimizer_export.h +43 -0
  218. mqt/core/include/mqt-core/datastructures/DirectedAcyclicGraph.hpp +117 -0
  219. mqt/core/include/mqt-core/datastructures/DirectedGraph.hpp +158 -0
  220. mqt/core/include/mqt-core/datastructures/DisjointSet.hpp +50 -0
  221. mqt/core/include/mqt-core/datastructures/Layer.hpp +172 -0
  222. mqt/core/include/mqt-core/datastructures/SymmetricMatrix.hpp +57 -0
  223. mqt/core/include/mqt-core/datastructures/UndirectedGraph.hpp +227 -0
  224. mqt/core/include/mqt-core/datastructures/mqt_core_ds_export.h +43 -0
  225. mqt/core/include/mqt-core/dd/Approximation.hpp +45 -0
  226. mqt/core/include/mqt-core/dd/CachedEdge.hpp +174 -0
  227. mqt/core/include/mqt-core/dd/Complex.hpp +165 -0
  228. mqt/core/include/mqt-core/dd/ComplexNumbers.hpp +150 -0
  229. mqt/core/include/mqt-core/dd/ComplexValue.hpp +184 -0
  230. mqt/core/include/mqt-core/dd/ComputeTable.hpp +183 -0
  231. mqt/core/include/mqt-core/dd/DDDefinitions.hpp +139 -0
  232. mqt/core/include/mqt-core/dd/DDpackageConfig.hpp +104 -0
  233. mqt/core/include/mqt-core/dd/DensityNoiseTable.hpp +114 -0
  234. mqt/core/include/mqt-core/dd/Edge.hpp +416 -0
  235. mqt/core/include/mqt-core/dd/Export.hpp +438 -0
  236. mqt/core/include/mqt-core/dd/FunctionalityConstruction.hpp +75 -0
  237. mqt/core/include/mqt-core/dd/GateMatrixDefinitions.hpp +43 -0
  238. mqt/core/include/mqt-core/dd/LinkedListBase.hpp +45 -0
  239. mqt/core/include/mqt-core/dd/MemoryManager.hpp +193 -0
  240. mqt/core/include/mqt-core/dd/Node.hpp +223 -0
  241. mqt/core/include/mqt-core/dd/NoiseFunctionality.hpp +144 -0
  242. mqt/core/include/mqt-core/dd/Operations.hpp +306 -0
  243. mqt/core/include/mqt-core/dd/Package.hpp +2036 -0
  244. mqt/core/include/mqt-core/dd/Package_fwd.hpp +22 -0
  245. mqt/core/include/mqt-core/dd/RealNumber.hpp +255 -0
  246. mqt/core/include/mqt-core/dd/RealNumberUniqueTable.hpp +217 -0
  247. mqt/core/include/mqt-core/dd/Simulation.hpp +98 -0
  248. mqt/core/include/mqt-core/dd/StateGeneration.hpp +143 -0
  249. mqt/core/include/mqt-core/dd/StochasticNoiseOperationTable.hpp +88 -0
  250. mqt/core/include/mqt-core/dd/UnaryComputeTable.hpp +121 -0
  251. mqt/core/include/mqt-core/dd/UniqueTable.hpp +243 -0
  252. mqt/core/include/mqt-core/dd/mqt_core_dd_export.h +43 -0
  253. mqt/core/include/mqt-core/dd/statistics/MemoryManagerStatistics.hpp +84 -0
  254. mqt/core/include/mqt-core/dd/statistics/PackageStatistics.hpp +55 -0
  255. mqt/core/include/mqt-core/dd/statistics/Statistics.hpp +48 -0
  256. mqt/core/include/mqt-core/dd/statistics/TableStatistics.hpp +79 -0
  257. mqt/core/include/mqt-core/dd/statistics/UniqueTableStatistics.hpp +31 -0
  258. mqt/core/include/mqt-core/fomac/FoMaC.hpp +568 -0
  259. mqt/core/include/mqt-core/ir/Definitions.hpp +108 -0
  260. mqt/core/include/mqt-core/ir/Permutation.hpp +213 -0
  261. mqt/core/include/mqt-core/ir/QuantumComputation.hpp +596 -0
  262. mqt/core/include/mqt-core/ir/Register.hpp +125 -0
  263. mqt/core/include/mqt-core/ir/mqt_core_ir_export.h +43 -0
  264. mqt/core/include/mqt-core/ir/operations/AodOperation.hpp +92 -0
  265. mqt/core/include/mqt-core/ir/operations/CompoundOperation.hpp +212 -0
  266. mqt/core/include/mqt-core/ir/operations/Control.hpp +142 -0
  267. mqt/core/include/mqt-core/ir/operations/Expression.hpp +847 -0
  268. mqt/core/include/mqt-core/ir/operations/IfElseOperation.hpp +169 -0
  269. mqt/core/include/mqt-core/ir/operations/NonUnitaryOperation.hpp +118 -0
  270. mqt/core/include/mqt-core/ir/operations/OpType.hpp +120 -0
  271. mqt/core/include/mqt-core/ir/operations/OpType.inc +76 -0
  272. mqt/core/include/mqt-core/ir/operations/Operation.hpp +247 -0
  273. mqt/core/include/mqt-core/ir/operations/StandardOperation.hpp +140 -0
  274. mqt/core/include/mqt-core/ir/operations/SymbolicOperation.hpp +144 -0
  275. mqt/core/include/mqt-core/mqt_na_qdmi/device.h +602 -0
  276. mqt/core/include/mqt-core/mqt_na_qdmi/types.h +78 -0
  277. mqt/core/include/mqt-core/na/NAComputation.hpp +185 -0
  278. mqt/core/include/mqt-core/na/device/Device.hpp +410 -0
  279. mqt/core/include/mqt-core/na/device/DeviceMemberInitializers.hpp +724 -0
  280. mqt/core/include/mqt-core/na/device/Generator.hpp +447 -0
  281. mqt/core/include/mqt-core/na/entities/Atom.hpp +62 -0
  282. mqt/core/include/mqt-core/na/entities/Location.hpp +154 -0
  283. mqt/core/include/mqt-core/na/entities/Zone.hpp +95 -0
  284. mqt/core/include/mqt-core/na/fomac/Device.hpp +169 -0
  285. mqt/core/include/mqt-core/na/mqt_core_na_export.h +43 -0
  286. mqt/core/include/mqt-core/na/operations/GlobalCZOp.hpp +38 -0
  287. mqt/core/include/mqt-core/na/operations/GlobalOp.hpp +58 -0
  288. mqt/core/include/mqt-core/na/operations/GlobalRYOp.hpp +42 -0
  289. mqt/core/include/mqt-core/na/operations/LoadOp.hpp +89 -0
  290. mqt/core/include/mqt-core/na/operations/LocalOp.hpp +56 -0
  291. mqt/core/include/mqt-core/na/operations/LocalRZOp.hpp +42 -0
  292. mqt/core/include/mqt-core/na/operations/LocalUOp.hpp +49 -0
  293. mqt/core/include/mqt-core/na/operations/MoveOp.hpp +66 -0
  294. mqt/core/include/mqt-core/na/operations/Op.hpp +62 -0
  295. mqt/core/include/mqt-core/na/operations/ShuttlingOp.hpp +51 -0
  296. mqt/core/include/mqt-core/na/operations/StoreOp.hpp +87 -0
  297. mqt/core/include/mqt-core/qasm3/Exception.hpp +85 -0
  298. mqt/core/include/mqt-core/qasm3/Gate.hpp +65 -0
  299. mqt/core/include/mqt-core/qasm3/Importer.hpp +192 -0
  300. mqt/core/include/mqt-core/qasm3/InstVisitor.hpp +145 -0
  301. mqt/core/include/mqt-core/qasm3/NestedEnvironment.hpp +41 -0
  302. mqt/core/include/mqt-core/qasm3/Parser.hpp +170 -0
  303. mqt/core/include/mqt-core/qasm3/Scanner.hpp +73 -0
  304. mqt/core/include/mqt-core/qasm3/Statement.hpp +486 -0
  305. mqt/core/include/mqt-core/qasm3/Statement_fwd.hpp +39 -0
  306. mqt/core/include/mqt-core/qasm3/StdGates.hpp +232 -0
  307. mqt/core/include/mqt-core/qasm3/Token.hpp +198 -0
  308. mqt/core/include/mqt-core/qasm3/Types.hpp +238 -0
  309. mqt/core/include/mqt-core/qasm3/Types_fwd.hpp +22 -0
  310. mqt/core/include/mqt-core/qasm3/mqt_core_qasm_export.h +43 -0
  311. mqt/core/include/mqt-core/qasm3/passes/CompilerPass.hpp +22 -0
  312. mqt/core/include/mqt-core/qasm3/passes/ConstEvalPass.hpp +102 -0
  313. mqt/core/include/mqt-core/qasm3/passes/TypeCheckPass.hpp +124 -0
  314. mqt/core/include/mqt-core/qdmi/Driver.hpp +431 -0
  315. mqt/core/include/mqt-core/zx/FunctionalityConstruction.hpp +125 -0
  316. mqt/core/include/mqt-core/zx/Rational.hpp +318 -0
  317. mqt/core/include/mqt-core/zx/Rules.hpp +132 -0
  318. mqt/core/include/mqt-core/zx/Simplify.hpp +182 -0
  319. mqt/core/include/mqt-core/zx/Utils.hpp +212 -0
  320. mqt/core/include/mqt-core/zx/ZXDefinitions.hpp +93 -0
  321. mqt/core/include/mqt-core/zx/ZXDiagram.hpp +480 -0
  322. mqt/core/include/mqt-core/zx/mqt_core_zx_export.h +43 -0
  323. mqt/core/include/nlohmann/adl_serializer.hpp +55 -0
  324. mqt/core/include/nlohmann/byte_container_with_subtype.hpp +103 -0
  325. mqt/core/include/nlohmann/detail/abi_macros.hpp +111 -0
  326. mqt/core/include/nlohmann/detail/conversions/from_json.hpp +577 -0
  327. mqt/core/include/nlohmann/detail/conversions/to_chars.hpp +1118 -0
  328. mqt/core/include/nlohmann/detail/conversions/to_json.hpp +479 -0
  329. mqt/core/include/nlohmann/detail/exceptions.hpp +291 -0
  330. mqt/core/include/nlohmann/detail/hash.hpp +129 -0
  331. mqt/core/include/nlohmann/detail/input/binary_reader.hpp +3068 -0
  332. mqt/core/include/nlohmann/detail/input/input_adapters.hpp +549 -0
  333. mqt/core/include/nlohmann/detail/input/json_sax.hpp +986 -0
  334. mqt/core/include/nlohmann/detail/input/lexer.hpp +1643 -0
  335. mqt/core/include/nlohmann/detail/input/parser.hpp +519 -0
  336. mqt/core/include/nlohmann/detail/input/position_t.hpp +37 -0
  337. mqt/core/include/nlohmann/detail/iterators/internal_iterator.hpp +35 -0
  338. mqt/core/include/nlohmann/detail/iterators/iter_impl.hpp +760 -0
  339. mqt/core/include/nlohmann/detail/iterators/iteration_proxy.hpp +235 -0
  340. mqt/core/include/nlohmann/detail/iterators/iterator_traits.hpp +61 -0
  341. mqt/core/include/nlohmann/detail/iterators/json_reverse_iterator.hpp +130 -0
  342. mqt/core/include/nlohmann/detail/iterators/primitive_iterator.hpp +132 -0
  343. mqt/core/include/nlohmann/detail/json_custom_base_class.hpp +39 -0
  344. mqt/core/include/nlohmann/detail/json_pointer.hpp +988 -0
  345. mqt/core/include/nlohmann/detail/json_ref.hpp +78 -0
  346. mqt/core/include/nlohmann/detail/macro_scope.hpp +595 -0
  347. mqt/core/include/nlohmann/detail/macro_unscope.hpp +46 -0
  348. mqt/core/include/nlohmann/detail/meta/call_std/begin.hpp +17 -0
  349. mqt/core/include/nlohmann/detail/meta/call_std/end.hpp +17 -0
  350. mqt/core/include/nlohmann/detail/meta/cpp_future.hpp +171 -0
  351. mqt/core/include/nlohmann/detail/meta/detected.hpp +70 -0
  352. mqt/core/include/nlohmann/detail/meta/identity_tag.hpp +21 -0
  353. mqt/core/include/nlohmann/detail/meta/is_sax.hpp +159 -0
  354. mqt/core/include/nlohmann/detail/meta/std_fs.hpp +29 -0
  355. mqt/core/include/nlohmann/detail/meta/type_traits.hpp +795 -0
  356. mqt/core/include/nlohmann/detail/meta/void_t.hpp +24 -0
  357. mqt/core/include/nlohmann/detail/output/binary_writer.hpp +1850 -0
  358. mqt/core/include/nlohmann/detail/output/output_adapters.hpp +147 -0
  359. mqt/core/include/nlohmann/detail/output/serializer.hpp +988 -0
  360. mqt/core/include/nlohmann/detail/string_concat.hpp +146 -0
  361. mqt/core/include/nlohmann/detail/string_escape.hpp +72 -0
  362. mqt/core/include/nlohmann/detail/string_utils.hpp +37 -0
  363. mqt/core/include/nlohmann/detail/value_t.hpp +118 -0
  364. mqt/core/include/nlohmann/json.hpp +5306 -0
  365. mqt/core/include/nlohmann/json_fwd.hpp +75 -0
  366. mqt/core/include/nlohmann/ordered_map.hpp +359 -0
  367. mqt/core/include/nlohmann/thirdparty/hedley/hedley.hpp +2045 -0
  368. mqt/core/include/nlohmann/thirdparty/hedley/hedley_undef.hpp +158 -0
  369. mqt/core/include/qdmi/qdmi/client.h +990 -0
  370. mqt/core/include/qdmi/qdmi/constants.h +1139 -0
  371. mqt/core/include/qdmi/qdmi/device.h +602 -0
  372. mqt/core/include/qdmi/qdmi/types.h +78 -0
  373. mqt/core/include/spdlog/async.h +99 -0
  374. mqt/core/include/spdlog/async_logger-inl.h +84 -0
  375. mqt/core/include/spdlog/async_logger.h +74 -0
  376. mqt/core/include/spdlog/cfg/argv.h +40 -0
  377. mqt/core/include/spdlog/cfg/env.h +36 -0
  378. mqt/core/include/spdlog/cfg/helpers-inl.h +107 -0
  379. mqt/core/include/spdlog/cfg/helpers.h +29 -0
  380. mqt/core/include/spdlog/common-inl.h +68 -0
  381. mqt/core/include/spdlog/common.h +406 -0
  382. mqt/core/include/spdlog/details/backtracer-inl.h +63 -0
  383. mqt/core/include/spdlog/details/backtracer.h +45 -0
  384. mqt/core/include/spdlog/details/circular_q.h +115 -0
  385. mqt/core/include/spdlog/details/console_globals.h +28 -0
  386. mqt/core/include/spdlog/details/file_helper-inl.h +153 -0
  387. mqt/core/include/spdlog/details/file_helper.h +61 -0
  388. mqt/core/include/spdlog/details/fmt_helper.h +141 -0
  389. mqt/core/include/spdlog/details/log_msg-inl.h +44 -0
  390. mqt/core/include/spdlog/details/log_msg.h +40 -0
  391. mqt/core/include/spdlog/details/log_msg_buffer-inl.h +54 -0
  392. mqt/core/include/spdlog/details/log_msg_buffer.h +32 -0
  393. mqt/core/include/spdlog/details/mpmc_blocking_q.h +177 -0
  394. mqt/core/include/spdlog/details/null_mutex.h +35 -0
  395. mqt/core/include/spdlog/details/os-inl.h +606 -0
  396. mqt/core/include/spdlog/details/os.h +127 -0
  397. mqt/core/include/spdlog/details/periodic_worker-inl.h +26 -0
  398. mqt/core/include/spdlog/details/periodic_worker.h +58 -0
  399. mqt/core/include/spdlog/details/registry-inl.h +270 -0
  400. mqt/core/include/spdlog/details/registry.h +131 -0
  401. mqt/core/include/spdlog/details/synchronous_factory.h +22 -0
  402. mqt/core/include/spdlog/details/tcp_client-windows.h +135 -0
  403. mqt/core/include/spdlog/details/tcp_client.h +127 -0
  404. mqt/core/include/spdlog/details/thread_pool-inl.h +126 -0
  405. mqt/core/include/spdlog/details/thread_pool.h +117 -0
  406. mqt/core/include/spdlog/details/udp_client-windows.h +98 -0
  407. mqt/core/include/spdlog/details/udp_client.h +81 -0
  408. mqt/core/include/spdlog/details/windows_include.h +11 -0
  409. mqt/core/include/spdlog/fmt/bin_to_hex.h +224 -0
  410. mqt/core/include/spdlog/fmt/bundled/args.h +220 -0
  411. mqt/core/include/spdlog/fmt/bundled/base.h +2989 -0
  412. mqt/core/include/spdlog/fmt/bundled/chrono.h +2330 -0
  413. mqt/core/include/spdlog/fmt/bundled/color.h +637 -0
  414. mqt/core/include/spdlog/fmt/bundled/compile.h +539 -0
  415. mqt/core/include/spdlog/fmt/bundled/core.h +5 -0
  416. mqt/core/include/spdlog/fmt/bundled/fmt.license.rst +27 -0
  417. mqt/core/include/spdlog/fmt/bundled/format-inl.h +1948 -0
  418. mqt/core/include/spdlog/fmt/bundled/format.h +4244 -0
  419. mqt/core/include/spdlog/fmt/bundled/os.h +427 -0
  420. mqt/core/include/spdlog/fmt/bundled/ostream.h +167 -0
  421. mqt/core/include/spdlog/fmt/bundled/printf.h +633 -0
  422. mqt/core/include/spdlog/fmt/bundled/ranges.h +850 -0
  423. mqt/core/include/spdlog/fmt/bundled/std.h +728 -0
  424. mqt/core/include/spdlog/fmt/bundled/xchar.h +369 -0
  425. mqt/core/include/spdlog/fmt/chrono.h +23 -0
  426. mqt/core/include/spdlog/fmt/compile.h +23 -0
  427. mqt/core/include/spdlog/fmt/fmt.h +30 -0
  428. mqt/core/include/spdlog/fmt/ostr.h +23 -0
  429. mqt/core/include/spdlog/fmt/ranges.h +23 -0
  430. mqt/core/include/spdlog/fmt/std.h +24 -0
  431. mqt/core/include/spdlog/fmt/xchar.h +23 -0
  432. mqt/core/include/spdlog/formatter.h +17 -0
  433. mqt/core/include/spdlog/fwd.h +18 -0
  434. mqt/core/include/spdlog/logger-inl.h +198 -0
  435. mqt/core/include/spdlog/logger.h +379 -0
  436. mqt/core/include/spdlog/mdc.h +52 -0
  437. mqt/core/include/spdlog/pattern_formatter-inl.h +1340 -0
  438. mqt/core/include/spdlog/pattern_formatter.h +118 -0
  439. mqt/core/include/spdlog/sinks/android_sink.h +137 -0
  440. mqt/core/include/spdlog/sinks/ansicolor_sink-inl.h +142 -0
  441. mqt/core/include/spdlog/sinks/ansicolor_sink.h +116 -0
  442. mqt/core/include/spdlog/sinks/base_sink-inl.h +59 -0
  443. mqt/core/include/spdlog/sinks/base_sink.h +51 -0
  444. mqt/core/include/spdlog/sinks/basic_file_sink-inl.h +48 -0
  445. mqt/core/include/spdlog/sinks/basic_file_sink.h +66 -0
  446. mqt/core/include/spdlog/sinks/callback_sink.h +56 -0
  447. mqt/core/include/spdlog/sinks/daily_file_sink.h +254 -0
  448. mqt/core/include/spdlog/sinks/dist_sink.h +81 -0
  449. mqt/core/include/spdlog/sinks/dup_filter_sink.h +91 -0
  450. mqt/core/include/spdlog/sinks/hourly_file_sink.h +193 -0
  451. mqt/core/include/spdlog/sinks/kafka_sink.h +119 -0
  452. mqt/core/include/spdlog/sinks/mongo_sink.h +108 -0
  453. mqt/core/include/spdlog/sinks/msvc_sink.h +68 -0
  454. mqt/core/include/spdlog/sinks/null_sink.h +41 -0
  455. mqt/core/include/spdlog/sinks/ostream_sink.h +43 -0
  456. mqt/core/include/spdlog/sinks/qt_sinks.h +304 -0
  457. mqt/core/include/spdlog/sinks/ringbuffer_sink.h +67 -0
  458. mqt/core/include/spdlog/sinks/rotating_file_sink-inl.h +179 -0
  459. mqt/core/include/spdlog/sinks/rotating_file_sink.h +93 -0
  460. mqt/core/include/spdlog/sinks/sink-inl.h +22 -0
  461. mqt/core/include/spdlog/sinks/sink.h +34 -0
  462. mqt/core/include/spdlog/sinks/stdout_color_sinks-inl.h +38 -0
  463. mqt/core/include/spdlog/sinks/stdout_color_sinks.h +49 -0
  464. mqt/core/include/spdlog/sinks/stdout_sinks-inl.h +127 -0
  465. mqt/core/include/spdlog/sinks/stdout_sinks.h +84 -0
  466. mqt/core/include/spdlog/sinks/syslog_sink.h +104 -0
  467. mqt/core/include/spdlog/sinks/systemd_sink.h +121 -0
  468. mqt/core/include/spdlog/sinks/tcp_sink.h +75 -0
  469. mqt/core/include/spdlog/sinks/udp_sink.h +69 -0
  470. mqt/core/include/spdlog/sinks/win_eventlog_sink.h +260 -0
  471. mqt/core/include/spdlog/sinks/wincolor_sink-inl.h +172 -0
  472. mqt/core/include/spdlog/sinks/wincolor_sink.h +82 -0
  473. mqt/core/include/spdlog/spdlog-inl.h +96 -0
  474. mqt/core/include/spdlog/spdlog.h +357 -0
  475. mqt/core/include/spdlog/stopwatch.h +66 -0
  476. mqt/core/include/spdlog/tweakme.h +148 -0
  477. mqt/core/include/spdlog/version.h +11 -0
  478. mqt/core/ir/__init__.pyi +2078 -0
  479. mqt/core/ir/operations.pyi +1011 -0
  480. mqt/core/ir/registers.pyi +91 -0
  481. mqt/core/ir/symbolic.pyi +177 -0
  482. mqt/core/ir.cp314t-win_amd64.pyd +0 -0
  483. mqt/core/lib/mqt-core-algorithms.lib +0 -0
  484. mqt/core/lib/mqt-core-circuit-optimizer.lib +0 -0
  485. mqt/core/lib/mqt-core-dd.lib +0 -0
  486. mqt/core/lib/mqt-core-ds.lib +0 -0
  487. mqt/core/lib/mqt-core-fomac.lib +0 -0
  488. mqt/core/lib/mqt-core-ir.lib +0 -0
  489. mqt/core/lib/mqt-core-na-fomac.lib +0 -0
  490. mqt/core/lib/mqt-core-na.lib +0 -0
  491. mqt/core/lib/mqt-core-qasm.lib +0 -0
  492. mqt/core/lib/mqt-core-qdmi-driver.lib +0 -0
  493. mqt/core/lib/mqt-core-qdmi-na-device-gen.lib +0 -0
  494. mqt/core/lib/mqt-core-qdmi-na-device.lib +0 -0
  495. mqt/core/lib/mqt-core-zx.lib +0 -0
  496. mqt/core/lib/pkgconfig/spdlog.pc +13 -0
  497. mqt/core/lib/spdlog.lib +0 -0
  498. mqt/core/na/__init__.py +12 -0
  499. mqt/core/na/fomac.cp314t-win_amd64.pyd +0 -0
  500. mqt/core/na/fomac.pyi +117 -0
  501. mqt/core/nlohmann_json.natvis +278 -0
  502. mqt/core/plugins/__init__.py +9 -0
  503. mqt/core/plugins/qiskit/__init__.py +19 -0
  504. mqt/core/plugins/qiskit/mqt_to_qiskit.py +420 -0
  505. mqt/core/plugins/qiskit/qiskit_to_mqt.py +562 -0
  506. mqt/core/py.typed +2 -0
  507. mqt/core/share/cmake/mqt-core/AddMQTPythonBinding.cmake +55 -0
  508. mqt/core/share/cmake/mqt-core/Cache.cmake +33 -0
  509. mqt/core/share/cmake/mqt-core/FindGMP.cmake +103 -0
  510. mqt/core/share/cmake/mqt-core/PackageAddTest.cmake +46 -0
  511. mqt/core/share/cmake/mqt-core/PreventInSourceBuilds.cmake +25 -0
  512. mqt/core/share/cmake/mqt-core/StandardProjectSettings.cmake +87 -0
  513. mqt/core/share/cmake/mqt-core/mqt-core-config-version.cmake +85 -0
  514. mqt/core/share/cmake/mqt-core/mqt-core-config.cmake +52 -0
  515. mqt/core/share/cmake/mqt-core/mqt-core-targets-release.cmake +141 -0
  516. mqt/core/share/cmake/mqt-core/mqt-core-targets.cmake +445 -0
  517. mqt/core/share/cmake/nlohmann_json/nlohmann_jsonConfig.cmake +15 -0
  518. mqt/core/share/cmake/nlohmann_json/nlohmann_jsonConfigVersion.cmake +20 -0
  519. mqt/core/share/cmake/nlohmann_json/nlohmann_jsonTargets.cmake +110 -0
  520. mqt/core/share/cmake/qdmi/Cache.cmake +44 -0
  521. mqt/core/share/cmake/qdmi/PrefixHandling.cmake +78 -0
  522. mqt/core/share/cmake/qdmi/prefix_defs.txt +26 -0
  523. mqt/core/share/cmake/qdmi/qdmi-config-version.cmake +85 -0
  524. mqt/core/share/cmake/qdmi/qdmi-config.cmake +42 -0
  525. mqt/core/share/cmake/qdmi/qdmi-targets.cmake +129 -0
  526. mqt/core/share/cmake/spdlog/spdlogConfig.cmake +44 -0
  527. mqt/core/share/cmake/spdlog/spdlogConfigTargets-release.cmake +19 -0
  528. mqt/core/share/cmake/spdlog/spdlogConfigTargets.cmake +121 -0
  529. mqt/core/share/cmake/spdlog/spdlogConfigVersion.cmake +65 -0
  530. mqt/core/share/pkgconfig/nlohmann_json.pc +7 -0
  531. mqt_core-3.3.2.dist-info/DELVEWHEEL +2 -0
  532. mqt_core-3.3.2.dist-info/METADATA +210 -0
  533. mqt_core-3.3.2.dist-info/RECORD +537 -0
  534. mqt_core-3.3.2.dist-info/WHEEL +5 -0
  535. mqt_core-3.3.2.dist-info/entry_points.txt +4 -0
  536. mqt_core-3.3.2.dist-info/licenses/LICENSE.md +22 -0
  537. mqt_core.libs/msvcp140.dll +0 -0
@@ -0,0 +1,1850 @@
1
+ // __ _____ _____ _____
2
+ // __| | __| | | | JSON for Modern C++
3
+ // | | |__ | | | | | | version 3.12.0
4
+ // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5
+ //
6
+ // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
7
+ // SPDX-License-Identifier: MIT
8
+
9
+ #pragma once
10
+
11
+ #include <algorithm> // reverse
12
+ #include <array> // array
13
+ #include <map> // map
14
+ #include <cmath> // isnan, isinf
15
+ #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
16
+ #include <cstring> // memcpy
17
+ #include <limits> // numeric_limits
18
+ #include <string> // string
19
+ #include <utility> // move
20
+ #include <vector> // vector
21
+
22
+ #include <nlohmann/detail/input/binary_reader.hpp>
23
+ #include <nlohmann/detail/macro_scope.hpp>
24
+ #include <nlohmann/detail/output/output_adapters.hpp>
25
+ #include <nlohmann/detail/string_concat.hpp>
26
+
27
+ NLOHMANN_JSON_NAMESPACE_BEGIN
28
+ namespace detail
29
+ {
30
+
31
+ /// how to encode BJData
32
+ enum class bjdata_version_t
33
+ {
34
+ draft2,
35
+ draft3,
36
+ };
37
+
38
+ ///////////////////
39
+ // binary writer //
40
+ ///////////////////
41
+
42
+ /*!
43
+ @brief serialization to CBOR and MessagePack values
44
+ */
45
+ template<typename BasicJsonType, typename CharType>
46
+ class binary_writer
47
+ {
48
+ using string_t = typename BasicJsonType::string_t;
49
+ using binary_t = typename BasicJsonType::binary_t;
50
+ using number_float_t = typename BasicJsonType::number_float_t;
51
+
52
+ public:
53
+ /*!
54
+ @brief create a binary writer
55
+
56
+ @param[in] adapter output adapter to write to
57
+ */
58
+ explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
59
+ {
60
+ JSON_ASSERT(oa);
61
+ }
62
+
63
+ /*!
64
+ @param[in] j JSON value to serialize
65
+ @pre j.type() == value_t::object
66
+ */
67
+ void write_bson(const BasicJsonType& j)
68
+ {
69
+ switch (j.type())
70
+ {
71
+ case value_t::object:
72
+ {
73
+ write_bson_object(*j.m_data.m_value.object);
74
+ break;
75
+ }
76
+
77
+ case value_t::null:
78
+ case value_t::array:
79
+ case value_t::string:
80
+ case value_t::boolean:
81
+ case value_t::number_integer:
82
+ case value_t::number_unsigned:
83
+ case value_t::number_float:
84
+ case value_t::binary:
85
+ case value_t::discarded:
86
+ default:
87
+ {
88
+ JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
89
+ }
90
+ }
91
+ }
92
+
93
+ /*!
94
+ @param[in] j JSON value to serialize
95
+ */
96
+ void write_cbor(const BasicJsonType& j)
97
+ {
98
+ switch (j.type())
99
+ {
100
+ case value_t::null:
101
+ {
102
+ oa->write_character(to_char_type(0xF6));
103
+ break;
104
+ }
105
+
106
+ case value_t::boolean:
107
+ {
108
+ oa->write_character(j.m_data.m_value.boolean
109
+ ? to_char_type(0xF5)
110
+ : to_char_type(0xF4));
111
+ break;
112
+ }
113
+
114
+ case value_t::number_integer:
115
+ {
116
+ if (j.m_data.m_value.number_integer >= 0)
117
+ {
118
+ // CBOR does not differentiate between positive signed
119
+ // integers and unsigned integers. Therefore, we used the
120
+ // code from the value_t::number_unsigned case here.
121
+ if (j.m_data.m_value.number_integer <= 0x17)
122
+ {
123
+ write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
124
+ }
125
+ else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
126
+ {
127
+ oa->write_character(to_char_type(0x18));
128
+ write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
129
+ }
130
+ else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
131
+ {
132
+ oa->write_character(to_char_type(0x19));
133
+ write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
134
+ }
135
+ else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
136
+ {
137
+ oa->write_character(to_char_type(0x1A));
138
+ write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
139
+ }
140
+ else
141
+ {
142
+ oa->write_character(to_char_type(0x1B));
143
+ write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
144
+ }
145
+ }
146
+ else
147
+ {
148
+ // The conversions below encode the sign in the first
149
+ // byte, and the value is converted to a positive number.
150
+ const auto positive_number = -1 - j.m_data.m_value.number_integer;
151
+ if (j.m_data.m_value.number_integer >= -24)
152
+ {
153
+ write_number(static_cast<std::uint8_t>(0x20 + positive_number));
154
+ }
155
+ else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
156
+ {
157
+ oa->write_character(to_char_type(0x38));
158
+ write_number(static_cast<std::uint8_t>(positive_number));
159
+ }
160
+ else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
161
+ {
162
+ oa->write_character(to_char_type(0x39));
163
+ write_number(static_cast<std::uint16_t>(positive_number));
164
+ }
165
+ else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
166
+ {
167
+ oa->write_character(to_char_type(0x3A));
168
+ write_number(static_cast<std::uint32_t>(positive_number));
169
+ }
170
+ else
171
+ {
172
+ oa->write_character(to_char_type(0x3B));
173
+ write_number(static_cast<std::uint64_t>(positive_number));
174
+ }
175
+ }
176
+ break;
177
+ }
178
+
179
+ case value_t::number_unsigned:
180
+ {
181
+ if (j.m_data.m_value.number_unsigned <= 0x17)
182
+ {
183
+ write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
184
+ }
185
+ else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
186
+ {
187
+ oa->write_character(to_char_type(0x18));
188
+ write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
189
+ }
190
+ else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
191
+ {
192
+ oa->write_character(to_char_type(0x19));
193
+ write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_unsigned));
194
+ }
195
+ else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
196
+ {
197
+ oa->write_character(to_char_type(0x1A));
198
+ write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_unsigned));
199
+ }
200
+ else
201
+ {
202
+ oa->write_character(to_char_type(0x1B));
203
+ write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
204
+ }
205
+ break;
206
+ }
207
+
208
+ case value_t::number_float:
209
+ {
210
+ if (std::isnan(j.m_data.m_value.number_float))
211
+ {
212
+ // NaN is 0xf97e00 in CBOR
213
+ oa->write_character(to_char_type(0xF9));
214
+ oa->write_character(to_char_type(0x7E));
215
+ oa->write_character(to_char_type(0x00));
216
+ }
217
+ else if (std::isinf(j.m_data.m_value.number_float))
218
+ {
219
+ // Infinity is 0xf97c00, -Infinity is 0xf9fc00
220
+ oa->write_character(to_char_type(0xf9));
221
+ oa->write_character(j.m_data.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
222
+ oa->write_character(to_char_type(0x00));
223
+ }
224
+ else
225
+ {
226
+ write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::cbor);
227
+ }
228
+ break;
229
+ }
230
+
231
+ case value_t::string:
232
+ {
233
+ // step 1: write control byte and the string length
234
+ const auto N = j.m_data.m_value.string->size();
235
+ if (N <= 0x17)
236
+ {
237
+ write_number(static_cast<std::uint8_t>(0x60 + N));
238
+ }
239
+ else if (N <= (std::numeric_limits<std::uint8_t>::max)())
240
+ {
241
+ oa->write_character(to_char_type(0x78));
242
+ write_number(static_cast<std::uint8_t>(N));
243
+ }
244
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
245
+ {
246
+ oa->write_character(to_char_type(0x79));
247
+ write_number(static_cast<std::uint16_t>(N));
248
+ }
249
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
250
+ {
251
+ oa->write_character(to_char_type(0x7A));
252
+ write_number(static_cast<std::uint32_t>(N));
253
+ }
254
+ // LCOV_EXCL_START
255
+ else if (N <= (std::numeric_limits<std::uint64_t>::max)())
256
+ {
257
+ oa->write_character(to_char_type(0x7B));
258
+ write_number(static_cast<std::uint64_t>(N));
259
+ }
260
+ // LCOV_EXCL_STOP
261
+
262
+ // step 2: write the string
263
+ oa->write_characters(
264
+ reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
265
+ j.m_data.m_value.string->size());
266
+ break;
267
+ }
268
+
269
+ case value_t::array:
270
+ {
271
+ // step 1: write control byte and the array size
272
+ const auto N = j.m_data.m_value.array->size();
273
+ if (N <= 0x17)
274
+ {
275
+ write_number(static_cast<std::uint8_t>(0x80 + N));
276
+ }
277
+ else if (N <= (std::numeric_limits<std::uint8_t>::max)())
278
+ {
279
+ oa->write_character(to_char_type(0x98));
280
+ write_number(static_cast<std::uint8_t>(N));
281
+ }
282
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
283
+ {
284
+ oa->write_character(to_char_type(0x99));
285
+ write_number(static_cast<std::uint16_t>(N));
286
+ }
287
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
288
+ {
289
+ oa->write_character(to_char_type(0x9A));
290
+ write_number(static_cast<std::uint32_t>(N));
291
+ }
292
+ // LCOV_EXCL_START
293
+ else if (N <= (std::numeric_limits<std::uint64_t>::max)())
294
+ {
295
+ oa->write_character(to_char_type(0x9B));
296
+ write_number(static_cast<std::uint64_t>(N));
297
+ }
298
+ // LCOV_EXCL_STOP
299
+
300
+ // step 2: write each element
301
+ for (const auto& el : *j.m_data.m_value.array)
302
+ {
303
+ write_cbor(el);
304
+ }
305
+ break;
306
+ }
307
+
308
+ case value_t::binary:
309
+ {
310
+ if (j.m_data.m_value.binary->has_subtype())
311
+ {
312
+ if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
313
+ {
314
+ write_number(static_cast<std::uint8_t>(0xd8));
315
+ write_number(static_cast<std::uint8_t>(j.m_data.m_value.binary->subtype()));
316
+ }
317
+ else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
318
+ {
319
+ write_number(static_cast<std::uint8_t>(0xd9));
320
+ write_number(static_cast<std::uint16_t>(j.m_data.m_value.binary->subtype()));
321
+ }
322
+ else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
323
+ {
324
+ write_number(static_cast<std::uint8_t>(0xda));
325
+ write_number(static_cast<std::uint32_t>(j.m_data.m_value.binary->subtype()));
326
+ }
327
+ else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
328
+ {
329
+ write_number(static_cast<std::uint8_t>(0xdb));
330
+ write_number(static_cast<std::uint64_t>(j.m_data.m_value.binary->subtype()));
331
+ }
332
+ }
333
+
334
+ // step 1: write control byte and the binary array size
335
+ const auto N = j.m_data.m_value.binary->size();
336
+ if (N <= 0x17)
337
+ {
338
+ write_number(static_cast<std::uint8_t>(0x40 + N));
339
+ }
340
+ else if (N <= (std::numeric_limits<std::uint8_t>::max)())
341
+ {
342
+ oa->write_character(to_char_type(0x58));
343
+ write_number(static_cast<std::uint8_t>(N));
344
+ }
345
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
346
+ {
347
+ oa->write_character(to_char_type(0x59));
348
+ write_number(static_cast<std::uint16_t>(N));
349
+ }
350
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
351
+ {
352
+ oa->write_character(to_char_type(0x5A));
353
+ write_number(static_cast<std::uint32_t>(N));
354
+ }
355
+ // LCOV_EXCL_START
356
+ else if (N <= (std::numeric_limits<std::uint64_t>::max)())
357
+ {
358
+ oa->write_character(to_char_type(0x5B));
359
+ write_number(static_cast<std::uint64_t>(N));
360
+ }
361
+ // LCOV_EXCL_STOP
362
+
363
+ // step 2: write each element
364
+ oa->write_characters(
365
+ reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
366
+ N);
367
+
368
+ break;
369
+ }
370
+
371
+ case value_t::object:
372
+ {
373
+ // step 1: write control byte and the object size
374
+ const auto N = j.m_data.m_value.object->size();
375
+ if (N <= 0x17)
376
+ {
377
+ write_number(static_cast<std::uint8_t>(0xA0 + N));
378
+ }
379
+ else if (N <= (std::numeric_limits<std::uint8_t>::max)())
380
+ {
381
+ oa->write_character(to_char_type(0xB8));
382
+ write_number(static_cast<std::uint8_t>(N));
383
+ }
384
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
385
+ {
386
+ oa->write_character(to_char_type(0xB9));
387
+ write_number(static_cast<std::uint16_t>(N));
388
+ }
389
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
390
+ {
391
+ oa->write_character(to_char_type(0xBA));
392
+ write_number(static_cast<std::uint32_t>(N));
393
+ }
394
+ // LCOV_EXCL_START
395
+ else if (N <= (std::numeric_limits<std::uint64_t>::max)())
396
+ {
397
+ oa->write_character(to_char_type(0xBB));
398
+ write_number(static_cast<std::uint64_t>(N));
399
+ }
400
+ // LCOV_EXCL_STOP
401
+
402
+ // step 2: write each element
403
+ for (const auto& el : *j.m_data.m_value.object)
404
+ {
405
+ write_cbor(el.first);
406
+ write_cbor(el.second);
407
+ }
408
+ break;
409
+ }
410
+
411
+ case value_t::discarded:
412
+ default:
413
+ break;
414
+ }
415
+ }
416
+
417
+ /*!
418
+ @param[in] j JSON value to serialize
419
+ */
420
+ void write_msgpack(const BasicJsonType& j)
421
+ {
422
+ switch (j.type())
423
+ {
424
+ case value_t::null: // nil
425
+ {
426
+ oa->write_character(to_char_type(0xC0));
427
+ break;
428
+ }
429
+
430
+ case value_t::boolean: // true and false
431
+ {
432
+ oa->write_character(j.m_data.m_value.boolean
433
+ ? to_char_type(0xC3)
434
+ : to_char_type(0xC2));
435
+ break;
436
+ }
437
+
438
+ case value_t::number_integer:
439
+ {
440
+ if (j.m_data.m_value.number_integer >= 0)
441
+ {
442
+ // MessagePack does not differentiate between positive
443
+ // signed integers and unsigned integers. Therefore, we used
444
+ // the code from the value_t::number_unsigned case here.
445
+ if (j.m_data.m_value.number_unsigned < 128)
446
+ {
447
+ // positive fixnum
448
+ write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
449
+ }
450
+ else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
451
+ {
452
+ // uint 8
453
+ oa->write_character(to_char_type(0xCC));
454
+ write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
455
+ }
456
+ else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
457
+ {
458
+ // uint 16
459
+ oa->write_character(to_char_type(0xCD));
460
+ write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
461
+ }
462
+ else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
463
+ {
464
+ // uint 32
465
+ oa->write_character(to_char_type(0xCE));
466
+ write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
467
+ }
468
+ else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
469
+ {
470
+ // uint 64
471
+ oa->write_character(to_char_type(0xCF));
472
+ write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
473
+ }
474
+ }
475
+ else
476
+ {
477
+ if (j.m_data.m_value.number_integer >= -32)
478
+ {
479
+ // negative fixnum
480
+ write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
481
+ }
482
+ else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
483
+ j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
484
+ {
485
+ // int 8
486
+ oa->write_character(to_char_type(0xD0));
487
+ write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
488
+ }
489
+ else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
490
+ j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
491
+ {
492
+ // int 16
493
+ oa->write_character(to_char_type(0xD1));
494
+ write_number(static_cast<std::int16_t>(j.m_data.m_value.number_integer));
495
+ }
496
+ else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
497
+ j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
498
+ {
499
+ // int 32
500
+ oa->write_character(to_char_type(0xD2));
501
+ write_number(static_cast<std::int32_t>(j.m_data.m_value.number_integer));
502
+ }
503
+ else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
504
+ j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
505
+ {
506
+ // int 64
507
+ oa->write_character(to_char_type(0xD3));
508
+ write_number(static_cast<std::int64_t>(j.m_data.m_value.number_integer));
509
+ }
510
+ }
511
+ break;
512
+ }
513
+
514
+ case value_t::number_unsigned:
515
+ {
516
+ if (j.m_data.m_value.number_unsigned < 128)
517
+ {
518
+ // positive fixnum
519
+ write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
520
+ }
521
+ else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
522
+ {
523
+ // uint 8
524
+ oa->write_character(to_char_type(0xCC));
525
+ write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
526
+ }
527
+ else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
528
+ {
529
+ // uint 16
530
+ oa->write_character(to_char_type(0xCD));
531
+ write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
532
+ }
533
+ else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
534
+ {
535
+ // uint 32
536
+ oa->write_character(to_char_type(0xCE));
537
+ write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
538
+ }
539
+ else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
540
+ {
541
+ // uint 64
542
+ oa->write_character(to_char_type(0xCF));
543
+ write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
544
+ }
545
+ break;
546
+ }
547
+
548
+ case value_t::number_float:
549
+ {
550
+ write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::msgpack);
551
+ break;
552
+ }
553
+
554
+ case value_t::string:
555
+ {
556
+ // step 1: write control byte and the string length
557
+ const auto N = j.m_data.m_value.string->size();
558
+ if (N <= 31)
559
+ {
560
+ // fixstr
561
+ write_number(static_cast<std::uint8_t>(0xA0 | N));
562
+ }
563
+ else if (N <= (std::numeric_limits<std::uint8_t>::max)())
564
+ {
565
+ // str 8
566
+ oa->write_character(to_char_type(0xD9));
567
+ write_number(static_cast<std::uint8_t>(N));
568
+ }
569
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
570
+ {
571
+ // str 16
572
+ oa->write_character(to_char_type(0xDA));
573
+ write_number(static_cast<std::uint16_t>(N));
574
+ }
575
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
576
+ {
577
+ // str 32
578
+ oa->write_character(to_char_type(0xDB));
579
+ write_number(static_cast<std::uint32_t>(N));
580
+ }
581
+
582
+ // step 2: write the string
583
+ oa->write_characters(
584
+ reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
585
+ j.m_data.m_value.string->size());
586
+ break;
587
+ }
588
+
589
+ case value_t::array:
590
+ {
591
+ // step 1: write control byte and the array size
592
+ const auto N = j.m_data.m_value.array->size();
593
+ if (N <= 15)
594
+ {
595
+ // fixarray
596
+ write_number(static_cast<std::uint8_t>(0x90 | N));
597
+ }
598
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
599
+ {
600
+ // array 16
601
+ oa->write_character(to_char_type(0xDC));
602
+ write_number(static_cast<std::uint16_t>(N));
603
+ }
604
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
605
+ {
606
+ // array 32
607
+ oa->write_character(to_char_type(0xDD));
608
+ write_number(static_cast<std::uint32_t>(N));
609
+ }
610
+
611
+ // step 2: write each element
612
+ for (const auto& el : *j.m_data.m_value.array)
613
+ {
614
+ write_msgpack(el);
615
+ }
616
+ break;
617
+ }
618
+
619
+ case value_t::binary:
620
+ {
621
+ // step 0: determine if the binary type has a set subtype to
622
+ // determine whether to use the ext or fixext types
623
+ const bool use_ext = j.m_data.m_value.binary->has_subtype();
624
+
625
+ // step 1: write control byte and the byte string length
626
+ const auto N = j.m_data.m_value.binary->size();
627
+ if (N <= (std::numeric_limits<std::uint8_t>::max)())
628
+ {
629
+ std::uint8_t output_type{};
630
+ bool fixed = true;
631
+ if (use_ext)
632
+ {
633
+ switch (N)
634
+ {
635
+ case 1:
636
+ output_type = 0xD4; // fixext 1
637
+ break;
638
+ case 2:
639
+ output_type = 0xD5; // fixext 2
640
+ break;
641
+ case 4:
642
+ output_type = 0xD6; // fixext 4
643
+ break;
644
+ case 8:
645
+ output_type = 0xD7; // fixext 8
646
+ break;
647
+ case 16:
648
+ output_type = 0xD8; // fixext 16
649
+ break;
650
+ default:
651
+ output_type = 0xC7; // ext 8
652
+ fixed = false;
653
+ break;
654
+ }
655
+
656
+ }
657
+ else
658
+ {
659
+ output_type = 0xC4; // bin 8
660
+ fixed = false;
661
+ }
662
+
663
+ oa->write_character(to_char_type(output_type));
664
+ if (!fixed)
665
+ {
666
+ write_number(static_cast<std::uint8_t>(N));
667
+ }
668
+ }
669
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
670
+ {
671
+ const std::uint8_t output_type = use_ext
672
+ ? 0xC8 // ext 16
673
+ : 0xC5; // bin 16
674
+
675
+ oa->write_character(to_char_type(output_type));
676
+ write_number(static_cast<std::uint16_t>(N));
677
+ }
678
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
679
+ {
680
+ const std::uint8_t output_type = use_ext
681
+ ? 0xC9 // ext 32
682
+ : 0xC6; // bin 32
683
+
684
+ oa->write_character(to_char_type(output_type));
685
+ write_number(static_cast<std::uint32_t>(N));
686
+ }
687
+
688
+ // step 1.5: if this is an ext type, write the subtype
689
+ if (use_ext)
690
+ {
691
+ write_number(static_cast<std::int8_t>(j.m_data.m_value.binary->subtype()));
692
+ }
693
+
694
+ // step 2: write the byte string
695
+ oa->write_characters(
696
+ reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
697
+ N);
698
+
699
+ break;
700
+ }
701
+
702
+ case value_t::object:
703
+ {
704
+ // step 1: write control byte and the object size
705
+ const auto N = j.m_data.m_value.object->size();
706
+ if (N <= 15)
707
+ {
708
+ // fixmap
709
+ write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
710
+ }
711
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
712
+ {
713
+ // map 16
714
+ oa->write_character(to_char_type(0xDE));
715
+ write_number(static_cast<std::uint16_t>(N));
716
+ }
717
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
718
+ {
719
+ // map 32
720
+ oa->write_character(to_char_type(0xDF));
721
+ write_number(static_cast<std::uint32_t>(N));
722
+ }
723
+
724
+ // step 2: write each element
725
+ for (const auto& el : *j.m_data.m_value.object)
726
+ {
727
+ write_msgpack(el.first);
728
+ write_msgpack(el.second);
729
+ }
730
+ break;
731
+ }
732
+
733
+ case value_t::discarded:
734
+ default:
735
+ break;
736
+ }
737
+ }
738
+
739
+ /*!
740
+ @param[in] j JSON value to serialize
741
+ @param[in] use_count whether to use '#' prefixes (optimized format)
742
+ @param[in] use_type whether to use '$' prefixes (optimized format)
743
+ @param[in] add_prefix whether prefixes need to be used for this value
744
+ @param[in] use_bjdata whether write in BJData format, default is false
745
+ @param[in] bjdata_version which BJData version to use, default is draft2
746
+ */
747
+ void write_ubjson(const BasicJsonType& j, const bool use_count,
748
+ const bool use_type, const bool add_prefix = true,
749
+ const bool use_bjdata = false, const bjdata_version_t bjdata_version = bjdata_version_t::draft2)
750
+ {
751
+ const bool bjdata_draft3 = use_bjdata && bjdata_version == bjdata_version_t::draft3;
752
+
753
+ switch (j.type())
754
+ {
755
+ case value_t::null:
756
+ {
757
+ if (add_prefix)
758
+ {
759
+ oa->write_character(to_char_type('Z'));
760
+ }
761
+ break;
762
+ }
763
+
764
+ case value_t::boolean:
765
+ {
766
+ if (add_prefix)
767
+ {
768
+ oa->write_character(j.m_data.m_value.boolean
769
+ ? to_char_type('T')
770
+ : to_char_type('F'));
771
+ }
772
+ break;
773
+ }
774
+
775
+ case value_t::number_integer:
776
+ {
777
+ write_number_with_ubjson_prefix(j.m_data.m_value.number_integer, add_prefix, use_bjdata);
778
+ break;
779
+ }
780
+
781
+ case value_t::number_unsigned:
782
+ {
783
+ write_number_with_ubjson_prefix(j.m_data.m_value.number_unsigned, add_prefix, use_bjdata);
784
+ break;
785
+ }
786
+
787
+ case value_t::number_float:
788
+ {
789
+ write_number_with_ubjson_prefix(j.m_data.m_value.number_float, add_prefix, use_bjdata);
790
+ break;
791
+ }
792
+
793
+ case value_t::string:
794
+ {
795
+ if (add_prefix)
796
+ {
797
+ oa->write_character(to_char_type('S'));
798
+ }
799
+ write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);
800
+ oa->write_characters(
801
+ reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
802
+ j.m_data.m_value.string->size());
803
+ break;
804
+ }
805
+
806
+ case value_t::array:
807
+ {
808
+ if (add_prefix)
809
+ {
810
+ oa->write_character(to_char_type('['));
811
+ }
812
+
813
+ bool prefix_required = true;
814
+ if (use_type && !j.m_data.m_value.array->empty())
815
+ {
816
+ JSON_ASSERT(use_count);
817
+ const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
818
+ const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
819
+ [this, first_prefix, use_bjdata](const BasicJsonType & v)
820
+ {
821
+ return ubjson_prefix(v, use_bjdata) == first_prefix;
822
+ });
823
+
824
+ std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
825
+
826
+ if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
827
+ {
828
+ prefix_required = false;
829
+ oa->write_character(to_char_type('$'));
830
+ oa->write_character(first_prefix);
831
+ }
832
+ }
833
+
834
+ if (use_count)
835
+ {
836
+ oa->write_character(to_char_type('#'));
837
+ write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);
838
+ }
839
+
840
+ for (const auto& el : *j.m_data.m_value.array)
841
+ {
842
+ write_ubjson(el, use_count, use_type, prefix_required, use_bjdata, bjdata_version);
843
+ }
844
+
845
+ if (!use_count)
846
+ {
847
+ oa->write_character(to_char_type(']'));
848
+ }
849
+
850
+ break;
851
+ }
852
+
853
+ case value_t::binary:
854
+ {
855
+ if (add_prefix)
856
+ {
857
+ oa->write_character(to_char_type('['));
858
+ }
859
+
860
+ if (use_type && (bjdata_draft3 || !j.m_data.m_value.binary->empty()))
861
+ {
862
+ JSON_ASSERT(use_count);
863
+ oa->write_character(to_char_type('$'));
864
+ oa->write_character(bjdata_draft3 ? 'B' : 'U');
865
+ }
866
+
867
+ if (use_count)
868
+ {
869
+ oa->write_character(to_char_type('#'));
870
+ write_number_with_ubjson_prefix(j.m_data.m_value.binary->size(), true, use_bjdata);
871
+ }
872
+
873
+ if (use_type)
874
+ {
875
+ oa->write_characters(
876
+ reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
877
+ j.m_data.m_value.binary->size());
878
+ }
879
+ else
880
+ {
881
+ for (size_t i = 0; i < j.m_data.m_value.binary->size(); ++i)
882
+ {
883
+ oa->write_character(to_char_type(bjdata_draft3 ? 'B' : 'U'));
884
+ oa->write_character(j.m_data.m_value.binary->data()[i]);
885
+ }
886
+ }
887
+
888
+ if (!use_count)
889
+ {
890
+ oa->write_character(to_char_type(']'));
891
+ }
892
+
893
+ break;
894
+ }
895
+
896
+ case value_t::object:
897
+ {
898
+ if (use_bjdata && j.m_data.m_value.object->size() == 3 && j.m_data.m_value.object->find("_ArrayType_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArraySize_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArrayData_") != j.m_data.m_value.object->end())
899
+ {
900
+ if (!write_bjdata_ndarray(*j.m_data.m_value.object, use_count, use_type, bjdata_version)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
901
+ {
902
+ break;
903
+ }
904
+ }
905
+
906
+ if (add_prefix)
907
+ {
908
+ oa->write_character(to_char_type('{'));
909
+ }
910
+
911
+ bool prefix_required = true;
912
+ if (use_type && !j.m_data.m_value.object->empty())
913
+ {
914
+ JSON_ASSERT(use_count);
915
+ const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
916
+ const bool same_prefix = std::all_of(j.begin(), j.end(),
917
+ [this, first_prefix, use_bjdata](const BasicJsonType & v)
918
+ {
919
+ return ubjson_prefix(v, use_bjdata) == first_prefix;
920
+ });
921
+
922
+ std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
923
+
924
+ if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
925
+ {
926
+ prefix_required = false;
927
+ oa->write_character(to_char_type('$'));
928
+ oa->write_character(first_prefix);
929
+ }
930
+ }
931
+
932
+ if (use_count)
933
+ {
934
+ oa->write_character(to_char_type('#'));
935
+ write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);
936
+ }
937
+
938
+ for (const auto& el : *j.m_data.m_value.object)
939
+ {
940
+ write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
941
+ oa->write_characters(
942
+ reinterpret_cast<const CharType*>(el.first.c_str()),
943
+ el.first.size());
944
+ write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata, bjdata_version);
945
+ }
946
+
947
+ if (!use_count)
948
+ {
949
+ oa->write_character(to_char_type('}'));
950
+ }
951
+
952
+ break;
953
+ }
954
+
955
+ case value_t::discarded:
956
+ default:
957
+ break;
958
+ }
959
+ }
960
+
961
+ private:
962
+ //////////
963
+ // BSON //
964
+ //////////
965
+
966
+ /*!
967
+ @return The size of a BSON document entry header, including the id marker
968
+ and the entry name size (and its null-terminator).
969
+ */
970
+ static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
971
+ {
972
+ const auto it = name.find(static_cast<typename string_t::value_type>(0));
973
+ if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
974
+ {
975
+ JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
976
+ static_cast<void>(j);
977
+ }
978
+
979
+ return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
980
+ }
981
+
982
+ /*!
983
+ @brief Writes the given @a element_type and @a name to the output adapter
984
+ */
985
+ void write_bson_entry_header(const string_t& name,
986
+ const std::uint8_t element_type)
987
+ {
988
+ oa->write_character(to_char_type(element_type)); // boolean
989
+ oa->write_characters(
990
+ reinterpret_cast<const CharType*>(name.c_str()),
991
+ name.size() + 1u);
992
+ }
993
+
994
+ /*!
995
+ @brief Writes a BSON element with key @a name and boolean value @a value
996
+ */
997
+ void write_bson_boolean(const string_t& name,
998
+ const bool value)
999
+ {
1000
+ write_bson_entry_header(name, 0x08);
1001
+ oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
1002
+ }
1003
+
1004
+ /*!
1005
+ @brief Writes a BSON element with key @a name and double value @a value
1006
+ */
1007
+ void write_bson_double(const string_t& name,
1008
+ const double value)
1009
+ {
1010
+ write_bson_entry_header(name, 0x01);
1011
+ write_number<double>(value, true);
1012
+ }
1013
+
1014
+ /*!
1015
+ @return The size of the BSON-encoded string in @a value
1016
+ */
1017
+ static std::size_t calc_bson_string_size(const string_t& value)
1018
+ {
1019
+ return sizeof(std::int32_t) + value.size() + 1ul;
1020
+ }
1021
+
1022
+ /*!
1023
+ @brief Writes a BSON element with key @a name and string value @a value
1024
+ */
1025
+ void write_bson_string(const string_t& name,
1026
+ const string_t& value)
1027
+ {
1028
+ write_bson_entry_header(name, 0x02);
1029
+
1030
+ write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
1031
+ oa->write_characters(
1032
+ reinterpret_cast<const CharType*>(value.c_str()),
1033
+ value.size() + 1);
1034
+ }
1035
+
1036
+ /*!
1037
+ @brief Writes a BSON element with key @a name and null value
1038
+ */
1039
+ void write_bson_null(const string_t& name)
1040
+ {
1041
+ write_bson_entry_header(name, 0x0A);
1042
+ }
1043
+
1044
+ /*!
1045
+ @return The size of the BSON-encoded integer @a value
1046
+ */
1047
+ static std::size_t calc_bson_integer_size(const std::int64_t value)
1048
+ {
1049
+ return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
1050
+ ? sizeof(std::int32_t)
1051
+ : sizeof(std::int64_t);
1052
+ }
1053
+
1054
+ /*!
1055
+ @brief Writes a BSON element with key @a name and integer @a value
1056
+ */
1057
+ void write_bson_integer(const string_t& name,
1058
+ const std::int64_t value)
1059
+ {
1060
+ if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
1061
+ {
1062
+ write_bson_entry_header(name, 0x10); // int32
1063
+ write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
1064
+ }
1065
+ else
1066
+ {
1067
+ write_bson_entry_header(name, 0x12); // int64
1068
+ write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
1069
+ }
1070
+ }
1071
+
1072
+ /*!
1073
+ @return The size of the BSON-encoded unsigned integer in @a j
1074
+ */
1075
+ static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
1076
+ {
1077
+ return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1078
+ ? sizeof(std::int32_t)
1079
+ : sizeof(std::int64_t);
1080
+ }
1081
+
1082
+ /*!
1083
+ @brief Writes a BSON element with key @a name and unsigned @a value
1084
+ */
1085
+ void write_bson_unsigned(const string_t& name,
1086
+ const BasicJsonType& j)
1087
+ {
1088
+ if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1089
+ {
1090
+ write_bson_entry_header(name, 0x10 /* int32 */);
1091
+ write_number<std::int32_t>(static_cast<std::int32_t>(j.m_data.m_value.number_unsigned), true);
1092
+ }
1093
+ else if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
1094
+ {
1095
+ write_bson_entry_header(name, 0x12 /* int64 */);
1096
+ write_number<std::int64_t>(static_cast<std::int64_t>(j.m_data.m_value.number_unsigned), true);
1097
+ }
1098
+ else
1099
+ {
1100
+ write_bson_entry_header(name, 0x11 /* uint64 */);
1101
+ write_number<std::uint64_t>(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned), true);
1102
+ }
1103
+ }
1104
+
1105
+ /*!
1106
+ @brief Writes a BSON element with key @a name and object @a value
1107
+ */
1108
+ void write_bson_object_entry(const string_t& name,
1109
+ const typename BasicJsonType::object_t& value)
1110
+ {
1111
+ write_bson_entry_header(name, 0x03); // object
1112
+ write_bson_object(value);
1113
+ }
1114
+
1115
+ /*!
1116
+ @return The size of the BSON-encoded array @a value
1117
+ */
1118
+ static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
1119
+ {
1120
+ std::size_t array_index = 0ul;
1121
+
1122
+ const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
1123
+ {
1124
+ return result + calc_bson_element_size(std::to_string(array_index++), el);
1125
+ });
1126
+
1127
+ return sizeof(std::int32_t) + embedded_document_size + 1ul;
1128
+ }
1129
+
1130
+ /*!
1131
+ @return The size of the BSON-encoded binary array @a value
1132
+ */
1133
+ static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
1134
+ {
1135
+ return sizeof(std::int32_t) + value.size() + 1ul;
1136
+ }
1137
+
1138
+ /*!
1139
+ @brief Writes a BSON element with key @a name and array @a value
1140
+ */
1141
+ void write_bson_array(const string_t& name,
1142
+ const typename BasicJsonType::array_t& value)
1143
+ {
1144
+ write_bson_entry_header(name, 0x04); // array
1145
+ write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
1146
+
1147
+ std::size_t array_index = 0ul;
1148
+
1149
+ for (const auto& el : value)
1150
+ {
1151
+ write_bson_element(std::to_string(array_index++), el);
1152
+ }
1153
+
1154
+ oa->write_character(to_char_type(0x00));
1155
+ }
1156
+
1157
+ /*!
1158
+ @brief Writes a BSON element with key @a name and binary value @a value
1159
+ */
1160
+ void write_bson_binary(const string_t& name,
1161
+ const binary_t& value)
1162
+ {
1163
+ write_bson_entry_header(name, 0x05);
1164
+
1165
+ write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
1166
+ write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
1167
+
1168
+ oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
1169
+ }
1170
+
1171
+ /*!
1172
+ @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
1173
+ @return The calculated size for the BSON document entry for @a j with the given @a name.
1174
+ */
1175
+ static std::size_t calc_bson_element_size(const string_t& name,
1176
+ const BasicJsonType& j)
1177
+ {
1178
+ const auto header_size = calc_bson_entry_header_size(name, j);
1179
+ switch (j.type())
1180
+ {
1181
+ case value_t::object:
1182
+ return header_size + calc_bson_object_size(*j.m_data.m_value.object);
1183
+
1184
+ case value_t::array:
1185
+ return header_size + calc_bson_array_size(*j.m_data.m_value.array);
1186
+
1187
+ case value_t::binary:
1188
+ return header_size + calc_bson_binary_size(*j.m_data.m_value.binary);
1189
+
1190
+ case value_t::boolean:
1191
+ return header_size + 1ul;
1192
+
1193
+ case value_t::number_float:
1194
+ return header_size + 8ul;
1195
+
1196
+ case value_t::number_integer:
1197
+ return header_size + calc_bson_integer_size(j.m_data.m_value.number_integer);
1198
+
1199
+ case value_t::number_unsigned:
1200
+ return header_size + calc_bson_unsigned_size(j.m_data.m_value.number_unsigned);
1201
+
1202
+ case value_t::string:
1203
+ return header_size + calc_bson_string_size(*j.m_data.m_value.string);
1204
+
1205
+ case value_t::null:
1206
+ return header_size + 0ul;
1207
+
1208
+ // LCOV_EXCL_START
1209
+ case value_t::discarded:
1210
+ default:
1211
+ JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
1212
+ return 0ul;
1213
+ // LCOV_EXCL_STOP
1214
+ }
1215
+ }
1216
+
1217
+ /*!
1218
+ @brief Serializes the JSON value @a j to BSON and associates it with the
1219
+ key @a name.
1220
+ @param name The name to associate with the JSON entity @a j within the
1221
+ current BSON document
1222
+ */
1223
+ void write_bson_element(const string_t& name,
1224
+ const BasicJsonType& j)
1225
+ {
1226
+ switch (j.type())
1227
+ {
1228
+ case value_t::object:
1229
+ return write_bson_object_entry(name, *j.m_data.m_value.object);
1230
+
1231
+ case value_t::array:
1232
+ return write_bson_array(name, *j.m_data.m_value.array);
1233
+
1234
+ case value_t::binary:
1235
+ return write_bson_binary(name, *j.m_data.m_value.binary);
1236
+
1237
+ case value_t::boolean:
1238
+ return write_bson_boolean(name, j.m_data.m_value.boolean);
1239
+
1240
+ case value_t::number_float:
1241
+ return write_bson_double(name, j.m_data.m_value.number_float);
1242
+
1243
+ case value_t::number_integer:
1244
+ return write_bson_integer(name, j.m_data.m_value.number_integer);
1245
+
1246
+ case value_t::number_unsigned:
1247
+ return write_bson_unsigned(name, j);
1248
+
1249
+ case value_t::string:
1250
+ return write_bson_string(name, *j.m_data.m_value.string);
1251
+
1252
+ case value_t::null:
1253
+ return write_bson_null(name);
1254
+
1255
+ // LCOV_EXCL_START
1256
+ case value_t::discarded:
1257
+ default:
1258
+ JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
1259
+ return;
1260
+ // LCOV_EXCL_STOP
1261
+ }
1262
+ }
1263
+
1264
+ /*!
1265
+ @brief Calculates the size of the BSON serialization of the given
1266
+ JSON-object @a j.
1267
+ @param[in] value JSON value to serialize
1268
+ @pre value.type() == value_t::object
1269
+ */
1270
+ static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
1271
+ {
1272
+ const std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
1273
+ [](size_t result, const typename BasicJsonType::object_t::value_type & el)
1274
+ {
1275
+ return result += calc_bson_element_size(el.first, el.second);
1276
+ });
1277
+
1278
+ return sizeof(std::int32_t) + document_size + 1ul;
1279
+ }
1280
+
1281
+ /*!
1282
+ @param[in] value JSON value to serialize
1283
+ @pre value.type() == value_t::object
1284
+ */
1285
+ void write_bson_object(const typename BasicJsonType::object_t& value)
1286
+ {
1287
+ write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
1288
+
1289
+ for (const auto& el : value)
1290
+ {
1291
+ write_bson_element(el.first, el.second);
1292
+ }
1293
+
1294
+ oa->write_character(to_char_type(0x00));
1295
+ }
1296
+
1297
+ //////////
1298
+ // CBOR //
1299
+ //////////
1300
+
1301
+ static constexpr CharType get_cbor_float_prefix(float /*unused*/)
1302
+ {
1303
+ return to_char_type(0xFA); // Single-Precision Float
1304
+ }
1305
+
1306
+ static constexpr CharType get_cbor_float_prefix(double /*unused*/)
1307
+ {
1308
+ return to_char_type(0xFB); // Double-Precision Float
1309
+ }
1310
+
1311
+ /////////////
1312
+ // MsgPack //
1313
+ /////////////
1314
+
1315
+ static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
1316
+ {
1317
+ return to_char_type(0xCA); // float 32
1318
+ }
1319
+
1320
+ static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
1321
+ {
1322
+ return to_char_type(0xCB); // float 64
1323
+ }
1324
+
1325
+ ////////////
1326
+ // UBJSON //
1327
+ ////////////
1328
+
1329
+ // UBJSON: write number (floating point)
1330
+ template<typename NumberType, typename std::enable_if<
1331
+ std::is_floating_point<NumberType>::value, int>::type = 0>
1332
+ void write_number_with_ubjson_prefix(const NumberType n,
1333
+ const bool add_prefix,
1334
+ const bool use_bjdata)
1335
+ {
1336
+ if (add_prefix)
1337
+ {
1338
+ oa->write_character(get_ubjson_float_prefix(n));
1339
+ }
1340
+ write_number(n, use_bjdata);
1341
+ }
1342
+
1343
+ // UBJSON: write number (unsigned integer)
1344
+ template<typename NumberType, typename std::enable_if<
1345
+ std::is_unsigned<NumberType>::value, int>::type = 0>
1346
+ void write_number_with_ubjson_prefix(const NumberType n,
1347
+ const bool add_prefix,
1348
+ const bool use_bjdata)
1349
+ {
1350
+ if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
1351
+ {
1352
+ if (add_prefix)
1353
+ {
1354
+ oa->write_character(to_char_type('i')); // int8
1355
+ }
1356
+ write_number(static_cast<std::uint8_t>(n), use_bjdata);
1357
+ }
1358
+ else if (n <= (std::numeric_limits<std::uint8_t>::max)())
1359
+ {
1360
+ if (add_prefix)
1361
+ {
1362
+ oa->write_character(to_char_type('U')); // uint8
1363
+ }
1364
+ write_number(static_cast<std::uint8_t>(n), use_bjdata);
1365
+ }
1366
+ else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
1367
+ {
1368
+ if (add_prefix)
1369
+ {
1370
+ oa->write_character(to_char_type('I')); // int16
1371
+ }
1372
+ write_number(static_cast<std::int16_t>(n), use_bjdata);
1373
+ }
1374
+ else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
1375
+ {
1376
+ if (add_prefix)
1377
+ {
1378
+ oa->write_character(to_char_type('u')); // uint16 - bjdata only
1379
+ }
1380
+ write_number(static_cast<std::uint16_t>(n), use_bjdata);
1381
+ }
1382
+ else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1383
+ {
1384
+ if (add_prefix)
1385
+ {
1386
+ oa->write_character(to_char_type('l')); // int32
1387
+ }
1388
+ write_number(static_cast<std::int32_t>(n), use_bjdata);
1389
+ }
1390
+ else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
1391
+ {
1392
+ if (add_prefix)
1393
+ {
1394
+ oa->write_character(to_char_type('m')); // uint32 - bjdata only
1395
+ }
1396
+ write_number(static_cast<std::uint32_t>(n), use_bjdata);
1397
+ }
1398
+ else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
1399
+ {
1400
+ if (add_prefix)
1401
+ {
1402
+ oa->write_character(to_char_type('L')); // int64
1403
+ }
1404
+ write_number(static_cast<std::int64_t>(n), use_bjdata);
1405
+ }
1406
+ else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
1407
+ {
1408
+ if (add_prefix)
1409
+ {
1410
+ oa->write_character(to_char_type('M')); // uint64 - bjdata only
1411
+ }
1412
+ write_number(static_cast<std::uint64_t>(n), use_bjdata);
1413
+ }
1414
+ else
1415
+ {
1416
+ if (add_prefix)
1417
+ {
1418
+ oa->write_character(to_char_type('H')); // high-precision number
1419
+ }
1420
+
1421
+ const auto number = BasicJsonType(n).dump();
1422
+ write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
1423
+ for (std::size_t i = 0; i < number.size(); ++i)
1424
+ {
1425
+ oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
1426
+ }
1427
+ }
1428
+ }
1429
+
1430
+ // UBJSON: write number (signed integer)
1431
+ template < typename NumberType, typename std::enable_if <
1432
+ std::is_signed<NumberType>::value&&
1433
+ !std::is_floating_point<NumberType>::value, int >::type = 0 >
1434
+ void write_number_with_ubjson_prefix(const NumberType n,
1435
+ const bool add_prefix,
1436
+ const bool use_bjdata)
1437
+ {
1438
+ if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
1439
+ {
1440
+ if (add_prefix)
1441
+ {
1442
+ oa->write_character(to_char_type('i')); // int8
1443
+ }
1444
+ write_number(static_cast<std::int8_t>(n), use_bjdata);
1445
+ }
1446
+ else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
1447
+ {
1448
+ if (add_prefix)
1449
+ {
1450
+ oa->write_character(to_char_type('U')); // uint8
1451
+ }
1452
+ write_number(static_cast<std::uint8_t>(n), use_bjdata);
1453
+ }
1454
+ else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
1455
+ {
1456
+ if (add_prefix)
1457
+ {
1458
+ oa->write_character(to_char_type('I')); // int16
1459
+ }
1460
+ write_number(static_cast<std::int16_t>(n), use_bjdata);
1461
+ }
1462
+ else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
1463
+ {
1464
+ if (add_prefix)
1465
+ {
1466
+ oa->write_character(to_char_type('u')); // uint16 - bjdata only
1467
+ }
1468
+ write_number(static_cast<uint16_t>(n), use_bjdata);
1469
+ }
1470
+ else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
1471
+ {
1472
+ if (add_prefix)
1473
+ {
1474
+ oa->write_character(to_char_type('l')); // int32
1475
+ }
1476
+ write_number(static_cast<std::int32_t>(n), use_bjdata);
1477
+ }
1478
+ else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
1479
+ {
1480
+ if (add_prefix)
1481
+ {
1482
+ oa->write_character(to_char_type('m')); // uint32 - bjdata only
1483
+ }
1484
+ write_number(static_cast<uint32_t>(n), use_bjdata);
1485
+ }
1486
+ else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
1487
+ {
1488
+ if (add_prefix)
1489
+ {
1490
+ oa->write_character(to_char_type('L')); // int64
1491
+ }
1492
+ write_number(static_cast<std::int64_t>(n), use_bjdata);
1493
+ }
1494
+ // LCOV_EXCL_START
1495
+ else
1496
+ {
1497
+ if (add_prefix)
1498
+ {
1499
+ oa->write_character(to_char_type('H')); // high-precision number
1500
+ }
1501
+
1502
+ const auto number = BasicJsonType(n).dump();
1503
+ write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
1504
+ for (std::size_t i = 0; i < number.size(); ++i)
1505
+ {
1506
+ oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
1507
+ }
1508
+ }
1509
+ // LCOV_EXCL_STOP
1510
+ }
1511
+
1512
+ /*!
1513
+ @brief determine the type prefix of container values
1514
+ */
1515
+ CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
1516
+ {
1517
+ switch (j.type())
1518
+ {
1519
+ case value_t::null:
1520
+ return 'Z';
1521
+
1522
+ case value_t::boolean:
1523
+ return j.m_data.m_value.boolean ? 'T' : 'F';
1524
+
1525
+ case value_t::number_integer:
1526
+ {
1527
+ if ((std::numeric_limits<std::int8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
1528
+ {
1529
+ return 'i';
1530
+ }
1531
+ if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
1532
+ {
1533
+ return 'U';
1534
+ }
1535
+ if ((std::numeric_limits<std::int16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
1536
+ {
1537
+ return 'I';
1538
+ }
1539
+ if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
1540
+ {
1541
+ return 'u';
1542
+ }
1543
+ if ((std::numeric_limits<std::int32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
1544
+ {
1545
+ return 'l';
1546
+ }
1547
+ if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
1548
+ {
1549
+ return 'm';
1550
+ }
1551
+ if ((std::numeric_limits<std::int64_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
1552
+ {
1553
+ return 'L';
1554
+ }
1555
+ // anything else is treated as high-precision number
1556
+ return 'H'; // LCOV_EXCL_LINE
1557
+ }
1558
+
1559
+ case value_t::number_unsigned:
1560
+ {
1561
+ if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
1562
+ {
1563
+ return 'i';
1564
+ }
1565
+ if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
1566
+ {
1567
+ return 'U';
1568
+ }
1569
+ if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
1570
+ {
1571
+ return 'I';
1572
+ }
1573
+ if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
1574
+ {
1575
+ return 'u';
1576
+ }
1577
+ if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1578
+ {
1579
+ return 'l';
1580
+ }
1581
+ if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
1582
+ {
1583
+ return 'm';
1584
+ }
1585
+ if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
1586
+ {
1587
+ return 'L';
1588
+ }
1589
+ if (use_bjdata && j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
1590
+ {
1591
+ return 'M';
1592
+ }
1593
+ // anything else is treated as high-precision number
1594
+ return 'H'; // LCOV_EXCL_LINE
1595
+ }
1596
+
1597
+ case value_t::number_float:
1598
+ return get_ubjson_float_prefix(j.m_data.m_value.number_float);
1599
+
1600
+ case value_t::string:
1601
+ return 'S';
1602
+
1603
+ case value_t::array: // fallthrough
1604
+ case value_t::binary:
1605
+ return '[';
1606
+
1607
+ case value_t::object:
1608
+ return '{';
1609
+
1610
+ case value_t::discarded:
1611
+ default: // discarded values
1612
+ return 'N';
1613
+ }
1614
+ }
1615
+
1616
+ static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
1617
+ {
1618
+ return 'd'; // float 32
1619
+ }
1620
+
1621
+ static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
1622
+ {
1623
+ return 'D'; // float 64
1624
+ }
1625
+
1626
+ /*!
1627
+ @return false if the object is successfully converted to a bjdata ndarray, true if the type or size is invalid
1628
+ */
1629
+ bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type, const bjdata_version_t bjdata_version)
1630
+ {
1631
+ std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
1632
+ {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'},
1633
+ {"char", 'C'}, {"byte", 'B'}
1634
+ };
1635
+
1636
+ string_t key = "_ArrayType_";
1637
+ auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
1638
+ if (it == bjdtype.end())
1639
+ {
1640
+ return true;
1641
+ }
1642
+ CharType dtype = it->second;
1643
+
1644
+ key = "_ArraySize_";
1645
+ std::size_t len = (value.at(key).empty() ? 0 : 1);
1646
+ for (const auto& el : value.at(key))
1647
+ {
1648
+ len *= static_cast<std::size_t>(el.m_data.m_value.number_unsigned);
1649
+ }
1650
+
1651
+ key = "_ArrayData_";
1652
+ if (value.at(key).size() != len)
1653
+ {
1654
+ return true;
1655
+ }
1656
+
1657
+ oa->write_character('[');
1658
+ oa->write_character('$');
1659
+ oa->write_character(dtype);
1660
+ oa->write_character('#');
1661
+
1662
+ key = "_ArraySize_";
1663
+ write_ubjson(value.at(key), use_count, use_type, true, true, bjdata_version);
1664
+
1665
+ key = "_ArrayData_";
1666
+ if (dtype == 'U' || dtype == 'C' || dtype == 'B')
1667
+ {
1668
+ for (const auto& el : value.at(key))
1669
+ {
1670
+ write_number(static_cast<std::uint8_t>(el.m_data.m_value.number_unsigned), true);
1671
+ }
1672
+ }
1673
+ else if (dtype == 'i')
1674
+ {
1675
+ for (const auto& el : value.at(key))
1676
+ {
1677
+ write_number(static_cast<std::int8_t>(el.m_data.m_value.number_integer), true);
1678
+ }
1679
+ }
1680
+ else if (dtype == 'u')
1681
+ {
1682
+ for (const auto& el : value.at(key))
1683
+ {
1684
+ write_number(static_cast<std::uint16_t>(el.m_data.m_value.number_unsigned), true);
1685
+ }
1686
+ }
1687
+ else if (dtype == 'I')
1688
+ {
1689
+ for (const auto& el : value.at(key))
1690
+ {
1691
+ write_number(static_cast<std::int16_t>(el.m_data.m_value.number_integer), true);
1692
+ }
1693
+ }
1694
+ else if (dtype == 'm')
1695
+ {
1696
+ for (const auto& el : value.at(key))
1697
+ {
1698
+ write_number(static_cast<std::uint32_t>(el.m_data.m_value.number_unsigned), true);
1699
+ }
1700
+ }
1701
+ else if (dtype == 'l')
1702
+ {
1703
+ for (const auto& el : value.at(key))
1704
+ {
1705
+ write_number(static_cast<std::int32_t>(el.m_data.m_value.number_integer), true);
1706
+ }
1707
+ }
1708
+ else if (dtype == 'M')
1709
+ {
1710
+ for (const auto& el : value.at(key))
1711
+ {
1712
+ write_number(static_cast<std::uint64_t>(el.m_data.m_value.number_unsigned), true);
1713
+ }
1714
+ }
1715
+ else if (dtype == 'L')
1716
+ {
1717
+ for (const auto& el : value.at(key))
1718
+ {
1719
+ write_number(static_cast<std::int64_t>(el.m_data.m_value.number_integer), true);
1720
+ }
1721
+ }
1722
+ else if (dtype == 'd')
1723
+ {
1724
+ for (const auto& el : value.at(key))
1725
+ {
1726
+ write_number(static_cast<float>(el.m_data.m_value.number_float), true);
1727
+ }
1728
+ }
1729
+ else if (dtype == 'D')
1730
+ {
1731
+ for (const auto& el : value.at(key))
1732
+ {
1733
+ write_number(static_cast<double>(el.m_data.m_value.number_float), true);
1734
+ }
1735
+ }
1736
+ return false;
1737
+ }
1738
+
1739
+ ///////////////////////
1740
+ // Utility functions //
1741
+ ///////////////////////
1742
+
1743
+ /*
1744
+ @brief write a number to output input
1745
+ @param[in] n number of type @a NumberType
1746
+ @param[in] OutputIsLittleEndian Set to true if output data is
1747
+ required to be little endian
1748
+ @tparam NumberType the type of the number
1749
+
1750
+ @note This function needs to respect the system's endianness, because bytes
1751
+ in CBOR, MessagePack, and UBJSON are stored in network order (big
1752
+ endian) and therefore need reordering on little endian systems.
1753
+ On the other hand, BSON and BJData use little endian and should reorder
1754
+ on big endian systems.
1755
+ */
1756
+ template<typename NumberType>
1757
+ void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
1758
+ {
1759
+ // step 1: write number to array of length NumberType
1760
+ std::array<CharType, sizeof(NumberType)> vec{};
1761
+ std::memcpy(vec.data(), &n, sizeof(NumberType));
1762
+
1763
+ // step 2: write array to output (with possible reordering)
1764
+ if (is_little_endian != OutputIsLittleEndian)
1765
+ {
1766
+ // reverse byte order prior to conversion if necessary
1767
+ std::reverse(vec.begin(), vec.end());
1768
+ }
1769
+
1770
+ oa->write_characters(vec.data(), sizeof(NumberType));
1771
+ }
1772
+
1773
+ void write_compact_float(const number_float_t n, detail::input_format_t format)
1774
+ {
1775
+ #ifdef __GNUC__
1776
+ #pragma GCC diagnostic push
1777
+ #pragma GCC diagnostic ignored "-Wfloat-equal"
1778
+ #endif
1779
+ if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
1780
+ static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
1781
+ static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
1782
+ {
1783
+ oa->write_character(format == detail::input_format_t::cbor
1784
+ ? get_cbor_float_prefix(static_cast<float>(n))
1785
+ : get_msgpack_float_prefix(static_cast<float>(n)));
1786
+ write_number(static_cast<float>(n));
1787
+ }
1788
+ else
1789
+ {
1790
+ oa->write_character(format == detail::input_format_t::cbor
1791
+ ? get_cbor_float_prefix(n)
1792
+ : get_msgpack_float_prefix(n));
1793
+ write_number(n);
1794
+ }
1795
+ #ifdef __GNUC__
1796
+ #pragma GCC diagnostic pop
1797
+ #endif
1798
+ }
1799
+
1800
+ public:
1801
+ // The following to_char_type functions are implement the conversion
1802
+ // between uint8_t and CharType. In case CharType is not unsigned,
1803
+ // such a conversion is required to allow values greater than 128.
1804
+ // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
1805
+ template < typename C = CharType,
1806
+ enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
1807
+ static constexpr CharType to_char_type(std::uint8_t x) noexcept
1808
+ {
1809
+ return *reinterpret_cast<char*>(&x);
1810
+ }
1811
+
1812
+ template < typename C = CharType,
1813
+ enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
1814
+ static CharType to_char_type(std::uint8_t x) noexcept
1815
+ {
1816
+ static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
1817
+ static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
1818
+ CharType result;
1819
+ std::memcpy(&result, &x, sizeof(x));
1820
+ return result;
1821
+ }
1822
+
1823
+ template<typename C = CharType,
1824
+ enable_if_t<std::is_unsigned<C>::value>* = nullptr>
1825
+ static constexpr CharType to_char_type(std::uint8_t x) noexcept
1826
+ {
1827
+ return x;
1828
+ }
1829
+
1830
+ template < typename InputCharType, typename C = CharType,
1831
+ enable_if_t <
1832
+ std::is_signed<C>::value &&
1833
+ std::is_signed<char>::value &&
1834
+ std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
1835
+ > * = nullptr >
1836
+ static constexpr CharType to_char_type(InputCharType x) noexcept
1837
+ {
1838
+ return x;
1839
+ }
1840
+
1841
+ private:
1842
+ /// whether we can assume little endianness
1843
+ const bool is_little_endian = little_endianness();
1844
+
1845
+ /// the output
1846
+ output_adapter_t<CharType> oa = nullptr;
1847
+ };
1848
+
1849
+ } // namespace detail
1850
+ NLOHMANN_JSON_NAMESPACE_END