koffi 0.9.2 → 0.9.5

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 (416) hide show
  1. package/CMakeLists.txt +60 -60
  2. package/README.md +163 -153
  3. package/package.json +19 -18
  4. package/src/call.hh +27 -27
  5. package/src/call_arm64.cc +482 -482
  6. package/src/call_arm64_fwd.S +115 -115
  7. package/src/call_x64_sysv.cc +477 -477
  8. package/src/call_x64_sysv_fwd.S +131 -131
  9. package/src/call_x64_win.cc +243 -243
  10. package/src/call_x64_win_fwd.asm +105 -105
  11. package/src/call_x86.cc +259 -259
  12. package/src/call_x86_fwd.S +48 -48
  13. package/src/call_x86_fwd.asm +50 -50
  14. package/src/ffi.cc +504 -504
  15. package/src/ffi.hh +135 -135
  16. package/src/util.cc +296 -296
  17. package/src/util.hh +80 -80
  18. package/vendor/dragonbox/CMakeLists.txt +122 -122
  19. package/vendor/dragonbox/LICENSE-Apache2-LLVM +218 -218
  20. package/vendor/dragonbox/LICENSE-Boost +23 -23
  21. package/vendor/dragonbox/README.md +277 -277
  22. package/vendor/dragonbox/cmake/dragonboxConfig.cmake +1 -1
  23. package/vendor/dragonbox/include/dragonbox/dragonbox.h +2670 -2670
  24. package/vendor/dragonbox/include/dragonbox/dragonbox_to_chars.h +108 -108
  25. package/vendor/dragonbox/other_files/unknown_win64_vc2019.html +539 -539
  26. package/vendor/dragonbox/source/dragonbox_to_chars.cpp +303 -303
  27. package/vendor/dragonbox/subproject/3rdparty/grisu_exact/CMakeLists.txt +23 -23
  28. package/vendor/dragonbox/subproject/3rdparty/grisu_exact/fp_to_chars.cpp +238 -238
  29. package/vendor/dragonbox/subproject/3rdparty/grisu_exact/fp_to_chars.h +95 -95
  30. package/vendor/dragonbox/subproject/3rdparty/grisu_exact/grisu_exact.h +2666 -2666
  31. package/vendor/dragonbox/subproject/3rdparty/ryu/CMakeLists.txt +16 -16
  32. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/common.h +114 -114
  33. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/d2s.c +509 -509
  34. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/d2s_full_table.h +367 -367
  35. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/d2s_intrinsics.h +357 -357
  36. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/digit_table.h +35 -35
  37. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/f2s.c +345 -345
  38. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/f2s_full_table.h +55 -55
  39. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/f2s_intrinsics.h +128 -128
  40. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/ryu.h +46 -46
  41. package/vendor/dragonbox/subproject/3rdparty/schubfach/CMakeLists.txt +21 -21
  42. package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_32.cc +699 -699
  43. package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_32.h +31 -31
  44. package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_64.cc +1354 -1354
  45. package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_64.h +31 -31
  46. package/vendor/dragonbox/subproject/3rdparty/shaded_plots/example_shaded_plots.m +68 -68
  47. package/vendor/dragonbox/subproject/3rdparty/shaded_plots/license.txt +25 -25
  48. package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_distribution.m +92 -92
  49. package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_distribution_prctile.m +121 -121
  50. package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_histogram_shaded.m +99 -99
  51. package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_shaded.m +93 -93
  52. package/vendor/dragonbox/subproject/benchmark/CMakeLists.txt +64 -64
  53. package/vendor/dragonbox/subproject/benchmark/include/benchmark.h +40 -40
  54. package/vendor/dragonbox/subproject/benchmark/matlab/plot_benchmarks.m +21 -21
  55. package/vendor/dragonbox/subproject/benchmark/matlab/plot_digit_benchmark.m +78 -78
  56. package/vendor/dragonbox/subproject/benchmark/matlab/plot_uniform_benchmark.m +95 -95
  57. package/vendor/dragonbox/subproject/benchmark/source/benchmark.cpp +237 -237
  58. package/vendor/dragonbox/subproject/benchmark/source/dragonbox.cpp +30 -30
  59. package/vendor/dragonbox/subproject/benchmark/source/grisu_exact.cpp +36 -36
  60. package/vendor/dragonbox/subproject/benchmark/source/ryu.cpp +27 -27
  61. package/vendor/dragonbox/subproject/benchmark/source/schubfach.cpp +31 -31
  62. package/vendor/dragonbox/subproject/common/CMakeLists.txt +41 -41
  63. package/vendor/dragonbox/subproject/common/include/best_rational_approx.h +96 -96
  64. package/vendor/dragonbox/subproject/common/include/big_uint.h +217 -217
  65. package/vendor/dragonbox/subproject/common/include/continued_fractions.h +173 -173
  66. package/vendor/dragonbox/subproject/common/include/good_rational_approx.h +266 -266
  67. package/vendor/dragonbox/subproject/common/include/random_float.h +182 -182
  68. package/vendor/dragonbox/subproject/common/include/rational_continued_fractions.h +56 -56
  69. package/vendor/dragonbox/subproject/common/source/big_uint.cpp +601 -601
  70. package/vendor/dragonbox/subproject/meta/CMakeLists.txt +40 -40
  71. package/vendor/dragonbox/subproject/meta/results/binary32_generated_cache.txt +81 -81
  72. package/vendor/dragonbox/subproject/meta/results/binary64_compressed_cache_error_table.txt +9 -9
  73. package/vendor/dragonbox/subproject/meta/results/binary64_generated_cache.txt +622 -622
  74. package/vendor/dragonbox/subproject/meta/source/generate_cache.cpp +126 -126
  75. package/vendor/dragonbox/subproject/meta/source/live_test.cpp +81 -81
  76. package/vendor/dragonbox/subproject/meta/source/perf_test.cpp +104 -104
  77. package/vendor/dragonbox/subproject/meta/source/sandbox.cpp +20 -20
  78. package/vendor/dragonbox/subproject/test/CMakeLists.txt +69 -69
  79. package/vendor/dragonbox/subproject/test/results/binary32.csv +255 -255
  80. package/vendor/dragonbox/subproject/test/results/binary64.csv +2047 -2047
  81. package/vendor/dragonbox/subproject/test/results/plot_required_bits.m +17 -17
  82. package/vendor/dragonbox/subproject/test/source/test_all_shorter_interval_cases.cpp +88 -88
  83. package/vendor/dragonbox/subproject/test/source/uniform_random_test.cpp +95 -95
  84. package/vendor/dragonbox/subproject/test/source/verify_cache_precision.cpp +337 -337
  85. package/vendor/dragonbox/subproject/test/source/verify_compressed_cache.cpp +154 -154
  86. package/vendor/dragonbox/subproject/test/source/verify_fast_multiplication.cpp +168 -168
  87. package/vendor/dragonbox/subproject/test/source/verify_log_computation.cpp +251 -251
  88. package/vendor/dragonbox/subproject/test/source/verify_magic_division.cpp +113 -113
  89. package/vendor/libcc/libcc.cc +7651 -7651
  90. package/vendor/libcc/libcc.hh +4312 -4312
  91. package/vendor/node-addon-api/CHANGELOG.md +859 -859
  92. package/vendor/node-addon-api/CODE_OF_CONDUCT.md +4 -4
  93. package/vendor/node-addon-api/CONTRIBUTING.md +93 -93
  94. package/vendor/node-addon-api/LICENSE.md +12 -12
  95. package/vendor/node-addon-api/README.md +293 -293
  96. package/vendor/node-addon-api/appveyor.yml +37 -37
  97. package/vendor/node-addon-api/benchmark/README.md +47 -47
  98. package/vendor/node-addon-api/benchmark/binding.gyp +25 -25
  99. package/vendor/node-addon-api/benchmark/function_args.cc +217 -217
  100. package/vendor/node-addon-api/benchmark/function_args.js +60 -60
  101. package/vendor/node-addon-api/benchmark/index.js +34 -34
  102. package/vendor/node-addon-api/benchmark/property_descriptor.cc +91 -91
  103. package/vendor/node-addon-api/benchmark/property_descriptor.js +37 -37
  104. package/vendor/node-addon-api/common.gypi +21 -21
  105. package/vendor/node-addon-api/doc/addon.md +163 -163
  106. package/vendor/node-addon-api/doc/array.md +81 -81
  107. package/vendor/node-addon-api/doc/array_buffer.md +155 -155
  108. package/vendor/node-addon-api/doc/async_context.md +86 -86
  109. package/vendor/node-addon-api/doc/async_operations.md +31 -31
  110. package/vendor/node-addon-api/doc/async_worker.md +427 -427
  111. package/vendor/node-addon-api/doc/async_worker_variants.md +557 -557
  112. package/vendor/node-addon-api/doc/bigint.md +97 -97
  113. package/vendor/node-addon-api/doc/boolean.md +68 -68
  114. package/vendor/node-addon-api/doc/buffer.md +150 -150
  115. package/vendor/node-addon-api/doc/callback_scope.md +54 -54
  116. package/vendor/node-addon-api/doc/callbackinfo.md +97 -97
  117. package/vendor/node-addon-api/doc/checker-tool.md +32 -32
  118. package/vendor/node-addon-api/doc/class_property_descriptor.md +115 -115
  119. package/vendor/node-addon-api/doc/cmake-js.md +68 -68
  120. package/vendor/node-addon-api/doc/conversion-tool.md +27 -27
  121. package/vendor/node-addon-api/doc/creating_a_release.md +62 -62
  122. package/vendor/node-addon-api/doc/dataview.md +248 -248
  123. package/vendor/node-addon-api/doc/date.md +68 -68
  124. package/vendor/node-addon-api/doc/env.md +196 -196
  125. package/vendor/node-addon-api/doc/error.md +120 -120
  126. package/vendor/node-addon-api/doc/error_handling.md +254 -254
  127. package/vendor/node-addon-api/doc/escapable_handle_scope.md +80 -80
  128. package/vendor/node-addon-api/doc/external.md +63 -63
  129. package/vendor/node-addon-api/doc/function.md +402 -402
  130. package/vendor/node-addon-api/doc/function_reference.md +238 -238
  131. package/vendor/node-addon-api/doc/generator.md +13 -13
  132. package/vendor/node-addon-api/doc/handle_scope.md +63 -63
  133. package/vendor/node-addon-api/doc/hierarchy.md +91 -91
  134. package/vendor/node-addon-api/doc/instance_wrap.md +408 -408
  135. package/vendor/node-addon-api/doc/maybe.md +76 -76
  136. package/vendor/node-addon-api/doc/memory_management.md +27 -27
  137. package/vendor/node-addon-api/doc/name.md +29 -29
  138. package/vendor/node-addon-api/doc/node-gyp.md +82 -82
  139. package/vendor/node-addon-api/doc/number.md +163 -163
  140. package/vendor/node-addon-api/doc/object.md +432 -432
  141. package/vendor/node-addon-api/doc/object_lifetime_management.md +83 -83
  142. package/vendor/node-addon-api/doc/object_reference.md +117 -117
  143. package/vendor/node-addon-api/doc/object_wrap.md +561 -561
  144. package/vendor/node-addon-api/doc/prebuild_tools.md +16 -16
  145. package/vendor/node-addon-api/doc/promises.md +79 -79
  146. package/vendor/node-addon-api/doc/property_descriptor.md +286 -286
  147. package/vendor/node-addon-api/doc/propertylvalue.md +50 -50
  148. package/vendor/node-addon-api/doc/range_error.md +59 -59
  149. package/vendor/node-addon-api/doc/reference.md +113 -113
  150. package/vendor/node-addon-api/doc/setup.md +110 -110
  151. package/vendor/node-addon-api/doc/string.md +93 -93
  152. package/vendor/node-addon-api/doc/symbol.md +60 -60
  153. package/vendor/node-addon-api/doc/threadsafe.md +121 -121
  154. package/vendor/node-addon-api/doc/threadsafe_function.md +290 -290
  155. package/vendor/node-addon-api/doc/type_error.md +59 -59
  156. package/vendor/node-addon-api/doc/typed_array.md +78 -78
  157. package/vendor/node-addon-api/doc/typed_array_of.md +137 -137
  158. package/vendor/node-addon-api/doc/typed_threadsafe_function.md +306 -306
  159. package/vendor/node-addon-api/doc/value.md +340 -340
  160. package/vendor/node-addon-api/doc/version_management.md +43 -43
  161. package/vendor/node-addon-api/except.gypi +25 -25
  162. package/vendor/node-addon-api/index.js +11 -11
  163. package/vendor/node-addon-api/napi-inl.deprecated.h +192 -192
  164. package/vendor/node-addon-api/napi-inl.h +6209 -6209
  165. package/vendor/node-addon-api/napi.h +2983 -2983
  166. package/vendor/node-addon-api/node_api.gyp +9 -9
  167. package/vendor/node-addon-api/noexcept.gypi +26 -26
  168. package/vendor/node-addon-api/package-support.json +21 -21
  169. package/vendor/node-addon-api/package.json +399 -399
  170. package/vendor/node-addon-api/test/README.md +91 -91
  171. package/vendor/node-addon-api/test/addon.cc +36 -36
  172. package/vendor/node-addon-api/test/addon.js +11 -11
  173. package/vendor/node-addon-api/test/addon_build/index.js +49 -49
  174. package/vendor/node-addon-api/test/addon_build/tpl/addon.cc +17 -17
  175. package/vendor/node-addon-api/test/addon_build/tpl/binding.gyp +62 -62
  176. package/vendor/node-addon-api/test/addon_build/tpl/index.js +9 -9
  177. package/vendor/node-addon-api/test/addon_build/tpl/package.json +11 -11
  178. package/vendor/node-addon-api/test/addon_data.cc +99 -99
  179. package/vendor/node-addon-api/test/addon_data.js +46 -46
  180. package/vendor/node-addon-api/test/array_buffer.cc +243 -243
  181. package/vendor/node-addon-api/test/array_buffer.js +69 -69
  182. package/vendor/node-addon-api/test/async_context.cc +21 -21
  183. package/vendor/node-addon-api/test/async_context.js +86 -86
  184. package/vendor/node-addon-api/test/async_progress_queue_worker.cc +83 -83
  185. package/vendor/node-addon-api/test/async_progress_queue_worker.js +46 -46
  186. package/vendor/node-addon-api/test/async_progress_worker.cc +134 -134
  187. package/vendor/node-addon-api/test/async_progress_worker.js +61 -61
  188. package/vendor/node-addon-api/test/async_worker.cc +106 -106
  189. package/vendor/node-addon-api/test/async_worker.js +179 -179
  190. package/vendor/node-addon-api/test/async_worker_nocallback.js +13 -13
  191. package/vendor/node-addon-api/test/async_worker_persistent.cc +63 -63
  192. package/vendor/node-addon-api/test/async_worker_persistent.js +24 -24
  193. package/vendor/node-addon-api/test/basic_types/array.cc +40 -40
  194. package/vendor/node-addon-api/test/basic_types/array.js +35 -35
  195. package/vendor/node-addon-api/test/basic_types/boolean.cc +38 -38
  196. package/vendor/node-addon-api/test/basic_types/boolean.js +35 -35
  197. package/vendor/node-addon-api/test/basic_types/number.cc +99 -99
  198. package/vendor/node-addon-api/test/basic_types/number.js +114 -114
  199. package/vendor/node-addon-api/test/basic_types/value.cc +120 -120
  200. package/vendor/node-addon-api/test/basic_types/value.js +133 -133
  201. package/vendor/node-addon-api/test/bigint.cc +91 -91
  202. package/vendor/node-addon-api/test/bigint.js +53 -53
  203. package/vendor/node-addon-api/test/binding-swallowexcept.cc +12 -12
  204. package/vendor/node-addon-api/test/binding.cc +171 -171
  205. package/vendor/node-addon-api/test/binding.gyp +117 -117
  206. package/vendor/node-addon-api/test/buffer.cc +183 -183
  207. package/vendor/node-addon-api/test/buffer.js +69 -69
  208. package/vendor/node-addon-api/test/callbackscope.cc +22 -22
  209. package/vendor/node-addon-api/test/callbackscope.js +49 -49
  210. package/vendor/node-addon-api/test/common/index.js +113 -113
  211. package/vendor/node-addon-api/test/common/test_helper.h +61 -61
  212. package/vendor/node-addon-api/test/dataview/dataview.cc +48 -48
  213. package/vendor/node-addon-api/test/dataview/dataview.js +35 -35
  214. package/vendor/node-addon-api/test/dataview/dataview_read_write.cc +115 -115
  215. package/vendor/node-addon-api/test/dataview/dataview_read_write.js +90 -90
  216. package/vendor/node-addon-api/test/date.cc +44 -44
  217. package/vendor/node-addon-api/test/date.js +18 -18
  218. package/vendor/node-addon-api/test/env_cleanup.cc +88 -88
  219. package/vendor/node-addon-api/test/env_cleanup.js +56 -56
  220. package/vendor/node-addon-api/test/error.cc +287 -287
  221. package/vendor/node-addon-api/test/error.js +81 -81
  222. package/vendor/node-addon-api/test/error_handling_for_primitives.cc +13 -13
  223. package/vendor/node-addon-api/test/error_handling_for_primitives.js +29 -29
  224. package/vendor/node-addon-api/test/error_terminating_environment.js +94 -94
  225. package/vendor/node-addon-api/test/external.cc +81 -81
  226. package/vendor/node-addon-api/test/external.js +88 -88
  227. package/vendor/node-addon-api/test/function.cc +295 -295
  228. package/vendor/node-addon-api/test/function.js +121 -121
  229. package/vendor/node-addon-api/test/function_reference.cc +202 -202
  230. package/vendor/node-addon-api/test/function_reference.js +157 -157
  231. package/vendor/node-addon-api/test/globalObject/global_object.cc +61 -61
  232. package/vendor/node-addon-api/test/globalObject/global_object_delete_property.cc +31 -31
  233. package/vendor/node-addon-api/test/globalObject/global_object_delete_property.js +61 -61
  234. package/vendor/node-addon-api/test/globalObject/global_object_get_property.cc +40 -40
  235. package/vendor/node-addon-api/test/globalObject/global_object_get_property.js +57 -57
  236. package/vendor/node-addon-api/test/globalObject/global_object_has_own_property.cc +28 -28
  237. package/vendor/node-addon-api/test/globalObject/global_object_has_own_property.js +48 -48
  238. package/vendor/node-addon-api/test/globalObject/global_object_set_property.cc +30 -30
  239. package/vendor/node-addon-api/test/globalObject/global_object_set_property.js +58 -58
  240. package/vendor/node-addon-api/test/handlescope.cc +60 -60
  241. package/vendor/node-addon-api/test/handlescope.js +14 -14
  242. package/vendor/node-addon-api/test/index.js +136 -136
  243. package/vendor/node-addon-api/test/maybe/check.cc +23 -23
  244. package/vendor/node-addon-api/test/maybe/index.js +38 -38
  245. package/vendor/node-addon-api/test/memory_management.cc +17 -17
  246. package/vendor/node-addon-api/test/memory_management.js +9 -9
  247. package/vendor/node-addon-api/test/movable_callbacks.cc +23 -23
  248. package/vendor/node-addon-api/test/movable_callbacks.js +21 -21
  249. package/vendor/node-addon-api/test/name.cc +108 -108
  250. package/vendor/node-addon-api/test/name.js +59 -59
  251. package/vendor/node-addon-api/test/napi_child.js +14 -14
  252. package/vendor/node-addon-api/test/object/delete_property.cc +38 -38
  253. package/vendor/node-addon-api/test/object/delete_property.js +41 -41
  254. package/vendor/node-addon-api/test/object/finalizer.cc +29 -29
  255. package/vendor/node-addon-api/test/object/finalizer.js +28 -28
  256. package/vendor/node-addon-api/test/object/get_property.cc +34 -34
  257. package/vendor/node-addon-api/test/object/get_property.js +40 -40
  258. package/vendor/node-addon-api/test/object/has_own_property.cc +34 -34
  259. package/vendor/node-addon-api/test/object/has_own_property.js +34 -34
  260. package/vendor/node-addon-api/test/object/has_property.cc +38 -38
  261. package/vendor/node-addon-api/test/object/has_property.js +37 -37
  262. package/vendor/node-addon-api/test/object/object.cc +348 -348
  263. package/vendor/node-addon-api/test/object/object.js +217 -217
  264. package/vendor/node-addon-api/test/object/object_deprecated.cc +66 -66
  265. package/vendor/node-addon-api/test/object/object_deprecated.js +47 -47
  266. package/vendor/node-addon-api/test/object/object_freeze_seal.cc +25 -25
  267. package/vendor/node-addon-api/test/object/object_freeze_seal.js +61 -61
  268. package/vendor/node-addon-api/test/object/set_property.cc +37 -37
  269. package/vendor/node-addon-api/test/object/set_property.js +29 -29
  270. package/vendor/node-addon-api/test/object/subscript_operator.cc +42 -42
  271. package/vendor/node-addon-api/test/object/subscript_operator.js +17 -17
  272. package/vendor/node-addon-api/test/object_reference.cc +219 -219
  273. package/vendor/node-addon-api/test/object_reference.js +259 -259
  274. package/vendor/node-addon-api/test/objectwrap.cc +268 -268
  275. package/vendor/node-addon-api/test/objectwrap.js +284 -284
  276. package/vendor/node-addon-api/test/objectwrap_constructor_exception.cc +26 -26
  277. package/vendor/node-addon-api/test/objectwrap_constructor_exception.js +18 -18
  278. package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.cc +30 -30
  279. package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.js +13 -13
  280. package/vendor/node-addon-api/test/objectwrap_removewrap.cc +45 -45
  281. package/vendor/node-addon-api/test/objectwrap_removewrap.js +40 -40
  282. package/vendor/node-addon-api/test/objectwrap_worker_thread.js +19 -19
  283. package/vendor/node-addon-api/test/promise.cc +29 -29
  284. package/vendor/node-addon-api/test/promise.js +18 -18
  285. package/vendor/node-addon-api/test/reference.cc +24 -24
  286. package/vendor/node-addon-api/test/reference.js +14 -14
  287. package/vendor/node-addon-api/test/run_script.cc +56 -56
  288. package/vendor/node-addon-api/test/run_script.js +45 -45
  289. package/vendor/node-addon-api/test/symbol.cc +79 -79
  290. package/vendor/node-addon-api/test/symbol.js +73 -73
  291. package/vendor/node-addon-api/test/testUtil.js +54 -54
  292. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.cc +195 -195
  293. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.js +188 -188
  294. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.cc +63 -63
  295. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.js +12 -12
  296. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.cc +115 -115
  297. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.js +14 -14
  298. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.cc +26 -26
  299. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.js +7 -7
  300. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.cc +225 -225
  301. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.js +59 -59
  302. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.cc +42 -42
  303. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.js +53 -53
  304. package/vendor/node-addon-api/test/thunking_manual.cc +140 -140
  305. package/vendor/node-addon-api/test/thunking_manual.js +17 -17
  306. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.cc +215 -215
  307. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.js +188 -188
  308. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.cc +68 -68
  309. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.js +12 -12
  310. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_existing_tsfn.cc +127 -127
  311. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_existing_tsfn.js +14 -14
  312. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.cc +28 -28
  313. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.js +7 -7
  314. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_sum.cc +237 -237
  315. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_sum.js +59 -59
  316. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.cc +53 -53
  317. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.js +53 -53
  318. package/vendor/node-addon-api/test/typedarray-bigint.js +58 -58
  319. package/vendor/node-addon-api/test/typedarray.cc +216 -216
  320. package/vendor/node-addon-api/test/typedarray.js +69 -69
  321. package/vendor/node-addon-api/test/version_management.cc +27 -27
  322. package/vendor/node-addon-api/test/version_management.js +31 -31
  323. package/vendor/node-addon-api/tools/README.md +73 -73
  324. package/vendor/node-addon-api/tools/check-napi.js +100 -100
  325. package/vendor/node-addon-api/tools/clang-format.js +68 -68
  326. package/vendor/node-addon-api/tools/conversion.js +309 -309
  327. package/vendor/node-addon-api/tools/eslint-format.js +71 -71
  328. package/build/ALL_BUILD.vcxproj +0 -186
  329. package/build/ALL_BUILD.vcxproj.filters +0 -8
  330. package/build/CMakeCache.txt +0 -417
  331. package/build/CMakeFiles/3.23.0-rc1/CMakeASMCompiler.cmake +0 -20
  332. package/build/CMakeFiles/3.23.0-rc1/CMakeASM_MASMCompiler.cmake +0 -20
  333. package/build/CMakeFiles/3.23.0-rc1/CMakeCCompiler.cmake +0 -72
  334. package/build/CMakeFiles/3.23.0-rc1/CMakeCXXCompiler.cmake +0 -83
  335. package/build/CMakeFiles/3.23.0-rc1/CMakeDetermineCompilerABI_C.bin +0 -0
  336. package/build/CMakeFiles/3.23.0-rc1/CMakeDetermineCompilerABI_CXX.bin +0 -0
  337. package/build/CMakeFiles/3.23.0-rc1/CMakeRCCompiler.cmake +0 -6
  338. package/build/CMakeFiles/3.23.0-rc1/CMakeSystem.cmake +0 -15
  339. package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/CMakeCCompilerId.c +0 -828
  340. package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/CompilerIdC.exe +0 -0
  341. package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/CompilerIdC.vcxproj +0 -71
  342. package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CMakeCCompilerId.obj +0 -0
  343. package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.exe.recipe +0 -11
  344. package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/CL.command.1.tlog +0 -0
  345. package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/CL.read.1.tlog +0 -0
  346. package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/CL.write.1.tlog +0 -0
  347. package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/CompilerIdC.lastbuildstate +0 -2
  348. package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/link.command.1.tlog +0 -0
  349. package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/link.read.1.tlog +0 -0
  350. package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/link.write.1.tlog +0 -0
  351. package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/CMakeCXXCompilerId.cpp +0 -816
  352. package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/CompilerIdCXX.exe +0 -0
  353. package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/CompilerIdCXX.vcxproj +0 -71
  354. package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CMakeCXXCompilerId.obj +0 -0
  355. package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.exe.recipe +0 -11
  356. package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/CL.command.1.tlog +0 -0
  357. package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/CL.read.1.tlog +0 -0
  358. package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/CL.write.1.tlog +0 -0
  359. package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/CompilerIdCXX.lastbuildstate +0 -2
  360. package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/link.command.1.tlog +0 -0
  361. package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/link.read.1.tlog +0 -0
  362. package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/link.write.1.tlog +0 -0
  363. package/build/CMakeFiles/3.23.0-rc1/VCTargetsPath.txt +0 -1
  364. package/build/CMakeFiles/3.23.0-rc1/VCTargetsPath.vcxproj +0 -31
  365. package/build/CMakeFiles/3.23.0-rc1/x64/Debug/VCTargetsPath.recipe +0 -11
  366. package/build/CMakeFiles/3.23.0-rc1/x64/Debug/VCTargetsPath.tlog/VCTargetsPath.lastbuildstate +0 -2
  367. package/build/CMakeFiles/41bcd16856091d4a38fd1f71fbe2f202/generate.stamp.rule +0 -1
  368. package/build/CMakeFiles/CMakeError.log +0 -108
  369. package/build/CMakeFiles/CMakeOutput.log +0 -413
  370. package/build/CMakeFiles/TargetDirectories.txt +0 -3
  371. package/build/CMakeFiles/cmake.check_cache +0 -1
  372. package/build/CMakeFiles/generate.stamp +0 -1
  373. package/build/CMakeFiles/generate.stamp.depend +0 -109
  374. package/build/CMakeFiles/generate.stamp.list +0 -1
  375. package/build/Release/koffi.exp +0 -0
  376. package/build/Release/koffi.lib +0 -0
  377. package/build/Release/koffi.node +0 -0
  378. package/build/ZERO_CHECK.vcxproj +0 -176
  379. package/build/ZERO_CHECK.vcxproj.filters +0 -13
  380. package/build/cmake_install.cmake +0 -44
  381. package/build/koffi.dir/Release/call_arm64.obj +0 -0
  382. package/build/koffi.dir/Release/call_x64_sysv.obj +0 -0
  383. package/build/koffi.dir/Release/call_x64_win.obj +0 -0
  384. package/build/koffi.dir/Release/call_x64_win_fwd.obj +0 -0
  385. package/build/koffi.dir/Release/call_x86.obj +0 -0
  386. package/build/koffi.dir/Release/ffi.obj +0 -0
  387. package/build/koffi.dir/Release/koffi.node.recipe +0 -14
  388. package/build/koffi.dir/Release/koffi.tlog/CL.command.1.tlog +0 -0
  389. package/build/koffi.dir/Release/koffi.tlog/CL.read.1.tlog +0 -0
  390. package/build/koffi.dir/Release/koffi.tlog/CL.write.1.tlog +0 -0
  391. package/build/koffi.dir/Release/koffi.tlog/CustomBuild.command.1.tlog +0 -10
  392. package/build/koffi.dir/Release/koffi.tlog/CustomBuild.read.1.tlog +0 -108
  393. package/build/koffi.dir/Release/koffi.tlog/CustomBuild.write.1.tlog +0 -2
  394. package/build/koffi.dir/Release/koffi.tlog/Masm.read.1u.tlog +0 -0
  395. package/build/koffi.dir/Release/koffi.tlog/Masm.write.1u.tlog +0 -0
  396. package/build/koffi.dir/Release/koffi.tlog/koffi.lastbuildstate +0 -2
  397. package/build/koffi.dir/Release/koffi.tlog/koffi.write.1u.tlog +0 -0
  398. package/build/koffi.dir/Release/koffi.tlog/link.command.1.tlog +0 -0
  399. package/build/koffi.dir/Release/koffi.tlog/link.read.1.tlog +0 -0
  400. package/build/koffi.dir/Release/koffi.tlog/link.write.1.tlog +0 -0
  401. package/build/koffi.dir/Release/libcc.obj +0 -0
  402. package/build/koffi.dir/Release/util.obj +0 -0
  403. package/build/koffi.dir/Release/win_delay_load_hook.obj +0 -0
  404. package/build/koffi.sln +0 -53
  405. package/build/koffi.vcxproj +0 -363
  406. package/build/koffi.vcxproj.filters +0 -40
  407. package/build/x64/Release/ALL_BUILD/ALL_BUILD.recipe +0 -17
  408. package/build/x64/Release/ALL_BUILD/ALL_BUILD.tlog/ALL_BUILD.lastbuildstate +0 -2
  409. package/build/x64/Release/ALL_BUILD/ALL_BUILD.tlog/CustomBuild.command.1.tlog +0 -10
  410. package/build/x64/Release/ALL_BUILD/ALL_BUILD.tlog/CustomBuild.read.1.tlog +0 -108
  411. package/build/x64/Release/ALL_BUILD/ALL_BUILD.tlog/CustomBuild.write.1.tlog +0 -2
  412. package/build/x64/Release/ZERO_CHECK/ZERO_CHECK.recipe +0 -11
  413. package/build/x64/Release/ZERO_CHECK/ZERO_CHECK.tlog/CustomBuild.command.1.tlog +0 -10
  414. package/build/x64/Release/ZERO_CHECK/ZERO_CHECK.tlog/CustomBuild.read.1.tlog +0 -109
  415. package/build/x64/Release/ZERO_CHECK/ZERO_CHECK.tlog/CustomBuild.write.1.tlog +0 -2
  416. package/build/x64/Release/ZERO_CHECK/ZERO_CHECK.tlog/ZERO_CHECK.lastbuildstate +0 -2
@@ -1,602 +1,602 @@
1
- // Copyright 2022 Junekey Jeon
2
- //
3
- // The contents of this file may be used under the terms of
4
- // the Apache License v2.0 with LLVM Exceptions.
5
- //
6
- // (See accompanying file LICENSE-Apache or copy at
7
- // https://llvm.org/foundation/relicensing/LICENSE.txt)
8
- //
9
- // Alternatively, the contents of this file may be used under the terms of
10
- // the Boost Software License, Version 1.0.
11
- // (See accompanying file LICENSE-Boost or copy at
12
- // https://www.boost.org/LICENSE_1_0.txt)
13
- //
14
- // Unless required by applicable law or agreed to in writing, this software
15
- // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
- // KIND, either express or implied.
17
-
18
- #include "big_uint.h"
19
- #include "dragonbox/dragonbox.h"
20
- #include <cassert>
21
- #include <limits>
22
-
23
- namespace jkj {
24
- static constexpr std::size_t log2p1(std::uint64_t x) noexcept {
25
- // C++20 std::log2p1 is not yet supported
26
- // return std::log2p1(x);
27
-
28
- std::size_t ret = 0;
29
- auto inspect = [&x, &ret](int shft) {
30
- if ((x >> shft) != 0) {
31
- x >>= shft;
32
- ret += shft;
33
- }
34
- };
35
-
36
- inspect(32);
37
- inspect(16);
38
- inspect(8);
39
- inspect(4);
40
- inspect(2);
41
- inspect(1);
42
-
43
- return ret + x;
44
- }
45
-
46
- std::size_t log2p1(big_uint const& n) noexcept {
47
- if (n.is_zero()) {
48
- return 0;
49
- }
50
- return (n.elements.size() - 1) * big_uint::element_number_of_bits +
51
- log2p1(n.elements.back());
52
- }
53
-
54
- big_uint big_uint::power_of_2(std::size_t k) {
55
- auto number_of_elmts = k / element_number_of_bits + 1;
56
- big_uint ret_val;
57
- ret_val.elements.resize(number_of_elmts, 0);
58
- ret_val.elements.back() = (element_type(1) << (k % element_number_of_bits));
59
- return ret_val;
60
- }
61
-
62
- big_uint big_uint::pow(big_uint base, std::size_t k) {
63
- big_uint result{1};
64
- while (true) {
65
- if (k % 2 != 0) {
66
- result *= base;
67
- }
68
- k /= 2;
69
- if (k == 0) {
70
- break;
71
- }
72
- base *= base;
73
- }
74
-
75
- return result;
76
- }
77
-
78
- std::size_t big_uint::multiply_2_until(big_uint const& n) {
79
- assert(elements.size() != 0);
80
-
81
- std::size_t number_of_multiplications = 0;
82
-
83
- // Perform left-shift to match the leading-1 position.
84
- // Perform element-wise shift first.
85
- assert(elements.size() <= n.elements.size());
86
- auto element_pos_offset = n.elements.size() - elements.size();
87
- if (element_pos_offset > 0) {
88
- number_of_multiplications = element_pos_offset * element_number_of_bits;
89
- auto old_size = elements.size();
90
- elements.resize(n.elements.size());
91
-
92
- std::move_backward(std::begin(elements), std::begin(elements) + old_size,
93
- std::begin(elements) + elements.size());
94
-
95
- std::fill_n(std::begin(elements), element_pos_offset, 0);
96
- }
97
- // And then perform bit-wise shift.
98
- auto new_bit_pos = log2p1(elements.back());
99
- auto bit_pos_offset =
100
- std::ptrdiff_t(log2p1(n.elements.back())) - std::ptrdiff_t(new_bit_pos);
101
- assert(element_pos_offset > 0 || (element_pos_offset == 0 && bit_pos_offset >= 0));
102
- number_of_multiplications += bit_pos_offset;
103
- if (bit_pos_offset > 0) {
104
- // Left-shfit
105
- auto shft = std::size_t(bit_pos_offset);
106
- auto remaining_bits = element_number_of_bits - shft;
107
- for (auto idx = elements.size() - 1; idx > 0; --idx) {
108
- auto bits_to_transfer = elements[idx - 1] >> remaining_bits;
109
-
110
- elements[idx] <<= shft;
111
- elements[idx] |= bits_to_transfer;
112
- }
113
- elements[0] <<= shft;
114
- }
115
- else if (bit_pos_offset < 0) {
116
- // Right-shift
117
- auto shft = std::size_t(-bit_pos_offset);
118
- auto remaining_bits = element_number_of_bits - shft;
119
- elements[0] >>= shft;
120
- for (std::size_t idx = 1; idx < elements.size(); ++idx) {
121
- auto bits_to_transfer = elements[idx] << remaining_bits;
122
-
123
- elements[idx - 1] |= bits_to_transfer;
124
- elements[idx] >>= shft;
125
- }
126
- }
127
-
128
- // Compare the shifted number with the given number.
129
- bool is_bigger_than_or_equal_to = true;
130
- for (auto idx = std::ptrdiff_t(elements.size()) - 1; idx >= 0; --idx) {
131
- if (elements[idx] > n.elements[idx])
132
- break;
133
- else if (elements[idx] < n.elements[idx]) {
134
- is_bigger_than_or_equal_to = false;
135
- break;
136
- }
137
- }
138
-
139
- // If our number is still less,
140
- if (!is_bigger_than_or_equal_to) {
141
- // Shift one more bit.
142
- ++number_of_multiplications;
143
- if (new_bit_pos == element_number_of_bits) {
144
- elements.resize(elements.size() + 1);
145
- }
146
-
147
- constexpr auto remaining_bits = element_number_of_bits - 1;
148
- for (auto idx = elements.size() - 1; idx > 0; --idx) {
149
- elements[idx] <<= 1;
150
- elements[idx] |= (elements[idx - 1] >> remaining_bits);
151
- }
152
- elements[0] <<= 1;
153
- }
154
-
155
- return number_of_multiplications;
156
- }
157
-
158
- std::size_t big_uint::multiply_2_while(big_uint const& n) {
159
- assert(elements.size() != 0);
160
-
161
- std::size_t number_of_multiplications = 0;
162
-
163
- // Perform left-shift to match the leading-1 position.
164
- // Perform element-wise shift first.
165
- assert(elements.size() <= n.elements.size());
166
- auto element_pos_offset = n.elements.size() - elements.size();
167
- if (element_pos_offset > 0) {
168
- number_of_multiplications = element_pos_offset * element_number_of_bits;
169
- auto old_size = elements.size();
170
- elements.resize(n.elements.size());
171
-
172
- std::move_backward(std::begin(elements), std::begin(elements) + old_size,
173
- std::begin(elements) + elements.size());
174
-
175
- std::fill_n(std::begin(elements), element_pos_offset, 0);
176
- }
177
- // And then perform bit-wise shift.
178
- auto new_bit_pos = log2p1(elements.back());
179
- auto bit_pos_offset =
180
- std::ptrdiff_t(log2p1(n.elements.back())) - std::ptrdiff_t(new_bit_pos);
181
- assert(element_pos_offset > 0 || (element_pos_offset == 0 && bit_pos_offset >= 0));
182
- number_of_multiplications += bit_pos_offset;
183
- if (bit_pos_offset > 0) {
184
- // Left-shfit
185
- auto shft = std::size_t(bit_pos_offset);
186
- auto remaining_bits = element_number_of_bits - shft;
187
- for (auto idx = elements.size() - 1; idx > 0; --idx) {
188
- auto bits_to_transfer = elements[idx - 1] >> remaining_bits;
189
-
190
- elements[idx] <<= shft;
191
- elements[idx] |= bits_to_transfer;
192
- }
193
- elements[0] <<= shft;
194
- }
195
- else if (bit_pos_offset < 0) {
196
- // Right-shift
197
- auto shft = std::size_t(-bit_pos_offset);
198
- auto remaining_bits = element_number_of_bits - shft;
199
- elements[0] >>= shft;
200
- for (std::size_t idx = 1; idx < elements.size(); ++idx) {
201
- auto bits_to_transfer = elements[idx] << remaining_bits;
202
-
203
- elements[idx - 1] |= bits_to_transfer;
204
- elements[idx] >>= shft;
205
- }
206
- }
207
-
208
- // Compare the shifted number with the given number.
209
- bool is_strictly_bigger = true;
210
- for (auto idx = std::ptrdiff_t(elements.size()) - 1; idx >= 0; --idx) {
211
- if (elements[idx] > n.elements[idx])
212
- break;
213
- else if (elements[idx] <= n.elements[idx]) {
214
- is_strictly_bigger = false;
215
- break;
216
- }
217
- }
218
-
219
- // If our number is strictly bigger,
220
- if (is_strictly_bigger) {
221
- // Shift one bit back.
222
- assert(number_of_multiplications > 0);
223
- --number_of_multiplications;
224
-
225
- constexpr auto remaining_bits = element_number_of_bits - 1;
226
- for (auto idx = 0; idx < elements.size() - 1; ++idx) {
227
- elements[idx] >>= 1;
228
- elements[idx] |= (elements[idx + 1] << remaining_bits);
229
- }
230
- elements.back() >>= 1;
231
-
232
- if (elements.back() == 0) {
233
- elements.pop_back();
234
- }
235
- }
236
-
237
- return number_of_multiplications;
238
- }
239
-
240
- void big_uint::multiply_2() & {
241
- // Shift to left by 1.
242
- element_type carry = 0;
243
- for (std::size_t idx = 0; idx < elements.size(); ++idx) {
244
- auto new_element = (elements[idx] << 1) | carry;
245
-
246
- // Keep the carry.
247
- carry = (elements[idx] >> (element_number_of_bits - 1));
248
-
249
- elements[idx] = new_element;
250
- }
251
-
252
- if (carry != 0) {
253
- elements.push_back(1);
254
- }
255
- }
256
-
257
- void big_uint::multiply_5() & {
258
- if (elements.size() == 0) {
259
- return;
260
- }
261
-
262
- element_type upper_2_bits = 0;
263
- element_type carry = 0;
264
- for (std::size_t idx = 0; idx < elements.size(); ++idx) {
265
- auto times_4 = (elements[idx] << 2) | upper_2_bits;
266
- upper_2_bits = (elements[idx] >> (element_number_of_bits - 2));
267
-
268
- element_type new_carry = 0;
269
- // Add *this with *this * 4.
270
- elements[idx] += times_4;
271
- // If carry happens,
272
- if (elements[idx] < times_4) {
273
- new_carry = 1;
274
- // Add the carry from the previous element.
275
- elements[idx] += carry;
276
- }
277
- // If no carry happens,
278
- else {
279
- // Add the carry from the previous element.
280
- elements[idx] += carry;
281
- // If carry happens,
282
- if (elements[idx] < carry) {
283
- new_carry = 1;
284
- }
285
- }
286
- carry = new_carry;
287
- }
288
-
289
- upper_2_bits += carry;
290
- if (upper_2_bits != 0) {
291
- elements.push_back(upper_2_bits);
292
- }
293
- }
294
-
295
- int big_uint::comparison_common(big_uint const& n) const noexcept {
296
- if (elements.size() < n.elements.size()) {
297
- return -1;
298
- }
299
- else if (elements.size() > n.elements.size()) {
300
- return +1;
301
- }
302
- else {
303
- for (auto idx_p1 = elements.size(); idx_p1 > 0; --idx_p1) {
304
- if (elements[idx_p1 - 1] < n.elements[idx_p1 - 1]) {
305
- return -1;
306
- }
307
- else if (elements[idx_p1 - 1] > n.elements[idx_p1 - 1]) {
308
- return +1;
309
- }
310
- }
311
- return 0;
312
- }
313
- }
314
-
315
- big_uint& big_uint::operator+=(big_uint const& n) & {
316
- std::size_t min_size;
317
- if (elements.size() >= n.elements.size()) {
318
- min_size = n.elements.size();
319
- }
320
- else {
321
- min_size = elements.size();
322
- elements.insert(elements.cend(), n.elements.cbegin() + min_size, n.elements.cend());
323
- }
324
-
325
- unsigned int carry = 0;
326
- for (std::size_t idx = 0; idx < min_size; ++idx) {
327
- auto with_carry = elements[idx] + carry;
328
- unsigned int first_carry = (with_carry < elements[idx]) ? 1 : 0;
329
-
330
- auto n_element = n.elements[idx];
331
- elements[idx] = with_carry + n_element;
332
- carry = first_carry | ((elements[idx] < n_element) ? 1 : 0);
333
- }
334
-
335
- if (carry != 0) {
336
- for (std::size_t idx = min_size; idx < elements.size(); ++idx) {
337
- ++elements[idx];
338
- if (elements[idx] != 0) {
339
- return *this;
340
- }
341
- }
342
- elements.push_back(1);
343
- }
344
-
345
- return *this;
346
- }
347
-
348
- big_uint& big_uint::operator+=(element_type n) & {
349
- if (is_zero()) {
350
- elements.push_back(n);
351
- return *this;
352
- }
353
-
354
- elements[0] += n;
355
-
356
- // If carry happens,
357
- if (elements[0] < n) {
358
- // Propagate carry.
359
- for (std::size_t idx = 1; idx < elements.size(); ++idx) {
360
- ++elements[idx];
361
- if (elements[idx] != 0) {
362
- return *this;
363
- }
364
- }
365
- elements.push_back(1);
366
- }
367
- return *this;
368
- }
369
-
370
- big_uint& big_uint::operator-=(big_uint const& n) & {
371
- // Underflow!
372
- assert(elements.size() >= n.elements.size());
373
-
374
- unsigned int borrow = 0;
375
- for (std::size_t idx = 0; idx < n.elements.size(); ++idx) {
376
- auto with_borrow = elements[idx] - borrow;
377
- unsigned int first_borrow = (with_borrow > elements[idx]) ? 1 : 0;
378
-
379
- auto n_element = n.elements[idx];
380
- elements[idx] = with_borrow - n_element;
381
- borrow = first_borrow | ((elements[idx] > with_borrow) ? 1 : 0);
382
- }
383
-
384
- if (borrow != 0) {
385
- for (std::size_t idx = n.elements.size(); idx < elements.size(); ++idx) {
386
- --elements[idx];
387
- if (elements[idx] != std::numeric_limits<element_type>::max()) {
388
- goto remove_leading_zeros;
389
- }
390
- }
391
- // Underflow!
392
- assert(elements.back() != std::numeric_limits<element_type>::max());
393
- }
394
-
395
- remove_leading_zeros:
396
- auto itr = elements.end();
397
- for (; itr != elements.begin(); --itr) {
398
- if (*(itr - 1) != 0) {
399
- break;
400
- }
401
- }
402
- elements.erase(itr, elements.end());
403
-
404
- return *this;
405
- }
406
-
407
- big_uint& big_uint::operator--() & {
408
- // Underflow!
409
- assert(!is_zero());
410
-
411
- for (std::size_t idx = 0; idx < elements.size(); ++idx) {
412
- --elements[idx];
413
- if (elements[idx] != std::numeric_limits<element_type>::max()) {
414
- break;
415
- }
416
- }
417
-
418
- // Remove leading zeros
419
- auto itr = elements.end();
420
- for (; itr != elements.begin(); --itr) {
421
- if (*(itr - 1) != 0) {
422
- break;
423
- }
424
- }
425
- elements.erase(itr, elements.end());
426
-
427
- return *this;
428
- }
429
-
430
- big_uint& big_uint::operator*=(element_type n) & {
431
- if (n == 0) {
432
- elements.clear();
433
- return *this;
434
- }
435
-
436
- element_type carry = 0;
437
- for (std::size_t idx = 0; idx < elements.size(); ++idx) {
438
- auto mul = jkj::dragonbox::detail::wuint::umul128(elements[idx], n);
439
- elements[idx] = mul.low() + carry;
440
- carry = mul.high() + (elements[idx] < mul.low() ? 1 : 0);
441
- }
442
- if (carry != 0) {
443
- elements.push_back(carry);
444
- }
445
-
446
- return *this;
447
- }
448
-
449
- big_uint operator*(big_uint const& x, big_uint const& y) {
450
- if (x.is_zero() || y.is_zero()) {
451
- return big_uint();
452
- }
453
-
454
- big_uint result;
455
- result.elements.resize(x.elements.size() + y.elements.size(), 0);
456
- decltype(x.elements) temp(x.elements.size());
457
-
458
- for (std::size_t y_idx = 0; y_idx < y.elements.size(); ++y_idx) {
459
- // Compute y.elements[y_idx] * x and accumulate it into the result
460
- for (std::size_t x_idx = 0; x_idx < x.elements.size(); ++x_idx) {
461
- auto mul = jkj::dragonbox::detail::wuint::umul128(x.elements[x_idx], y.elements[y_idx]);
462
-
463
- // Add the first half
464
- result.elements[x_idx + y_idx] += mul.low();
465
- unsigned int carry = result.elements[x_idx + y_idx] < mul.low() ? 1 : 0;
466
-
467
- // Add the second half
468
- auto with_carry = mul.high() + carry;
469
- carry = with_carry < mul.high() ? 1 : 0;
470
- result.elements[x_idx + y_idx + 1] += with_carry;
471
-
472
- // If there is carry,
473
- if (result.elements[x_idx + y_idx + 1] < with_carry) {
474
- // Propagate.
475
- assert(x_idx + y_idx + 2 < result.elements.size());
476
- for (auto idx = x_idx + y_idx + 2; idx < result.elements.size(); ++idx) {
477
- ++result.elements[idx];
478
- if (result.elements[idx] != 0) {
479
- break;
480
- }
481
- }
482
- }
483
- }
484
- }
485
-
486
- // Remove the last element if it is zero.
487
- if (result.elements.back() == 0) {
488
- result.elements.pop_back();
489
- }
490
-
491
- return result;
492
- }
493
-
494
- big_uint big_uint::long_division(big_uint const& n) {
495
- assert(!n.is_zero());
496
-
497
- if (this == &n) {
498
- elements.clear();
499
- return big_uint(1);
500
- }
501
-
502
- big_uint quotient;
503
- big_uint n_shifted;
504
-
505
- while (true) {
506
- // Break if *this is smaller than n.
507
- if (elements.size() < n.elements.size()) {
508
- break;
509
- }
510
-
511
- // Shift n element-wise first.
512
- n_shifted.elements.resize(elements.size());
513
- std::fill_n(n_shifted.elements.begin(), (elements.size() - n.elements.size()), 0);
514
- std::copy(n.elements.cbegin(), n.elements.cend(),
515
- n_shifted.elements.begin() + (elements.size() - n.elements.size()));
516
-
517
- std::size_t total_shift_amount =
518
- element_number_of_bits * (elements.size() - n.elements.size());
519
-
520
- // Shift n bit-wise to match the leading 1 position.
521
- auto leading_1_pos = log2p1(elements.back());
522
- auto n_leading_1_pos = log2p1(n_shifted.elements.back());
523
-
524
- if (leading_1_pos > n_leading_1_pos) {
525
- // Shift left.
526
- auto shift_amount = leading_1_pos - n_leading_1_pos;
527
- total_shift_amount += shift_amount;
528
-
529
- element_type carry = 0;
530
- for (std::size_t idx = elements.size() - n.elements.size(); idx < elements.size();
531
- ++idx) {
532
- auto new_element = (n_shifted.elements[idx] << shift_amount) | carry;
533
- carry = (n_shifted.elements[idx] >> (element_number_of_bits - shift_amount));
534
- n_shifted.elements[idx] = new_element;
535
- }
536
- assert(carry == 0);
537
- }
538
- else if (leading_1_pos < n_leading_1_pos) {
539
- // Break if *this is smaller than n.
540
- if (total_shift_amount == 0) {
541
- break;
542
- }
543
-
544
- // Shift right.
545
- auto shift_amount = n_leading_1_pos - leading_1_pos;
546
- assert(total_shift_amount > shift_amount);
547
- total_shift_amount -= shift_amount;
548
- for (std::size_t idx = elements.size() - n.elements.size(); idx < elements.size();
549
- ++idx) {
550
- n_shifted.elements[idx - 1] |=
551
- (n_shifted.elements[idx] << (element_number_of_bits - shift_amount));
552
- n_shifted.elements[idx] >>= shift_amount;
553
- }
554
- }
555
-
556
- // Check if n_shifted is bigger than *this; if that's the case, shift one bit to right.
557
- if (n_shifted > *this) {
558
- // If we actually didn't shift anything,
559
- if (total_shift_amount == 0) {
560
- // *this is smaller than n.
561
- break;
562
- }
563
-
564
- // Shift right.
565
- --total_shift_amount;
566
- n_shifted.elements[0] >>= 1;
567
- for (std::size_t idx = 1; idx < elements.size(); ++idx) {
568
- n_shifted.elements[idx - 1] |=
569
- (n_shifted.elements[idx] << (element_number_of_bits - 1));
570
- n_shifted.elements[idx] >>= 1;
571
- }
572
- }
573
-
574
- // Subtract n_shifted from *this.
575
- *this -= n_shifted;
576
-
577
- // Update the quotient.
578
- auto quotient_element_idx = total_shift_amount / element_number_of_bits;
579
- auto quotient_bit_idx = total_shift_amount % element_number_of_bits;
580
- if (quotient.elements.size() <= quotient_element_idx) {
581
- quotient.elements.resize(quotient_element_idx + 1);
582
- }
583
- quotient.elements[quotient_element_idx] |= (element_type(1) << quotient_bit_idx);
584
- }
585
-
586
- return quotient;
587
- }
588
-
589
- std::vector<std::uint64_t> big_uint::to_decimal() const {
590
- std::vector<std::uint64_t> ret;
591
- auto n = *this;
592
- auto divisor = big_uint{1000'0000'0000'0000'0000};
593
-
594
- do {
595
- auto quotient = n.long_division(divisor);
596
- ret.push_back(n.is_zero() ? 0 : n[0]);
597
- n = quotient;
598
- } while (!n.is_zero());
599
-
600
- return ret;
601
- }
1
+ // Copyright 2022 Junekey Jeon
2
+ //
3
+ // The contents of this file may be used under the terms of
4
+ // the Apache License v2.0 with LLVM Exceptions.
5
+ //
6
+ // (See accompanying file LICENSE-Apache or copy at
7
+ // https://llvm.org/foundation/relicensing/LICENSE.txt)
8
+ //
9
+ // Alternatively, the contents of this file may be used under the terms of
10
+ // the Boost Software License, Version 1.0.
11
+ // (See accompanying file LICENSE-Boost or copy at
12
+ // https://www.boost.org/LICENSE_1_0.txt)
13
+ //
14
+ // Unless required by applicable law or agreed to in writing, this software
15
+ // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ // KIND, either express or implied.
17
+
18
+ #include "big_uint.h"
19
+ #include "dragonbox/dragonbox.h"
20
+ #include <cassert>
21
+ #include <limits>
22
+
23
+ namespace jkj {
24
+ static constexpr std::size_t log2p1(std::uint64_t x) noexcept {
25
+ // C++20 std::log2p1 is not yet supported
26
+ // return std::log2p1(x);
27
+
28
+ std::size_t ret = 0;
29
+ auto inspect = [&x, &ret](int shft) {
30
+ if ((x >> shft) != 0) {
31
+ x >>= shft;
32
+ ret += shft;
33
+ }
34
+ };
35
+
36
+ inspect(32);
37
+ inspect(16);
38
+ inspect(8);
39
+ inspect(4);
40
+ inspect(2);
41
+ inspect(1);
42
+
43
+ return ret + x;
44
+ }
45
+
46
+ std::size_t log2p1(big_uint const& n) noexcept {
47
+ if (n.is_zero()) {
48
+ return 0;
49
+ }
50
+ return (n.elements.size() - 1) * big_uint::element_number_of_bits +
51
+ log2p1(n.elements.back());
52
+ }
53
+
54
+ big_uint big_uint::power_of_2(std::size_t k) {
55
+ auto number_of_elmts = k / element_number_of_bits + 1;
56
+ big_uint ret_val;
57
+ ret_val.elements.resize(number_of_elmts, 0);
58
+ ret_val.elements.back() = (element_type(1) << (k % element_number_of_bits));
59
+ return ret_val;
60
+ }
61
+
62
+ big_uint big_uint::pow(big_uint base, std::size_t k) {
63
+ big_uint result{1};
64
+ while (true) {
65
+ if (k % 2 != 0) {
66
+ result *= base;
67
+ }
68
+ k /= 2;
69
+ if (k == 0) {
70
+ break;
71
+ }
72
+ base *= base;
73
+ }
74
+
75
+ return result;
76
+ }
77
+
78
+ std::size_t big_uint::multiply_2_until(big_uint const& n) {
79
+ assert(elements.size() != 0);
80
+
81
+ std::size_t number_of_multiplications = 0;
82
+
83
+ // Perform left-shift to match the leading-1 position.
84
+ // Perform element-wise shift first.
85
+ assert(elements.size() <= n.elements.size());
86
+ auto element_pos_offset = n.elements.size() - elements.size();
87
+ if (element_pos_offset > 0) {
88
+ number_of_multiplications = element_pos_offset * element_number_of_bits;
89
+ auto old_size = elements.size();
90
+ elements.resize(n.elements.size());
91
+
92
+ std::move_backward(std::begin(elements), std::begin(elements) + old_size,
93
+ std::begin(elements) + elements.size());
94
+
95
+ std::fill_n(std::begin(elements), element_pos_offset, 0);
96
+ }
97
+ // And then perform bit-wise shift.
98
+ auto new_bit_pos = log2p1(elements.back());
99
+ auto bit_pos_offset =
100
+ std::ptrdiff_t(log2p1(n.elements.back())) - std::ptrdiff_t(new_bit_pos);
101
+ assert(element_pos_offset > 0 || (element_pos_offset == 0 && bit_pos_offset >= 0));
102
+ number_of_multiplications += bit_pos_offset;
103
+ if (bit_pos_offset > 0) {
104
+ // Left-shfit
105
+ auto shft = std::size_t(bit_pos_offset);
106
+ auto remaining_bits = element_number_of_bits - shft;
107
+ for (auto idx = elements.size() - 1; idx > 0; --idx) {
108
+ auto bits_to_transfer = elements[idx - 1] >> remaining_bits;
109
+
110
+ elements[idx] <<= shft;
111
+ elements[idx] |= bits_to_transfer;
112
+ }
113
+ elements[0] <<= shft;
114
+ }
115
+ else if (bit_pos_offset < 0) {
116
+ // Right-shift
117
+ auto shft = std::size_t(-bit_pos_offset);
118
+ auto remaining_bits = element_number_of_bits - shft;
119
+ elements[0] >>= shft;
120
+ for (std::size_t idx = 1; idx < elements.size(); ++idx) {
121
+ auto bits_to_transfer = elements[idx] << remaining_bits;
122
+
123
+ elements[idx - 1] |= bits_to_transfer;
124
+ elements[idx] >>= shft;
125
+ }
126
+ }
127
+
128
+ // Compare the shifted number with the given number.
129
+ bool is_bigger_than_or_equal_to = true;
130
+ for (auto idx = std::ptrdiff_t(elements.size()) - 1; idx >= 0; --idx) {
131
+ if (elements[idx] > n.elements[idx])
132
+ break;
133
+ else if (elements[idx] < n.elements[idx]) {
134
+ is_bigger_than_or_equal_to = false;
135
+ break;
136
+ }
137
+ }
138
+
139
+ // If our number is still less,
140
+ if (!is_bigger_than_or_equal_to) {
141
+ // Shift one more bit.
142
+ ++number_of_multiplications;
143
+ if (new_bit_pos == element_number_of_bits) {
144
+ elements.resize(elements.size() + 1);
145
+ }
146
+
147
+ constexpr auto remaining_bits = element_number_of_bits - 1;
148
+ for (auto idx = elements.size() - 1; idx > 0; --idx) {
149
+ elements[idx] <<= 1;
150
+ elements[idx] |= (elements[idx - 1] >> remaining_bits);
151
+ }
152
+ elements[0] <<= 1;
153
+ }
154
+
155
+ return number_of_multiplications;
156
+ }
157
+
158
+ std::size_t big_uint::multiply_2_while(big_uint const& n) {
159
+ assert(elements.size() != 0);
160
+
161
+ std::size_t number_of_multiplications = 0;
162
+
163
+ // Perform left-shift to match the leading-1 position.
164
+ // Perform element-wise shift first.
165
+ assert(elements.size() <= n.elements.size());
166
+ auto element_pos_offset = n.elements.size() - elements.size();
167
+ if (element_pos_offset > 0) {
168
+ number_of_multiplications = element_pos_offset * element_number_of_bits;
169
+ auto old_size = elements.size();
170
+ elements.resize(n.elements.size());
171
+
172
+ std::move_backward(std::begin(elements), std::begin(elements) + old_size,
173
+ std::begin(elements) + elements.size());
174
+
175
+ std::fill_n(std::begin(elements), element_pos_offset, 0);
176
+ }
177
+ // And then perform bit-wise shift.
178
+ auto new_bit_pos = log2p1(elements.back());
179
+ auto bit_pos_offset =
180
+ std::ptrdiff_t(log2p1(n.elements.back())) - std::ptrdiff_t(new_bit_pos);
181
+ assert(element_pos_offset > 0 || (element_pos_offset == 0 && bit_pos_offset >= 0));
182
+ number_of_multiplications += bit_pos_offset;
183
+ if (bit_pos_offset > 0) {
184
+ // Left-shfit
185
+ auto shft = std::size_t(bit_pos_offset);
186
+ auto remaining_bits = element_number_of_bits - shft;
187
+ for (auto idx = elements.size() - 1; idx > 0; --idx) {
188
+ auto bits_to_transfer = elements[idx - 1] >> remaining_bits;
189
+
190
+ elements[idx] <<= shft;
191
+ elements[idx] |= bits_to_transfer;
192
+ }
193
+ elements[0] <<= shft;
194
+ }
195
+ else if (bit_pos_offset < 0) {
196
+ // Right-shift
197
+ auto shft = std::size_t(-bit_pos_offset);
198
+ auto remaining_bits = element_number_of_bits - shft;
199
+ elements[0] >>= shft;
200
+ for (std::size_t idx = 1; idx < elements.size(); ++idx) {
201
+ auto bits_to_transfer = elements[idx] << remaining_bits;
202
+
203
+ elements[idx - 1] |= bits_to_transfer;
204
+ elements[idx] >>= shft;
205
+ }
206
+ }
207
+
208
+ // Compare the shifted number with the given number.
209
+ bool is_strictly_bigger = true;
210
+ for (auto idx = std::ptrdiff_t(elements.size()) - 1; idx >= 0; --idx) {
211
+ if (elements[idx] > n.elements[idx])
212
+ break;
213
+ else if (elements[idx] <= n.elements[idx]) {
214
+ is_strictly_bigger = false;
215
+ break;
216
+ }
217
+ }
218
+
219
+ // If our number is strictly bigger,
220
+ if (is_strictly_bigger) {
221
+ // Shift one bit back.
222
+ assert(number_of_multiplications > 0);
223
+ --number_of_multiplications;
224
+
225
+ constexpr auto remaining_bits = element_number_of_bits - 1;
226
+ for (auto idx = 0; idx < elements.size() - 1; ++idx) {
227
+ elements[idx] >>= 1;
228
+ elements[idx] |= (elements[idx + 1] << remaining_bits);
229
+ }
230
+ elements.back() >>= 1;
231
+
232
+ if (elements.back() == 0) {
233
+ elements.pop_back();
234
+ }
235
+ }
236
+
237
+ return number_of_multiplications;
238
+ }
239
+
240
+ void big_uint::multiply_2() & {
241
+ // Shift to left by 1.
242
+ element_type carry = 0;
243
+ for (std::size_t idx = 0; idx < elements.size(); ++idx) {
244
+ auto new_element = (elements[idx] << 1) | carry;
245
+
246
+ // Keep the carry.
247
+ carry = (elements[idx] >> (element_number_of_bits - 1));
248
+
249
+ elements[idx] = new_element;
250
+ }
251
+
252
+ if (carry != 0) {
253
+ elements.push_back(1);
254
+ }
255
+ }
256
+
257
+ void big_uint::multiply_5() & {
258
+ if (elements.size() == 0) {
259
+ return;
260
+ }
261
+
262
+ element_type upper_2_bits = 0;
263
+ element_type carry = 0;
264
+ for (std::size_t idx = 0; idx < elements.size(); ++idx) {
265
+ auto times_4 = (elements[idx] << 2) | upper_2_bits;
266
+ upper_2_bits = (elements[idx] >> (element_number_of_bits - 2));
267
+
268
+ element_type new_carry = 0;
269
+ // Add *this with *this * 4.
270
+ elements[idx] += times_4;
271
+ // If carry happens,
272
+ if (elements[idx] < times_4) {
273
+ new_carry = 1;
274
+ // Add the carry from the previous element.
275
+ elements[idx] += carry;
276
+ }
277
+ // If no carry happens,
278
+ else {
279
+ // Add the carry from the previous element.
280
+ elements[idx] += carry;
281
+ // If carry happens,
282
+ if (elements[idx] < carry) {
283
+ new_carry = 1;
284
+ }
285
+ }
286
+ carry = new_carry;
287
+ }
288
+
289
+ upper_2_bits += carry;
290
+ if (upper_2_bits != 0) {
291
+ elements.push_back(upper_2_bits);
292
+ }
293
+ }
294
+
295
+ int big_uint::comparison_common(big_uint const& n) const noexcept {
296
+ if (elements.size() < n.elements.size()) {
297
+ return -1;
298
+ }
299
+ else if (elements.size() > n.elements.size()) {
300
+ return +1;
301
+ }
302
+ else {
303
+ for (auto idx_p1 = elements.size(); idx_p1 > 0; --idx_p1) {
304
+ if (elements[idx_p1 - 1] < n.elements[idx_p1 - 1]) {
305
+ return -1;
306
+ }
307
+ else if (elements[idx_p1 - 1] > n.elements[idx_p1 - 1]) {
308
+ return +1;
309
+ }
310
+ }
311
+ return 0;
312
+ }
313
+ }
314
+
315
+ big_uint& big_uint::operator+=(big_uint const& n) & {
316
+ std::size_t min_size;
317
+ if (elements.size() >= n.elements.size()) {
318
+ min_size = n.elements.size();
319
+ }
320
+ else {
321
+ min_size = elements.size();
322
+ elements.insert(elements.cend(), n.elements.cbegin() + min_size, n.elements.cend());
323
+ }
324
+
325
+ unsigned int carry = 0;
326
+ for (std::size_t idx = 0; idx < min_size; ++idx) {
327
+ auto with_carry = elements[idx] + carry;
328
+ unsigned int first_carry = (with_carry < elements[idx]) ? 1 : 0;
329
+
330
+ auto n_element = n.elements[idx];
331
+ elements[idx] = with_carry + n_element;
332
+ carry = first_carry | ((elements[idx] < n_element) ? 1 : 0);
333
+ }
334
+
335
+ if (carry != 0) {
336
+ for (std::size_t idx = min_size; idx < elements.size(); ++idx) {
337
+ ++elements[idx];
338
+ if (elements[idx] != 0) {
339
+ return *this;
340
+ }
341
+ }
342
+ elements.push_back(1);
343
+ }
344
+
345
+ return *this;
346
+ }
347
+
348
+ big_uint& big_uint::operator+=(element_type n) & {
349
+ if (is_zero()) {
350
+ elements.push_back(n);
351
+ return *this;
352
+ }
353
+
354
+ elements[0] += n;
355
+
356
+ // If carry happens,
357
+ if (elements[0] < n) {
358
+ // Propagate carry.
359
+ for (std::size_t idx = 1; idx < elements.size(); ++idx) {
360
+ ++elements[idx];
361
+ if (elements[idx] != 0) {
362
+ return *this;
363
+ }
364
+ }
365
+ elements.push_back(1);
366
+ }
367
+ return *this;
368
+ }
369
+
370
+ big_uint& big_uint::operator-=(big_uint const& n) & {
371
+ // Underflow!
372
+ assert(elements.size() >= n.elements.size());
373
+
374
+ unsigned int borrow = 0;
375
+ for (std::size_t idx = 0; idx < n.elements.size(); ++idx) {
376
+ auto with_borrow = elements[idx] - borrow;
377
+ unsigned int first_borrow = (with_borrow > elements[idx]) ? 1 : 0;
378
+
379
+ auto n_element = n.elements[idx];
380
+ elements[idx] = with_borrow - n_element;
381
+ borrow = first_borrow | ((elements[idx] > with_borrow) ? 1 : 0);
382
+ }
383
+
384
+ if (borrow != 0) {
385
+ for (std::size_t idx = n.elements.size(); idx < elements.size(); ++idx) {
386
+ --elements[idx];
387
+ if (elements[idx] != std::numeric_limits<element_type>::max()) {
388
+ goto remove_leading_zeros;
389
+ }
390
+ }
391
+ // Underflow!
392
+ assert(elements.back() != std::numeric_limits<element_type>::max());
393
+ }
394
+
395
+ remove_leading_zeros:
396
+ auto itr = elements.end();
397
+ for (; itr != elements.begin(); --itr) {
398
+ if (*(itr - 1) != 0) {
399
+ break;
400
+ }
401
+ }
402
+ elements.erase(itr, elements.end());
403
+
404
+ return *this;
405
+ }
406
+
407
+ big_uint& big_uint::operator--() & {
408
+ // Underflow!
409
+ assert(!is_zero());
410
+
411
+ for (std::size_t idx = 0; idx < elements.size(); ++idx) {
412
+ --elements[idx];
413
+ if (elements[idx] != std::numeric_limits<element_type>::max()) {
414
+ break;
415
+ }
416
+ }
417
+
418
+ // Remove leading zeros
419
+ auto itr = elements.end();
420
+ for (; itr != elements.begin(); --itr) {
421
+ if (*(itr - 1) != 0) {
422
+ break;
423
+ }
424
+ }
425
+ elements.erase(itr, elements.end());
426
+
427
+ return *this;
428
+ }
429
+
430
+ big_uint& big_uint::operator*=(element_type n) & {
431
+ if (n == 0) {
432
+ elements.clear();
433
+ return *this;
434
+ }
435
+
436
+ element_type carry = 0;
437
+ for (std::size_t idx = 0; idx < elements.size(); ++idx) {
438
+ auto mul = jkj::dragonbox::detail::wuint::umul128(elements[idx], n);
439
+ elements[idx] = mul.low() + carry;
440
+ carry = mul.high() + (elements[idx] < mul.low() ? 1 : 0);
441
+ }
442
+ if (carry != 0) {
443
+ elements.push_back(carry);
444
+ }
445
+
446
+ return *this;
447
+ }
448
+
449
+ big_uint operator*(big_uint const& x, big_uint const& y) {
450
+ if (x.is_zero() || y.is_zero()) {
451
+ return big_uint();
452
+ }
453
+
454
+ big_uint result;
455
+ result.elements.resize(x.elements.size() + y.elements.size(), 0);
456
+ decltype(x.elements) temp(x.elements.size());
457
+
458
+ for (std::size_t y_idx = 0; y_idx < y.elements.size(); ++y_idx) {
459
+ // Compute y.elements[y_idx] * x and accumulate it into the result
460
+ for (std::size_t x_idx = 0; x_idx < x.elements.size(); ++x_idx) {
461
+ auto mul = jkj::dragonbox::detail::wuint::umul128(x.elements[x_idx], y.elements[y_idx]);
462
+
463
+ // Add the first half
464
+ result.elements[x_idx + y_idx] += mul.low();
465
+ unsigned int carry = result.elements[x_idx + y_idx] < mul.low() ? 1 : 0;
466
+
467
+ // Add the second half
468
+ auto with_carry = mul.high() + carry;
469
+ carry = with_carry < mul.high() ? 1 : 0;
470
+ result.elements[x_idx + y_idx + 1] += with_carry;
471
+
472
+ // If there is carry,
473
+ if (result.elements[x_idx + y_idx + 1] < with_carry) {
474
+ // Propagate.
475
+ assert(x_idx + y_idx + 2 < result.elements.size());
476
+ for (auto idx = x_idx + y_idx + 2; idx < result.elements.size(); ++idx) {
477
+ ++result.elements[idx];
478
+ if (result.elements[idx] != 0) {
479
+ break;
480
+ }
481
+ }
482
+ }
483
+ }
484
+ }
485
+
486
+ // Remove the last element if it is zero.
487
+ if (result.elements.back() == 0) {
488
+ result.elements.pop_back();
489
+ }
490
+
491
+ return result;
492
+ }
493
+
494
+ big_uint big_uint::long_division(big_uint const& n) {
495
+ assert(!n.is_zero());
496
+
497
+ if (this == &n) {
498
+ elements.clear();
499
+ return big_uint(1);
500
+ }
501
+
502
+ big_uint quotient;
503
+ big_uint n_shifted;
504
+
505
+ while (true) {
506
+ // Break if *this is smaller than n.
507
+ if (elements.size() < n.elements.size()) {
508
+ break;
509
+ }
510
+
511
+ // Shift n element-wise first.
512
+ n_shifted.elements.resize(elements.size());
513
+ std::fill_n(n_shifted.elements.begin(), (elements.size() - n.elements.size()), 0);
514
+ std::copy(n.elements.cbegin(), n.elements.cend(),
515
+ n_shifted.elements.begin() + (elements.size() - n.elements.size()));
516
+
517
+ std::size_t total_shift_amount =
518
+ element_number_of_bits * (elements.size() - n.elements.size());
519
+
520
+ // Shift n bit-wise to match the leading 1 position.
521
+ auto leading_1_pos = log2p1(elements.back());
522
+ auto n_leading_1_pos = log2p1(n_shifted.elements.back());
523
+
524
+ if (leading_1_pos > n_leading_1_pos) {
525
+ // Shift left.
526
+ auto shift_amount = leading_1_pos - n_leading_1_pos;
527
+ total_shift_amount += shift_amount;
528
+
529
+ element_type carry = 0;
530
+ for (std::size_t idx = elements.size() - n.elements.size(); idx < elements.size();
531
+ ++idx) {
532
+ auto new_element = (n_shifted.elements[idx] << shift_amount) | carry;
533
+ carry = (n_shifted.elements[idx] >> (element_number_of_bits - shift_amount));
534
+ n_shifted.elements[idx] = new_element;
535
+ }
536
+ assert(carry == 0);
537
+ }
538
+ else if (leading_1_pos < n_leading_1_pos) {
539
+ // Break if *this is smaller than n.
540
+ if (total_shift_amount == 0) {
541
+ break;
542
+ }
543
+
544
+ // Shift right.
545
+ auto shift_amount = n_leading_1_pos - leading_1_pos;
546
+ assert(total_shift_amount > shift_amount);
547
+ total_shift_amount -= shift_amount;
548
+ for (std::size_t idx = elements.size() - n.elements.size(); idx < elements.size();
549
+ ++idx) {
550
+ n_shifted.elements[idx - 1] |=
551
+ (n_shifted.elements[idx] << (element_number_of_bits - shift_amount));
552
+ n_shifted.elements[idx] >>= shift_amount;
553
+ }
554
+ }
555
+
556
+ // Check if n_shifted is bigger than *this; if that's the case, shift one bit to right.
557
+ if (n_shifted > *this) {
558
+ // If we actually didn't shift anything,
559
+ if (total_shift_amount == 0) {
560
+ // *this is smaller than n.
561
+ break;
562
+ }
563
+
564
+ // Shift right.
565
+ --total_shift_amount;
566
+ n_shifted.elements[0] >>= 1;
567
+ for (std::size_t idx = 1; idx < elements.size(); ++idx) {
568
+ n_shifted.elements[idx - 1] |=
569
+ (n_shifted.elements[idx] << (element_number_of_bits - 1));
570
+ n_shifted.elements[idx] >>= 1;
571
+ }
572
+ }
573
+
574
+ // Subtract n_shifted from *this.
575
+ *this -= n_shifted;
576
+
577
+ // Update the quotient.
578
+ auto quotient_element_idx = total_shift_amount / element_number_of_bits;
579
+ auto quotient_bit_idx = total_shift_amount % element_number_of_bits;
580
+ if (quotient.elements.size() <= quotient_element_idx) {
581
+ quotient.elements.resize(quotient_element_idx + 1);
582
+ }
583
+ quotient.elements[quotient_element_idx] |= (element_type(1) << quotient_bit_idx);
584
+ }
585
+
586
+ return quotient;
587
+ }
588
+
589
+ std::vector<std::uint64_t> big_uint::to_decimal() const {
590
+ std::vector<std::uint64_t> ret;
591
+ auto n = *this;
592
+ auto divisor = big_uint{1000'0000'0000'0000'0000};
593
+
594
+ do {
595
+ auto quotient = n.long_division(divisor);
596
+ ret.push_back(n.is_zero() ? 0 : n[0]);
597
+ n = quotient;
598
+ } while (!n.is_zero());
599
+
600
+ return ret;
601
+ }
602
602
  }