usearch 2.21.4 → 2.25.1

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 (604) hide show
  1. package/README.md +65 -69
  2. package/binding.gyp +15 -37
  3. package/c/CMakeLists.txt +4 -5
  4. package/c/README.md +8 -8
  5. package/c/lib.cpp +32 -14
  6. package/c/test.c +124 -1
  7. package/c/usearch.h +24 -3
  8. package/cpp/CMakeLists.txt +4 -0
  9. package/cpp/README.md +5 -5
  10. package/cpp/bench.cpp +97 -116
  11. package/cpp/test.cpp +117 -20
  12. package/include/usearch/index.hpp +224 -48
  13. package/include/usearch/index_dense.hpp +105 -40
  14. package/include/usearch/index_plugins.hpp +1387 -204
  15. package/javascript/README.md +1 -1
  16. package/javascript/dist/cjs/usearch.d.ts +8 -3
  17. package/javascript/dist/cjs/usearch.js +12 -4
  18. package/javascript/dist/esm/usearch.d.ts +8 -3
  19. package/javascript/dist/esm/usearch.js +12 -4
  20. package/javascript/lib.cpp +17 -0
  21. package/javascript/usearch.test.js +117 -94
  22. package/javascript/usearch.ts +14 -6
  23. package/numkong/.clang-tidy +30 -0
  24. package/{simsimd → numkong}/.cmake-format.py +18 -0
  25. package/numkong/.editorconfig +12 -0
  26. package/numkong/.git-blame-ignore-revs +123 -0
  27. package/numkong/.mailmap +15 -0
  28. package/numkong/.spi.yml +11 -0
  29. package/numkong/.swift-format +14 -0
  30. package/numkong/CITATION.cff +81 -0
  31. package/numkong/CONTRIBUTING.md +500 -0
  32. package/numkong/Cargo.toml +54 -0
  33. package/numkong/MANIFEST.in +8 -0
  34. package/numkong/Package.swift +84 -0
  35. package/numkong/README.md +569 -0
  36. package/numkong/bench/README.md +217 -0
  37. package/numkong/bench/bench-browser.html +323 -0
  38. package/numkong/bench/bench.cpp +344 -0
  39. package/numkong/bench/bench.hpp +816 -0
  40. package/numkong/bench/bench.js +148 -0
  41. package/numkong/bench/bench.mjs +616 -0
  42. package/numkong/bench/bench_attention.cpp +113 -0
  43. package/numkong/bench/bench_cast.cpp +264 -0
  44. package/numkong/bench/bench_cross_amx.cpp +62 -0
  45. package/numkong/bench/bench_cross_arm.cpp +245 -0
  46. package/numkong/bench/bench_cross_blas.cpp +309 -0
  47. package/numkong/bench/bench_cross_loongarch.cpp +106 -0
  48. package/numkong/bench/bench_cross_power.cpp +84 -0
  49. package/numkong/bench/bench_cross_rvv.cpp +121 -0
  50. package/numkong/bench/bench_cross_serial.cpp +151 -0
  51. package/numkong/bench/bench_cross_sme.cpp +163 -0
  52. package/numkong/bench/bench_cross_wasm.cpp +142 -0
  53. package/numkong/bench/bench_cross_x86.cpp +455 -0
  54. package/numkong/bench/bench_curved.cpp +210 -0
  55. package/numkong/bench/bench_dot.cpp +315 -0
  56. package/numkong/bench/bench_each.cpp +503 -0
  57. package/numkong/bench/bench_geospatial.cpp +112 -0
  58. package/numkong/bench/bench_maxsim.cpp +154 -0
  59. package/numkong/bench/bench_mesh.cpp +148 -0
  60. package/numkong/bench/bench_probability.cpp +60 -0
  61. package/numkong/bench/bench_reduce.cpp +371 -0
  62. package/numkong/bench/bench_set.cpp +73 -0
  63. package/numkong/bench/bench_sparse.cpp +198 -0
  64. package/numkong/bench/bench_spatial.cpp +347 -0
  65. package/numkong/bench/bench_trigonometry.cpp +137 -0
  66. package/numkong/bench/swift/Bench.swift +506 -0
  67. package/numkong/binding.gyp +169 -0
  68. package/numkong/build.rs +484 -0
  69. package/numkong/c/dispatch.h +512 -0
  70. package/numkong/c/dispatch_bf16.c +447 -0
  71. package/numkong/c/dispatch_bf16c.c +52 -0
  72. package/numkong/c/dispatch_e2m3.c +296 -0
  73. package/numkong/c/dispatch_e3m2.c +284 -0
  74. package/numkong/c/dispatch_e4m3.c +318 -0
  75. package/numkong/c/dispatch_e5m2.c +316 -0
  76. package/numkong/c/dispatch_f16.c +452 -0
  77. package/numkong/c/dispatch_f16c.c +58 -0
  78. package/numkong/c/dispatch_f32.c +434 -0
  79. package/numkong/c/dispatch_f32c.c +99 -0
  80. package/numkong/c/dispatch_f64.c +348 -0
  81. package/numkong/c/dispatch_f64c.c +98 -0
  82. package/numkong/c/dispatch_i16.c +96 -0
  83. package/numkong/c/dispatch_i32.c +89 -0
  84. package/numkong/c/dispatch_i4.c +153 -0
  85. package/numkong/c/dispatch_i64.c +86 -0
  86. package/numkong/c/dispatch_i8.c +348 -0
  87. package/numkong/c/dispatch_other.c +348 -0
  88. package/numkong/c/dispatch_u1.c +193 -0
  89. package/numkong/c/dispatch_u16.c +124 -0
  90. package/numkong/c/dispatch_u32.c +118 -0
  91. package/numkong/c/dispatch_u4.c +153 -0
  92. package/numkong/c/dispatch_u64.c +102 -0
  93. package/numkong/c/dispatch_u8.c +364 -0
  94. package/numkong/c/numkong.c +940 -0
  95. package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
  96. package/numkong/cmake/nk_isa_probe.cmake +90 -0
  97. package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
  98. package/numkong/cmake/nk_math_lib.cmake +46 -0
  99. package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
  100. package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
  101. package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
  102. package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
  103. package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
  104. package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
  105. package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
  106. package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
  107. package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
  108. package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
  109. package/numkong/cmake/toolchain-wasi.cmake +77 -0
  110. package/numkong/cmake/toolchain-wasm.cmake +70 -0
  111. package/numkong/cmake/toolchain-wasm64.cmake +62 -0
  112. package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
  113. package/numkong/include/README.md +643 -0
  114. package/numkong/include/module.modulemap +129 -0
  115. package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
  116. package/numkong/include/numkong/attention/sme.h +2075 -0
  117. package/numkong/include/numkong/attention.h +49 -0
  118. package/numkong/include/numkong/capabilities.h +930 -0
  119. package/numkong/include/numkong/cast/README.md +262 -0
  120. package/numkong/include/numkong/cast/diamond.h +64 -0
  121. package/numkong/include/numkong/cast/haswell.h +823 -0
  122. package/numkong/include/numkong/cast/icelake.h +475 -0
  123. package/numkong/include/numkong/cast/loongsonasx.h +252 -0
  124. package/numkong/include/numkong/cast/neon.h +1174 -0
  125. package/numkong/include/numkong/cast/powervsx.h +449 -0
  126. package/numkong/include/numkong/cast/rvv.h +970 -0
  127. package/numkong/include/numkong/cast/sapphire.h +262 -0
  128. package/numkong/include/numkong/cast/serial.h +2336 -0
  129. package/numkong/include/numkong/cast/skylake.h +915 -0
  130. package/numkong/include/numkong/cast/v128relaxed.h +537 -0
  131. package/numkong/include/numkong/cast.h +254 -0
  132. package/numkong/include/numkong/cast.hpp +44 -0
  133. package/numkong/include/numkong/curved/README.md +223 -0
  134. package/numkong/include/numkong/curved/genoa.h +182 -0
  135. package/numkong/include/numkong/curved/haswell.h +276 -0
  136. package/numkong/include/numkong/curved/neon.h +329 -0
  137. package/numkong/include/numkong/curved/neonbfdot.h +211 -0
  138. package/numkong/include/numkong/curved/rvv.h +305 -0
  139. package/numkong/include/numkong/curved/serial.h +207 -0
  140. package/numkong/include/numkong/curved/skylake.h +457 -0
  141. package/numkong/include/numkong/curved/smef64.h +530 -0
  142. package/numkong/include/numkong/curved.h +513 -0
  143. package/numkong/include/numkong/curved.hpp +144 -0
  144. package/numkong/include/numkong/dot/README.md +442 -0
  145. package/numkong/include/numkong/dot/alder.h +563 -0
  146. package/numkong/include/numkong/dot/diamond.h +158 -0
  147. package/numkong/include/numkong/dot/genoa.h +289 -0
  148. package/numkong/include/numkong/dot/haswell.h +1723 -0
  149. package/numkong/include/numkong/dot/icelake.h +997 -0
  150. package/numkong/include/numkong/dot/loongsonasx.h +671 -0
  151. package/numkong/include/numkong/dot/neon.h +869 -0
  152. package/numkong/include/numkong/dot/neonbfdot.h +243 -0
  153. package/numkong/include/numkong/dot/neonfhm.h +358 -0
  154. package/numkong/include/numkong/dot/neonfp8.h +323 -0
  155. package/numkong/include/numkong/dot/neonsdot.h +622 -0
  156. package/numkong/include/numkong/dot/powervsx.h +752 -0
  157. package/numkong/include/numkong/dot/rvv.h +722 -0
  158. package/numkong/include/numkong/dot/rvvbb.h +72 -0
  159. package/numkong/include/numkong/dot/rvvbf16.h +123 -0
  160. package/numkong/include/numkong/dot/rvvhalf.h +129 -0
  161. package/numkong/include/numkong/dot/sapphire.h +141 -0
  162. package/numkong/include/numkong/dot/serial.h +874 -0
  163. package/numkong/include/numkong/dot/sierra.h +405 -0
  164. package/numkong/include/numkong/dot/skylake.h +1116 -0
  165. package/numkong/include/numkong/dot/sve.h +420 -0
  166. package/numkong/include/numkong/dot/svebfdot.h +75 -0
  167. package/numkong/include/numkong/dot/svehalf.h +168 -0
  168. package/numkong/include/numkong/dot/svesdot.h +90 -0
  169. package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
  170. package/numkong/include/numkong/dot.h +1136 -0
  171. package/numkong/include/numkong/dot.hpp +94 -0
  172. package/numkong/include/numkong/dots/README.md +496 -0
  173. package/numkong/include/numkong/dots/alder.h +117 -0
  174. package/numkong/include/numkong/dots/diamond.h +86 -0
  175. package/numkong/include/numkong/dots/genoa.h +100 -0
  176. package/numkong/include/numkong/dots/graniteamx.h +733 -0
  177. package/numkong/include/numkong/dots/haswell.h +310 -0
  178. package/numkong/include/numkong/dots/icelake.h +180 -0
  179. package/numkong/include/numkong/dots/loongsonasx.h +176 -0
  180. package/numkong/include/numkong/dots/neon.h +123 -0
  181. package/numkong/include/numkong/dots/neonbfdot.h +59 -0
  182. package/numkong/include/numkong/dots/neonfhm.h +96 -0
  183. package/numkong/include/numkong/dots/neonfp8.h +99 -0
  184. package/numkong/include/numkong/dots/neonsdot.h +144 -0
  185. package/numkong/include/numkong/dots/powervsx.h +194 -0
  186. package/numkong/include/numkong/dots/rvv.h +2593 -0
  187. package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
  188. package/numkong/include/numkong/dots/serial.h +2867 -0
  189. package/numkong/include/numkong/dots/sierra.h +100 -0
  190. package/numkong/include/numkong/dots/skylake.h +207 -0
  191. package/numkong/include/numkong/dots/sme.h +5041 -0
  192. package/numkong/include/numkong/dots/smebi32.h +477 -0
  193. package/numkong/include/numkong/dots/smef64.h +1328 -0
  194. package/numkong/include/numkong/dots/smehalf.h +47 -0
  195. package/numkong/include/numkong/dots/v128relaxed.h +317 -0
  196. package/numkong/include/numkong/dots.h +3110 -0
  197. package/numkong/include/numkong/dots.hpp +641 -0
  198. package/numkong/include/numkong/each/README.md +465 -0
  199. package/numkong/include/numkong/each/haswell.h +1658 -0
  200. package/numkong/include/numkong/each/icelake.h +272 -0
  201. package/numkong/include/numkong/each/neon.h +1138 -0
  202. package/numkong/include/numkong/each/neonbfdot.h +211 -0
  203. package/numkong/include/numkong/each/neonhalf.h +318 -0
  204. package/numkong/include/numkong/each/rvv.h +1121 -0
  205. package/numkong/include/numkong/each/sapphire.h +343 -0
  206. package/numkong/include/numkong/each/serial.h +282 -0
  207. package/numkong/include/numkong/each/skylake.h +1562 -0
  208. package/numkong/include/numkong/each/v128relaxed.h +562 -0
  209. package/numkong/include/numkong/each.h +2232 -0
  210. package/numkong/include/numkong/each.hpp +434 -0
  211. package/numkong/include/numkong/geospatial/README.md +147 -0
  212. package/numkong/include/numkong/geospatial/haswell.h +633 -0
  213. package/numkong/include/numkong/geospatial/neon.h +615 -0
  214. package/numkong/include/numkong/geospatial/rvv.h +701 -0
  215. package/numkong/include/numkong/geospatial/serial.h +309 -0
  216. package/numkong/include/numkong/geospatial/skylake.h +613 -0
  217. package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
  218. package/numkong/include/numkong/geospatial.h +453 -0
  219. package/numkong/include/numkong/geospatial.hpp +235 -0
  220. package/numkong/include/numkong/matrix.hpp +336 -0
  221. package/numkong/include/numkong/maxsim/README.md +187 -0
  222. package/numkong/include/numkong/maxsim/alder.h +511 -0
  223. package/numkong/include/numkong/maxsim/genoa.h +115 -0
  224. package/numkong/include/numkong/maxsim/haswell.h +553 -0
  225. package/numkong/include/numkong/maxsim/icelake.h +480 -0
  226. package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
  227. package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
  228. package/numkong/include/numkong/maxsim/serial.h +490 -0
  229. package/numkong/include/numkong/maxsim/sme.h +993 -0
  230. package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
  231. package/numkong/include/numkong/maxsim.h +571 -0
  232. package/numkong/include/numkong/maxsim.hpp +133 -0
  233. package/numkong/include/numkong/mesh/README.md +219 -0
  234. package/numkong/include/numkong/mesh/haswell.h +2013 -0
  235. package/numkong/include/numkong/mesh/neon.h +1821 -0
  236. package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
  237. package/numkong/include/numkong/mesh/rvv.h +936 -0
  238. package/numkong/include/numkong/mesh/serial.h +721 -0
  239. package/numkong/include/numkong/mesh/skylake.h +2344 -0
  240. package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
  241. package/numkong/include/numkong/mesh.h +666 -0
  242. package/numkong/include/numkong/mesh.hpp +701 -0
  243. package/numkong/include/numkong/numkong.h +78 -0
  244. package/numkong/include/numkong/numkong.hpp +58 -0
  245. package/numkong/include/numkong/probability/README.md +177 -0
  246. package/numkong/include/numkong/probability/haswell.h +267 -0
  247. package/numkong/include/numkong/probability/neon.h +255 -0
  248. package/numkong/include/numkong/probability/rvv.h +414 -0
  249. package/numkong/include/numkong/probability/serial.h +181 -0
  250. package/numkong/include/numkong/probability/skylake.h +324 -0
  251. package/numkong/include/numkong/probability.h +380 -0
  252. package/numkong/include/numkong/probability.hpp +120 -0
  253. package/numkong/include/numkong/random.h +50 -0
  254. package/numkong/include/numkong/random.hpp +285 -0
  255. package/numkong/include/numkong/reduce/README.md +552 -0
  256. package/numkong/include/numkong/reduce/alder.h +636 -0
  257. package/numkong/include/numkong/reduce/genoa.h +201 -0
  258. package/numkong/include/numkong/reduce/haswell.h +3785 -0
  259. package/numkong/include/numkong/reduce/icelake.h +549 -0
  260. package/numkong/include/numkong/reduce/neon.h +3980 -0
  261. package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
  262. package/numkong/include/numkong/reduce/neonfhm.h +293 -0
  263. package/numkong/include/numkong/reduce/neonsdot.h +357 -0
  264. package/numkong/include/numkong/reduce/rvv.h +3533 -0
  265. package/numkong/include/numkong/reduce/serial.h +753 -0
  266. package/numkong/include/numkong/reduce/sierra.h +338 -0
  267. package/numkong/include/numkong/reduce/skylake.h +3794 -0
  268. package/numkong/include/numkong/reduce/sve.h +52 -0
  269. package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
  270. package/numkong/include/numkong/reduce.h +1582 -0
  271. package/numkong/include/numkong/reduce.hpp +778 -0
  272. package/numkong/include/numkong/scalar/README.md +89 -0
  273. package/numkong/include/numkong/scalar/haswell.h +122 -0
  274. package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
  275. package/numkong/include/numkong/scalar/neon.h +122 -0
  276. package/numkong/include/numkong/scalar/neonhalf.h +70 -0
  277. package/numkong/include/numkong/scalar/powervsx.h +96 -0
  278. package/numkong/include/numkong/scalar/rvv.h +211 -0
  279. package/numkong/include/numkong/scalar/sapphire.h +74 -0
  280. package/numkong/include/numkong/scalar/serial.h +332 -0
  281. package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
  282. package/numkong/include/numkong/scalar.h +696 -0
  283. package/numkong/include/numkong/set/README.md +179 -0
  284. package/numkong/include/numkong/set/haswell.h +334 -0
  285. package/numkong/include/numkong/set/icelake.h +485 -0
  286. package/numkong/include/numkong/set/loongsonasx.h +181 -0
  287. package/numkong/include/numkong/set/neon.h +363 -0
  288. package/numkong/include/numkong/set/powervsx.h +326 -0
  289. package/numkong/include/numkong/set/rvv.h +226 -0
  290. package/numkong/include/numkong/set/rvvbb.h +117 -0
  291. package/numkong/include/numkong/set/serial.h +174 -0
  292. package/numkong/include/numkong/set/sve.h +187 -0
  293. package/numkong/include/numkong/set/v128relaxed.h +240 -0
  294. package/numkong/include/numkong/set.h +471 -0
  295. package/numkong/include/numkong/set.hpp +114 -0
  296. package/numkong/include/numkong/sets/README.md +149 -0
  297. package/numkong/include/numkong/sets/haswell.h +63 -0
  298. package/numkong/include/numkong/sets/icelake.h +66 -0
  299. package/numkong/include/numkong/sets/loongsonasx.h +52 -0
  300. package/numkong/include/numkong/sets/neon.h +61 -0
  301. package/numkong/include/numkong/sets/powervsx.h +65 -0
  302. package/numkong/include/numkong/sets/serial.h +43 -0
  303. package/numkong/include/numkong/sets/smebi32.h +1135 -0
  304. package/numkong/include/numkong/sets/v128relaxed.h +58 -0
  305. package/numkong/include/numkong/sets.h +382 -0
  306. package/numkong/include/numkong/sparse/README.md +156 -0
  307. package/numkong/include/numkong/sparse/icelake.h +463 -0
  308. package/numkong/include/numkong/sparse/neon.h +288 -0
  309. package/numkong/include/numkong/sparse/serial.h +117 -0
  310. package/numkong/include/numkong/sparse/sve2.h +504 -0
  311. package/numkong/include/numkong/sparse/turin.h +322 -0
  312. package/numkong/include/numkong/sparse.h +363 -0
  313. package/numkong/include/numkong/sparse.hpp +113 -0
  314. package/numkong/include/numkong/spatial/README.md +439 -0
  315. package/numkong/include/numkong/spatial/alder.h +604 -0
  316. package/numkong/include/numkong/spatial/diamond.h +240 -0
  317. package/numkong/include/numkong/spatial/genoa.h +222 -0
  318. package/numkong/include/numkong/spatial/haswell.h +979 -0
  319. package/numkong/include/numkong/spatial/icelake.h +1067 -0
  320. package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
  321. package/numkong/include/numkong/spatial/neon.h +846 -0
  322. package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
  323. package/numkong/include/numkong/spatial/neonfp8.h +258 -0
  324. package/numkong/include/numkong/spatial/neonsdot.h +429 -0
  325. package/numkong/include/numkong/spatial/powervsx.h +738 -0
  326. package/numkong/include/numkong/spatial/rvv.h +991 -0
  327. package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
  328. package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
  329. package/numkong/include/numkong/spatial/serial.h +347 -0
  330. package/numkong/include/numkong/spatial/sierra.h +516 -0
  331. package/numkong/include/numkong/spatial/skylake.h +605 -0
  332. package/numkong/include/numkong/spatial/sve.h +246 -0
  333. package/numkong/include/numkong/spatial/svebfdot.h +125 -0
  334. package/numkong/include/numkong/spatial/svehalf.h +136 -0
  335. package/numkong/include/numkong/spatial/svesdot.h +143 -0
  336. package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
  337. package/numkong/include/numkong/spatial.h +1681 -0
  338. package/numkong/include/numkong/spatial.hpp +183 -0
  339. package/numkong/include/numkong/spatials/README.md +580 -0
  340. package/numkong/include/numkong/spatials/alder.h +94 -0
  341. package/numkong/include/numkong/spatials/diamond.h +82 -0
  342. package/numkong/include/numkong/spatials/genoa.h +94 -0
  343. package/numkong/include/numkong/spatials/graniteamx.h +173 -0
  344. package/numkong/include/numkong/spatials/haswell.h +219 -0
  345. package/numkong/include/numkong/spatials/icelake.h +113 -0
  346. package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
  347. package/numkong/include/numkong/spatials/neon.h +109 -0
  348. package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
  349. package/numkong/include/numkong/spatials/neonfhm.h +92 -0
  350. package/numkong/include/numkong/spatials/neonfp8.h +111 -0
  351. package/numkong/include/numkong/spatials/neonsdot.h +143 -0
  352. package/numkong/include/numkong/spatials/powervsx.h +153 -0
  353. package/numkong/include/numkong/spatials/rvv.h +1976 -0
  354. package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
  355. package/numkong/include/numkong/spatials/serial.h +248 -0
  356. package/numkong/include/numkong/spatials/sierra.h +96 -0
  357. package/numkong/include/numkong/spatials/skylake.h +184 -0
  358. package/numkong/include/numkong/spatials/sme.h +1927 -0
  359. package/numkong/include/numkong/spatials/smef64.h +483 -0
  360. package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
  361. package/numkong/include/numkong/spatials.h +3374 -0
  362. package/numkong/include/numkong/spatials.hpp +509 -0
  363. package/numkong/include/numkong/tensor.hpp +1981 -0
  364. package/numkong/include/numkong/trigonometry/README.md +184 -0
  365. package/numkong/include/numkong/trigonometry/haswell.h +653 -0
  366. package/numkong/include/numkong/trigonometry/neon.h +638 -0
  367. package/numkong/include/numkong/trigonometry/rvv.h +700 -0
  368. package/numkong/include/numkong/trigonometry/serial.h +703 -0
  369. package/numkong/include/numkong/trigonometry/skylake.h +725 -0
  370. package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
  371. package/numkong/include/numkong/trigonometry.h +467 -0
  372. package/numkong/include/numkong/trigonometry.hpp +166 -0
  373. package/numkong/include/numkong/types.h +1695 -0
  374. package/numkong/include/numkong/types.hpp +6027 -0
  375. package/numkong/include/numkong/vector.hpp +766 -0
  376. package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
  377. package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
  378. package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
  379. package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
  380. package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
  381. package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
  382. package/numkong/javascript/README.md +254 -0
  383. package/numkong/javascript/node-gyp-build.d.ts +4 -0
  384. package/numkong/javascript/numkong-browser.ts +40 -0
  385. package/numkong/javascript/numkong-wasm.ts +750 -0
  386. package/numkong/javascript/numkong.c +712 -0
  387. package/numkong/javascript/numkong.ts +613 -0
  388. package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
  389. package/numkong/javascript/tsconfig-cjs.json +13 -0
  390. package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
  391. package/numkong/javascript/types.ts +784 -0
  392. package/numkong/numkong.gypi +104 -0
  393. package/numkong/package.json +108 -0
  394. package/numkong/probes/arm_neon.c +8 -0
  395. package/numkong/probes/arm_neon_bfdot.c +9 -0
  396. package/numkong/probes/arm_neon_fhm.c +9 -0
  397. package/numkong/probes/arm_neon_half.c +8 -0
  398. package/numkong/probes/arm_neon_sdot.c +9 -0
  399. package/numkong/probes/arm_neonfp8.c +9 -0
  400. package/numkong/probes/arm_sme.c +16 -0
  401. package/numkong/probes/arm_sme2.c +16 -0
  402. package/numkong/probes/arm_sme2p1.c +16 -0
  403. package/numkong/probes/arm_sme_bf16.c +16 -0
  404. package/numkong/probes/arm_sme_bi32.c +16 -0
  405. package/numkong/probes/arm_sme_f64.c +16 -0
  406. package/numkong/probes/arm_sme_fa64.c +14 -0
  407. package/numkong/probes/arm_sme_half.c +16 -0
  408. package/numkong/probes/arm_sme_lut2.c +15 -0
  409. package/numkong/probes/arm_sve.c +18 -0
  410. package/numkong/probes/arm_sve2.c +20 -0
  411. package/numkong/probes/arm_sve2p1.c +18 -0
  412. package/numkong/probes/arm_sve_bfdot.c +20 -0
  413. package/numkong/probes/arm_sve_half.c +18 -0
  414. package/numkong/probes/arm_sve_sdot.c +21 -0
  415. package/numkong/probes/loongarch_lasx.c +12 -0
  416. package/numkong/probes/power_vsx.c +12 -0
  417. package/numkong/probes/probe.js +127 -0
  418. package/numkong/probes/riscv_rvv.c +14 -0
  419. package/numkong/probes/riscv_rvv_bb.c +15 -0
  420. package/numkong/probes/riscv_rvv_bf16.c +17 -0
  421. package/numkong/probes/riscv_rvv_half.c +14 -0
  422. package/numkong/probes/wasm_v128relaxed.c +11 -0
  423. package/numkong/probes/x86_alder.c +17 -0
  424. package/numkong/probes/x86_diamond.c +17 -0
  425. package/numkong/probes/x86_genoa.c +17 -0
  426. package/numkong/probes/x86_graniteamx.c +19 -0
  427. package/numkong/probes/x86_haswell.c +11 -0
  428. package/numkong/probes/x86_icelake.c +17 -0
  429. package/numkong/probes/x86_sapphire.c +16 -0
  430. package/numkong/probes/x86_sapphireamx.c +18 -0
  431. package/numkong/probes/x86_sierra.c +17 -0
  432. package/numkong/probes/x86_skylake.c +15 -0
  433. package/numkong/probes/x86_turin.c +17 -0
  434. package/numkong/rust/README.md +698 -0
  435. package/numkong/rust/capabilities.rs +96 -0
  436. package/numkong/rust/cast.rs +314 -0
  437. package/numkong/rust/curved.rs +391 -0
  438. package/numkong/rust/each.rs +2721 -0
  439. package/numkong/rust/geospatial.rs +343 -0
  440. package/numkong/rust/matrix.rs +5424 -0
  441. package/numkong/rust/maxsim.rs +540 -0
  442. package/numkong/rust/mesh.rs +837 -0
  443. package/numkong/rust/numkong.rs +409 -0
  444. package/numkong/rust/probability.rs +272 -0
  445. package/numkong/rust/reduce.rs +1249 -0
  446. package/numkong/rust/set.rs +194 -0
  447. package/numkong/rust/sparse.rs +513 -0
  448. package/numkong/rust/spatial.rs +1815 -0
  449. package/numkong/rust/tensor.rs +7565 -0
  450. package/numkong/rust/types.rs +3666 -0
  451. package/numkong/rust/vector.rs +1899 -0
  452. package/numkong/rustfmt.toml +2 -0
  453. package/numkong/swift/Matrix.swift +1388 -0
  454. package/numkong/swift/MaxSim.swift +151 -0
  455. package/numkong/swift/NumKong.swift +283 -0
  456. package/numkong/swift/Numerics.swift +329 -0
  457. package/numkong/swift/README.md +433 -0
  458. package/numkong/swift/Scalar.swift +741 -0
  459. package/numkong/swift/Tensor.swift +209 -0
  460. package/numkong/test/README.md +315 -0
  461. package/numkong/test/playwright.config.ts +16 -0
  462. package/numkong/test/swift/Test.swift +534 -0
  463. package/numkong/test/test-browser-bundle-runner.mjs +36 -0
  464. package/numkong/test/test-browser-bundle.html +188 -0
  465. package/numkong/test/test-browser-runner.mjs +43 -0
  466. package/numkong/test/test-browser.html +305 -0
  467. package/numkong/test/test-dtypes.mjs +453 -0
  468. package/numkong/test/test-wasm.mjs +267 -0
  469. package/numkong/test/test.cpp +442 -0
  470. package/numkong/test/test.hpp +580 -0
  471. package/numkong/test/test.mjs +363 -0
  472. package/numkong/test/test_base.py +1041 -0
  473. package/numkong/test/test_cast.cpp +242 -0
  474. package/numkong/test/test_cross.hpp +551 -0
  475. package/numkong/test/test_cross.py +467 -0
  476. package/numkong/test/test_cross_amx.cpp +50 -0
  477. package/numkong/test/test_cross_arm.cpp +225 -0
  478. package/numkong/test/test_cross_blas.cpp +354 -0
  479. package/numkong/test/test_cross_loongarch.cpp +90 -0
  480. package/numkong/test/test_cross_power.cpp +73 -0
  481. package/numkong/test/test_cross_rvv.cpp +109 -0
  482. package/numkong/test/test_cross_serial.cpp +181 -0
  483. package/numkong/test/test_cross_sme.cpp +148 -0
  484. package/numkong/test/test_cross_wasm.cpp +141 -0
  485. package/numkong/test/test_cross_x86.cpp +442 -0
  486. package/numkong/test/test_curved.cpp +182 -0
  487. package/numkong/test/test_curved.py +207 -0
  488. package/numkong/test/test_dot.cpp +353 -0
  489. package/numkong/test/test_dot.py +296 -0
  490. package/numkong/test/test_each.cpp +437 -0
  491. package/numkong/test/test_each.py +756 -0
  492. package/numkong/test/test_geospatial.cpp +155 -0
  493. package/numkong/test/test_geospatial.py +241 -0
  494. package/numkong/test/test_maxsim.cpp +138 -0
  495. package/numkong/test/test_maxsim.py +209 -0
  496. package/numkong/test/test_mesh.cpp +203 -0
  497. package/numkong/test/test_mesh.py +394 -0
  498. package/numkong/test/test_probability.cpp +136 -0
  499. package/numkong/test/test_probability.py +166 -0
  500. package/numkong/test/test_reduce.cpp +563 -0
  501. package/numkong/test/test_reduce.py +781 -0
  502. package/numkong/test/test_set.cpp +151 -0
  503. package/numkong/test/test_set.py +120 -0
  504. package/numkong/test/test_similarities.py +579 -0
  505. package/numkong/test/test_sparse.cpp +121 -0
  506. package/numkong/test/test_sparse.py +118 -0
  507. package/numkong/test/test_spatial.cpp +518 -0
  508. package/numkong/test/test_spatial.py +269 -0
  509. package/numkong/test/test_tensor.cpp +884 -0
  510. package/numkong/test/test_tensor.py +1417 -0
  511. package/numkong/test/test_trigonometry.cpp +156 -0
  512. package/numkong/test/test_trigonometry.py +180 -0
  513. package/package.json +7 -8
  514. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  515. package/prebuilds/linux-arm64/usearch.node +0 -0
  516. package/prebuilds/linux-x64/usearch.node +0 -0
  517. package/fp16/CMakeLists.txt +0 -176
  518. package/fp16/LICENSE +0 -11
  519. package/fp16/README.md +0 -20
  520. package/fp16/bench/alt-element.cc +0 -89
  521. package/fp16/bench/from-alt-array.cc +0 -175
  522. package/fp16/bench/from-ieee-array.cc +0 -399
  523. package/fp16/bench/ieee-element.cc +0 -272
  524. package/fp16/bench/to-alt-array.cc +0 -91
  525. package/fp16/bench/to-ieee-array.cc +0 -303
  526. package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
  527. package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
  528. package/fp16/cmake/DownloadPSimd.cmake +0 -15
  529. package/fp16/configure.py +0 -65
  530. package/fp16/confu.yaml +0 -8
  531. package/fp16/include/fp16/__init__.py +0 -0
  532. package/fp16/include/fp16/avx.py +0 -50
  533. package/fp16/include/fp16/avx2.py +0 -53
  534. package/fp16/include/fp16/bitcasts.h +0 -92
  535. package/fp16/include/fp16/fp16.h +0 -451
  536. package/fp16/include/fp16/psimd.h +0 -131
  537. package/fp16/include/fp16.h +0 -11
  538. package/fp16/jni/Android.mk +0 -6
  539. package/fp16/jni/Application.mk +0 -4
  540. package/fp16/test/alt-from-fp32-value.cc +0 -498
  541. package/fp16/test/alt-to-fp32-bits.cc +0 -263
  542. package/fp16/test/alt-to-fp32-psimd.cc +0 -145
  543. package/fp16/test/alt-to-fp32-value.cc +0 -348
  544. package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
  545. package/fp16/test/bitcasts.cc +0 -56
  546. package/fp16/test/ieee-from-fp32-value.cc +0 -523
  547. package/fp16/test/ieee-to-fp32-bits.cc +0 -333
  548. package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
  549. package/fp16/test/ieee-to-fp32-value.cc +0 -420
  550. package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
  551. package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
  552. package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
  553. package/fp16/test/peachpy/stubs.py +0 -38
  554. package/fp16/test/tables.cc +0 -530
  555. package/fp16/test/tables.h +0 -13
  556. package/fp16/third-party/THHalf.h +0 -92
  557. package/fp16/third-party/eigen-half.h +0 -170
  558. package/fp16/third-party/float16-compressor.h +0 -80
  559. package/fp16/third-party/half.hpp +0 -2916
  560. package/fp16/third-party/npy-halffloat.h +0 -328
  561. package/simsimd/.git-blame-ignore-revs +0 -2
  562. package/simsimd/CONTRIBUTING.md +0 -321
  563. package/simsimd/Cargo.toml +0 -49
  564. package/simsimd/MANIFEST.in +0 -4
  565. package/simsimd/Package.swift +0 -28
  566. package/simsimd/README.md +0 -1493
  567. package/simsimd/binding.gyp +0 -35
  568. package/simsimd/build.rs +0 -70
  569. package/simsimd/c/lib.c +0 -374
  570. package/simsimd/include/module.modulemap +0 -4
  571. package/simsimd/include/simsimd/binary.h +0 -486
  572. package/simsimd/include/simsimd/curved.h +0 -1541
  573. package/simsimd/include/simsimd/dot.h +0 -1853
  574. package/simsimd/include/simsimd/elementwise.h +0 -2465
  575. package/simsimd/include/simsimd/geospatial.h +0 -43
  576. package/simsimd/include/simsimd/mesh.h +0 -69
  577. package/simsimd/include/simsimd/probability.h +0 -606
  578. package/simsimd/include/simsimd/simsimd.h +0 -2567
  579. package/simsimd/include/simsimd/sparse.h +0 -1384
  580. package/simsimd/include/simsimd/spatial.h +0 -2335
  581. package/simsimd/include/simsimd/types.h +0 -666
  582. package/simsimd/javascript/fallback.ts +0 -233
  583. package/simsimd/javascript/lib.c +0 -125
  584. package/simsimd/javascript/node-gyp-build.d.ts +0 -1
  585. package/simsimd/javascript/simsimd.ts +0 -179
  586. package/simsimd/javascript/tsconfig-cjs.json +0 -8
  587. package/simsimd/package-lock.json +0 -1761
  588. package/simsimd/package.json +0 -61
  589. package/simsimd/rust/lib.rs +0 -1821
  590. package/simsimd/scripts/bench.cxx +0 -1170
  591. package/simsimd/scripts/bench.ipynb +0 -187
  592. package/simsimd/scripts/bench.js +0 -127
  593. package/simsimd/scripts/bench.rs +0 -876
  594. package/simsimd/scripts/bench_vectors.py +0 -734
  595. package/simsimd/scripts/bench_vectors_live.py +0 -213
  596. package/simsimd/scripts/test.c +0 -187
  597. package/simsimd/scripts/test.mjs +0 -220
  598. package/simsimd/scripts/test.py +0 -1505
  599. package/simsimd/swift/SimSIMD.swift +0 -149
  600. package/simsimd/swift/Test.swift +0 -128
  601. /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
  602. /package/{simsimd → numkong}/LICENSE +0 -0
  603. /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
  604. /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
@@ -0,0 +1,766 @@
1
+ /**
2
+ * @brief NumKong Vector types for C++23 and newer.
3
+ * @file include/numkong/vector.hpp
4
+ * @author Ash Vardanian
5
+ * @date January 7, 2026
6
+ *
7
+ * Provides owning and non-owning vector types with signed indexing,
8
+ * strided views, and sub-byte element support.
9
+ *
10
+ * - `nk::vector<T, A>`: Owning, non-resizable, SIMD-aligned
11
+ * - `nk::vector_view<T>`: Non-owning, const, strided
12
+ * - `nk::vector_span<T>`: Non-owning, mutable, strided
13
+ *
14
+ * @section vector_terminology Terminology: Dimensions vs Values
15
+ *
16
+ * The `nk::vector<value_type_>` container uses two distinct counts:
17
+ *
18
+ * - `size()`: Number of logical dimensions (what kernels see).
19
+ * For `vector<i4x2_t>` with 100 dimensions, you have 100 nibbles.
20
+ *
21
+ * - `size_values()`: Number of C++ container elements (`value_type_` instances).
22
+ * For `vector<i4x2_t>` with 100 dimensions, you have 50 values (2 dims/value).
23
+ *
24
+ * @code
25
+ * auto v = nk::vector<float>::try_zeros(5);
26
+ * v.size(); // 5
27
+ * v[-1]; // last element (signed indexing)
28
+ * v[nk::range(0,3)]; // view of first 3 elements
29
+ * @endcode
30
+ *
31
+ * See `types.hpp` for the full terminology reference.
32
+ */
33
+
34
+ #ifndef NK_VECTOR_HPP
35
+ #define NK_VECTOR_HPP
36
+
37
+ #include <concepts> // `std::integral`
38
+ #include <cstdlib> // `std::aligned_alloc`, `std::free`
39
+ #include <cstring> // `std::memset`
40
+ #include <iterator> // `std::random_access_iterator_tag`
41
+ #include <memory> // `std::allocator_traits`
42
+ #include <type_traits> // `std::conditional_t`
43
+ #include <utility> // `std::exchange`, `std::swap`
44
+
45
+ #include "types.hpp"
46
+
47
+ namespace ashvardanian::numkong {
48
+
49
+ #pragma region Aligned Allocator
50
+
51
+ /**
52
+ * @brief Cache-aligned allocator with non-throwing allocation.
53
+ * @tparam value_type_ Value type to allocate.
54
+ * @tparam alignment_ Alignment in bytes (default: 64 for cache line).
55
+ *
56
+ * This allocator uses `std::aligned_alloc` and returns `nullptr` on failure
57
+ * instead of throwing. It is stateless and always compares equal.
58
+ */
59
+ template <typename value_type_, std::size_t alignment_ = 64>
60
+ struct aligned_allocator {
61
+ using value_type = value_type_;
62
+ using size_type = std::size_t;
63
+ using difference_type = std::ptrdiff_t;
64
+ using propagate_on_container_move_assignment = std::true_type;
65
+ using is_always_equal = std::true_type;
66
+
67
+ template <typename other_type_>
68
+ struct rebind {
69
+ using other = aligned_allocator<other_type_, alignment_>;
70
+ };
71
+
72
+ static constexpr std::size_t alignment = alignment_;
73
+
74
+ constexpr aligned_allocator() noexcept = default;
75
+
76
+ template <typename other_type_>
77
+ constexpr aligned_allocator(aligned_allocator<other_type_, alignment_> const &) noexcept {}
78
+
79
+ [[nodiscard]] value_type *allocate(std::size_t n) noexcept {
80
+ if (n == 0) return nullptr;
81
+ std::size_t bytes = n * sizeof(value_type);
82
+ // Round up to alignment boundary (required by aligned_alloc)
83
+ std::size_t aligned_bytes = ((bytes + alignment_ - 1) / alignment_) * alignment_;
84
+ #if defined(_MSC_VER)
85
+ return static_cast<value_type *>(::_aligned_malloc(aligned_bytes, alignment_));
86
+ #else
87
+ return static_cast<value_type *>(std::aligned_alloc(alignment_, aligned_bytes));
88
+ #endif
89
+ }
90
+
91
+ void deallocate(value_type *p, std::size_t) noexcept {
92
+ #if defined(_MSC_VER)
93
+ if (p) ::_aligned_free(p);
94
+ #else
95
+ if (p) std::free(p);
96
+ #endif
97
+ }
98
+
99
+ template <typename other_type_>
100
+ constexpr bool operator==(aligned_allocator<other_type_, alignment_> const &) const noexcept {
101
+ return true;
102
+ }
103
+ };
104
+
105
+ #pragma endregion Aligned Allocator
106
+
107
+ #pragma region Slicing Infrastructure
108
+
109
+ /** @brief Tag type for selecting all elements along a dimension. */
110
+ struct all_t {};
111
+
112
+ /** @brief Global instance of `all_t` for use in slicing expressions. */
113
+ inline constexpr all_t all {};
114
+
115
+ /** @brief Slicing descriptor: [start, stop) with optional step.
116
+ * `step` must be non-zero. Negative start/stop indices wrap from the end. */
117
+ struct range {
118
+ std::ptrdiff_t start, stop, step;
119
+ template <std::integral start_type_, std::integral stop_type_, std::integral step_type_ = int>
120
+ constexpr range(start_type_ start, stop_type_ stop, step_type_ step = 1) noexcept
121
+ : start(static_cast<std::ptrdiff_t>(start)), stop(static_cast<std::ptrdiff_t>(stop)),
122
+ step(static_cast<std::ptrdiff_t>(step)) {}
123
+ };
124
+
125
+ /** @brief Resolve an integral index to an unsigned offset. Negative wraps from end. */
126
+ template <std::integral index_type_>
127
+ constexpr std::size_t resolve_index_(index_type_ idx, std::size_t extent) noexcept {
128
+ if constexpr (std::signed_integral<index_type_>)
129
+ return static_cast<std::size_t>(idx >= 0 ? idx : static_cast<std::ptrdiff_t>(extent) + idx);
130
+ else return static_cast<std::size_t>(idx);
131
+ }
132
+
133
+ /** @brief Normalize any integral stride input to the signed internal representation. */
134
+ template <std::integral stride_type_>
135
+ constexpr std::ptrdiff_t resolve_stride_(stride_type_ stride) noexcept {
136
+ return static_cast<std::ptrdiff_t>(stride);
137
+ }
138
+
139
+ /** @brief Normalize any unsigned extent input to the internal representation. */
140
+ template <std::unsigned_integral extent_type_>
141
+ constexpr std::size_t resolve_extent_(extent_type_ extent) noexcept {
142
+ return static_cast<std::size_t>(extent);
143
+ }
144
+
145
+ /** @brief Resolve range start/stop against an extent (handles negatives). */
146
+ constexpr void resolve_range_(range const &r, std::size_t extent, //
147
+ std::size_t &out_start, std::size_t &out_stop) noexcept {
148
+ out_start = resolve_index_(r.start, extent);
149
+ out_stop = resolve_index_(r.stop, extent);
150
+ }
151
+
152
+ /** @brief Number of elements in a resolved range with the given step. */
153
+ constexpr std::size_t range_extent_(std::size_t start, std::size_t stop, std::ptrdiff_t step) noexcept {
154
+ if (step > 0)
155
+ return start < stop ? (stop - start + static_cast<std::size_t>(step) - 1) / static_cast<std::size_t>(step) : 0;
156
+ else {
157
+ auto abs_step = static_cast<std::size_t>(-step);
158
+ return start > stop ? (start - stop + abs_step - 1) / abs_step : 0;
159
+ }
160
+ }
161
+
162
+ #pragma endregion Slicing Infrastructure
163
+
164
+ #pragma region Forward Declarations
165
+
166
+ template <typename value_type_>
167
+ struct vector_view;
168
+ template <typename value_type_>
169
+ struct vector_span;
170
+
171
+ #pragma endregion Forward Declarations
172
+
173
+ #pragma region Dim Iterator
174
+
175
+ template <typename value_type_, typename allocator_type_>
176
+ struct vector;
177
+
178
+ /**
179
+ * @brief Random-access iterator over logical dimensions.
180
+ *
181
+ * For sub-byte types (i4x2_t, u1x8_t), dereference returns a proxy reference.
182
+ * For normal types, dereference returns a direct reference.
183
+ */
184
+ template <typename container_type_>
185
+ class dim_iterator {
186
+ static constexpr bool is_const_ = std::is_const<container_type_>::value;
187
+ using container_t = typename std::remove_reference<container_type_>::type;
188
+ using container_ptr_t = std::conditional_t<is_const_, container_t const *, container_t *>;
189
+
190
+ container_ptr_t container_;
191
+ std::size_t index_;
192
+
193
+ public:
194
+ using container_type = container_type_;
195
+ using iterator_category = std::random_access_iterator_tag;
196
+ using difference_type = std::ptrdiff_t;
197
+ using size_type = std::size_t;
198
+
199
+ constexpr dim_iterator() noexcept : container_(nullptr), index_(0) {}
200
+ constexpr dim_iterator(container_type &c, size_type i) noexcept : container_(&c), index_(i) {}
201
+
202
+ constexpr decltype(auto) operator*() const noexcept { return (*container_)[index_]; }
203
+
204
+ constexpr auto operator->() const noexcept { return &(*container_)[index_]; }
205
+
206
+ constexpr decltype(auto) operator[](difference_type n) const noexcept {
207
+ return (*container_)[static_cast<difference_type>(index_) + n];
208
+ }
209
+
210
+ constexpr dim_iterator &operator++() noexcept {
211
+ ++index_;
212
+ return *this;
213
+ }
214
+ constexpr dim_iterator operator++(int) noexcept {
215
+ auto tmp = *this;
216
+ ++index_;
217
+ return tmp;
218
+ }
219
+ constexpr dim_iterator &operator--() noexcept {
220
+ --index_;
221
+ return *this;
222
+ }
223
+ constexpr dim_iterator operator--(int) noexcept {
224
+ auto tmp = *this;
225
+ --index_;
226
+ return tmp;
227
+ }
228
+
229
+ constexpr dim_iterator &operator+=(difference_type n) noexcept {
230
+ index_ += n;
231
+ return *this;
232
+ }
233
+ constexpr dim_iterator &operator-=(difference_type n) noexcept {
234
+ index_ -= n;
235
+ return *this;
236
+ }
237
+ constexpr dim_iterator operator+(difference_type n) const noexcept {
238
+ return {*container_, index_ + static_cast<size_type>(n)};
239
+ }
240
+ constexpr dim_iterator operator-(difference_type n) const noexcept {
241
+ return {*container_, index_ - static_cast<size_type>(n)};
242
+ }
243
+ constexpr difference_type operator-(dim_iterator const &other) const noexcept {
244
+ return static_cast<difference_type>(index_) - static_cast<difference_type>(other.index_);
245
+ }
246
+
247
+ constexpr bool operator==(dim_iterator const &other) const noexcept { return index_ == other.index_; }
248
+ constexpr bool operator!=(dim_iterator const &other) const noexcept { return index_ != other.index_; }
249
+ constexpr bool operator<(dim_iterator const &other) const noexcept { return index_ < other.index_; }
250
+ constexpr bool operator<=(dim_iterator const &other) const noexcept { return index_ <= other.index_; }
251
+ constexpr bool operator>(dim_iterator const &other) const noexcept { return index_ > other.index_; }
252
+ constexpr bool operator>=(dim_iterator const &other) const noexcept { return index_ >= other.index_; }
253
+
254
+ constexpr size_type index() const noexcept { return index_; }
255
+
256
+ friend constexpr dim_iterator operator+(difference_type n, dim_iterator const &it) noexcept { return it + n; }
257
+ };
258
+
259
+ /** Lightweight view yielding (index, value) pairs from a container's iterator. */
260
+ template <typename container_type_>
261
+ struct enumerate_view_ {
262
+ container_type_ &container_;
263
+
264
+ struct iterator_ {
265
+ using inner_iterator = decltype(std::declval<container_type_ &>().begin());
266
+ using difference_type = std::ptrdiff_t;
267
+ using iterator_category = std::input_iterator_tag;
268
+
269
+ inner_iterator it_;
270
+ std::size_t index_;
271
+
272
+ constexpr auto operator*() const noexcept { return std::pair<std::size_t, decltype(*it_)> {index_, *it_}; }
273
+ constexpr iterator_ &operator++() noexcept {
274
+ ++it_;
275
+ ++index_;
276
+ return *this;
277
+ }
278
+ constexpr iterator_ operator++(int) noexcept {
279
+ auto t = *this;
280
+ ++*this;
281
+ return t;
282
+ }
283
+ constexpr bool operator==(iterator_ const &o) const noexcept { return it_ == o.it_; }
284
+ constexpr bool operator!=(iterator_ const &o) const noexcept { return it_ != o.it_; }
285
+ };
286
+
287
+ constexpr iterator_ begin() noexcept { return {container_.begin(), 0}; }
288
+ constexpr iterator_ end() noexcept { return {container_.end(), container_.size()}; }
289
+ };
290
+
291
+ /** Returns a view yielding (index, value) pairs over a vector, view, or span. */
292
+ template <typename container_type_>
293
+ constexpr enumerate_view_<container_type_> enumerate(container_type_ &c) noexcept {
294
+ return {c};
295
+ }
296
+
297
+ template <typename container_type_>
298
+ constexpr enumerate_view_<container_type_ const> enumerate(container_type_ const &c) noexcept {
299
+ return {c};
300
+ }
301
+
302
+ #pragma endregion Dim Iterator
303
+
304
+ #pragma region Vector View
305
+
306
+ /**
307
+ * @brief Non-owning, immutable, strided view into a vector.
308
+ * @tparam value_type_ Element type.
309
+ *
310
+ * Supports signed indexing (`v[-1]` = last element) and strided access.
311
+ * For sub-byte types, only contiguous views are meaningful.
312
+ */
313
+ template <typename value_type_>
314
+ struct vector_view {
315
+ using value_type = value_type_;
316
+ using size_type = std::size_t;
317
+ using difference_type = std::ptrdiff_t;
318
+
319
+ using const_iterator = dim_iterator<vector_view const>;
320
+
321
+ private:
322
+ char const *data_ = nullptr;
323
+ size_type dimensions_ = 0;
324
+ difference_type stride_bytes_ = 0;
325
+
326
+ public:
327
+ constexpr vector_view() noexcept = default;
328
+
329
+ template <std::unsigned_integral dims_type_, std::integral stride_type_>
330
+ constexpr vector_view(char const *data, dims_type_ dims, stride_type_ stride_bytes) noexcept
331
+ : data_(data), dimensions_(resolve_extent_(dims)), stride_bytes_(resolve_stride_(stride_bytes)) {}
332
+
333
+ /** @brief Construct from contiguous typed pointer. */
334
+ template <std::unsigned_integral dims_type_>
335
+ constexpr vector_view(value_type const *data, dims_type_ dims) noexcept
336
+ : data_(reinterpret_cast<char const *>(data)), dimensions_(resolve_extent_(dims)),
337
+ stride_bytes_(static_cast<difference_type>(sizeof(value_type))) {}
338
+
339
+ /** @brief Number of logical dimensions. */
340
+ constexpr size_type size() const noexcept { return dimensions_; }
341
+
342
+ /** @brief Check if empty. */
343
+ constexpr bool empty() const noexcept { return dimensions_ == 0; }
344
+
345
+ /** @brief Stride in bytes between consecutive elements. */
346
+ constexpr difference_type stride_bytes() const noexcept { return stride_bytes_; }
347
+
348
+ /** @brief True if elements are stored contiguously. */
349
+ constexpr bool is_contiguous() const noexcept {
350
+ return stride_bytes_ == static_cast<difference_type>(sizeof(value_type));
351
+ }
352
+
353
+ /** @brief Raw byte pointer to the first element. */
354
+ constexpr char const *byte_data() const noexcept { return data_; }
355
+
356
+ /** @brief Typed pointer (only valid if contiguous). */
357
+ constexpr value_type const *data() const noexcept { return reinterpret_cast<value_type const *>(data_); }
358
+
359
+ /** @brief Integral indexing: signed negatives wrap from end. */
360
+ template <std::integral index_type_>
361
+ decltype(auto) operator[](index_type_ idx) const noexcept {
362
+ auto i = resolve_index_(idx, dimensions_);
363
+ if constexpr (dimensions_per_value<value_type>() > 1) {
364
+ constexpr auto dims_per_value = dimensions_per_value<value_type>();
365
+ auto value_index = i / dims_per_value;
366
+ auto sub_index = i % dims_per_value;
367
+ using raw_type = typename raw_pod_type<value_type>::type;
368
+ auto *base = const_cast<raw_type *>(
369
+ reinterpret_cast<raw_type const *>(data_ + static_cast<difference_type>(value_index) * stride_bytes_));
370
+ return sub_byte_ref<value_type>(base, sub_index).get();
371
+ }
372
+ else { return *reinterpret_cast<value_type const *>(data_ + static_cast<difference_type>(i) * stride_bytes_); }
373
+ }
374
+
375
+ /** @brief Sub-slice via range. */
376
+ vector_view operator[](range r) const noexcept {
377
+ size_type start, stop;
378
+ resolve_range_(r, dimensions_, start, stop);
379
+ auto count = range_extent_(start, stop, r.step);
380
+ return {data_ + static_cast<difference_type>(start) * stride_bytes_, count, stride_bytes_ * r.step};
381
+ }
382
+
383
+ /** @brief Select all elements (identity). */
384
+ vector_view operator[](all_t) const noexcept { return *this; }
385
+
386
+ /** @brief Create a reversed view by negating the stride and pointing to the last element.
387
+ * Iterating the returned view visits elements in reverse order. */
388
+ constexpr vector_view rev() const noexcept {
389
+ if (dimensions_ == 0) return *this;
390
+ return {data_ + static_cast<difference_type>(dimensions_ - 1) * stride_bytes_, dimensions_, -stride_bytes_};
391
+ }
392
+
393
+ /** @brief Dimension iterator to beginning. */
394
+ const_iterator begin() const noexcept { return {*this, 0}; }
395
+ const_iterator cbegin() const noexcept { return {*this, 0}; }
396
+
397
+ /** @brief Dimension iterator to end. */
398
+ const_iterator end() const noexcept { return {*this, dimensions_}; }
399
+ const_iterator cend() const noexcept { return {*this, dimensions_}; }
400
+ };
401
+
402
+ #pragma endregion Vector View
403
+
404
+ #pragma region Vector Span
405
+
406
+ /**
407
+ * @brief Non-owning, mutable, strided view into a vector.
408
+ * @tparam value_type_ Element type.
409
+ *
410
+ * Same as `vector_view` but allows mutation. Implicitly converts to `vector_view`.
411
+ */
412
+ template <typename value_type_>
413
+ struct vector_span {
414
+ using value_type = value_type_;
415
+ using size_type = std::size_t;
416
+ using difference_type = std::ptrdiff_t;
417
+
418
+ using iterator = dim_iterator<vector_span>;
419
+ using const_iterator = dim_iterator<vector_span const>;
420
+
421
+ private:
422
+ char *data_ = nullptr;
423
+ size_type dimensions_ = 0;
424
+ difference_type stride_bytes_ = 0;
425
+
426
+ public:
427
+ constexpr vector_span() noexcept = default;
428
+
429
+ template <std::unsigned_integral dims_type_, std::integral stride_type_>
430
+ constexpr vector_span(char *data, dims_type_ dims, stride_type_ stride_bytes) noexcept
431
+ : data_(data), dimensions_(resolve_extent_(dims)), stride_bytes_(resolve_stride_(stride_bytes)) {}
432
+
433
+ /** @brief Construct from contiguous typed pointer. */
434
+ template <std::unsigned_integral dims_type_>
435
+ constexpr vector_span(value_type *data, dims_type_ dims) noexcept
436
+ : data_(reinterpret_cast<char *>(data)), dimensions_(resolve_extent_(dims)),
437
+ stride_bytes_(static_cast<difference_type>(sizeof(value_type))) {}
438
+
439
+ /** @brief Number of logical dimensions. */
440
+ constexpr size_type size() const noexcept { return dimensions_; }
441
+
442
+ /** @brief Check if empty. */
443
+ constexpr bool empty() const noexcept { return dimensions_ == 0; }
444
+
445
+ /** @brief Stride in bytes. */
446
+ constexpr difference_type stride_bytes() const noexcept { return stride_bytes_; }
447
+
448
+ /** @brief True if contiguous. */
449
+ constexpr bool is_contiguous() const noexcept {
450
+ return stride_bytes_ == static_cast<difference_type>(sizeof(value_type));
451
+ }
452
+
453
+ /** @brief Raw byte pointer. */
454
+ constexpr char *byte_data() noexcept { return data_; }
455
+ constexpr char const *byte_data() const noexcept { return data_; }
456
+
457
+ /** @brief Typed pointer (only valid if contiguous). */
458
+ constexpr value_type *data() noexcept { return reinterpret_cast<value_type *>(data_); }
459
+ constexpr value_type const *data() const noexcept { return reinterpret_cast<value_type const *>(data_); }
460
+
461
+ /** @brief Implicit conversion to const view. */
462
+ constexpr operator vector_view<value_type>() const noexcept {
463
+ return {static_cast<char const *>(data_), dimensions_, stride_bytes_};
464
+ }
465
+
466
+ /** @brief Mutable integral indexing. Signed negatives wrap from end. */
467
+ template <std::integral index_type_>
468
+ decltype(auto) operator[](index_type_ idx) noexcept {
469
+ auto i = resolve_index_(idx, dimensions_);
470
+ if constexpr (dimensions_per_value<value_type>() > 1) {
471
+ constexpr auto dims_per_value = dimensions_per_value<value_type>();
472
+ auto value_index = i / dims_per_value;
473
+ auto sub_index = i % dims_per_value;
474
+ using raw_type = typename raw_pod_type<value_type>::type;
475
+ auto *base = reinterpret_cast<raw_type *>(data_ +
476
+ static_cast<difference_type>(value_index) * stride_bytes_);
477
+ return sub_byte_ref<value_type>(base, sub_index);
478
+ }
479
+ else { return *reinterpret_cast<value_type *>(data_ + static_cast<difference_type>(i) * stride_bytes_); }
480
+ }
481
+
482
+ /** @brief Const integral indexing. Signed negatives wrap from end. */
483
+ template <std::integral index_type_>
484
+ decltype(auto) operator[](index_type_ idx) const noexcept {
485
+ return static_cast<vector_view<value_type>>(*this)[idx];
486
+ }
487
+
488
+ /** @brief Sub-slice via range. */
489
+ vector_span operator[](range r) noexcept {
490
+ size_type start, stop;
491
+ resolve_range_(r, dimensions_, start, stop);
492
+ auto count = range_extent_(start, stop, r.step);
493
+ return {data_ + static_cast<difference_type>(start) * stride_bytes_, count, stride_bytes_ * r.step};
494
+ }
495
+
496
+ /** @brief Const sub-slice via range. */
497
+ vector_view<value_type> operator[](range r) const noexcept {
498
+ return static_cast<vector_view<value_type>>(*this)[r];
499
+ }
500
+
501
+ /** @brief Select all elements. */
502
+ vector_span operator[](all_t) noexcept { return *this; }
503
+
504
+ /** @brief Dimension iterator to beginning. */
505
+ iterator begin() noexcept { return {*this, 0}; }
506
+ const_iterator begin() const noexcept { return {*this, 0}; }
507
+ const_iterator cbegin() const noexcept { return {*this, 0}; }
508
+
509
+ /** @brief Dimension iterator to end. */
510
+ iterator end() noexcept { return {*this, dimensions_}; }
511
+ const_iterator end() const noexcept { return {*this, dimensions_}; }
512
+ const_iterator cend() const noexcept { return {*this, dimensions_}; }
513
+ };
514
+
515
+ #pragma endregion Vector Span
516
+
517
+ #pragma region Vector
518
+
519
+ /**
520
+ * @brief Owning, non-resizable, SIMD-aligned vector.
521
+ *
522
+ * Size is fixed at construction. Use `try_zeros()` factory for
523
+ * non-throwing construction, or `from_raw()` to adopt existing memory.
524
+ *
525
+ * Supports signed indexing (`v[-1]`), sub-byte types via proxy references,
526
+ * and slicing via `operator[](range)`.
527
+ *
528
+ * @tparam value_type_ Element type.
529
+ * @tparam allocator_type_ Allocator (default: aligned_allocator).
530
+ */
531
+ template <typename value_type_, typename allocator_type_ = aligned_allocator<value_type_>>
532
+ struct vector {
533
+ using value_type = value_type_;
534
+ using raw_value_type = typename raw_pod_type<value_type>::type;
535
+
536
+ using allocator_type = allocator_type_;
537
+ using alloc_traits = std::allocator_traits<allocator_type_>;
538
+ using size_type = std::size_t;
539
+ using difference_type = std::ptrdiff_t;
540
+ using pointer = value_type_ *;
541
+ using const_pointer = value_type_ const *;
542
+
543
+ using iterator = dim_iterator<vector>;
544
+ using const_iterator = dim_iterator<vector const>;
545
+
546
+ private:
547
+ pointer data_ = nullptr;
548
+ size_type dimensions_ = 0;
549
+ [[no_unique_address]] allocator_type_ alloc_;
550
+
551
+ /** @brief Convert dimension count to value count. */
552
+ static constexpr size_type dims_to_values(size_type dims) noexcept {
553
+ return divide_round_up(dims, dimensions_per_value<value_type>());
554
+ }
555
+
556
+ public:
557
+ /** @brief Default constructor — empty vector with default allocator. */
558
+ vector() noexcept = default;
559
+
560
+ /** @brief Construct with custom allocator. */
561
+ explicit vector(allocator_type_ const &alloc) noexcept : alloc_(alloc) {}
562
+
563
+ /** @brief Destructor — deallocates memory. */
564
+ ~vector() noexcept {
565
+ if (data_) alloc_traits::deallocate(alloc_, data_, dims_to_values(dimensions_));
566
+ }
567
+
568
+ /** @brief Move constructor. */
569
+ vector(vector &&other) noexcept
570
+ : data_(std::exchange(other.data_, nullptr)), dimensions_(std::exchange(other.dimensions_, 0)),
571
+ alloc_(std::move(other.alloc_)) {}
572
+
573
+ /** @brief Move assignment with allocator propagation. */
574
+ vector &operator=(vector &&other) noexcept {
575
+ if (this != &other) {
576
+ if (data_) alloc_traits::deallocate(alloc_, data_, dims_to_values(dimensions_));
577
+ if constexpr (alloc_traits::propagate_on_container_move_assignment::value) alloc_ = std::move(other.alloc_);
578
+ data_ = std::exchange(other.data_, nullptr);
579
+ dimensions_ = std::exchange(other.dimensions_, 0);
580
+ }
581
+ return *this;
582
+ }
583
+
584
+ vector(vector const &) = delete;
585
+ vector &operator=(vector const &) = delete;
586
+
587
+ /**
588
+ * @brief Factory: allocate a zero-initialized vector with `dims` dimensions.
589
+ * @return Non-empty vector on success, empty vector on allocation failure.
590
+ */
591
+ [[nodiscard]] static vector try_zeros(size_type dims, allocator_type_ alloc = {}) noexcept {
592
+ vector v(alloc);
593
+ size_type values = dims_to_values(dims);
594
+ if (values == 0) return v;
595
+ pointer ptr = alloc_traits::allocate(v.alloc_, values);
596
+ if (!ptr) return v;
597
+ if constexpr (is_memset_zero_safe_v<value_type_>) std::memset(ptr, 0, values * sizeof(value_type_));
598
+ else
599
+ for (size_type i = 0; i < values; ++i) ptr[i] = value_type_ {};
600
+ v.data_ = ptr;
601
+ v.dimensions_ = dims;
602
+ return v;
603
+ }
604
+
605
+ /**
606
+ * @brief Factory: allocate a vector filled with ones.
607
+ * @return Non-empty vector on success, empty vector on allocation failure.
608
+ */
609
+ [[nodiscard]] static vector try_ones(size_type dims, allocator_type_ alloc = {}) noexcept {
610
+ return try_full(dims, value_type_ {1}, alloc);
611
+ }
612
+
613
+ /**
614
+ * @brief Factory: allocate a vector filled with `val`.
615
+ * @return Non-empty vector on success, empty vector on allocation failure.
616
+ */
617
+ [[nodiscard]] static vector try_full(size_type dims, value_type_ val, allocator_type_ alloc = {}) noexcept {
618
+ vector v(alloc);
619
+ size_type values = dims_to_values(dims);
620
+ if (values == 0) return v;
621
+ pointer ptr = alloc_traits::allocate(v.alloc_, values);
622
+ if (!ptr) return v;
623
+ for (size_type i = 0; i < values; ++i) ptr[i] = val;
624
+ v.data_ = ptr;
625
+ v.dimensions_ = dims;
626
+ return v;
627
+ }
628
+
629
+ /**
630
+ * @brief Factory: allocate an uninitialized vector.
631
+ * @return Non-empty vector on success, empty vector on allocation failure.
632
+ * @warning Contents are uninitialized. Caller must fill before reading.
633
+ */
634
+ [[nodiscard]] static vector try_empty(size_type dims, allocator_type_ alloc = {}) noexcept {
635
+ vector v(alloc);
636
+ size_type values = dims_to_values(dims);
637
+ if (values == 0) return v;
638
+ pointer ptr = alloc_traits::allocate(v.alloc_, values);
639
+ if (!ptr) return v;
640
+ v.data_ = ptr;
641
+ v.dimensions_ = dims;
642
+ return v;
643
+ }
644
+
645
+ /**
646
+ * @brief Factory: adopt raw memory. Caller transfers ownership.
647
+ * @param ptr Pointer to data (must have been allocated by `alloc`).
648
+ * @param dims Number of logical dimensions.
649
+ * @param alloc Allocator instance.
650
+ */
651
+ [[nodiscard]] static vector from_raw(pointer ptr, size_type dims, allocator_type_ alloc = {}) noexcept {
652
+ vector v(alloc);
653
+ v.data_ = ptr;
654
+ v.dimensions_ = dims;
655
+ return v;
656
+ }
657
+
658
+ /** @brief Swap with another vector. */
659
+ void swap(vector &other) noexcept {
660
+ using std::swap;
661
+ swap(data_, other.data_);
662
+ swap(dimensions_, other.dimensions_);
663
+ if constexpr (alloc_traits::propagate_on_container_swap::value) swap(alloc_, other.alloc_);
664
+ }
665
+
666
+ /** @brief Number of logical dimensions. */
667
+ size_type size() const noexcept { return dimensions_; }
668
+
669
+ /** @brief Check if empty. */
670
+ bool empty() const noexcept { return dimensions_ == 0; }
671
+
672
+ /** @brief Number of storage values. */
673
+ size_type size_values() const noexcept { return dims_to_values(dimensions_); }
674
+
675
+ /** @brief Size in bytes. */
676
+ size_type size_bytes() const noexcept { return dims_to_values(dimensions_) * sizeof(value_type_); }
677
+
678
+ /** @brief Pointer to underlying data. */
679
+ value_type *values_data() noexcept { return data_; }
680
+ value_type const *values_data() const noexcept { return data_; }
681
+
682
+ raw_value_type *raw_values_data() noexcept { return reinterpret_cast<raw_value_type *>(data_); }
683
+ raw_value_type const *raw_values_data() const noexcept { return reinterpret_cast<raw_value_type const *>(data_); }
684
+
685
+ /** @brief Get a copy of the allocator. */
686
+ allocator_type get_allocator() const noexcept { return alloc_; }
687
+
688
+ /**
689
+ * @brief Signed dimension access. Negative indices wrap from end.
690
+ * @retval For sub-byte types, returns proxy reference.
691
+ * @retval For normal types, returns direct reference.
692
+ */
693
+ template <std::integral index_type_>
694
+ decltype(auto) operator[](index_type_ idx) noexcept {
695
+ auto i = resolve_index_(idx, dimensions_);
696
+ if constexpr (dimensions_per_value<value_type>() > 1)
697
+ return sub_byte_ref<value_type>(reinterpret_cast<raw_value_type *>(data_), i);
698
+ else return data_[i];
699
+ }
700
+
701
+ template <std::integral index_type_>
702
+ decltype(auto) operator[](index_type_ idx) const noexcept {
703
+ auto i = resolve_index_(idx, dimensions_);
704
+ if constexpr (dimensions_per_value<value_type>() > 1)
705
+ return sub_byte_ref<value_type>(
706
+ const_cast<raw_value_type *>(reinterpret_cast<raw_value_type const *>(data_)), i)
707
+ .get();
708
+ else return data_[i];
709
+ }
710
+
711
+ /** @brief Slice via range, returns a vector_span. */
712
+ vector_span<value_type> operator[](range r) noexcept {
713
+ size_type start, stop;
714
+ resolve_range_(r, dimensions_, start, stop);
715
+ auto count = range_extent_(start, stop, r.step);
716
+ auto stride = static_cast<difference_type>(sizeof(value_type)) * r.step;
717
+ return {reinterpret_cast<char *>(data_) +
718
+ static_cast<difference_type>(start) * static_cast<difference_type>(sizeof(value_type)),
719
+ count, stride};
720
+ }
721
+
722
+ /** @brief Slice via range (const), returns a vector_view. */
723
+ vector_view<value_type> operator[](range r) const noexcept {
724
+ size_type start, stop;
725
+ resolve_range_(r, dimensions_, start, stop);
726
+ auto count = range_extent_(start, stop, r.step);
727
+ auto stride = static_cast<difference_type>(sizeof(value_type)) * r.step;
728
+ return {reinterpret_cast<char const *>(data_) +
729
+ static_cast<difference_type>(start) * static_cast<difference_type>(sizeof(value_type)),
730
+ count, stride};
731
+ }
732
+
733
+ /** @brief Select all elements as a span. */
734
+ vector_span<value_type> operator[](all_t) noexcept { return span(); }
735
+
736
+ /** @brief Select all elements as a view. */
737
+ vector_view<value_type> operator[](all_t) const noexcept { return view(); }
738
+
739
+ /** @brief Create an immutable view. */
740
+ vector_view<value_type> view() const noexcept { return {data_, dimensions_}; }
741
+
742
+ /** @brief Create a mutable span. */
743
+ vector_span<value_type> span() noexcept { return {data_, dimensions_}; }
744
+
745
+ /** @brief Dimension iterator to beginning. */
746
+ iterator begin() noexcept { return {*this, 0}; }
747
+ const_iterator begin() const noexcept { return {*this, 0}; }
748
+ const_iterator cbegin() const noexcept { return {*this, 0}; }
749
+
750
+ /** @brief Dimension iterator to end. */
751
+ iterator end() noexcept { return {*this, dimensions_}; }
752
+ const_iterator end() const noexcept { return {*this, dimensions_}; }
753
+ const_iterator cend() const noexcept { return {*this, dimensions_}; }
754
+ };
755
+
756
+ /** @brief Non-member swap. */
757
+ template <typename value_type_, typename allocator_type_>
758
+ void swap(vector<value_type_, allocator_type_> &a, vector<value_type_, allocator_type_> &b) noexcept {
759
+ a.swap(b);
760
+ }
761
+
762
+ #pragma endregion Vector
763
+
764
+ } // namespace ashvardanian::numkong
765
+
766
+ #endif // NK_VECTOR_HPP