@zigc/lib 0.17.0-dev.131 → 0.17.0-dev.215

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 (786) hide show
  1. package/c/stdlib.zig +32 -22
  2. package/compiler/aro/aro/Compilation.zig +0 -3
  3. package/compiler/translate-c/ast.zig +5 -2
  4. package/compiler_rt/arm.zig +3 -3
  5. package/compiler_rt/trunctfhf2.zig +3 -0
  6. package/compiler_rt.zig +1 -22
  7. package/docs/wasm/markdown/Parser.zig +5 -9
  8. package/include/__clang_spirv_builtins.h +12 -12
  9. package/include/__float_float.h +176 -0
  10. package/include/__float_header_macro.h +12 -0
  11. package/include/__float_infinity_nan.h +20 -0
  12. package/include/amo.h +131 -0
  13. package/include/amxavx512intrin.h +215 -1
  14. package/include/amxintrin.h +0 -2
  15. package/include/arm_acle.h +37 -27
  16. package/include/arm_neon.h +218 -82
  17. package/include/arm_sme.h +8 -8
  18. package/include/arm_sve.h +4162 -3782
  19. package/include/avx10_2_512bf16intrin.h +19 -12
  20. package/include/avx10_2_512convertintrin.h +1 -1
  21. package/include/avx10_2_512niintrin.h +31 -31
  22. package/include/avx10_2_512satcvtdsintrin.h +1 -1
  23. package/include/avx10_2bf16intrin.h +54 -45
  24. package/include/avx10_2convertintrin.h +2 -2
  25. package/include/avx10_2copyintrin.h +1 -1
  26. package/include/avx10_2niintrin.h +14 -14
  27. package/include/avx10_2satcvtdsintrin.h +2 -2
  28. package/include/avx2intrin.h +275 -377
  29. package/include/avx512bf16intrin.h +25 -16
  30. package/include/avx512bitalgintrin.h +19 -30
  31. package/include/avx512bwintrin.h +386 -505
  32. package/include/avx512cdintrin.h +42 -55
  33. package/include/avx512dqintrin.h +132 -161
  34. package/include/avx512fintrin.h +1015 -1424
  35. package/include/avx512fp16intrin.h +112 -110
  36. package/include/avx512ifmaintrin.h +32 -34
  37. package/include/avx512ifmavlintrin.h +73 -46
  38. package/include/avx512vbmi2intrin.h +43 -32
  39. package/include/avx512vbmiintrin.h +19 -27
  40. package/include/avx512vbmivlintrin.h +35 -49
  41. package/include/avx512vlbf16intrin.h +32 -22
  42. package/include/avx512vlbitalgintrin.h +37 -53
  43. package/include/avx512vlbwintrin.h +470 -573
  44. package/include/avx512vlcdintrin.h +74 -102
  45. package/include/avx512vldqintrin.h +110 -127
  46. package/include/avx512vlfp16intrin.h +130 -111
  47. package/include/avx512vlintrin.h +945 -1299
  48. package/include/avx512vlvbmi2intrin.h +78 -63
  49. package/include/avx512vlvnniintrin.h +21 -18
  50. package/include/avx512vlvp2intersectintrin.h +2 -2
  51. package/include/avx512vnniintrin.h +10 -10
  52. package/include/avx512vp2intersectintrin.h +1 -2
  53. package/include/avx512vpopcntdqintrin.h +8 -10
  54. package/include/avx512vpopcntdqvlintrin.h +17 -15
  55. package/include/avxifmaintrin.h +16 -0
  56. package/include/avxintrin.h +165 -241
  57. package/include/avxvnniint16intrin.h +118 -99
  58. package/include/avxvnniint8intrin.h +56 -32
  59. package/include/avxvnniintrin.h +16 -8
  60. package/include/cpuid.h +101 -4
  61. package/include/emmintrin.h +168 -168
  62. package/include/f16cintrin.h +23 -9
  63. package/include/float.h +16 -155
  64. package/include/fma4intrin.h +98 -96
  65. package/include/fmaintrin.h +96 -66
  66. package/include/gfniintrin.h +21 -16
  67. package/include/hexagon_types.h +23 -20
  68. package/include/hvx_hexagon_protos.h +649 -860
  69. package/include/immintrin.h +0 -12
  70. package/include/intrin.h +4 -0
  71. package/include/lasxintrin.h +113 -0
  72. package/include/llvm_libc_wrappers/assert.h +3 -5
  73. package/include/llvm_libc_wrappers/ctype.h +3 -115
  74. package/include/llvm_libc_wrappers/inttypes.h +3 -5
  75. package/include/llvm_libc_wrappers/stdio.h +10 -38
  76. package/include/llvm_libc_wrappers/stdlib.h +3 -24
  77. package/include/llvm_libc_wrappers/string.h +2 -70
  78. package/include/llvm_libc_wrappers/time.h +4 -10
  79. package/include/mmintrin.h +188 -257
  80. package/include/module.modulemap +23 -4
  81. package/include/movrs_avx10_2_512intrin.h +2 -2
  82. package/include/movrs_avx10_2intrin.h +4 -4
  83. package/include/pmmintrin.h +12 -24
  84. package/include/ptrauth.h +16 -2
  85. package/include/riscv_mips.h +34 -0
  86. package/include/riscv_nds.h +89 -0
  87. package/include/sifive_vector.h +58 -2
  88. package/include/sm4evexintrin.h +2 -2
  89. package/include/smmintrin.h +77 -59
  90. package/include/spirvintrin.h +194 -0
  91. package/include/stddefer.h +19 -0
  92. package/include/tmmintrin.h +116 -147
  93. package/include/vaesintrin.h +1 -2
  94. package/include/xmmintrin.h +44 -70
  95. package/include/xopintrin.h +20 -10
  96. package/libc/include/aarch64-linux-any/asm/hwcap.h +1 -0
  97. package/libc/include/aarch64-linux-any/asm/unistd_64.h +1 -0
  98. package/libc/include/any-linux-any/asm-generic/errno.h +2 -0
  99. package/libc/include/any-linux-any/asm-generic/unistd.h +4 -1
  100. package/libc/include/any-linux-any/drm/amdgpu_drm.h +20 -6
  101. package/libc/include/any-linux-any/drm/amdxdna_accel.h +8 -0
  102. package/libc/include/any-linux-any/drm/drm_fourcc.h +6 -6
  103. package/libc/include/any-linux-any/drm/panfrost_drm.h +75 -1
  104. package/libc/include/any-linux-any/drm/panthor_drm.h +154 -3
  105. package/libc/include/any-linux-any/drm/rocket_accel.h +74 -24
  106. package/libc/include/any-linux-any/drm/xe_drm.h +89 -6
  107. package/libc/include/any-linux-any/linux/android/binder.h +1 -1
  108. package/libc/include/any-linux-any/linux/bpf.h +28 -0
  109. package/libc/include/any-linux-any/linux/btrfs.h +1 -0
  110. package/libc/include/any-linux-any/linux/btrfs_tree.h +32 -2
  111. package/libc/include/any-linux-any/linux/dma-buf.h +1 -0
  112. package/libc/include/any-linux-any/linux/dpll.h +1 -0
  113. package/libc/include/any-linux-any/linux/elf.h +2 -0
  114. package/libc/include/any-linux-any/linux/ethtool.h +21 -5
  115. package/libc/include/any-linux-any/linux/fs.h +1 -0
  116. package/libc/include/any-linux-any/linux/hyperv.h +1 -1
  117. package/libc/include/any-linux-any/linux/idxd.h +134 -134
  118. package/libc/include/any-linux-any/linux/if_alg.h +1 -1
  119. package/libc/include/any-linux-any/linux/if_link.h +1 -0
  120. package/libc/include/any-linux-any/linux/input-event-codes.h +4 -0
  121. package/libc/include/any-linux-any/linux/io_uring/bpf_filter.h +68 -0
  122. package/libc/include/any-linux-any/linux/io_uring/query.h +5 -1
  123. package/libc/include/any-linux-any/linux/io_uring.h +33 -2
  124. package/libc/include/any-linux-any/linux/iommufd.h +39 -0
  125. package/libc/include/any-linux-any/linux/kfd_ioctl.h +13 -3
  126. package/libc/include/any-linux-any/linux/kfd_sysfs.h +2 -1
  127. package/libc/include/any-linux-any/linux/kvm.h +30 -6
  128. package/libc/include/any-linux-any/linux/landlock.h +22 -8
  129. package/libc/include/any-linux-any/linux/magic.h +1 -0
  130. package/libc/include/any-linux-any/linux/mempolicy.h +3 -0
  131. package/libc/include/any-linux-any/linux/mount.h +11 -2
  132. package/libc/include/any-linux-any/linux/mptcp_pm.h +1 -1
  133. package/libc/include/any-linux-any/linux/mshv.h +2 -0
  134. package/libc/include/any-linux-any/linux/netfilter_bridge.h +5 -4
  135. package/libc/include/any-linux-any/linux/netfilter_ipv4.h +4 -5
  136. package/libc/include/any-linux-any/linux/netfilter_ipv6.h +3 -4
  137. package/libc/include/any-linux-any/linux/nfs.h +1 -1
  138. package/libc/include/any-linux-any/linux/nfsd_netlink.h +1 -0
  139. package/libc/include/any-linux-any/linux/nilfs2_api.h +2 -2
  140. package/libc/include/any-linux-any/linux/nilfs2_ondisk.h +97 -66
  141. package/libc/include/any-linux-any/linux/nl80211.h +104 -3
  142. package/libc/include/any-linux-any/linux/pci.h +7 -0
  143. package/libc/include/any-linux-any/linux/pci_regs.h +65 -6
  144. package/libc/include/any-linux-any/linux/pcitest.h +1 -0
  145. package/libc/include/any-linux-any/linux/perf_event.h +24 -3
  146. package/libc/include/any-linux-any/linux/pkt_sched.h +1 -0
  147. package/libc/include/any-linux-any/linux/prctl.h +30 -0
  148. package/libc/include/any-linux-any/linux/rseq.h +62 -5
  149. package/libc/include/any-linux-any/linux/shm.h +0 -1
  150. package/libc/include/any-linux-any/linux/stddef.h +4 -0
  151. package/libc/include/any-linux-any/linux/sysctl.h +1 -2
  152. package/libc/include/any-linux-any/linux/taskstats.h +12 -1
  153. package/libc/include/any-linux-any/linux/tcp.h +23 -3
  154. package/libc/include/any-linux-any/linux/typelimits.h +8 -0
  155. package/libc/include/any-linux-any/linux/ublk_cmd.h +120 -1
  156. package/libc/include/any-linux-any/linux/v4l2-controls.h +63 -0
  157. package/libc/include/any-linux-any/linux/vbox_vmmdev_types.h +2 -2
  158. package/libc/include/any-linux-any/linux/vduse.h +80 -5
  159. package/libc/include/any-linux-any/linux/version.h +3 -3
  160. package/libc/include/any-linux-any/linux/vfio.h +4 -0
  161. package/libc/include/any-linux-any/linux/videodev2.h +3 -0
  162. package/libc/include/any-linux-any/linux/virtio_ring.h +1 -2
  163. package/libc/include/any-linux-any/linux/vmclock-abi.h +20 -0
  164. package/libc/include/any-linux-any/rdma/bnxt_re-abi.h +16 -0
  165. package/libc/include/any-linux-any/rdma/ib_user_ioctl_cmds.h +16 -0
  166. package/libc/include/any-linux-any/rdma/mana-abi.h +3 -0
  167. package/libc/include/any-linux-any/scsi/scsi_bsg_ufs.h +8 -9
  168. package/libc/include/any-linux-any/sound/sof/tokens.h +6 -0
  169. package/libc/include/arc-linux-any/asm/swab.h +0 -63
  170. package/libc/include/arc-linux-any/asm/unistd_32.h +1 -0
  171. package/libc/include/arm-linux-any/asm/ptrace.h +0 -9
  172. package/libc/include/arm-linux-any/asm/unistd-eabi.h +1 -0
  173. package/libc/include/arm-linux-any/asm/unistd-oabi.h +1 -0
  174. package/libc/include/csky-linux-any/asm/unistd_32.h +1 -0
  175. package/libc/include/hexagon-linux-any/asm/unistd_32.h +1 -0
  176. package/libc/include/loongarch-linux-any/asm/hwcap.h +1 -0
  177. package/libc/include/loongarch-linux-any/asm/kvm.h +1 -0
  178. package/libc/include/loongarch-linux-any/asm/kvm_para.h +1 -0
  179. package/libc/include/loongarch-linux-any/asm/unistd_32.h +2 -0
  180. package/libc/include/loongarch-linux-any/asm/unistd_64.h +2 -0
  181. package/libc/include/m68k-linux-any/asm/unistd_32.h +1 -0
  182. package/libc/include/mips-linux-any/asm/errno.h +2 -0
  183. package/libc/include/mips-linux-any/asm/unistd_n32.h +1 -0
  184. package/libc/include/mips-linux-any/asm/unistd_n64.h +1 -0
  185. package/libc/include/mips-linux-any/asm/unistd_o32.h +1 -0
  186. package/libc/include/powerpc-linux-any/asm/unistd_32.h +1 -0
  187. package/libc/include/powerpc-linux-any/asm/unistd_64.h +1 -0
  188. package/libc/include/riscv-linux-any/asm/hwprobe.h +4 -0
  189. package/libc/include/riscv-linux-any/asm/kvm.h +3 -0
  190. package/libc/include/riscv-linux-any/asm/ptrace.h +37 -0
  191. package/libc/include/riscv-linux-any/asm/sigcontext.h +1 -0
  192. package/libc/include/riscv-linux-any/asm/unistd_32.h +1 -0
  193. package/libc/include/riscv-linux-any/asm/unistd_64.h +1 -0
  194. package/libc/include/s390x-linux-any/asm/unistd_64.h +1 -0
  195. package/libc/include/sparc-linux-any/asm/errno.h +2 -0
  196. package/libc/include/sparc-linux-any/asm/ioctls.h +4 -4
  197. package/libc/include/sparc-linux-any/asm/unistd_32.h +2 -0
  198. package/libc/include/sparc-linux-any/asm/unistd_64.h +2 -0
  199. package/libc/include/x86-linux-any/asm/auxvec.h +0 -4
  200. package/libc/include/x86-linux-any/asm/kvm.h +13 -8
  201. package/libc/include/x86-linux-any/asm/svm.h +16 -16
  202. package/libc/include/x86-linux-any/asm/unistd_32.h +1 -0
  203. package/libc/include/x86-linux-any/asm/unistd_64.h +1 -0
  204. package/libc/include/x86-linux-any/asm/unistd_x32.h +1 -0
  205. package/libc/include/xtensa-linux-any/asm/unistd_32.h +1 -0
  206. package/libcxx/include/__algorithm/all_of.h +11 -5
  207. package/libcxx/include/__algorithm/comp.h +4 -0
  208. package/libcxx/include/__algorithm/copy.h +28 -147
  209. package/libcxx/include/__algorithm/copy_backward.h +9 -24
  210. package/libcxx/include/__algorithm/copy_n.h +50 -16
  211. package/libcxx/include/__algorithm/count.h +2 -2
  212. package/libcxx/include/__algorithm/equal.h +43 -55
  213. package/libcxx/include/__algorithm/fill.h +26 -8
  214. package/libcxx/include/__algorithm/fill_n.h +32 -46
  215. package/libcxx/include/__algorithm/find.h +96 -39
  216. package/libcxx/include/__algorithm/find_end.h +105 -0
  217. package/libcxx/include/__algorithm/for_each.h +18 -24
  218. package/libcxx/include/__algorithm/for_each_n.h +20 -47
  219. package/libcxx/include/__algorithm/for_each_n_segment.h +1 -1
  220. package/libcxx/include/__algorithm/for_each_segment.h +26 -0
  221. package/libcxx/include/__algorithm/generate.h +4 -2
  222. package/libcxx/include/__algorithm/generate_n.h +19 -6
  223. package/libcxx/include/__algorithm/is_permutation.h +4 -4
  224. package/libcxx/include/__algorithm/iterator_operations.h +3 -0
  225. package/libcxx/include/__algorithm/lexicographical_compare.h +2 -2
  226. package/libcxx/include/__algorithm/lexicographical_compare_three_way.h +6 -6
  227. package/libcxx/include/__algorithm/make_heap.h +16 -4
  228. package/libcxx/include/__algorithm/mismatch.h +2 -2
  229. package/libcxx/include/__algorithm/move.h +8 -19
  230. package/libcxx/include/__algorithm/move_backward.h +9 -24
  231. package/libcxx/include/__algorithm/none_of.h +4 -4
  232. package/libcxx/include/__algorithm/partial_sort.h +1 -1
  233. package/libcxx/include/__algorithm/partial_sort_copy.h +1 -1
  234. package/libcxx/include/__algorithm/pstl.h +9 -9
  235. package/libcxx/include/__algorithm/radix_sort.h +27 -25
  236. package/libcxx/include/__algorithm/ranges_copy_n.h +3 -26
  237. package/libcxx/include/__algorithm/ranges_equal.h +17 -26
  238. package/libcxx/include/__algorithm/ranges_fill.h +7 -6
  239. package/libcxx/include/__algorithm/ranges_for_each.h +9 -1
  240. package/libcxx/include/__algorithm/ranges_generate_n.h +2 -6
  241. package/libcxx/include/__algorithm/ranges_search_n.h +2 -2
  242. package/libcxx/include/__algorithm/rotate.h +27 -44
  243. package/libcxx/include/__algorithm/search_n.h +49 -37
  244. package/libcxx/include/__algorithm/sift_down.h +19 -18
  245. package/libcxx/include/__algorithm/simd_utils.h +33 -4
  246. package/libcxx/include/__algorithm/specialized_algorithms.h +54 -0
  247. package/libcxx/include/__algorithm/stable_sort.h +1 -1
  248. package/libcxx/include/__assertion_handler +31 -4
  249. package/libcxx/include/__atomic/atomic.h +36 -60
  250. package/libcxx/include/__atomic/atomic_flag.h +19 -37
  251. package/libcxx/include/__atomic/atomic_ref.h +29 -12
  252. package/libcxx/include/__atomic/atomic_sync.h +127 -55
  253. package/libcxx/include/__atomic/atomic_sync_timed.h +144 -0
  254. package/libcxx/include/__atomic/atomic_waitable_traits.h +103 -0
  255. package/libcxx/include/__atomic/contention_t.h +27 -3
  256. package/libcxx/include/__atomic/floating_point_helper.h +55 -0
  257. package/libcxx/include/__bit/countl.h +1 -2
  258. package/libcxx/include/__bit/countr.h +1 -2
  259. package/libcxx/include/__bit/has_single_bit.h +1 -1
  260. package/libcxx/include/__bit/popcount.h +0 -1
  261. package/libcxx/include/__bit/rotate.h +15 -26
  262. package/libcxx/include/__bit_reference +207 -18
  263. package/libcxx/include/__charconv/from_chars_integral.h +1 -1
  264. package/libcxx/include/__charconv/from_chars_result.h +1 -1
  265. package/libcxx/include/__charconv/to_chars_integral.h +1 -0
  266. package/libcxx/include/__charconv/to_chars_result.h +1 -1
  267. package/libcxx/include/__charconv/traits.h +3 -24
  268. package/libcxx/include/__chrono/day.h +11 -0
  269. package/libcxx/include/__chrono/duration.h +58 -33
  270. package/libcxx/include/__chrono/file_clock.h +4 -2
  271. package/libcxx/include/__chrono/is_clock.h +72 -0
  272. package/libcxx/include/__chrono/leap_second.h +13 -0
  273. package/libcxx/include/__chrono/month.h +13 -0
  274. package/libcxx/include/__chrono/month_weekday.h +22 -0
  275. package/libcxx/include/__chrono/monthday.h +20 -0
  276. package/libcxx/include/__chrono/steady_clock.h +1 -1
  277. package/libcxx/include/__chrono/system_clock.h +3 -3
  278. package/libcxx/include/__chrono/time_point.h +37 -13
  279. package/libcxx/include/__chrono/weekday.h +25 -0
  280. package/libcxx/include/__chrono/year.h +11 -0
  281. package/libcxx/include/__chrono/year_month.h +13 -0
  282. package/libcxx/include/__chrono/year_month_day.h +23 -0
  283. package/libcxx/include/__chrono/year_month_weekday.h +26 -0
  284. package/libcxx/include/__chrono/zoned_time.h +16 -0
  285. package/libcxx/include/__compare/is_eq.h +6 -6
  286. package/libcxx/include/__compare/strong_order.h +12 -30
  287. package/libcxx/include/__compare/three_way_comparable.h +2 -2
  288. package/libcxx/include/__concepts/comparison_common_type.h +40 -0
  289. package/libcxx/include/__concepts/equality_comparable.h +2 -1
  290. package/libcxx/include/__condition_variable/condition_variable.h +1 -1
  291. package/libcxx/include/__config +63 -280
  292. package/libcxx/include/__configuration/abi.h +14 -24
  293. package/libcxx/include/__configuration/availability.h +65 -118
  294. package/libcxx/include/__configuration/compiler.h +6 -6
  295. package/libcxx/include/__configuration/experimental.h +38 -0
  296. package/libcxx/include/__configuration/hardening.h +215 -0
  297. package/libcxx/include/__configuration/language.h +3 -0
  298. package/libcxx/include/__configuration/platform.h +9 -16
  299. package/libcxx/include/__coroutine/coroutine_handle.h +9 -9
  300. package/libcxx/include/__coroutine/noop_coroutine_handle.h +11 -13
  301. package/libcxx/include/__debug_utils/strict_weak_ordering_check.h +1 -1
  302. package/libcxx/include/__exception/exception.h +6 -4
  303. package/libcxx/include/__exception/exception_ptr.h +27 -5
  304. package/libcxx/include/__exception/nested_exception.h +2 -2
  305. package/libcxx/include/__exception/operations.h +5 -5
  306. package/libcxx/include/__expected/bad_expected_access.h +8 -6
  307. package/libcxx/include/__expected/expected.h +62 -64
  308. package/libcxx/include/__expected/unexpected.h +4 -4
  309. package/libcxx/include/__filesystem/copy_options.h +4 -4
  310. package/libcxx/include/__filesystem/directory_entry.h +37 -33
  311. package/libcxx/include/__filesystem/directory_iterator.h +9 -11
  312. package/libcxx/include/__filesystem/directory_options.h +7 -4
  313. package/libcxx/include/__filesystem/file_status.h +3 -3
  314. package/libcxx/include/__filesystem/filesystem_error.h +9 -10
  315. package/libcxx/include/__filesystem/operations.h +97 -66
  316. package/libcxx/include/__filesystem/path.h +68 -64
  317. package/libcxx/include/__filesystem/path_iterator.h +1 -3
  318. package/libcxx/include/__filesystem/perm_options.h +4 -4
  319. package/libcxx/include/__filesystem/perms.h +4 -4
  320. package/libcxx/include/__filesystem/recursive_directory_iterator.h +9 -14
  321. package/libcxx/include/__filesystem/space_info.h +1 -1
  322. package/libcxx/include/__filesystem/u8path.h +12 -14
  323. package/libcxx/include/__flat_map/flat_map.h +88 -71
  324. package/libcxx/include/__flat_map/flat_multimap.h +251 -172
  325. package/libcxx/include/__flat_map/key_value_iterator.h +0 -1
  326. package/libcxx/include/__flat_map/utils.h +1 -0
  327. package/libcxx/include/__flat_set/flat_multiset.h +211 -143
  328. package/libcxx/include/__flat_set/flat_set.h +86 -68
  329. package/libcxx/include/__format/concepts.h +0 -14
  330. package/libcxx/include/__format/extended_grapheme_cluster_table.h +3 -2
  331. package/libcxx/include/__format/fmt_pair_like.h +42 -0
  332. package/libcxx/include/__format/format_arg.h +7 -10
  333. package/libcxx/include/__format/format_args.h +1 -1
  334. package/libcxx/include/__format/format_context.h +5 -5
  335. package/libcxx/include/__format/format_parse_context.h +2 -2
  336. package/libcxx/include/__format/formatter_output.h +30 -34
  337. package/libcxx/include/__format/indic_conjunct_break_table.h +3 -2
  338. package/libcxx/include/__format/range_default_formatter.h +2 -41
  339. package/libcxx/include/__format/range_format.h +71 -0
  340. package/libcxx/include/__format/range_formatter.h +1 -0
  341. package/libcxx/include/__format/width_estimation_table.h +4 -2
  342. package/libcxx/include/__functional/bind.h +10 -15
  343. package/libcxx/include/__functional/bind_back.h +1 -1
  344. package/libcxx/include/__functional/bind_front.h +1 -1
  345. package/libcxx/include/__functional/function.h +57 -75
  346. package/libcxx/include/__functional/hash.h +1 -10
  347. package/libcxx/include/__functional/identity.h +1 -1
  348. package/libcxx/include/__functional/is_transparent.h +8 -0
  349. package/libcxx/include/__functional/mem_fn.h +2 -1
  350. package/libcxx/include/__functional/operations.h +18 -0
  351. package/libcxx/include/__functional/ranges_operations.h +7 -0
  352. package/libcxx/include/__functional/reference_wrapper.h +7 -5
  353. package/libcxx/include/__functional/weak_result_type.h +14 -28
  354. package/libcxx/include/__fwd/ios.h +1 -1
  355. package/libcxx/include/__fwd/tuple.h +14 -0
  356. package/libcxx/include/__hash_table +371 -357
  357. package/libcxx/include/__ios/fpos.h +4 -4
  358. package/libcxx/include/__iterator/back_insert_iterator.h +1 -7
  359. package/libcxx/include/__iterator/bounded_iter.h +7 -8
  360. package/libcxx/include/__iterator/concepts.h +6 -9
  361. package/libcxx/include/__iterator/cpp17_iterator_concepts.h +13 -12
  362. package/libcxx/include/__iterator/distance.h +40 -18
  363. package/libcxx/include/__iterator/front_insert_iterator.h +1 -7
  364. package/libcxx/include/__iterator/insert_iterator.h +1 -7
  365. package/libcxx/include/__iterator/istream_iterator.h +6 -7
  366. package/libcxx/include/__iterator/istreambuf_iterator.h +6 -7
  367. package/libcxx/include/__iterator/iter_move.h +1 -1
  368. package/libcxx/include/__iterator/iterator.h +13 -0
  369. package/libcxx/include/__iterator/iterator_traits.h +13 -14
  370. package/libcxx/include/__iterator/ostream_iterator.h +1 -7
  371. package/libcxx/include/__iterator/ostreambuf_iterator.h +1 -7
  372. package/libcxx/include/__iterator/reverse_iterator.h +8 -13
  373. package/libcxx/include/__iterator/segmented_iterator.h +3 -8
  374. package/libcxx/include/__iterator/static_bounded_iter.h +3 -3
  375. package/libcxx/include/__iterator/wrap_iter.h +8 -6
  376. package/libcxx/include/__locale +3 -10
  377. package/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h +0 -10
  378. package/libcxx/include/__locale_dir/locale_base_api.h +5 -28
  379. package/libcxx/include/__locale_dir/messages.h +1 -1
  380. package/libcxx/include/__locale_dir/money.h +2 -2
  381. package/libcxx/include/__locale_dir/num.h +190 -243
  382. package/libcxx/include/__locale_dir/pad_and_output.h +5 -6
  383. package/libcxx/include/__locale_dir/support/bsd_like.h +0 -20
  384. package/libcxx/include/__locale_dir/support/fuchsia.h +0 -7
  385. package/libcxx/include/__locale_dir/support/linux.h +0 -37
  386. package/libcxx/include/__locale_dir/support/netbsd.h +0 -2
  387. package/libcxx/include/__locale_dir/support/newlib.h +243 -0
  388. package/libcxx/include/__locale_dir/support/no_locale/characters.h +0 -4
  389. package/libcxx/include/__locale_dir/support/no_locale/strtonum.h +0 -9
  390. package/libcxx/include/__locale_dir/support/windows.h +0 -29
  391. package/libcxx/include/__locale_dir/time.h +3 -7
  392. package/libcxx/include/__math/hypot.h +1 -1
  393. package/libcxx/include/__math/logarithms.h +1 -1
  394. package/libcxx/include/__math/traits.h +80 -11
  395. package/libcxx/include/__mdspan/extents.h +7 -4
  396. package/libcxx/include/__mdspan/layout_stride.h +4 -5
  397. package/libcxx/include/__mdspan/mdspan.h +29 -23
  398. package/libcxx/include/__memory/addressof.h +7 -5
  399. package/libcxx/include/__memory/align.h +18 -1
  400. package/libcxx/include/__memory/allocate_at_least.h +15 -10
  401. package/libcxx/include/__memory/allocator.h +14 -26
  402. package/libcxx/include/__memory/allocator_traits.h +6 -4
  403. package/libcxx/include/__memory/compressed_pair.h +15 -9
  404. package/libcxx/include/__memory/construct_at.h +12 -23
  405. package/libcxx/include/__memory/inout_ptr.h +1 -1
  406. package/libcxx/include/__memory/is_sufficiently_aligned.h +1 -1
  407. package/libcxx/include/__memory/out_ptr.h +1 -1
  408. package/libcxx/include/__memory/pointer_traits.h +1 -1
  409. package/libcxx/include/__memory/raw_storage_iterator.h +3 -9
  410. package/libcxx/include/__memory/shared_count.h +9 -30
  411. package/libcxx/include/__memory/shared_ptr.h +100 -145
  412. package/libcxx/include/__memory/temp_value.h +1 -2
  413. package/libcxx/include/__memory/uninitialized_algorithms.h +44 -115
  414. package/libcxx/include/__memory/unique_ptr.h +14 -16
  415. package/libcxx/include/__memory/uses_allocator_construction.h +1 -0
  416. package/libcxx/include/__memory_resource/memory_resource.h +4 -2
  417. package/libcxx/include/__memory_resource/monotonic_buffer_resource.h +1 -1
  418. package/libcxx/include/__memory_resource/polymorphic_allocator.h +13 -8
  419. package/libcxx/include/__memory_resource/pool_options.h +1 -1
  420. package/libcxx/include/__memory_resource/synchronized_pool_resource.h +4 -2
  421. package/libcxx/include/__memory_resource/unsynchronized_pool_resource.h +1 -1
  422. package/libcxx/include/__mutex/mutex.h +2 -2
  423. package/libcxx/include/__mutex/once_flag.h +14 -11
  424. package/libcxx/include/__mutex/tag_types.h +3 -3
  425. package/libcxx/include/__mutex/unique_lock.h +8 -7
  426. package/libcxx/include/__new/align_val_t.h +6 -0
  427. package/libcxx/include/__new/allocate.h +1 -2
  428. package/libcxx/include/__new/exceptions.h +8 -2
  429. package/libcxx/include/__new/global_new_delete.h +4 -11
  430. package/libcxx/include/__new/interference_size.h +0 -4
  431. package/libcxx/include/__new/launder.h +3 -5
  432. package/libcxx/include/__new/nothrow_t.h +1 -1
  433. package/libcxx/include/__numeric/gcd_lcm.h +24 -34
  434. package/libcxx/include/__numeric/midpoint.h +9 -14
  435. package/libcxx/include/__numeric/pstl.h +2 -2
  436. package/libcxx/include/__numeric/saturation_arithmetic.h +13 -5
  437. package/libcxx/include/__ostream/basic_ostream.h +8 -8
  438. package/libcxx/include/__pstl/backends/default.h +14 -14
  439. package/libcxx/include/__pstl/backends/libdispatch.h +2 -2
  440. package/libcxx/include/__pstl/cpu_algos/find_if.h +1 -1
  441. package/libcxx/include/__pstl/cpu_algos/transform.h +5 -6
  442. package/libcxx/include/__pstl/cpu_algos/transform_reduce.h +5 -4
  443. package/libcxx/include/__random/binomial_distribution.h +10 -4
  444. package/libcxx/include/__random/mersenne_twister_engine.h +50 -154
  445. package/libcxx/include/__random/piecewise_constant_distribution.h +3 -2
  446. package/libcxx/include/__random/piecewise_linear_distribution.h +3 -2
  447. package/libcxx/include/__ranges/adjacent_transform_view.h +406 -0
  448. package/libcxx/include/__ranges/adjacent_view.h +419 -0
  449. package/libcxx/include/__ranges/as_rvalue_view.h +9 -9
  450. package/libcxx/include/__ranges/chunk_by_view.h +6 -6
  451. package/libcxx/include/__ranges/common_view.h +7 -7
  452. package/libcxx/include/__ranges/drop_view.h +8 -8
  453. package/libcxx/include/__ranges/drop_while_view.h +5 -5
  454. package/libcxx/include/__ranges/elements_of.h +49 -0
  455. package/libcxx/include/__ranges/empty_view.h +5 -5
  456. package/libcxx/include/__ranges/filter_view.h +10 -10
  457. package/libcxx/include/__ranges/iota_view.h +41 -22
  458. package/libcxx/include/__ranges/owning_view.h +15 -15
  459. package/libcxx/include/__ranges/ref_view.h +6 -6
  460. package/libcxx/include/__ranges/repeat_view.h +17 -10
  461. package/libcxx/include/__ranges/single_view.h +8 -8
  462. package/libcxx/include/__ranges/take_view.h +9 -9
  463. package/libcxx/include/__ranges/transform_view.h +1 -2
  464. package/libcxx/include/__ranges/view_interface.h +10 -10
  465. package/libcxx/include/__ranges/zip_transform_view.h +357 -0
  466. package/libcxx/include/__ranges/zip_view.h +20 -20
  467. package/libcxx/include/__split_buffer +612 -240
  468. package/libcxx/include/__stop_token/atomic_unique_lock.h +1 -1
  469. package/libcxx/include/__stop_token/stop_callback.h +2 -2
  470. package/libcxx/include/__stop_token/stop_source.h +1 -1
  471. package/libcxx/include/__stop_token/stop_state.h +4 -4
  472. package/libcxx/include/__stop_token/stop_token.h +1 -1
  473. package/libcxx/include/__string/char_traits.h +51 -31
  474. package/libcxx/include/__string/constexpr_c_functions.h +5 -5
  475. package/libcxx/include/__support/xlocale/__strtonum_fallback.h +0 -8
  476. package/libcxx/include/__system_error/error_category.h +8 -8
  477. package/libcxx/include/__system_error/error_code.h +5 -5
  478. package/libcxx/include/__system_error/error_condition.h +4 -4
  479. package/libcxx/include/__system_error/system_error.h +1 -1
  480. package/libcxx/include/__thread/id.h +1 -1
  481. package/libcxx/include/__thread/jthread.h +1 -1
  482. package/libcxx/include/__thread/poll_with_backoff.h +27 -8
  483. package/libcxx/include/__thread/support/c11.h +8 -8
  484. package/libcxx/include/__thread/support/pthread.h +8 -8
  485. package/libcxx/include/__thread/support/windows.h +8 -8
  486. package/libcxx/include/__thread/thread.h +13 -8
  487. package/libcxx/include/__thread/timed_backoff_policy.h +3 -2
  488. package/libcxx/include/__tree +849 -701
  489. package/libcxx/include/__tuple/sfinae_helpers.h +1 -44
  490. package/libcxx/include/__tuple/tuple_element.h +0 -12
  491. package/libcxx/include/__tuple/tuple_size.h +0 -4
  492. package/libcxx/include/__tuple/tuple_transform.h +45 -0
  493. package/libcxx/include/__type_traits/aligned_storage.h +13 -40
  494. package/libcxx/include/__type_traits/desugars_to.h +4 -0
  495. package/libcxx/include/__type_traits/invoke.h +8 -0
  496. package/libcxx/include/__type_traits/is_allocator.h +6 -7
  497. package/libcxx/include/__type_traits/is_array.h +26 -0
  498. package/libcxx/include/__type_traits/is_equality_comparable.h +16 -21
  499. package/libcxx/include/__type_traits/is_final.h +1 -1
  500. package/libcxx/include/__type_traits/is_floating_point.h +7 -6
  501. package/libcxx/include/__type_traits/is_generic_transparent_comparator.h +30 -0
  502. package/libcxx/include/__type_traits/is_specialization.h +2 -6
  503. package/libcxx/include/__type_traits/is_within_lifetime.h +29 -0
  504. package/libcxx/include/__type_traits/make_transparent.h +52 -0
  505. package/libcxx/include/__type_traits/reference_constructs_from_temporary.h +1 -7
  506. package/libcxx/include/__type_traits/reference_converts_from_temporary.h +1 -1
  507. package/libcxx/include/__utility/cmp.h +19 -7
  508. package/libcxx/include/__utility/default_three_way_comparator.h +70 -0
  509. package/libcxx/include/__utility/in_place.h +1 -1
  510. package/libcxx/include/__utility/integer_sequence.h +56 -41
  511. package/libcxx/include/__utility/lazy_synth_three_way_comparator.h +120 -0
  512. package/libcxx/include/__utility/pair.h +22 -25
  513. package/libcxx/include/__utility/scope_guard.h +2 -0
  514. package/libcxx/include/__utility/try_key_extraction.h +114 -0
  515. package/libcxx/include/__vector/vector.h +187 -160
  516. package/libcxx/include/__vector/vector_bool.h +76 -83
  517. package/libcxx/include/any +118 -155
  518. package/libcxx/include/array +88 -56
  519. package/libcxx/include/atomic +2 -0
  520. package/libcxx/include/barrier +20 -24
  521. package/libcxx/include/bitset +49 -30
  522. package/libcxx/include/ccomplex +3 -11
  523. package/libcxx/include/chrono +47 -0
  524. package/libcxx/include/ciso646 +3 -6
  525. package/libcxx/include/complex +77 -65
  526. package/libcxx/include/complex.h +10 -10
  527. package/libcxx/include/condition_variable +3 -3
  528. package/libcxx/include/cstdalign +3 -10
  529. package/libcxx/include/cstdbool +3 -10
  530. package/libcxx/include/ctgmath +2 -11
  531. package/libcxx/include/ctype.h +24 -24
  532. package/libcxx/include/cwchar +2 -2
  533. package/libcxx/include/deque +109 -225
  534. package/libcxx/include/errno.h +269 -269
  535. package/libcxx/include/exception +4 -1
  536. package/libcxx/include/ext/hash_map +7 -48
  537. package/libcxx/include/ext/hash_set +2 -8
  538. package/libcxx/include/fenv.h +43 -43
  539. package/libcxx/include/flat_map +663 -11
  540. package/libcxx/include/flat_set +543 -8
  541. package/libcxx/include/float.h +16 -16
  542. package/libcxx/include/forward_list +33 -53
  543. package/libcxx/include/fstream +57 -42
  544. package/libcxx/include/future +41 -51
  545. package/libcxx/include/initializer_list +9 -3
  546. package/libcxx/include/inttypes.h +16 -16
  547. package/libcxx/include/ios +28 -28
  548. package/libcxx/include/istream +19 -13
  549. package/libcxx/include/iterator +10 -0
  550. package/libcxx/include/latch +7 -5
  551. package/libcxx/include/limits +4 -4
  552. package/libcxx/include/list +61 -79
  553. package/libcxx/include/map +386 -274
  554. package/libcxx/include/math.h +19 -0
  555. package/libcxx/include/mdspan +1 -5
  556. package/libcxx/include/mutex +29 -19
  557. package/libcxx/include/optional +644 -149
  558. package/libcxx/include/print +9 -5
  559. package/libcxx/include/queue +39 -37
  560. package/libcxx/include/ranges +48 -0
  561. package/libcxx/include/regex +33 -31
  562. package/libcxx/include/scoped_allocator +16 -11
  563. package/libcxx/include/semaphore +15 -18
  564. package/libcxx/include/set +220 -192
  565. package/libcxx/include/shared_mutex +3 -8
  566. package/libcxx/include/span +53 -37
  567. package/libcxx/include/sstream +34 -28
  568. package/libcxx/include/stack +13 -15
  569. package/libcxx/include/stddef.h +10 -10
  570. package/libcxx/include/stdexcept +2 -2
  571. package/libcxx/include/stdio.h +20 -21
  572. package/libcxx/include/streambuf +59 -19
  573. package/libcxx/include/string +574 -573
  574. package/libcxx/include/string_view +113 -89
  575. package/libcxx/include/strstream +10 -10
  576. package/libcxx/include/syncstream +4 -4
  577. package/libcxx/include/tgmath.h +12 -12
  578. package/libcxx/include/tuple +242 -212
  579. package/libcxx/include/type_traits +8 -2
  580. package/libcxx/include/typeindex +5 -3
  581. package/libcxx/include/typeinfo +92 -89
  582. package/libcxx/include/unordered_map +179 -304
  583. package/libcxx/include/unordered_set +168 -195
  584. package/libcxx/include/utility +12 -0
  585. package/libcxx/include/valarray +106 -161
  586. package/libcxx/include/variant +25 -33
  587. package/libcxx/include/version +41 -24
  588. package/libcxx/include/wctype.h +29 -29
  589. package/libcxx/src/any.cpp +4 -0
  590. package/libcxx/src/atomic.cpp +365 -80
  591. package/libcxx/src/barrier.cpp +4 -3
  592. package/libcxx/src/charconv.cpp +6 -3
  593. package/libcxx/src/condition_variable_destructor.cpp +1 -1
  594. package/libcxx/src/error_category.cpp +3 -1
  595. package/libcxx/src/exception.cpp +2 -10
  596. package/libcxx/src/experimental/time_zone.cpp +1 -1
  597. package/libcxx/src/experimental/tzdb.cpp +4 -1
  598. package/libcxx/src/filesystem/error.h +4 -22
  599. package/libcxx/src/filesystem/format_string.h +9 -18
  600. package/libcxx/src/filesystem/int128_builtins.cpp +2 -0
  601. package/libcxx/src/filesystem/operations.cpp +2 -9
  602. package/libcxx/src/filesystem/path.cpp +3 -1
  603. package/libcxx/src/include/aligned_alloc.h +65 -0
  604. package/libcxx/src/include/config_elast.h +1 -1
  605. package/libcxx/src/include/from_chars_floating_point.h +11 -7
  606. package/libcxx/src/include/overridable_function.h +8 -10
  607. package/libcxx/src/iostream.cpp +56 -37
  608. package/libcxx/src/locale.cpp +213 -196
  609. package/libcxx/src/memory.cpp +12 -14
  610. package/libcxx/src/mutex_destructor.cpp +1 -1
  611. package/libcxx/src/new.cpp +5 -5
  612. package/libcxx/src/optional.cpp +4 -0
  613. package/libcxx/src/print.cpp +9 -1
  614. package/libcxx/src/random.cpp +0 -26
  615. package/libcxx/src/string.cpp +10 -25
  616. package/libcxx/src/support/runtime/exception_fallback.ipp +2 -0
  617. package/libcxx/src/support/runtime/exception_glibcxx.ipp +3 -0
  618. package/libcxx/src/support/runtime/exception_libcxxabi.ipp +6 -2
  619. package/libcxx/src/support/runtime/exception_libcxxrt.ipp +2 -0
  620. package/libcxx/src/support/runtime/exception_msvc.ipp +2 -0
  621. package/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp +9 -10
  622. package/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp +2 -0
  623. package/libcxx/src/support/runtime/exception_pointer_msvc.ipp +1 -0
  624. package/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp +1 -0
  625. package/libcxx/src/support/win32/locale_win32.cpp +1 -1
  626. package/libcxx/src/system_error.cpp +2 -0
  627. package/libcxx/src/thread.cpp +1 -3
  628. package/libcxx/src/valarray.cpp +1 -2
  629. package/libcxx/src/vector.cpp +2 -2
  630. package/libcxxabi/include/__cxxabi_config.h +42 -23
  631. package/libcxxabi/src/cxa_exception.cpp +4 -2
  632. package/libcxxabi/src/cxa_exception.h +16 -14
  633. package/libcxxabi/src/cxa_personality.cpp +126 -9
  634. package/libcxxabi/src/cxa_thread_atexit.cpp +2 -1
  635. package/libcxxabi/src/demangle/DemangleConfig.h +4 -0
  636. package/libcxxabi/src/demangle/ItaniumDemangle.h +9 -6
  637. package/libcxxabi/src/demangle/Utility.h +21 -7
  638. package/libcxxabi/src/fallback_malloc.cpp +1 -1
  639. package/libcxxabi/src/private_typeinfo.cpp +6 -0
  640. package/libcxxabi/src/stdlib_new_delete.cpp +5 -5
  641. package/libtsan/LICENSE.TXT +311 -0
  642. package/libtsan/builtins/assembly.h +41 -8
  643. package/libtsan/interception/interception_win.cpp +4 -0
  644. package/libtsan/sanitizer_common/sanitizer_allocator_primary32.h +1 -0
  645. package/libtsan/sanitizer_common/sanitizer_allocator_primary64.h +18 -0
  646. package/libtsan/sanitizer_common/sanitizer_common.h +15 -2
  647. package/libtsan/sanitizer_common/sanitizer_common_interceptors.inc +30 -4
  648. package/libtsan/sanitizer_common/sanitizer_common_interceptors_ioctl.inc +4 -0
  649. package/libtsan/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S +2 -1
  650. package/libtsan/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S +2 -0
  651. package/libtsan/sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S +2 -0
  652. package/libtsan/sanitizer_common/sanitizer_common_syscalls.inc +18 -0
  653. package/libtsan/sanitizer_common/sanitizer_file.cpp +40 -12
  654. package/libtsan/sanitizer_common/sanitizer_file.h +3 -0
  655. package/libtsan/sanitizer_common/sanitizer_flags.inc +7 -0
  656. package/libtsan/sanitizer_common/sanitizer_fuchsia.cpp +30 -3
  657. package/libtsan/sanitizer_common/sanitizer_haiku.cpp +2 -2
  658. package/libtsan/sanitizer_common/sanitizer_internal_defs.h +1 -1
  659. package/libtsan/sanitizer_common/sanitizer_libc.cpp +8 -0
  660. package/libtsan/sanitizer_common/sanitizer_libc.h +1 -0
  661. package/libtsan/sanitizer_common/sanitizer_linux.cpp +15 -7
  662. package/libtsan/sanitizer_common/sanitizer_linux.h +3 -3
  663. package/libtsan/sanitizer_common/sanitizer_linux_libcdep.cpp +1 -0
  664. package/libtsan/sanitizer_common/sanitizer_mac.cpp +255 -104
  665. package/libtsan/sanitizer_common/sanitizer_mac.h +5 -0
  666. package/libtsan/sanitizer_common/sanitizer_netbsd.cpp +2 -2
  667. package/libtsan/sanitizer_common/sanitizer_platform.h +27 -1
  668. package/libtsan/sanitizer_common/sanitizer_platform_interceptors.h +5 -4
  669. package/libtsan/sanitizer_common/sanitizer_platform_limits_posix.cpp +15 -17
  670. package/libtsan/sanitizer_common/sanitizer_platform_limits_posix.h +32 -6
  671. package/libtsan/sanitizer_common/sanitizer_posix.cpp +3 -12
  672. package/libtsan/sanitizer_common/sanitizer_posix.h +2 -1
  673. package/libtsan/sanitizer_common/sanitizer_posix_libcdep.cpp +19 -0
  674. package/libtsan/sanitizer_common/sanitizer_procmaps_mac.cpp +102 -37
  675. package/libtsan/sanitizer_common/sanitizer_redefine_builtins.h +1 -1
  676. package/libtsan/sanitizer_common/sanitizer_signal_interceptors.inc +40 -2
  677. package/libtsan/sanitizer_common/sanitizer_stoptheworld.h +1 -1
  678. package/libtsan/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +83 -12
  679. package/libtsan/sanitizer_common/sanitizer_stoptheworld_mac.cpp +3 -3
  680. package/libtsan/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp +7 -7
  681. package/libtsan/sanitizer_common/sanitizer_stoptheworld_win.cpp +2 -2
  682. package/libtsan/sanitizer_common/sanitizer_symbolizer_internal.h +5 -1
  683. package/libtsan/sanitizer_common/sanitizer_symbolizer_libcdep.cpp +11 -1
  684. package/libtsan/sanitizer_common/sanitizer_symbolizer_mac.cpp +86 -29
  685. package/libtsan/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp +27 -16
  686. package/libtsan/sanitizer_common/sanitizer_thread_registry.cpp +5 -4
  687. package/libtsan/sanitizer_common/sanitizer_thread_registry.h +4 -4
  688. package/libtsan/sanitizer_common/sanitizer_win.cpp +1 -3
  689. package/libtsan/tsan_debugging.cpp +2 -2
  690. package/libtsan/tsan_flags.cpp +37 -0
  691. package/libtsan/tsan_flags.h +8 -0
  692. package/libtsan/tsan_flags.inc +12 -0
  693. package/libtsan/tsan_interceptors.h +9 -1
  694. package/libtsan/tsan_interceptors_mac.cpp +19 -0
  695. package/libtsan/tsan_interceptors_posix.cpp +78 -32
  696. package/libtsan/tsan_interface.h +3 -3
  697. package/libtsan/tsan_interface_ann.cpp +23 -9
  698. package/libtsan/tsan_mman.cpp +18 -4
  699. package/libtsan/tsan_platform.h +44 -7
  700. package/libtsan/tsan_platform_linux.cpp +42 -14
  701. package/libtsan/tsan_platform_mac.cpp +16 -3
  702. package/libtsan/tsan_report.h +14 -1
  703. package/libtsan/tsan_rtl.cpp +14 -0
  704. package/libtsan/tsan_rtl.h +7 -2
  705. package/libtsan/tsan_rtl_aarch64.S +3 -5
  706. package/libtsan/tsan_rtl_access.cpp +8 -3
  707. package/libtsan/tsan_rtl_amd64.S +2 -0
  708. package/libtsan/tsan_rtl_mutex.cpp +94 -49
  709. package/libtsan/tsan_rtl_report.cpp +132 -65
  710. package/libtsan/tsan_rtl_thread.cpp +31 -9
  711. package/libtsan/tsan_symbolize.cpp +1 -1
  712. package/libtsan/tsan_symbolize.h +1 -1
  713. package/libtsan/tsan_trace.h +1 -1
  714. package/libunwind/include/__libunwind_config.h +11 -2
  715. package/libunwind/include/libunwind.h +117 -11
  716. package/libunwind/include/unwind_arm_ehabi.h +4 -1
  717. package/libunwind/src/AddressSpace.hpp +40 -19
  718. package/libunwind/src/CompactUnwinder.hpp +16 -5
  719. package/libunwind/src/DwarfInstructions.hpp +24 -13
  720. package/libunwind/src/DwarfParser.hpp +60 -22
  721. package/libunwind/src/EHHeaderParser.hpp +7 -4
  722. package/libunwind/src/Registers.hpp +226 -22
  723. package/libunwind/src/Unwind-seh.cpp +6 -7
  724. package/libunwind/src/Unwind-wasm.c +7 -7
  725. package/libunwind/src/UnwindCursor.hpp +167 -49
  726. package/libunwind/src/UnwindLevel1.c +46 -17
  727. package/libunwind/src/UnwindRegistersRestore.S +46 -5
  728. package/libunwind/src/UnwindRegistersSave.S +86 -2
  729. package/libunwind/src/assembly.h +5 -1
  730. package/libunwind/src/config.h +9 -0
  731. package/libunwind/src/gcc_personality_v0.c +79 -6
  732. package/libunwind/src/libunwind.cpp +104 -4
  733. package/libunwind/src/libunwind_ext.h +7 -1
  734. package/libunwind/src/shadow_stack_unwind.h +2 -2
  735. package/lldb/pretty_printers.py +948 -0
  736. package/package.json +1 -1
  737. package/std/Build/Step/Compile.zig +18 -19
  738. package/std/Build/Step/Run.zig +13 -6
  739. package/std/Build/Step.zig +0 -3
  740. package/std/Io/Threaded.zig +3 -0
  741. package/std/Target/aarch64.zig +620 -77
  742. package/std/Target/amdgcn.zig +421 -21
  743. package/std/Target/arm.zig +40 -6
  744. package/std/Target/bpf.zig +6 -0
  745. package/std/Target/hexagon.zig +41 -6
  746. package/std/Target/loongarch.zig +18 -0
  747. package/std/Target/mips.zig +6 -0
  748. package/std/Target/nvptx.zig +58 -35
  749. package/std/Target/powerpc.zig +27 -19
  750. package/std/Target/riscv.zig +415 -177
  751. package/std/Target/sparc.zig +17 -0
  752. package/std/Target/wasm.zig +7 -0
  753. package/std/Target/x86.zig +200 -31
  754. package/std/Target/xtensa.zig +65 -0
  755. package/std/Target.zig +11 -2
  756. package/std/c.zig +7 -0
  757. package/std/debug/Dwarf.zig +14 -11
  758. package/std/debug/Pdb.zig +24 -16
  759. package/std/hash/xxhash.zig +0 -6
  760. package/std/math/log10.zig +0 -2
  761. package/std/math/modf.zig +0 -1
  762. package/std/mem.zig +1 -2
  763. package/std/os/linux/syscalls.zig +26 -1
  764. package/std/os/linux/x86.zig +2 -2
  765. package/std/os/windows.zig +130 -1
  766. package/std/simd.zig +4 -21
  767. package/std/start.zig +4 -3
  768. package/std/zig/Ast.zig +5 -7
  769. package/std/zig/AstGen.zig +20 -14
  770. package/std/zig/ErrorBundle.zig +6 -2
  771. package/std/zig/ZonGen.zig +13 -21
  772. package/std/zig/llvm/Builder.zig +2 -2
  773. package/std/zig/system/arm.zig +56 -2
  774. package/std/zig/system/windows.zig +34 -1
  775. package/std/zig/system/x86.zig +60 -16
  776. package/std/zig/system.zig +0 -10
  777. package/include/amxbf16transposeintrin.h +0 -94
  778. package/include/amxcomplextransposeintrin.h +0 -303
  779. package/include/amxfp16transposeintrin.h +0 -94
  780. package/include/amxmovrstransposeintrin.h +0 -200
  781. package/include/amxtf32transposeintrin.h +0 -105
  782. package/include/amxtransposeintrin.h +0 -248
  783. package/libc/include/hexagon-linux-any/asm/signal.h +0 -29
  784. package/libc/include/s390x-linux-any/asm/tape390.h +0 -103
  785. package/libtsan/sanitizer_common/sanitizer_coverage_interface.inc +0 -43
  786. package/std/Build/Step/CheckObject.zig +0 -2764
@@ -11,37 +11,39 @@
11
11
  #define _LIBCPP___TREE
12
12
 
13
13
  #include <__algorithm/min.h>
14
+ #include <__algorithm/specialized_algorithms.h>
14
15
  #include <__assert>
15
16
  #include <__config>
16
- #include <__fwd/map.h>
17
17
  #include <__fwd/pair.h>
18
- #include <__fwd/set.h>
19
18
  #include <__iterator/distance.h>
20
19
  #include <__iterator/iterator_traits.h>
21
20
  #include <__iterator/next.h>
22
21
  #include <__memory/addressof.h>
23
22
  #include <__memory/allocator_traits.h>
24
23
  #include <__memory/compressed_pair.h>
24
+ #include <__memory/construct_at.h>
25
25
  #include <__memory/pointer_traits.h>
26
26
  #include <__memory/swap_allocator.h>
27
27
  #include <__memory/unique_ptr.h>
28
- #include <__type_traits/can_extract_key.h>
28
+ #include <__new/launder.h>
29
29
  #include <__type_traits/copy_cvref.h>
30
30
  #include <__type_traits/enable_if.h>
31
31
  #include <__type_traits/invoke.h>
32
- #include <__type_traits/is_const.h>
33
32
  #include <__type_traits/is_constructible.h>
34
33
  #include <__type_traits/is_nothrow_assignable.h>
35
34
  #include <__type_traits/is_nothrow_constructible.h>
36
35
  #include <__type_traits/is_same.h>
36
+ #include <__type_traits/is_specialization.h>
37
37
  #include <__type_traits/is_swappable.h>
38
+ #include <__type_traits/make_transparent.h>
38
39
  #include <__type_traits/remove_const.h>
39
- #include <__type_traits/remove_const_ref.h>
40
40
  #include <__type_traits/remove_cvref.h>
41
41
  #include <__utility/forward.h>
42
+ #include <__utility/lazy_synth_three_way_comparator.h>
42
43
  #include <__utility/move.h>
43
44
  #include <__utility/pair.h>
44
45
  #include <__utility/swap.h>
46
+ #include <__utility/try_key_extraction.h>
45
47
  #include <limits>
46
48
 
47
49
  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -51,14 +53,31 @@
51
53
  _LIBCPP_PUSH_MACROS
52
54
  #include <__undef_macros>
53
55
 
54
- _LIBCPP_BEGIN_NAMESPACE_STD
56
+ _LIBCPP_DIAGNOSTIC_PUSH
57
+ // GCC complains about the backslashes at the end, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121528
58
+ _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wcomment")
59
+ // __tree is a red-black-tree implementation used for the associative containers (i.e. (multi)map/set). It stores
60
+ // - (1) a pointer to the node with the smallest (i.e. leftmost) element, namely __begin_node_
61
+ // - (2) the number of nodes in the tree, namely __size_
62
+ // - (3) a pointer to the root of the tree, namely __end_node_
63
+ //
64
+ // Storing (1) and (2) is required to allow for constant time lookups. A tree looks like this in memory:
65
+ //
66
+ // __end_node_
67
+ // |
68
+ // root
69
+ // / \
70
+ // l1 r1
71
+ // / \ / \
72
+ // ... ... ... ...
73
+ //
74
+ // All nodes except __end_node_ have a __left_ and __right_ pointer as well as a __parent_ pointer.
75
+ // __end_node_ only contains a __left_ pointer, which points to the root of the tree.
76
+ // This layout allows for iteration through the tree without a need for special handling of the end node. See
77
+ // __tree_next_iter and __tree_prev_iter for more details.
78
+ _LIBCPP_DIAGNOSTIC_POP
55
79
 
56
- template <class _Tp, class _Compare, class _Allocator>
57
- class __tree;
58
- template <class _Tp, class _NodePtr, class _DiffType>
59
- class __tree_iterator;
60
- template <class _Tp, class _ConstNodePtr, class _DiffType>
61
- class __tree_const_iterator;
80
+ _LIBCPP_BEGIN_NAMESPACE_STD
62
81
 
63
82
  template <class _Pointer>
64
83
  class __tree_end_node;
@@ -70,13 +89,6 @@ class __tree_node;
70
89
  template <class _Key, class _Value>
71
90
  struct __value_type;
72
91
 
73
- template <class _Allocator>
74
- class __map_node_destructor;
75
- template <class _TreeIterator>
76
- class __map_iterator;
77
- template <class _TreeIterator>
78
- class __map_const_iterator;
79
-
80
92
  /*
81
93
 
82
94
  _NodePtr algorithms
@@ -185,6 +197,11 @@ _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_next(_NodePtr __x) _NOEXCEPT {
185
197
  return __x->__parent_unsafe();
186
198
  }
187
199
 
200
+ // __tree_next_iter and __tree_prev_iter implement iteration through the tree. The order is as follows:
201
+ // left sub-tree -> node -> right sub-tree. When the right-most node of a sub-tree is reached, we walk up the tree until
202
+ // we find a node where we were in the left sub-tree. We are _always_ in a left sub-tree, since the __end_node_ points
203
+ // to the actual root of the tree through a __left_ pointer. Incrementing the end() pointer is UB, so we can assume that
204
+ // never happens.
188
205
  template <class _EndNodePtr, class _NodePtr>
189
206
  inline _LIBCPP_HIDE_FROM_ABI _EndNodePtr __tree_next_iter(_NodePtr __x) _NOEXCEPT {
190
207
  _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
@@ -494,16 +511,7 @@ _LIBCPP_HIDE_FROM_ABI void __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEP
494
511
  // node traits
495
512
 
496
513
  template <class _Tp>
497
- struct __is_tree_value_type_imp : false_type {};
498
-
499
- template <class _Key, class _Value>
500
- struct __is_tree_value_type_imp<__value_type<_Key, _Value> > : true_type {};
501
-
502
- template <class... _Args>
503
- struct __is_tree_value_type : false_type {};
504
-
505
- template <class _One>
506
- struct __is_tree_value_type<_One> : __is_tree_value_type_imp<__remove_cvref_t<_One> > {};
514
+ inline const bool __is_tree_value_type_v = __is_specialization_v<_Tp, __value_type>;
507
515
 
508
516
  template <class _Tp>
509
517
  struct __get_tree_key_type {
@@ -549,15 +557,14 @@ private:
549
557
  template <class _Pointer>
550
558
  class __tree_end_node {
551
559
  public:
552
- typedef _Pointer pointer;
560
+ using pointer = _Pointer;
553
561
  pointer __left_;
554
562
 
555
563
  _LIBCPP_HIDE_FROM_ABI __tree_end_node() _NOEXCEPT : __left_() {}
556
564
  };
557
565
 
558
566
  template <class _VoidPtr>
559
- class _LIBCPP_STANDALONE_DEBUG
560
- __tree_node_base : public __tree_end_node<__rebind_pointer_t<_VoidPtr, __tree_node_base<_VoidPtr> > > {
567
+ class __tree_node_base : public __tree_end_node<__rebind_pointer_t<_VoidPtr, __tree_node_base<_VoidPtr> > > {
561
568
  public:
562
569
  using pointer = __rebind_pointer_t<_VoidPtr, __tree_node_base>;
563
570
  using __end_node_pointer _LIBCPP_NODEBUG = __rebind_pointer_t<_VoidPtr, __tree_end_node<pointer> >;
@@ -570,20 +577,41 @@ public:
570
577
 
571
578
  _LIBCPP_HIDE_FROM_ABI void __set_parent(pointer __p) { __parent_ = static_cast<__end_node_pointer>(__p); }
572
579
 
573
- ~__tree_node_base() = delete;
580
+ _LIBCPP_HIDE_FROM_ABI __tree_node_base() = default;
574
581
  __tree_node_base(__tree_node_base const&) = delete;
575
582
  __tree_node_base& operator=(__tree_node_base const&) = delete;
576
583
  };
577
584
 
578
585
  template <class _Tp, class _VoidPtr>
579
- class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> {
586
+ class __tree_node : public __tree_node_base<_VoidPtr> {
580
587
  public:
581
588
  using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t<_Tp>;
582
589
 
583
- __node_value_type __value_;
590
+ // We use a union to avoid initialization during member initialization, which allows us
591
+ // to use the allocator from the container to construct the `__node_value_type` in the
592
+ // memory provided by the union member
593
+ #ifndef _LIBCPP_CXX03_LANG
594
+
595
+ private:
596
+ union {
597
+ __node_value_type __value_;
598
+ };
584
599
 
600
+ public:
585
601
  _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return __value_; }
602
+ #else
603
+
604
+ private:
605
+ _ALIGNAS_TYPE(__node_value_type) unsigned char __buffer_[sizeof(__node_value_type)];
606
+
607
+ public:
608
+ _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return *reinterpret_cast<__node_value_type*>(__buffer_); }
609
+ #endif
586
610
 
611
+ template <class _Alloc, class... _Args>
612
+ _LIBCPP_HIDE_FROM_ABI explicit __tree_node(_Alloc& __na, _Args&&... __args) {
613
+ allocator_traits<_Alloc>::construct(__na, std::addressof(__get_value()), std::forward<_Args>(__args)...);
614
+ }
587
615
  ~__tree_node() = delete;
588
616
  __tree_node(__tree_node const&) = delete;
589
617
  __tree_node& operator=(__tree_node const&) = delete;
@@ -591,11 +619,11 @@ public:
591
619
 
592
620
  template <class _Allocator>
593
621
  class __tree_node_destructor {
594
- typedef _Allocator allocator_type;
595
- typedef allocator_traits<allocator_type> __alloc_traits;
622
+ using allocator_type = _Allocator;
623
+ using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;
596
624
 
597
625
  public:
598
- typedef typename __alloc_traits::pointer pointer;
626
+ using pointer = typename __alloc_traits::pointer;
599
627
 
600
628
  private:
601
629
  allocator_type& __na_;
@@ -612,7 +640,7 @@ public:
612
640
 
613
641
  _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
614
642
  if (__value_constructed)
615
- __alloc_traits::destroy(__na_, std::addressof(__p->__value_));
643
+ __alloc_traits::destroy(__na_, std::addressof(__p->__get_value()));
616
644
  if (__p)
617
645
  __alloc_traits::deallocate(__na_, __p, 1);
618
646
  }
@@ -630,12 +658,60 @@ struct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc> :
630
658
  };
631
659
  #endif
632
660
 
661
+ // Do an in-order traversal of the tree until `__break` returns true. Takes the root node of the tree.
662
+ template <class _Reference, class _Break, class _NodePtr, class _Func, class _Proj>
663
+ #ifndef _LIBCPP_COMPILER_GCC // This function is recursive, so GCC complains about always_inline.
664
+ _LIBCPP_HIDE_FROM_ABI
665
+ #endif
666
+ bool __tree_iterate_from_root(_Break __break, _NodePtr __root, _Func& __func, _Proj& __proj) {
667
+ if (__root->__left_) {
668
+ if (std::__tree_iterate_from_root<_Reference>(__break, static_cast<_NodePtr>(__root->__left_), __func, __proj))
669
+ return true;
670
+ }
671
+ if (__break(__root))
672
+ return true;
673
+ std::__invoke(__func, std::__invoke(__proj, static_cast<_Reference>(__root->__get_value())));
674
+ if (__root->__right_)
675
+ return std::__tree_iterate_from_root<_Reference>(__break, static_cast<_NodePtr>(__root->__right_), __func, __proj);
676
+ return false;
677
+ }
678
+
679
+ // Do an in-order traversal of the tree from __first to __last.
680
+ template <class _NodeIter, class _Func, class _Proj>
681
+ _LIBCPP_HIDE_FROM_ABI void
682
+ __tree_iterate_subrange(_NodeIter __first_it, _NodeIter __last_it, _Func& __func, _Proj& __proj) {
683
+ using _NodePtr = typename _NodeIter::__node_pointer;
684
+ using _Reference = typename _NodeIter::reference;
685
+
686
+ auto __first = __first_it.__ptr_;
687
+ auto __last = __last_it.__ptr_;
688
+
689
+ while (true) {
690
+ if (__first == __last)
691
+ return;
692
+ const auto __nfirst = static_cast<_NodePtr>(__first);
693
+ std::__invoke(__func, std::__invoke(__proj, static_cast<_Reference>(__nfirst->__get_value())));
694
+ if (__nfirst->__right_) {
695
+ if (std::__tree_iterate_from_root<_Reference>(
696
+ [&](_NodePtr __node) -> bool { return __node == __last; },
697
+ static_cast<_NodePtr>(__nfirst->__right_),
698
+ __func,
699
+ __proj))
700
+ return;
701
+ }
702
+ while (!std::__tree_is_left_child(static_cast<_NodePtr>(__first)))
703
+ __first = static_cast<_NodePtr>(__first)->__parent_;
704
+ __first = static_cast<_NodePtr>(__first)->__parent_;
705
+ }
706
+ }
707
+
633
708
  template <class _Tp, class _NodePtr, class _DiffType>
634
709
  class __tree_iterator {
635
- typedef __tree_node_types<_NodePtr> _NodeTypes;
636
- typedef _NodePtr __node_pointer;
637
- typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
638
- typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
710
+ using _NodeTypes _LIBCPP_NODEBUG = __tree_node_types<_NodePtr>;
711
+ // NOLINTNEXTLINE(libcpp-nodebug-on-aliases) lldb relies on this alias for pretty printing
712
+ using __node_pointer = _NodePtr;
713
+ using __node_base_pointer _LIBCPP_NODEBUG = typename _NodeTypes::__node_base_pointer;
714
+ using __end_node_pointer _LIBCPP_NODEBUG = typename _NodeTypes::__end_node_pointer;
639
715
 
640
716
  __end_node_pointer __ptr_;
641
717
 
@@ -646,15 +722,12 @@ public:
646
722
  using reference = value_type&;
647
723
  using pointer = __rebind_pointer_t<_NodePtr, value_type>;
648
724
 
649
- _LIBCPP_HIDE_FROM_ABI __tree_iterator() _NOEXCEPT
650
- #if _LIBCPP_STD_VER >= 14
651
- : __ptr_(nullptr)
652
- #endif
653
- {
654
- }
725
+ _LIBCPP_HIDE_FROM_ABI __tree_iterator() _NOEXCEPT : __ptr_(nullptr) {}
655
726
 
656
- _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__value_; }
657
- _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__get_np()->__value_); }
727
+ _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__get_value(); }
728
+ _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
729
+ return pointer_traits<pointer>::pointer_to(__get_np()->__get_value());
730
+ }
658
731
 
659
732
  _LIBCPP_HIDE_FROM_ABI __tree_iterator& operator++() {
660
733
  __ptr_ = std::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_));
@@ -691,50 +764,54 @@ private:
691
764
  friend class __tree;
692
765
  template <class, class, class>
693
766
  friend class __tree_const_iterator;
694
- template <class>
695
- friend class __map_iterator;
696
- template <class, class, class, class>
697
- friend class map;
698
- template <class, class, class, class>
699
- friend class multimap;
700
- template <class, class, class>
701
- friend class set;
702
- template <class, class, class>
703
- friend class multiset;
767
+
768
+ template <class _NodeIter, class _Func, class _Proj>
769
+ friend void __tree_iterate_subrange(_NodeIter, _NodeIter, _Func&, _Proj&);
770
+ };
771
+
772
+ #ifndef _LIBCPP_CXX03_LANG
773
+ // This also handles {multi,}set::iterator, since they're just aliases to __tree::iterator
774
+ template <class _Tp, class _NodePtr, class _DiffType>
775
+ struct __specialized_algorithm<
776
+ _Algorithm::__for_each,
777
+ __iterator_pair<__tree_iterator<_Tp, _NodePtr, _DiffType>, __tree_iterator<_Tp, _NodePtr, _DiffType>>> {
778
+ static const bool __has_algorithm = true;
779
+
780
+ using __iterator _LIBCPP_NODEBUG = __tree_iterator<_Tp, _NodePtr, _DiffType>;
781
+
782
+ template <class _Func, class _Proj>
783
+ _LIBCPP_HIDE_FROM_ABI static void operator()(__iterator __first, __iterator __last, _Func& __func, _Proj& __proj) {
784
+ std::__tree_iterate_subrange(__first, __last, __func, __proj);
785
+ }
704
786
  };
787
+ #endif
705
788
 
706
789
  template <class _Tp, class _NodePtr, class _DiffType>
707
790
  class __tree_const_iterator {
708
- typedef __tree_node_types<_NodePtr> _NodeTypes;
791
+ using _NodeTypes _LIBCPP_NODEBUG = __tree_node_types<_NodePtr>;
709
792
  // NOLINTNEXTLINE(libcpp-nodebug-on-aliases) lldb relies on this alias for pretty printing
710
- using __node_pointer = _NodePtr;
711
- typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
712
- typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
793
+ using __node_pointer = _NodePtr;
794
+ using __node_base_pointer _LIBCPP_NODEBUG = typename _NodeTypes::__node_base_pointer;
795
+ using __end_node_pointer _LIBCPP_NODEBUG = typename _NodeTypes::__end_node_pointer;
713
796
 
714
797
  __end_node_pointer __ptr_;
715
798
 
716
799
  public:
717
- using iterator_category = bidirectional_iterator_tag;
718
- using value_type = __get_node_value_type_t<_Tp>;
719
- using difference_type = _DiffType;
720
- using reference = const value_type&;
721
- using pointer = __rebind_pointer_t<_NodePtr, const value_type>;
800
+ using iterator_category = bidirectional_iterator_tag;
801
+ using value_type = __get_node_value_type_t<_Tp>;
802
+ using difference_type = _DiffType;
803
+ using reference = const value_type&;
804
+ using pointer = __rebind_pointer_t<_NodePtr, const value_type>;
805
+ using __non_const_iterator _LIBCPP_NODEBUG = __tree_iterator<_Tp, __node_pointer, difference_type>;
722
806
 
723
- _LIBCPP_HIDE_FROM_ABI __tree_const_iterator() _NOEXCEPT
724
- #if _LIBCPP_STD_VER >= 14
725
- : __ptr_(nullptr)
726
- #endif
727
- {
728
- }
729
-
730
- private:
731
- typedef __tree_iterator<_Tp, __node_pointer, difference_type> __non_const_iterator;
807
+ _LIBCPP_HIDE_FROM_ABI __tree_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
732
808
 
733
- public:
734
809
  _LIBCPP_HIDE_FROM_ABI __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
735
810
 
736
- _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__value_; }
737
- _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__get_np()->__value_); }
811
+ _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__get_value(); }
812
+ _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
813
+ return pointer_traits<pointer>::pointer_to(__get_np()->__get_value());
814
+ }
738
815
 
739
816
  _LIBCPP_HIDE_FROM_ABI __tree_const_iterator& operator++() {
740
817
  __ptr_ = std::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_));
@@ -772,18 +849,28 @@ private:
772
849
 
773
850
  template <class, class, class>
774
851
  friend class __tree;
775
- template <class, class, class, class>
776
- friend class map;
777
- template <class, class, class, class>
778
- friend class multimap;
779
- template <class, class, class>
780
- friend class set;
781
- template <class, class, class>
782
- friend class multiset;
783
- template <class>
784
- friend class __map_const_iterator;
852
+
853
+ template <class _NodeIter, class _Func, class _Proj>
854
+ friend void __tree_iterate_subrange(_NodeIter, _NodeIter, _Func&, _Proj&);
785
855
  };
786
856
 
857
+ #ifndef _LIBCPP_CXX03_LANG
858
+ // This also handles {multi,}set::const_iterator, since they're just aliases to __tree::iterator
859
+ template <class _Tp, class _NodePtr, class _DiffType>
860
+ struct __specialized_algorithm<
861
+ _Algorithm::__for_each,
862
+ __iterator_pair<__tree_const_iterator<_Tp, _NodePtr, _DiffType>, __tree_const_iterator<_Tp, _NodePtr, _DiffType>>> {
863
+ static const bool __has_algorithm = true;
864
+
865
+ using __iterator _LIBCPP_NODEBUG = __tree_const_iterator<_Tp, _NodePtr, _DiffType>;
866
+
867
+ template <class _Func, class _Proj>
868
+ _LIBCPP_HIDE_FROM_ABI static void operator()(__iterator __first, __iterator __last, _Func& __func, _Proj& __proj) {
869
+ std::__tree_iterate_subrange(__first, __last, __func, __proj);
870
+ }
871
+ };
872
+ #endif
873
+
787
874
  template <class _Tp, class _Compare>
788
875
  #ifndef _LIBCPP_CXX03_LANG
789
876
  _LIBCPP_DIAGNOSE_WARNING(!__is_invocable_v<_Compare const&, _Tp const&, _Tp const&>,
@@ -794,21 +881,20 @@ int __diagnose_non_const_comparator();
794
881
  template <class _Tp, class _Compare, class _Allocator>
795
882
  class __tree {
796
883
  public:
797
- using value_type = __get_node_value_type_t<_Tp>;
798
- typedef _Compare value_compare;
799
- typedef _Allocator allocator_type;
884
+ using value_type = __get_node_value_type_t<_Tp>;
885
+ using value_compare = _Compare;
886
+ using allocator_type = _Allocator;
800
887
 
801
888
  private:
802
- typedef allocator_traits<allocator_type> __alloc_traits;
803
- using key_type = __get_tree_key_type_t<_Tp>;
889
+ using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;
890
+ using key_type = __get_tree_key_type_t<_Tp>;
804
891
 
805
892
  public:
806
- typedef typename __alloc_traits::pointer pointer;
807
- typedef typename __alloc_traits::const_pointer const_pointer;
808
- typedef typename __alloc_traits::size_type size_type;
809
- typedef typename __alloc_traits::difference_type difference_type;
893
+ using pointer = typename __alloc_traits::pointer;
894
+ using const_pointer = typename __alloc_traits::const_pointer;
895
+ using size_type = typename __alloc_traits::size_type;
896
+ using difference_type = typename __alloc_traits::difference_type;
810
897
 
811
- public:
812
898
  using __void_pointer _LIBCPP_NODEBUG = typename __alloc_traits::void_pointer;
813
899
 
814
900
  using __node _LIBCPP_NODEBUG = __tree_node<_Tp, __void_pointer>;
@@ -821,22 +907,8 @@ public:
821
907
  using __end_node_t _LIBCPP_NODEBUG = __tree_end_node<__node_base_pointer>;
822
908
  using __end_node_pointer _LIBCPP_NODEBUG = __rebind_pointer_t<__void_pointer, __end_node_t>;
823
909
 
824
- using __parent_pointer _LIBCPP_NODEBUG = __end_node_pointer; // TODO: Remove this once the uses in <map> are removed
825
-
826
- typedef __rebind_alloc<__alloc_traits, __node> __node_allocator;
827
- typedef allocator_traits<__node_allocator> __node_traits;
828
-
829
- // TODO(LLVM 22): Remove this check
830
- #ifndef _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB
831
- static_assert(sizeof(__node_base_pointer) == sizeof(__end_node_pointer) && _LIBCPP_ALIGNOF(__node_base_pointer) ==
832
- _LIBCPP_ALIGNOF(__end_node_pointer),
833
- "It looks like you are using std::__tree (an implementation detail for (multi)map/set) with a fancy "
834
- "pointer type that thas a different representation depending on whether it points to a __tree base "
835
- "pointer or a __tree node pointer (both of which are implementation details of the standard library). "
836
- "This means that your ABI is being broken between LLVM 19 and LLVM 20. If you don't care about your "
837
- "ABI being broken, define the _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB macro to silence this "
838
- "diagnostic.");
839
- #endif
910
+ using __node_allocator _LIBCPP_NODEBUG = __rebind_alloc<__alloc_traits, __node>;
911
+ using __node_traits _LIBCPP_NODEBUG = allocator_traits<__node_allocator>;
840
912
 
841
913
  private:
842
914
  // check for sane allocator pointer rebinding semantics. Rebinding the
@@ -844,8 +916,8 @@ private:
844
916
  // the pointer using 'pointer_traits'.
845
917
  static_assert(is_same<__node_pointer, typename __node_traits::pointer>::value,
846
918
  "Allocator does not rebind pointers in a sane manner.");
847
- typedef __rebind_alloc<__node_traits, __node_base> __node_base_allocator;
848
- typedef allocator_traits<__node_base_allocator> __node_base_traits;
919
+ using __node_base_allocator _LIBCPP_NODEBUG = __rebind_alloc<__node_traits, __node_base>;
920
+ using __node_base_traits _LIBCPP_NODEBUG = allocator_traits<__node_base_allocator>;
849
921
  static_assert(is_same<__node_base_pointer, typename __node_base_traits::pointer>::value,
850
922
  "Allocator does not rebind pointers in a sane manner.");
851
923
 
@@ -865,17 +937,11 @@ public:
865
937
 
866
938
  private:
867
939
  _LIBCPP_HIDE_FROM_ABI const __node_allocator& __node_alloc() const _NOEXCEPT { return __node_alloc_; }
868
- _LIBCPP_HIDE_FROM_ABI __end_node_pointer& __begin_node() _NOEXCEPT { return __begin_node_; }
869
- _LIBCPP_HIDE_FROM_ABI const __end_node_pointer& __begin_node() const _NOEXCEPT { return __begin_node_; }
870
940
 
871
941
  public:
872
942
  _LIBCPP_HIDE_FROM_ABI allocator_type __alloc() const _NOEXCEPT { return allocator_type(__node_alloc()); }
873
943
 
874
- private:
875
- _LIBCPP_HIDE_FROM_ABI size_type& size() _NOEXCEPT { return __size_; }
876
-
877
- public:
878
- _LIBCPP_HIDE_FROM_ABI const size_type& size() const _NOEXCEPT { return __size_; }
944
+ _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }
879
945
  _LIBCPP_HIDE_FROM_ABI value_compare& value_comp() _NOEXCEPT { return __value_comp_; }
880
946
  _LIBCPP_HIDE_FROM_ABI const value_compare& value_comp() const _NOEXCEPT { return __value_comp_; }
881
947
 
@@ -888,32 +954,61 @@ public:
888
954
  return std::addressof(__end_node()->__left_);
889
955
  }
890
956
 
891
- typedef __tree_iterator<_Tp, __node_pointer, difference_type> iterator;
892
- typedef __tree_const_iterator<_Tp, __node_pointer, difference_type> const_iterator;
957
+ using iterator = __tree_iterator<_Tp, __node_pointer, difference_type>;
958
+ using const_iterator = __tree_const_iterator<_Tp, __node_pointer, difference_type>;
893
959
 
894
960
  _LIBCPP_HIDE_FROM_ABI explicit __tree(const value_compare& __comp) _NOEXCEPT_(
895
- is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_copy_constructible<value_compare>::value);
896
- _LIBCPP_HIDE_FROM_ABI explicit __tree(const allocator_type& __a);
897
- _LIBCPP_HIDE_FROM_ABI __tree(const value_compare& __comp, const allocator_type& __a);
961
+ is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_copy_constructible<value_compare>::value)
962
+ : __size_(0), __value_comp_(__comp) {
963
+ __begin_node_ = __end_node();
964
+ }
965
+
966
+ _LIBCPP_HIDE_FROM_ABI explicit __tree(const allocator_type& __a)
967
+ : __begin_node_(), __node_alloc_(__node_allocator(__a)), __size_(0) {
968
+ __begin_node_ = __end_node();
969
+ }
970
+
971
+ _LIBCPP_HIDE_FROM_ABI __tree(const value_compare& __comp, const allocator_type& __a)
972
+ : __begin_node_(), __node_alloc_(__node_allocator(__a)), __size_(0), __value_comp_(__comp) {
973
+ __begin_node_ = __end_node();
974
+ }
975
+
898
976
  _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __t);
977
+
978
+ _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __other, const allocator_type& __alloc)
979
+ : __begin_node_(__end_node()), __node_alloc_(__alloc), __size_(0), __value_comp_(__other.value_comp()) {
980
+ if (__other.size() == 0)
981
+ return;
982
+
983
+ *__root_ptr() = static_cast<__node_base_pointer>(__copy_construct_tree(__other.__root()));
984
+ __root()->__parent_ = __end_node();
985
+ __begin_node_ = static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_));
986
+ __size_ = __other.size();
987
+ }
988
+
899
989
  _LIBCPP_HIDE_FROM_ABI __tree& operator=(const __tree& __t);
900
990
  template <class _ForwardIterator>
901
991
  _LIBCPP_HIDE_FROM_ABI void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
902
- template <class _InputIterator>
903
- _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last);
904
992
  _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t) _NOEXCEPT_(
905
993
  is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value);
906
994
  _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t, const allocator_type& __a);
995
+
907
996
  _LIBCPP_HIDE_FROM_ABI __tree& operator=(__tree&& __t)
908
997
  _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
909
998
  ((__node_traits::propagate_on_container_move_assignment::value &&
910
999
  is_nothrow_move_assignable<__node_allocator>::value) ||
911
- allocator_traits<__node_allocator>::is_always_equal::value));
1000
+ allocator_traits<__node_allocator>::is_always_equal::value)) {
1001
+ __move_assign(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
1002
+ return *this;
1003
+ }
912
1004
 
913
- _LIBCPP_HIDE_FROM_ABI ~__tree();
1005
+ _LIBCPP_HIDE_FROM_ABI ~__tree() {
1006
+ static_assert(is_copy_constructible<value_compare>::value, "Comparator must be copy-constructible.");
1007
+ destroy(__root());
1008
+ }
914
1009
 
915
- _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__begin_node()); }
916
- _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return const_iterator(__begin_node()); }
1010
+ _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__begin_node_); }
1011
+ _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return const_iterator(__begin_node_); }
917
1012
  _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(__end_node()); }
918
1013
  _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return const_iterator(__end_node()); }
919
1014
 
@@ -931,116 +1026,151 @@ public:
931
1026
  _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>);
932
1027
  #endif
933
1028
 
934
- template <class _Key, class... _Args>
935
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args&&... __args);
936
- template <class _Key, class... _Args>
937
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...);
938
-
939
- template <class... _Args>
940
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
941
-
942
- template <class... _Args>
943
- _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
944
-
945
1029
  template <class... _Args>
946
1030
  _LIBCPP_HIDE_FROM_ABI iterator __emplace_multi(_Args&&... __args);
947
1031
 
948
1032
  template <class... _Args>
949
1033
  _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
950
1034
 
951
- template <class _Pp>
952
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_Pp&& __x) {
953
- return __emplace_unique_extract_key(std::forward<_Pp>(__x), __can_extract_key<_Pp, key_type>());
954
- }
955
-
956
- template <class _First,
957
- class _Second,
958
- __enable_if_t<__can_extract_map_key<_First, key_type, value_type>::value, int> = 0>
959
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_First&& __f, _Second&& __s) {
960
- return __emplace_unique_key_args(__f, std::forward<_First>(__f), std::forward<_Second>(__s));
961
- }
962
-
963
1035
  template <class... _Args>
964
1036
  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_Args&&... __args) {
965
- return __emplace_unique_impl(std::forward<_Args>(__args)...);
966
- }
967
-
968
- template <class _Pp>
969
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
970
- return __emplace_unique_impl(std::forward<_Pp>(__x));
971
- }
972
-
973
- template <class _Pp>
974
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
975
- return __emplace_unique_key_args(__x, std::forward<_Pp>(__x));
976
- }
977
-
978
- template <class _Pp>
979
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
980
- return __emplace_unique_key_args(__x.first, std::forward<_Pp>(__x));
981
- }
982
-
983
- template <class _Pp>
984
- _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) {
985
- return __emplace_hint_unique_extract_key(__p, std::forward<_Pp>(__x), __can_extract_key<_Pp, key_type>());
986
- }
987
-
988
- template <class _First,
989
- class _Second,
990
- __enable_if_t<__can_extract_map_key<_First, key_type, value_type>::value, int> = 0>
991
- _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) {
992
- return __emplace_hint_unique_key_args(__p, __f, std::forward<_First>(__f), std::forward<_Second>(__s)).first;
1037
+ return std::__try_key_extraction<key_type>(
1038
+ [this](const key_type& __key, _Args&&... __args2) {
1039
+ auto [__parent, __child] = __find_equal(__key);
1040
+ __node_pointer __r = static_cast<__node_pointer>(__child);
1041
+ bool __inserted = false;
1042
+ if (__child == nullptr) {
1043
+ __node_holder __h = __construct_node(std::forward<_Args>(__args2)...);
1044
+ __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1045
+ __r = __h.release();
1046
+ __inserted = true;
1047
+ }
1048
+ return pair<iterator, bool>(iterator(__r), __inserted);
1049
+ },
1050
+ [this](_Args&&... __args2) {
1051
+ __node_holder __h = __construct_node(std::forward<_Args>(__args2)...);
1052
+ auto [__parent, __child] = __find_equal(__h->__get_value());
1053
+ __node_pointer __r = static_cast<__node_pointer>(__child);
1054
+ bool __inserted = false;
1055
+ if (__child == nullptr) {
1056
+ __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1057
+ __r = __h.release();
1058
+ __inserted = true;
1059
+ }
1060
+ return pair<iterator, bool>(iterator(__r), __inserted);
1061
+ },
1062
+ std::forward<_Args>(__args)...);
993
1063
  }
994
1064
 
995
1065
  template <class... _Args>
996
- _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
997
- return __emplace_hint_unique_impl(__p, std::forward<_Args>(__args)...);
1066
+ _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
1067
+ return std::__try_key_extraction<key_type>(
1068
+ [this, __p](const key_type& __key, _Args&&... __args2) {
1069
+ __node_base_pointer __dummy;
1070
+ auto [__parent, __child] = __find_equal(__p, __dummy, __key);
1071
+ __node_pointer __r = static_cast<__node_pointer>(__child);
1072
+ bool __inserted = false;
1073
+ if (__child == nullptr) {
1074
+ __node_holder __h = __construct_node(std::forward<_Args>(__args2)...);
1075
+ __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1076
+ __r = __h.release();
1077
+ __inserted = true;
1078
+ }
1079
+ return pair<iterator, bool>(iterator(__r), __inserted);
1080
+ },
1081
+ [this, __p](_Args&&... __args2) {
1082
+ __node_holder __h = __construct_node(std::forward<_Args>(__args2)...);
1083
+ __node_base_pointer __dummy;
1084
+ auto [__parent, __child] = __find_equal(__p, __dummy, __h->__get_value());
1085
+ __node_pointer __r = static_cast<__node_pointer>(__child);
1086
+ if (__child == nullptr) {
1087
+ __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1088
+ __r = __h.release();
1089
+ }
1090
+ return pair<iterator, bool>(iterator(__r), __child == nullptr);
1091
+ },
1092
+ std::forward<_Args>(__args)...);
998
1093
  }
999
1094
 
1000
- template <class _Pp>
1001
- _LIBCPP_HIDE_FROM_ABI iterator
1002
- __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) {
1003
- return __emplace_hint_unique_impl(__p, std::forward<_Pp>(__x));
1004
- }
1095
+ template <class _InIter, class _Sent>
1096
+ _LIBCPP_HIDE_FROM_ABI void __insert_range_multi(_InIter __first, _Sent __last) {
1097
+ if (__first == __last)
1098
+ return;
1005
1099
 
1006
- template <class _Pp>
1007
- _LIBCPP_HIDE_FROM_ABI iterator
1008
- __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) {
1009
- return __emplace_hint_unique_key_args(__p, __x, std::forward<_Pp>(__x)).first;
1010
- }
1100
+ if (__root() == nullptr) { // Make sure we always have a root node
1101
+ __insert_node_at(
1102
+ __end_node(), __end_node()->__left_, static_cast<__node_base_pointer>(__construct_node(*__first).release()));
1103
+ ++__first;
1104
+ }
1011
1105
 
1012
- template <class _Pp>
1013
- _LIBCPP_HIDE_FROM_ABI iterator
1014
- __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) {
1015
- return __emplace_hint_unique_key_args(__p, __x.first, std::forward<_Pp>(__x)).first;
1016
- }
1106
+ auto __max_node = static_cast<__node_pointer>(std::__tree_max(static_cast<__node_base_pointer>(__root())));
1017
1107
 
1018
- template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type<_ValueT>::value, int> = 0>
1019
- _LIBCPP_HIDE_FROM_ABI void
1020
- __insert_unique_from_orphaned_node(const_iterator __p, __get_node_value_type_t<_Tp>&& __value) {
1021
- __emplace_hint_unique(__p, const_cast<key_type&&>(__value.first), std::move(__value.second));
1108
+ for (; __first != __last; ++__first) {
1109
+ __node_holder __nd = __construct_node(*__first);
1110
+ // Always check the max node first. This optimizes for sorted ranges inserted at the end.
1111
+ if (!value_comp()(__nd->__get_value(), __max_node->__get_value())) { // __node >= __max_val
1112
+ __insert_node_at(static_cast<__end_node_pointer>(__max_node),
1113
+ __max_node->__right_,
1114
+ static_cast<__node_base_pointer>(__nd.get()));
1115
+ __max_node = __nd.release();
1116
+ } else {
1117
+ __end_node_pointer __parent;
1118
+ __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__get_value());
1119
+ __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd.release()));
1120
+ }
1121
+ }
1022
1122
  }
1023
1123
 
1024
- template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type<_ValueT>::value, int> = 0>
1025
- _LIBCPP_HIDE_FROM_ABI void __insert_unique_from_orphaned_node(const_iterator __p, _Tp&& __value) {
1026
- __emplace_hint_unique(__p, std::move(__value));
1027
- }
1124
+ template <class _InIter, class _Sent>
1125
+ _LIBCPP_HIDE_FROM_ABI void __insert_range_unique(_InIter __first, _Sent __last) {
1126
+ if (__first == __last)
1127
+ return;
1028
1128
 
1029
- template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type<_ValueT>::value, int> = 0>
1030
- _LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(const_iterator __p, value_type&& __value) {
1031
- __emplace_hint_multi(__p, const_cast<key_type&&>(__value.first), std::move(__value.second));
1032
- }
1129
+ if (__root() == nullptr) {
1130
+ __insert_node_at(
1131
+ __end_node(), __end_node()->__left_, static_cast<__node_base_pointer>(__construct_node(*__first).release()));
1132
+ ++__first;
1133
+ }
1033
1134
 
1034
- template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type<_ValueT>::value, int> = 0>
1035
- _LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(const_iterator __p, _Tp&& __value) {
1036
- __emplace_hint_multi(__p, std::move(__value));
1135
+ auto __max_node = static_cast<__node_pointer>(std::__tree_max(static_cast<__node_base_pointer>(__root())));
1136
+
1137
+ using __reference = decltype(*__first);
1138
+
1139
+ for (; __first != __last; ++__first) {
1140
+ std::__try_key_extraction<key_type>(
1141
+ [this, &__max_node](const key_type& __key, __reference&& __val) {
1142
+ if (value_comp()(__max_node->__get_value(), __key)) { // __key > __max_node
1143
+ __node_holder __nd = __construct_node(std::forward<__reference>(__val));
1144
+ __insert_node_at(static_cast<__end_node_pointer>(__max_node),
1145
+ __max_node->__right_,
1146
+ static_cast<__node_base_pointer>(__nd.get()));
1147
+ __max_node = __nd.release();
1148
+ } else {
1149
+ auto [__parent, __child] = __find_equal(__key);
1150
+ if (__child == nullptr) {
1151
+ __node_holder __nd = __construct_node(std::forward<__reference>(__val));
1152
+ __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd.release()));
1153
+ }
1154
+ }
1155
+ },
1156
+ [this, &__max_node](__reference&& __val) {
1157
+ __node_holder __nd = __construct_node(std::forward<__reference>(__val));
1158
+ if (value_comp()(__max_node->__get_value(), __nd->__get_value())) { // __node > __max_node
1159
+ __insert_node_at(static_cast<__end_node_pointer>(__max_node),
1160
+ __max_node->__right_,
1161
+ static_cast<__node_base_pointer>(__nd.get()));
1162
+ __max_node = __nd.release();
1163
+ } else {
1164
+ auto [__parent, __child] = __find_equal(__nd->__get_value());
1165
+ if (__child == nullptr) {
1166
+ __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd.release()));
1167
+ }
1168
+ }
1169
+ },
1170
+ *__first);
1171
+ }
1037
1172
  }
1038
1173
 
1039
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __node_assign_unique(const value_type& __v, __node_pointer __dest);
1040
-
1041
- _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(__node_pointer __nd);
1042
- _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
1043
-
1044
1174
  _LIBCPP_HIDE_FROM_ABI iterator __remove_node_pointer(__node_pointer) _NOEXCEPT;
1045
1175
 
1046
1176
  #if _LIBCPP_STD_VER >= 17
@@ -1048,15 +1178,15 @@ public:
1048
1178
  _LIBCPP_HIDE_FROM_ABI _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
1049
1179
  template <class _NodeHandle>
1050
1180
  _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&);
1051
- template <class _Tree>
1052
- _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_unique(_Tree& __source);
1181
+ template <class _Comp2>
1182
+ _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_unique(__tree<_Tp, _Comp2, _Allocator>& __source);
1053
1183
 
1054
1184
  template <class _NodeHandle>
1055
1185
  _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(_NodeHandle&&);
1056
1186
  template <class _NodeHandle>
1057
1187
  _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&);
1058
- template <class _Tree>
1059
- _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_multi(_Tree& __source);
1188
+ template <class _Comp2>
1189
+ _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_multi(__tree<_Tp, _Comp2, _Allocator>& __source);
1060
1190
 
1061
1191
  template <class _NodeHandle>
1062
1192
  _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(key_type const&);
@@ -1075,41 +1205,157 @@ public:
1075
1205
  __insert_node_at(__end_node_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node) _NOEXCEPT;
1076
1206
 
1077
1207
  template <class _Key>
1078
- _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __v);
1208
+ _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __key) {
1209
+ auto [__, __match] = __find_equal(__key);
1210
+ if (__match == nullptr)
1211
+ return end();
1212
+ return iterator(static_cast<__node_pointer>(__match));
1213
+ }
1214
+
1079
1215
  template <class _Key>
1080
- _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __v) const;
1216
+ _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __key) const {
1217
+ auto [__, __match] = __find_equal(__key);
1218
+ if (__match == nullptr)
1219
+ return end();
1220
+ return const_iterator(static_cast<__node_pointer>(__match));
1221
+ }
1081
1222
 
1082
1223
  template <class _Key>
1083
1224
  _LIBCPP_HIDE_FROM_ABI size_type __count_unique(const _Key& __k) const;
1084
1225
  template <class _Key>
1085
1226
  _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const;
1086
1227
 
1228
+ template <bool _LowerBound, class _Key>
1229
+ _LIBCPP_HIDE_FROM_ABI __end_node_pointer __lower_upper_bound_unique_impl(const _Key& __v) const {
1230
+ auto __rt = __root();
1231
+ auto __result = __end_node();
1232
+ auto __comp = __lazy_synth_three_way_comparator<_Compare, _Key, value_type>(value_comp());
1233
+ while (__rt != nullptr) {
1234
+ auto __comp_res = __comp(__v, __rt->__get_value());
1235
+
1236
+ if (__comp_res.__less()) {
1237
+ __result = static_cast<__end_node_pointer>(__rt);
1238
+ __rt = static_cast<__node_pointer>(__rt->__left_);
1239
+ } else if (__comp_res.__greater()) {
1240
+ __rt = static_cast<__node_pointer>(__rt->__right_);
1241
+ } else if _LIBCPP_CONSTEXPR (_LowerBound) {
1242
+ return static_cast<__end_node_pointer>(__rt);
1243
+ } else {
1244
+ return __rt->__right_ ? static_cast<__end_node_pointer>(std::__tree_min(__rt->__right_)) : __result;
1245
+ }
1246
+ }
1247
+ return __result;
1248
+ }
1249
+
1250
+ // Compatibility escape hatch for comparators that are not strict weak orderings. This
1251
+ // can be removed for the LLVM 23 release.
1252
+ #if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
1087
1253
  template <class _Key>
1088
- _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _Key& __v) {
1089
- return __lower_bound(__v, __root(), __end_node());
1254
+ _LIBCPP_HIDE_FROM_ABI __end_node_pointer __lower_bound_unique_compat_impl(const _Key& __v) const {
1255
+ auto __rt = __root();
1256
+ auto __result = __end_node();
1257
+ while (__rt != nullptr) {
1258
+ if (!value_comp()(__rt->__get_value(), __v)) {
1259
+ __result = std::__static_fancy_pointer_cast<__end_node_pointer>(__rt);
1260
+ __rt = std::__static_fancy_pointer_cast<__node_pointer>(__rt->__left_);
1261
+ } else {
1262
+ __rt = std::__static_fancy_pointer_cast<__node_pointer>(__rt->__right_);
1263
+ }
1264
+ }
1265
+ return __result;
1090
1266
  }
1267
+
1091
1268
  template <class _Key>
1092
- _LIBCPP_HIDE_FROM_ABI iterator __lower_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result);
1269
+ _LIBCPP_HIDE_FROM_ABI __end_node_pointer __upper_bound_unique_compat_impl(const _Key& __v) const {
1270
+ auto __rt = __root();
1271
+ auto __result = __end_node();
1272
+ while (__rt != nullptr) {
1273
+ if (value_comp()(__v, __rt->__get_value())) {
1274
+ __result = std::__static_fancy_pointer_cast<__end_node_pointer>(__rt);
1275
+ __rt = std::__static_fancy_pointer_cast<__node_pointer>(__rt->__left_);
1276
+ } else {
1277
+ __rt = std::__static_fancy_pointer_cast<__node_pointer>(__rt->__right_);
1278
+ }
1279
+ }
1280
+ return __result;
1281
+ }
1282
+ #endif // _LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND
1283
+
1093
1284
  template <class _Key>
1094
- _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _Key& __v) const {
1095
- return __lower_bound(__v, __root(), __end_node());
1285
+ _LIBCPP_HIDE_FROM_ABI iterator __lower_bound_unique(const _Key& __v) {
1286
+ #if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
1287
+ return iterator(__lower_bound_unique_compat_impl(__v));
1288
+ #else
1289
+ return iterator(__lower_upper_bound_unique_impl<true>(__v));
1290
+ #endif
1096
1291
  }
1292
+
1293
+ template <class _Key>
1294
+ _LIBCPP_HIDE_FROM_ABI const_iterator __lower_bound_unique(const _Key& __v) const {
1295
+ #if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
1296
+ return const_iterator(__lower_bound_unique_compat_impl(__v));
1297
+ #else
1298
+ return const_iterator(__lower_upper_bound_unique_impl<true>(__v));
1299
+ #endif
1300
+ }
1301
+
1302
+ template <class _Key>
1303
+ _LIBCPP_HIDE_FROM_ABI iterator __upper_bound_unique(const _Key& __v) {
1304
+ #if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
1305
+ return iterator(__upper_bound_unique_compat_impl(__v));
1306
+ #else
1307
+ return iterator(__lower_upper_bound_unique_impl<false>(__v));
1308
+ #endif
1309
+ }
1310
+
1311
+ template <class _Key>
1312
+ _LIBCPP_HIDE_FROM_ABI const_iterator __upper_bound_unique(const _Key& __v) const {
1313
+ #if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
1314
+ return iterator(__upper_bound_unique_compat_impl(__v));
1315
+ #else
1316
+ return iterator(__lower_upper_bound_unique_impl<false>(__v));
1317
+ #endif
1318
+ }
1319
+
1320
+ private:
1321
+ template <class _Key>
1322
+ _LIBCPP_HIDE_FROM_ABI iterator
1323
+ __lower_bound_multi(const _Key& __v, __node_pointer __root, __end_node_pointer __result);
1324
+
1097
1325
  template <class _Key>
1098
1326
  _LIBCPP_HIDE_FROM_ABI const_iterator
1099
- __lower_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) const;
1327
+ __lower_bound_multi(const _Key& __v, __node_pointer __root, __end_node_pointer __result) const;
1328
+
1329
+ public:
1100
1330
  template <class _Key>
1101
- _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _Key& __v) {
1102
- return __upper_bound(__v, __root(), __end_node());
1331
+ _LIBCPP_HIDE_FROM_ABI iterator __lower_bound_multi(const _Key& __v) {
1332
+ return __lower_bound_multi(__v, __root(), __end_node());
1103
1333
  }
1104
1334
  template <class _Key>
1105
- _LIBCPP_HIDE_FROM_ABI iterator __upper_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result);
1335
+ _LIBCPP_HIDE_FROM_ABI const_iterator __lower_bound_multi(const _Key& __v) const {
1336
+ return __lower_bound_multi(__v, __root(), __end_node());
1337
+ }
1338
+
1339
+ template <class _Key>
1340
+ _LIBCPP_HIDE_FROM_ABI iterator __upper_bound_multi(const _Key& __v) {
1341
+ return __upper_bound_multi(__v, __root(), __end_node());
1342
+ }
1343
+
1106
1344
  template <class _Key>
1107
- _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _Key& __v) const {
1108
- return __upper_bound(__v, __root(), __end_node());
1345
+ _LIBCPP_HIDE_FROM_ABI const_iterator __upper_bound_multi(const _Key& __v) const {
1346
+ return __upper_bound_multi(__v, __root(), __end_node());
1109
1347
  }
1348
+
1349
+ private:
1350
+ template <class _Key>
1351
+ _LIBCPP_HIDE_FROM_ABI iterator
1352
+ __upper_bound_multi(const _Key& __v, __node_pointer __root, __end_node_pointer __result);
1353
+
1110
1354
  template <class _Key>
1111
1355
  _LIBCPP_HIDE_FROM_ABI const_iterator
1112
- __upper_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) const;
1356
+ __upper_bound_multi(const _Key& __v, __node_pointer __root, __end_node_pointer __result) const;
1357
+
1358
+ public:
1113
1359
  template <class _Key>
1114
1360
  _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> __equal_range_unique(const _Key& __k);
1115
1361
  template <class _Key>
@@ -1120,22 +1366,24 @@ public:
1120
1366
  template <class _Key>
1121
1367
  _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> __equal_range_multi(const _Key& __k) const;
1122
1368
 
1123
- typedef __tree_node_destructor<__node_allocator> _Dp;
1124
- typedef unique_ptr<__node, _Dp> __node_holder;
1369
+ using _Dp _LIBCPP_NODEBUG = __tree_node_destructor<__node_allocator>;
1370
+ using __node_holder _LIBCPP_NODEBUG = unique_ptr<__node, _Dp>;
1125
1371
 
1126
1372
  _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT;
1127
1373
 
1128
1374
  // FIXME: Make this function const qualified. Unfortunately doing so
1129
1375
  // breaks existing code which uses non-const callable comparators.
1130
1376
  template <class _Key>
1131
- _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_equal(__end_node_pointer& __parent, const _Key& __v);
1377
+ _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&> __find_equal(const _Key& __v);
1378
+
1132
1379
  template <class _Key>
1133
- _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_equal(__end_node_pointer& __parent, const _Key& __v) const {
1134
- return const_cast<__tree*>(this)->__find_equal(__parent, __v);
1380
+ _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&> __find_equal(const _Key& __v) const {
1381
+ return const_cast<__tree*>(this)->__find_equal(__v);
1135
1382
  }
1383
+
1136
1384
  template <class _Key>
1137
- _LIBCPP_HIDE_FROM_ABI __node_base_pointer&
1138
- __find_equal(const_iterator __hint, __end_node_pointer& __parent, __node_base_pointer& __dummy, const _Key& __v);
1385
+ _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&>
1386
+ __find_equal(const_iterator __hint, __node_base_pointer& __dummy, const _Key& __v);
1139
1387
 
1140
1388
  _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __tree& __t) {
1141
1389
  __copy_assign_alloc(__t, integral_constant<bool, __node_traits::propagate_on_container_copy_assignment::value>());
@@ -1160,7 +1408,7 @@ private:
1160
1408
  _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&&... __args);
1161
1409
 
1162
1410
  // TODO: Make this _LIBCPP_HIDE_FROM_ABI
1163
- _LIBCPP_HIDDEN void destroy(__node_pointer __nd) _NOEXCEPT;
1411
+ _LIBCPP_HIDDEN void destroy(__node_pointer __nd) _NOEXCEPT { (__tree_deleter(__node_alloc_))(__nd); }
1164
1412
 
1165
1413
  _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, false_type);
1166
1414
  _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, true_type) _NOEXCEPT_(
@@ -1178,7 +1426,7 @@ private:
1178
1426
  }
1179
1427
  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
1180
1428
 
1181
- template <class _From, class _ValueT = _Tp, __enable_if_t<__is_tree_value_type<_ValueT>::value, int> = 0>
1429
+ template <class _From, class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0>
1182
1430
  _LIBCPP_HIDE_FROM_ABI static void __assign_value(__get_node_value_type_t<value_type>& __lhs, _From&& __rhs) {
1183
1431
  using __key_type = __remove_const_t<typename value_type::first_type>;
1184
1432
 
@@ -1188,166 +1436,203 @@ private:
1188
1436
  __lhs.second = std::forward<_From>(__rhs).second;
1189
1437
  }
1190
1438
 
1191
- template <class _To, class _From, class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type<_ValueT>::value, int> = 0>
1439
+ template <class _To, class _From, class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0>
1192
1440
  _LIBCPP_HIDE_FROM_ABI static void __assign_value(_To& __lhs, _From&& __rhs) {
1193
1441
  __lhs = std::forward<_From>(__rhs);
1194
1442
  }
1195
1443
 
1196
- struct _DetachedTreeCache {
1197
- _LIBCPP_HIDE_FROM_ABI explicit _DetachedTreeCache(__tree* __t) _NOEXCEPT
1198
- : __t_(__t),
1199
- __cache_root_(__detach_from_tree(__t)) {
1200
- __advance();
1444
+ class __tree_deleter {
1445
+ __node_allocator& __alloc_;
1446
+
1447
+ public:
1448
+ using pointer = __node_pointer;
1449
+
1450
+ _LIBCPP_HIDE_FROM_ABI __tree_deleter(__node_allocator& __alloc) : __alloc_(__alloc) {}
1451
+
1452
+ #ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
1453
+ _LIBCPP_HIDE_FROM_ABI
1454
+ #endif
1455
+ void
1456
+ operator()(__node_pointer __ptr) {
1457
+ if (!__ptr)
1458
+ return;
1459
+
1460
+ (*this)(static_cast<__node_pointer>(__ptr->__left_));
1461
+
1462
+ auto __right = __ptr->__right_;
1463
+
1464
+ __node_traits::destroy(__alloc_, std::addressof(__ptr->__get_value()));
1465
+ __node_traits::deallocate(__alloc_, __ptr, 1);
1466
+
1467
+ (*this)(static_cast<__node_pointer>(__right));
1201
1468
  }
1469
+ };
1470
+
1471
+ // This copy construction will always produce a correct red-black-tree assuming the incoming tree is correct, since we
1472
+ // copy the exact structure 1:1. Since this is for copy construction _only_ we know that we get a correct tree. If we
1473
+ // didn't get a correct tree, the invariants of __tree are broken and we have a much bigger problem than an improperly
1474
+ // balanced tree.
1475
+ template <class _NodeConstructor>
1476
+ #ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
1477
+ _LIBCPP_HIDE_FROM_ABI
1478
+ #endif
1479
+ __node_pointer __construct_from_tree(__node_pointer __src, _NodeConstructor __construct) {
1480
+ if (!__src)
1481
+ return nullptr;
1202
1482
 
1203
- _LIBCPP_HIDE_FROM_ABI __node_pointer __get() const _NOEXCEPT { return __cache_elem_; }
1483
+ __node_holder __new_node = __construct(__src->__get_value());
1204
1484
 
1205
- _LIBCPP_HIDE_FROM_ABI void __advance() _NOEXCEPT {
1206
- __cache_elem_ = __cache_root_;
1207
- if (__cache_root_) {
1208
- __cache_root_ = __detach_next(__cache_root_);
1209
- }
1485
+ unique_ptr<__node, __tree_deleter> __left(
1486
+ __construct_from_tree(static_cast<__node_pointer>(__src->__left_), __construct), __node_alloc_);
1487
+ __node_pointer __right = __construct_from_tree(static_cast<__node_pointer>(__src->__right_), __construct);
1488
+
1489
+ __node_pointer __new_node_ptr = __new_node.release();
1490
+
1491
+ __new_node_ptr->__is_black_ = __src->__is_black_;
1492
+ __new_node_ptr->__left_ = static_cast<__node_base_pointer>(__left.release());
1493
+ __new_node_ptr->__right_ = static_cast<__node_base_pointer>(__right);
1494
+ if (__new_node_ptr->__left_)
1495
+ __new_node_ptr->__left_->__parent_ = static_cast<__end_node_pointer>(__new_node_ptr);
1496
+ if (__new_node_ptr->__right_)
1497
+ __new_node_ptr->__right_->__parent_ = static_cast<__end_node_pointer>(__new_node_ptr);
1498
+ return __new_node_ptr;
1499
+ }
1500
+
1501
+ _LIBCPP_HIDE_FROM_ABI __node_pointer __copy_construct_tree(__node_pointer __src) {
1502
+ return __construct_from_tree(__src, [this](const value_type& __val) { return __construct_node(__val); });
1503
+ }
1504
+
1505
+ template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0>
1506
+ _LIBCPP_HIDE_FROM_ABI __node_pointer __move_construct_tree(__node_pointer __src) {
1507
+ return __construct_from_tree(__src, [this](value_type& __val) {
1508
+ return __construct_node(const_cast<key_type&&>(__val.first), std::move(__val.second));
1509
+ });
1510
+ }
1511
+
1512
+ template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0>
1513
+ _LIBCPP_HIDE_FROM_ABI __node_pointer __move_construct_tree(__node_pointer __src) {
1514
+ return __construct_from_tree(__src, [this](value_type& __val) { return __construct_node(std::move(__val)); });
1515
+ }
1516
+
1517
+ template <class _Assignment, class _ConstructionAlg>
1518
+ // This copy assignment will always produce a correct red-black-tree assuming the incoming tree is correct, since our
1519
+ // own tree is a red-black-tree and the incoming tree is a red-black-tree. The invariants of a red-black-tree are
1520
+ // temporarily not met until all of the incoming red-black tree is copied.
1521
+ #ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
1522
+ _LIBCPP_HIDE_FROM_ABI
1523
+ #endif
1524
+ __node_pointer __assign_from_tree(
1525
+ __node_pointer __dest, __node_pointer __src, _Assignment __assign, _ConstructionAlg __construct_subtree) {
1526
+ if (!__src) {
1527
+ destroy(__dest);
1528
+ return nullptr;
1210
1529
  }
1211
1530
 
1212
- _LIBCPP_HIDE_FROM_ABI ~_DetachedTreeCache() {
1213
- __t_->destroy(__cache_elem_);
1214
- if (__cache_root_) {
1215
- while (__cache_root_->__parent_ != nullptr)
1216
- __cache_root_ = static_cast<__node_pointer>(__cache_root_->__parent_);
1217
- __t_->destroy(__cache_root_);
1218
- }
1531
+ __assign(__dest->__get_value(), __src->__get_value());
1532
+ __dest->__is_black_ = __src->__is_black_;
1533
+
1534
+ // If we already have a left node in the destination tree, reuse it and copy-assign recursively
1535
+ if (__dest->__left_) {
1536
+ __dest->__left_ = static_cast<__node_base_pointer>(__assign_from_tree(
1537
+ static_cast<__node_pointer>(__dest->__left_),
1538
+ static_cast<__node_pointer>(__src->__left_),
1539
+ __assign,
1540
+ __construct_subtree));
1541
+
1542
+ // Otherwise, we must create new nodes; copy-construct from here on
1543
+ } else if (__src->__left_) {
1544
+ auto __new_left = __construct_subtree(static_cast<__node_pointer>(__src->__left_));
1545
+ __dest->__left_ = static_cast<__node_base_pointer>(__new_left);
1546
+ __new_left->__parent_ = static_cast<__end_node_pointer>(__dest);
1219
1547
  }
1220
1548
 
1221
- _DetachedTreeCache(_DetachedTreeCache const&) = delete;
1222
- _DetachedTreeCache& operator=(_DetachedTreeCache const&) = delete;
1549
+ // Identical to the left case above, just for the right nodes
1550
+ if (__dest->__right_) {
1551
+ __dest->__right_ = static_cast<__node_base_pointer>(__assign_from_tree(
1552
+ static_cast<__node_pointer>(__dest->__right_),
1553
+ static_cast<__node_pointer>(__src->__right_),
1554
+ __assign,
1555
+ __construct_subtree));
1556
+ } else if (__src->__right_) {
1557
+ auto __new_right = __construct_subtree(static_cast<__node_pointer>(__src->__right_));
1558
+ __dest->__right_ = static_cast<__node_base_pointer>(__new_right);
1559
+ __new_right->__parent_ = static_cast<__end_node_pointer>(__dest);
1560
+ }
1223
1561
 
1224
- private:
1225
- _LIBCPP_HIDE_FROM_ABI static __node_pointer __detach_from_tree(__tree* __t) _NOEXCEPT;
1226
- _LIBCPP_HIDE_FROM_ABI static __node_pointer __detach_next(__node_pointer) _NOEXCEPT;
1562
+ return __dest;
1563
+ }
1227
1564
 
1228
- __tree* __t_;
1229
- __node_pointer __cache_root_;
1230
- __node_pointer __cache_elem_;
1231
- };
1232
- };
1565
+ _LIBCPP_HIDE_FROM_ABI __node_pointer __copy_assign_tree(__node_pointer __dest, __node_pointer __src) {
1566
+ return __assign_from_tree(
1567
+ __dest,
1568
+ __src,
1569
+ [](value_type& __lhs, const value_type& __rhs) { __assign_value(__lhs, __rhs); },
1570
+ [this](__node_pointer __nd) { return __copy_construct_tree(__nd); });
1571
+ }
1233
1572
 
1234
- template <class _Tp, class _Compare, class _Allocator>
1235
- __tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp) _NOEXCEPT_(
1236
- is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_copy_constructible<value_compare>::value)
1237
- : __size_(0), __value_comp_(__comp) {
1238
- __begin_node() = __end_node();
1239
- }
1573
+ _LIBCPP_HIDE_FROM_ABI __node_pointer __move_assign_tree(__node_pointer __dest, __node_pointer __src) {
1574
+ return __assign_from_tree(
1575
+ __dest,
1576
+ __src,
1577
+ [](value_type& __lhs, value_type& __rhs) { __assign_value(__lhs, std::move(__rhs)); },
1578
+ [this](__node_pointer __nd) { return __move_construct_tree(__nd); });
1579
+ }
1240
1580
 
1241
- template <class _Tp, class _Compare, class _Allocator>
1242
- __tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
1243
- : __begin_node_(), __node_alloc_(__node_allocator(__a)), __size_(0) {
1244
- __begin_node() = __end_node();
1245
- }
1581
+ friend struct __specialized_algorithm<_Algorithm::__for_each, __single_range<__tree> >;
1582
+ };
1246
1583
 
1584
+ #if _LIBCPP_STD_VER >= 14
1247
1585
  template <class _Tp, class _Compare, class _Allocator>
1248
- __tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp, const allocator_type& __a)
1249
- : __begin_node_(), __node_alloc_(__node_allocator(__a)), __size_(0), __value_comp_(__comp) {
1250
- __begin_node() = __end_node();
1251
- }
1586
+ struct __specialized_algorithm<_Algorithm::__for_each, __single_range<__tree<_Tp, _Compare, _Allocator> > > {
1587
+ static const bool __has_algorithm = true;
1252
1588
 
1253
- // Precondition: size() != 0
1254
- template <class _Tp, class _Compare, class _Allocator>
1255
- typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1256
- __tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_from_tree(__tree* __t) _NOEXCEPT {
1257
- __node_pointer __cache = static_cast<__node_pointer>(__t->__begin_node());
1258
- __t->__begin_node() = __t->__end_node();
1259
- __t->__end_node()->__left_->__parent_ = nullptr;
1260
- __t->__end_node()->__left_ = nullptr;
1261
- __t->size() = 0;
1262
- // __cache->__left_ == nullptr
1263
- if (__cache->__right_ != nullptr)
1264
- __cache = static_cast<__node_pointer>(__cache->__right_);
1265
- // __cache->__left_ == nullptr
1266
- // __cache->__right_ == nullptr
1267
- return __cache;
1268
- }
1589
+ using __node_pointer _LIBCPP_NODEBUG = typename __tree<_Tp, _Compare, _Allocator>::__node_pointer;
1269
1590
 
1270
- // Precondition: __cache != nullptr
1271
- // __cache->left_ == nullptr
1272
- // __cache->right_ == nullptr
1273
- // This is no longer a red-black tree
1274
- template <class _Tp, class _Compare, class _Allocator>
1275
- typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1276
- __tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_next(__node_pointer __cache) _NOEXCEPT {
1277
- if (__cache->__parent_ == nullptr)
1278
- return nullptr;
1279
- if (std::__tree_is_left_child(static_cast<__node_base_pointer>(__cache))) {
1280
- __cache->__parent_->__left_ = nullptr;
1281
- __cache = static_cast<__node_pointer>(__cache->__parent_);
1282
- if (__cache->__right_ == nullptr)
1283
- return __cache;
1284
- return static_cast<__node_pointer>(std::__tree_leaf(__cache->__right_));
1285
- }
1286
- // __cache is right child
1287
- __cache->__parent_unsafe()->__right_ = nullptr;
1288
- __cache = static_cast<__node_pointer>(__cache->__parent_);
1289
- if (__cache->__left_ == nullptr)
1290
- return __cache;
1291
- return static_cast<__node_pointer>(std::__tree_leaf(__cache->__left_));
1292
- }
1591
+ template <class _Tree, class _Func, class _Proj>
1592
+ _LIBCPP_HIDE_FROM_ABI static auto operator()(_Tree&& __range, _Func __func, _Proj __proj) {
1593
+ if (__range.size() != 0)
1594
+ std::__tree_iterate_from_root<__copy_cvref_t<_Tree, typename __remove_cvref_t<_Tree>::value_type>>(
1595
+ [](__node_pointer) { return false; }, __range.__root(), __func, __proj);
1596
+ return std::make_pair(__range.end(), std::move(__func));
1597
+ }
1598
+ };
1599
+ #endif
1293
1600
 
1294
1601
  template <class _Tp, class _Compare, class _Allocator>
1295
1602
  __tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t) {
1296
- if (this != std::addressof(__t)) {
1297
- value_comp() = __t.value_comp();
1298
- __copy_assign_alloc(__t);
1299
- __assign_multi(__t.begin(), __t.end());
1300
- }
1301
- return *this;
1302
- }
1603
+ if (this == std::addressof(__t))
1604
+ return *this;
1303
1605
 
1304
- template <class _Tp, class _Compare, class _Allocator>
1305
- template <class _ForwardIterator>
1306
- void __tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _ForwardIterator __last) {
1307
- typedef iterator_traits<_ForwardIterator> _ITraits;
1308
- typedef typename _ITraits::value_type _ItValueType;
1309
- static_assert(
1310
- is_same<_ItValueType, value_type>::value, "__assign_unique may only be called with the containers value type");
1311
- static_assert(
1312
- __has_forward_iterator_category<_ForwardIterator>::value, "__assign_unique requires a forward iterator");
1313
- if (size() != 0) {
1314
- _DetachedTreeCache __cache(this);
1315
- for (; __cache.__get() != nullptr && __first != __last; ++__first) {
1316
- if (__node_assign_unique(*__first, __cache.__get()).second)
1317
- __cache.__advance();
1318
- }
1319
- }
1320
- for (; __first != __last; ++__first)
1321
- __emplace_unique(*__first);
1322
- }
1606
+ value_comp() = __t.value_comp();
1607
+ __copy_assign_alloc(__t);
1323
1608
 
1324
- template <class _Tp, class _Compare, class _Allocator>
1325
- template <class _InputIterator>
1326
- void __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last) {
1327
- typedef iterator_traits<_InputIterator> _ITraits;
1328
- typedef typename _ITraits::value_type _ItValueType;
1329
- static_assert(
1330
- is_same<_ItValueType, value_type>::value, "__assign_multi may only be called with the containers value_type");
1331
- if (size() != 0) {
1332
- _DetachedTreeCache __cache(this);
1333
- for (; __cache.__get() && __first != __last; ++__first) {
1334
- __assign_value(__cache.__get()->__value_, *__first);
1335
- __node_insert_multi(__cache.__get());
1336
- __cache.__advance();
1337
- }
1609
+ if (__size_ != 0) {
1610
+ *__root_ptr() = static_cast<__node_base_pointer>(__copy_assign_tree(__root(), __t.__root()));
1611
+ } else {
1612
+ *__root_ptr() = static_cast<__node_base_pointer>(__copy_construct_tree(__t.__root()));
1613
+ if (__root())
1614
+ __root()->__parent_ = __end_node();
1338
1615
  }
1339
- const_iterator __e = end();
1340
- for (; __first != __last; ++__first)
1341
- __emplace_hint_multi(__e, *__first);
1616
+ __begin_node_ =
1617
+ __end_node()->__left_ ? static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_)) : __end_node();
1618
+ __size_ = __t.size();
1619
+
1620
+ return *this;
1342
1621
  }
1343
1622
 
1344
1623
  template <class _Tp, class _Compare, class _Allocator>
1345
1624
  __tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
1346
- : __begin_node_(),
1625
+ : __begin_node_(__end_node()),
1347
1626
  __node_alloc_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())),
1348
1627
  __size_(0),
1349
1628
  __value_comp_(__t.value_comp()) {
1350
- __begin_node() = __end_node();
1629
+ if (__t.size() == 0)
1630
+ return;
1631
+
1632
+ *__root_ptr() = static_cast<__node_base_pointer>(__copy_construct_tree(__t.__root()));
1633
+ __root()->__parent_ = __end_node();
1634
+ __begin_node_ = static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_));
1635
+ __size_ = __t.size();
1351
1636
  }
1352
1637
 
1353
1638
  template <class _Tp, class _Compare, class _Allocator>
@@ -1358,33 +1643,38 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_(
1358
1643
  __node_alloc_(std::move(__t.__node_alloc_)),
1359
1644
  __size_(__t.__size_),
1360
1645
  __value_comp_(std::move(__t.__value_comp_)) {
1361
- if (size() == 0)
1362
- __begin_node() = __end_node();
1646
+ if (__size_ == 0)
1647
+ __begin_node_ = __end_node();
1363
1648
  else {
1364
1649
  __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
1365
- __t.__begin_node() = __t.__end_node();
1650
+ __t.__begin_node_ = __t.__end_node();
1366
1651
  __t.__end_node()->__left_ = nullptr;
1367
- __t.size() = 0;
1652
+ __t.__size_ = 0;
1368
1653
  }
1369
1654
  }
1370
1655
 
1371
1656
  template <class _Tp, class _Compare, class _Allocator>
1372
1657
  __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
1373
- : __node_alloc_(__node_allocator(__a)), __size_(0), __value_comp_(std::move(__t.value_comp())) {
1658
+ : __begin_node_(__end_node()),
1659
+ __node_alloc_(__node_allocator(__a)),
1660
+ __size_(0),
1661
+ __value_comp_(std::move(__t.value_comp())) {
1662
+ if (__t.size() == 0)
1663
+ return;
1374
1664
  if (__a == __t.__alloc()) {
1375
- if (__t.size() == 0)
1376
- __begin_node() = __end_node();
1377
- else {
1378
- __begin_node() = __t.__begin_node();
1379
- __end_node()->__left_ = __t.__end_node()->__left_;
1380
- __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
1381
- size() = __t.size();
1382
- __t.__begin_node() = __t.__end_node();
1383
- __t.__end_node()->__left_ = nullptr;
1384
- __t.size() = 0;
1385
- }
1665
+ __begin_node_ = __t.__begin_node_;
1666
+ __end_node()->__left_ = __t.__end_node()->__left_;
1667
+ __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
1668
+ __size_ = __t.__size_;
1669
+ __t.__begin_node_ = __t.__end_node();
1670
+ __t.__end_node()->__left_ = nullptr;
1671
+ __t.__size_ = 0;
1386
1672
  } else {
1387
- __begin_node() = __end_node();
1673
+ *__root_ptr() = static_cast<__node_base_pointer>(__move_construct_tree(__t.__root()));
1674
+ __root()->__parent_ = __end_node();
1675
+ __begin_node_ = static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_));
1676
+ __size_ = __t.size();
1677
+ __t.clear(); // Ensure that __t is in a valid state after moving out the keys
1388
1678
  }
1389
1679
  }
1390
1680
 
@@ -1397,61 +1687,33 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
1397
1687
  __move_assign_alloc(__t);
1398
1688
  __size_ = __t.__size_;
1399
1689
  __value_comp_ = std::move(__t.__value_comp_);
1400
- if (size() == 0)
1401
- __begin_node() = __end_node();
1690
+ if (__size_ == 0)
1691
+ __begin_node_ = __end_node();
1402
1692
  else {
1403
1693
  __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
1404
- __t.__begin_node() = __t.__end_node();
1694
+ __t.__begin_node_ = __t.__end_node();
1405
1695
  __t.__end_node()->__left_ = nullptr;
1406
- __t.size() = 0;
1696
+ __t.__size_ = 0;
1407
1697
  }
1408
1698
  }
1409
1699
 
1410
1700
  template <class _Tp, class _Compare, class _Allocator>
1411
1701
  void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
1412
- if (__node_alloc() == __t.__node_alloc())
1702
+ if (__node_alloc() == __t.__node_alloc()) {
1413
1703
  __move_assign(__t, true_type());
1414
- else {
1415
- value_comp() = std::move(__t.value_comp());
1416
- const_iterator __e = end();
1417
- if (size() != 0) {
1418
- _DetachedTreeCache __cache(this);
1419
- while (__cache.__get() != nullptr && __t.size() != 0) {
1420
- __assign_value(__cache.__get()->__value_, std::move(__t.remove(__t.begin())->__value_));
1421
- __node_insert_multi(__cache.__get());
1422
- __cache.__advance();
1423
- }
1424
- }
1425
- while (__t.size() != 0) {
1426
- __insert_multi_from_orphaned_node(__e, std::move(__t.remove(__t.begin())->__value_));
1704
+ } else {
1705
+ value_comp() = std::move(__t.value_comp());
1706
+ if (__size_ != 0) {
1707
+ *__root_ptr() = static_cast<__node_base_pointer>(__move_assign_tree(__root(), __t.__root()));
1708
+ } else {
1709
+ *__root_ptr() = static_cast<__node_base_pointer>(__move_construct_tree(__t.__root()));
1710
+ if (__root())
1711
+ __root()->__parent_ = __end_node();
1427
1712
  }
1428
- }
1429
- }
1430
-
1431
- template <class _Tp, class _Compare, class _Allocator>
1432
- __tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
1433
- _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1434
- ((__node_traits::propagate_on_container_move_assignment::value &&
1435
- is_nothrow_move_assignable<__node_allocator>::value) ||
1436
- allocator_traits<__node_allocator>::is_always_equal::value)) {
1437
- __move_assign(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
1438
- return *this;
1439
- }
1440
-
1441
- template <class _Tp, class _Compare, class _Allocator>
1442
- __tree<_Tp, _Compare, _Allocator>::~__tree() {
1443
- static_assert(is_copy_constructible<value_compare>::value, "Comparator must be copy-constructible.");
1444
- destroy(__root());
1445
- }
1446
-
1447
- template <class _Tp, class _Compare, class _Allocator>
1448
- void __tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT {
1449
- if (__nd != nullptr) {
1450
- destroy(static_cast<__node_pointer>(__nd->__left_));
1451
- destroy(static_cast<__node_pointer>(__nd->__right_));
1452
- __node_allocator& __na = __node_alloc();
1453
- __node_traits::destroy(__na, std::addressof(__nd->__value_));
1454
- __node_traits::deallocate(__na, __nd, 1);
1713
+ __begin_node_ =
1714
+ __end_node()->__left_ ? static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_)) : __end_node();
1715
+ __size_ = __t.size();
1716
+ __t.clear(); // Ensure that __t is in a valid state after moving out the keys
1455
1717
  }
1456
1718
  }
1457
1719
 
@@ -1470,12 +1732,12 @@ void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
1470
1732
  std::__swap_allocator(__node_alloc(), __t.__node_alloc());
1471
1733
  swap(__size_, __t.__size_);
1472
1734
  swap(__value_comp_, __t.__value_comp_);
1473
- if (size() == 0)
1474
- __begin_node() = __end_node();
1735
+ if (__size_ == 0)
1736
+ __begin_node_ = __end_node();
1475
1737
  else
1476
1738
  __end_node()->__left_->__parent_ = __end_node();
1477
- if (__t.size() == 0)
1478
- __t.__begin_node() = __t.__end_node();
1739
+ if (__t.__size_ == 0)
1740
+ __t.__begin_node_ = __t.__end_node();
1479
1741
  else
1480
1742
  __t.__end_node()->__left_->__parent_ = __t.__end_node();
1481
1743
  }
@@ -1483,8 +1745,8 @@ void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
1483
1745
  template <class _Tp, class _Compare, class _Allocator>
1484
1746
  void __tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT {
1485
1747
  destroy(__root());
1486
- size() = 0;
1487
- __begin_node() = __end_node();
1748
+ __size_ = 0;
1749
+ __begin_node_ = __end_node();
1488
1750
  __end_node()->__left_ = nullptr;
1489
1751
  }
1490
1752
 
@@ -1497,7 +1759,7 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__end_node_pointer& __parent,
1497
1759
  __node_pointer __nd = __root();
1498
1760
  if (__nd != nullptr) {
1499
1761
  while (true) {
1500
- if (value_comp()(__nd->__value_, __v)) {
1762
+ if (value_comp()(__nd->__get_value(), __v)) {
1501
1763
  if (__nd->__right_ != nullptr)
1502
1764
  __nd = static_cast<__node_pointer>(__nd->__right_);
1503
1765
  else {
@@ -1527,7 +1789,7 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__end_node_pointer& __parent
1527
1789
  __node_pointer __nd = __root();
1528
1790
  if (__nd != nullptr) {
1529
1791
  while (true) {
1530
- if (value_comp()(__v, __nd->__value_)) {
1792
+ if (value_comp()(__v, __nd->__get_value())) {
1531
1793
  if (__nd->__left_ != nullptr)
1532
1794
  __nd = static_cast<__node_pointer>(__nd->__left_);
1533
1795
  else {
@@ -1578,92 +1840,91 @@ typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Co
1578
1840
  return __find_leaf_low(__parent, __v);
1579
1841
  }
1580
1842
 
1581
- // Find place to insert if __v doesn't exist
1582
- // Set __parent to parent of null leaf
1583
- // Return reference to null leaf
1584
- // If __v exists, set parent to node of __v and return reference to node of __v
1843
+ // Find __v
1844
+ // If __v exists, return the parent of the node of __v and a reference to the pointer to the node of __v.
1845
+ // If __v doesn't exist, return the parent of the null leaf and a reference to the pointer to the null leaf.
1585
1846
  template <class _Tp, class _Compare, class _Allocator>
1586
1847
  template <class _Key>
1587
- typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1588
- __tree<_Tp, _Compare, _Allocator>::__find_equal(__end_node_pointer& __parent, const _Key& __v) {
1589
- __node_pointer __nd = __root();
1590
- __node_base_pointer* __nd_ptr = __root_ptr();
1591
- if (__nd != nullptr) {
1592
- while (true) {
1593
- if (value_comp()(__v, __nd->__value_)) {
1594
- if (__nd->__left_ != nullptr) {
1595
- __nd_ptr = std::addressof(__nd->__left_);
1596
- __nd = static_cast<__node_pointer>(__nd->__left_);
1597
- } else {
1598
- __parent = static_cast<__end_node_pointer>(__nd);
1599
- return __parent->__left_;
1600
- }
1601
- } else if (value_comp()(__nd->__value_, __v)) {
1602
- if (__nd->__right_ != nullptr) {
1603
- __nd_ptr = std::addressof(__nd->__right_);
1604
- __nd = static_cast<__node_pointer>(__nd->__right_);
1605
- } else {
1606
- __parent = static_cast<__end_node_pointer>(__nd);
1607
- return __nd->__right_;
1608
- }
1609
- } else {
1610
- __parent = static_cast<__end_node_pointer>(__nd);
1611
- return *__nd_ptr;
1612
- }
1848
+ _LIBCPP_HIDE_FROM_ABI pair<typename __tree<_Tp, _Compare, _Allocator>::__end_node_pointer,
1849
+ typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&>
1850
+ __tree<_Tp, _Compare, _Allocator>::__find_equal(const _Key& __v) {
1851
+ using _Pair = pair<__end_node_pointer, __node_base_pointer&>;
1852
+
1853
+ __node_pointer __nd = __root();
1854
+
1855
+ if (__nd == nullptr) {
1856
+ auto __end = __end_node();
1857
+ return _Pair(__end, __end->__left_);
1858
+ }
1859
+
1860
+ __node_base_pointer* __node_ptr = __root_ptr();
1861
+ auto&& __transparent = std::__as_transparent<_Key>(value_comp());
1862
+ auto __comp =
1863
+ __lazy_synth_three_way_comparator<__make_transparent_t<_Key, _Compare>, _Key, value_type>(__transparent);
1864
+
1865
+ while (true) {
1866
+ auto __comp_res = __comp(__v, __nd->__get_value());
1867
+
1868
+ if (__comp_res.__less()) {
1869
+ if (__nd->__left_ == nullptr)
1870
+ return _Pair(static_cast<__end_node_pointer>(__nd), __nd->__left_);
1871
+
1872
+ __node_ptr = std::addressof(__nd->__left_);
1873
+ __nd = static_cast<__node_pointer>(__nd->__left_);
1874
+ } else if (__comp_res.__greater()) {
1875
+ if (__nd->__right_ == nullptr)
1876
+ return _Pair(static_cast<__end_node_pointer>(__nd), __nd->__right_);
1877
+
1878
+ __node_ptr = std::addressof(__nd->__right_);
1879
+ __nd = static_cast<__node_pointer>(__nd->__right_);
1880
+ } else {
1881
+ return _Pair(static_cast<__end_node_pointer>(__nd), *__node_ptr);
1613
1882
  }
1614
1883
  }
1615
- __parent = __end_node();
1616
- return __parent->__left_;
1617
1884
  }
1618
1885
 
1619
- // Find place to insert if __v doesn't exist
1886
+ // Find __v
1620
1887
  // First check prior to __hint.
1621
1888
  // Next check after __hint.
1622
1889
  // Next do O(log N) search.
1623
- // Set __parent to parent of null leaf
1624
- // Return reference to null leaf
1625
- // If __v exists, set parent to node of __v and return reference to node of __v
1890
+ // If __v exists, return the parent of the node of __v and a reference to the pointer to the node of __v.
1891
+ // If __v doesn't exist, return the parent of the null leaf and a reference to the pointer to the null leaf.
1626
1892
  template <class _Tp, class _Compare, class _Allocator>
1627
1893
  template <class _Key>
1628
- typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_equal(
1629
- const_iterator __hint, __end_node_pointer& __parent, __node_base_pointer& __dummy, const _Key& __v) {
1630
- if (__hint == end() || value_comp()(__v, *__hint)) // check before
1631
- {
1894
+ _LIBCPP_HIDE_FROM_ABI pair<typename __tree<_Tp, _Compare, _Allocator>::__end_node_pointer,
1895
+ typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&>
1896
+ __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, __node_base_pointer& __dummy, const _Key& __v) {
1897
+ using _Pair = pair<__end_node_pointer, __node_base_pointer&>;
1898
+
1899
+ if (__hint == end() || value_comp()(__v, *__hint)) { // check before
1632
1900
  // __v < *__hint
1633
1901
  const_iterator __prior = __hint;
1634
1902
  if (__prior == begin() || value_comp()(*--__prior, __v)) {
1635
1903
  // *prev(__hint) < __v < *__hint
1636
- if (__hint.__ptr_->__left_ == nullptr) {
1637
- __parent = __hint.__ptr_;
1638
- return __parent->__left_;
1639
- } else {
1640
- __parent = __prior.__ptr_;
1641
- return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
1642
- }
1904
+ if (__hint.__ptr_->__left_ == nullptr)
1905
+ return _Pair(__hint.__ptr_, __hint.__ptr_->__left_);
1906
+ return _Pair(__prior.__ptr_, static_cast<__node_pointer>(__prior.__ptr_)->__right_);
1643
1907
  }
1644
1908
  // __v <= *prev(__hint)
1645
- return __find_equal(__parent, __v);
1646
- } else if (value_comp()(*__hint, __v)) // check after
1647
- {
1909
+ return __find_equal(__v);
1910
+ }
1911
+
1912
+ if (value_comp()(*__hint, __v)) { // check after
1648
1913
  // *__hint < __v
1649
1914
  const_iterator __next = std::next(__hint);
1650
1915
  if (__next == end() || value_comp()(__v, *__next)) {
1651
1916
  // *__hint < __v < *std::next(__hint)
1652
- if (__hint.__get_np()->__right_ == nullptr) {
1653
- __parent = __hint.__ptr_;
1654
- return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_;
1655
- } else {
1656
- __parent = __next.__ptr_;
1657
- return __parent->__left_;
1658
- }
1917
+ if (__hint.__get_np()->__right_ == nullptr)
1918
+ return _Pair(__hint.__ptr_, static_cast<__node_pointer>(__hint.__ptr_)->__right_);
1919
+ return _Pair(__next.__ptr_, __next.__ptr_->__left_);
1659
1920
  }
1660
1921
  // *next(__hint) <= __v
1661
- return __find_equal(__parent, __v);
1922
+ return __find_equal(__v);
1662
1923
  }
1924
+
1663
1925
  // else __v == *__hint
1664
- __parent = __hint.__ptr_;
1665
- __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
1666
- return __dummy;
1926
+ __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
1927
+ return _Pair(__hint.__ptr_, __dummy);
1667
1928
  }
1668
1929
 
1669
1930
  template <class _Tp, class _Compare, class _Allocator>
@@ -1674,46 +1935,10 @@ void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
1674
1935
  __new_node->__parent_ = __parent;
1675
1936
  // __new_node->__is_black_ is initialized in __tree_balance_after_insert
1676
1937
  __child = __new_node;
1677
- if (__begin_node()->__left_ != nullptr)
1678
- __begin_node() = static_cast<__end_node_pointer>(__begin_node()->__left_);
1938
+ if (__begin_node_->__left_ != nullptr)
1939
+ __begin_node_ = static_cast<__end_node_pointer>(__begin_node_->__left_);
1679
1940
  std::__tree_balance_after_insert(__end_node()->__left_, __child);
1680
- ++size();
1681
- }
1682
-
1683
- template <class _Tp, class _Compare, class _Allocator>
1684
- template <class _Key, class... _Args>
1685
- pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1686
- __tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) {
1687
- __end_node_pointer __parent;
1688
- __node_base_pointer& __child = __find_equal(__parent, __k);
1689
- __node_pointer __r = static_cast<__node_pointer>(__child);
1690
- bool __inserted = false;
1691
- if (__child == nullptr) {
1692
- __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
1693
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1694
- __r = __h.release();
1695
- __inserted = true;
1696
- }
1697
- return pair<iterator, bool>(iterator(__r), __inserted);
1698
- }
1699
-
1700
- template <class _Tp, class _Compare, class _Allocator>
1701
- template <class _Key, class... _Args>
1702
- pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1703
- __tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
1704
- const_iterator __p, _Key const& __k, _Args&&... __args) {
1705
- __end_node_pointer __parent;
1706
- __node_base_pointer __dummy;
1707
- __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k);
1708
- __node_pointer __r = static_cast<__node_pointer>(__child);
1709
- bool __inserted = false;
1710
- if (__child == nullptr) {
1711
- __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
1712
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1713
- __r = __h.release();
1714
- __inserted = true;
1715
- }
1716
- return pair<iterator, bool>(iterator(__r), __inserted);
1941
+ ++__size_;
1717
1942
  }
1718
1943
 
1719
1944
  template <class _Tp, class _Compare, class _Allocator>
@@ -1722,51 +1947,18 @@ typename __tree<_Tp, _Compare, _Allocator>::__node_holder
1722
1947
  __tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&&... __args) {
1723
1948
  __node_allocator& __na = __node_alloc();
1724
1949
  __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1725
- __node_traits::construct(__na, std::addressof(__h->__value_), std::forward<_Args>(__args)...);
1950
+ std::__construct_at(std::addressof(*__h), __na, std::forward<_Args>(__args)...);
1726
1951
  __h.get_deleter().__value_constructed = true;
1727
1952
  return __h;
1728
1953
  }
1729
1954
 
1730
- template <class _Tp, class _Compare, class _Allocator>
1731
- template <class... _Args>
1732
- pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1733
- __tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) {
1734
- __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
1735
- __end_node_pointer __parent;
1736
- __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
1737
- __node_pointer __r = static_cast<__node_pointer>(__child);
1738
- bool __inserted = false;
1739
- if (__child == nullptr) {
1740
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1741
- __r = __h.release();
1742
- __inserted = true;
1743
- }
1744
- return pair<iterator, bool>(iterator(__r), __inserted);
1745
- }
1746
-
1747
- template <class _Tp, class _Compare, class _Allocator>
1748
- template <class... _Args>
1749
- typename __tree<_Tp, _Compare, _Allocator>::iterator
1750
- __tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args) {
1751
- __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
1752
- __end_node_pointer __parent;
1753
- __node_base_pointer __dummy;
1754
- __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
1755
- __node_pointer __r = static_cast<__node_pointer>(__child);
1756
- if (__child == nullptr) {
1757
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1758
- __r = __h.release();
1759
- }
1760
- return iterator(__r);
1761
- }
1762
-
1763
1955
  template <class _Tp, class _Compare, class _Allocator>
1764
1956
  template <class... _Args>
1765
1957
  typename __tree<_Tp, _Compare, _Allocator>::iterator
1766
1958
  __tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) {
1767
1959
  __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
1768
1960
  __end_node_pointer __parent;
1769
- __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
1961
+ __node_base_pointer& __child = __find_leaf_high(__parent, __h->__get_value());
1770
1962
  __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1771
1963
  return iterator(static_cast<__node_pointer>(__h.release()));
1772
1964
  }
@@ -1777,53 +1969,19 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator
1777
1969
  __tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, _Args&&... __args) {
1778
1970
  __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
1779
1971
  __end_node_pointer __parent;
1780
- __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
1972
+ __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__get_value());
1781
1973
  __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1782
1974
  return iterator(static_cast<__node_pointer>(__h.release()));
1783
1975
  }
1784
1976
 
1785
- template <class _Tp, class _Compare, class _Allocator>
1786
- pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1787
- __tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const value_type& __v, __node_pointer __nd) {
1788
- __end_node_pointer __parent;
1789
- __node_base_pointer& __child = __find_equal(__parent, __v);
1790
- __node_pointer __r = static_cast<__node_pointer>(__child);
1791
- bool __inserted = false;
1792
- if (__child == nullptr) {
1793
- __assign_value(__nd->__value_, __v);
1794
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
1795
- __r = __nd;
1796
- __inserted = true;
1797
- }
1798
- return pair<iterator, bool>(iterator(__r), __inserted);
1799
- }
1800
-
1801
- template <class _Tp, class _Compare, class _Allocator>
1802
- typename __tree<_Tp, _Compare, _Allocator>::iterator
1803
- __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) {
1804
- __end_node_pointer __parent;
1805
- __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_);
1806
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
1807
- return iterator(__nd);
1808
- }
1809
-
1810
- template <class _Tp, class _Compare, class _Allocator>
1811
- typename __tree<_Tp, _Compare, _Allocator>::iterator
1812
- __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, __node_pointer __nd) {
1813
- __end_node_pointer __parent;
1814
- __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_);
1815
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
1816
- return iterator(__nd);
1817
- }
1818
-
1819
1977
  template <class _Tp, class _Compare, class _Allocator>
1820
1978
  typename __tree<_Tp, _Compare, _Allocator>::iterator
1821
1979
  __tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT {
1822
1980
  iterator __r(__ptr);
1823
1981
  ++__r;
1824
- if (__begin_node() == __ptr)
1825
- __begin_node() = __r.__ptr_;
1826
- --size();
1982
+ if (__begin_node_ == __ptr)
1983
+ __begin_node_ = __r.__ptr_;
1984
+ --__size_;
1827
1985
  std::__tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__ptr));
1828
1986
  return __r;
1829
1987
  }
@@ -1837,8 +1995,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(_NodeHandle&& __n
1837
1995
  return _InsertReturnType{end(), false, _NodeHandle()};
1838
1996
 
1839
1997
  __node_pointer __ptr = __nh.__ptr_;
1840
- __end_node_pointer __parent;
1841
- __node_base_pointer& __child = __find_equal(__parent, __ptr->__value_);
1998
+ auto [__parent, __child] = __find_equal(__ptr->__get_value());
1842
1999
  if (__child != nullptr)
1843
2000
  return _InsertReturnType{iterator(static_cast<__node_pointer>(__child)), false, std::move(__nh)};
1844
2001
 
@@ -1855,10 +2012,9 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(const_iterator __
1855
2012
  return end();
1856
2013
 
1857
2014
  __node_pointer __ptr = __nh.__ptr_;
1858
- __end_node_pointer __parent;
1859
2015
  __node_base_pointer __dummy;
1860
- __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy, __ptr->__value_);
1861
- __node_pointer __r = static_cast<__node_pointer>(__child);
2016
+ auto [__parent, __child] = __find_equal(__hint, __dummy, __ptr->__get_value());
2017
+ __node_pointer __r = static_cast<__node_pointer>(__child);
1862
2018
  if (__child == nullptr) {
1863
2019
  __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
1864
2020
  __r = __ptr;
@@ -1885,14 +2041,12 @@ _LIBCPP_HIDE_FROM_ABI _NodeHandle __tree<_Tp, _Compare, _Allocator>::__node_hand
1885
2041
  }
1886
2042
 
1887
2043
  template <class _Tp, class _Compare, class _Allocator>
1888
- template <class _Tree>
1889
- _LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source) {
1890
- static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
1891
-
1892
- for (typename _Tree::iterator __i = __source.begin(); __i != __source.end();) {
2044
+ template <class _Comp2>
2045
+ _LIBCPP_HIDE_FROM_ABI void
2046
+ __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(__tree<_Tp, _Comp2, _Allocator>& __source) {
2047
+ for (iterator __i = __source.begin(); __i != __source.end();) {
1893
2048
  __node_pointer __src_ptr = __i.__get_np();
1894
- __end_node_pointer __parent;
1895
- __node_base_pointer& __child = __find_equal(__parent, __src_ptr->__value_);
2049
+ auto [__parent, __child] = __find_equal(__src_ptr->__get_value());
1896
2050
  ++__i;
1897
2051
  if (__child != nullptr)
1898
2052
  continue;
@@ -1909,7 +2063,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh
1909
2063
  return end();
1910
2064
  __node_pointer __ptr = __nh.__ptr_;
1911
2065
  __end_node_pointer __parent;
1912
- __node_base_pointer& __child = __find_leaf_high(__parent, __ptr->__value_);
2066
+ __node_base_pointer& __child = __find_leaf_high(__parent, __ptr->__get_value());
1913
2067
  __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
1914
2068
  __nh.__release_ptr();
1915
2069
  return iterator(__ptr);
@@ -1924,21 +2078,20 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(const_iterator __h
1924
2078
 
1925
2079
  __node_pointer __ptr = __nh.__ptr_;
1926
2080
  __end_node_pointer __parent;
1927
- __node_base_pointer& __child = __find_leaf(__hint, __parent, __ptr->__value_);
2081
+ __node_base_pointer& __child = __find_leaf(__hint, __parent, __ptr->__get_value());
1928
2082
  __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
1929
2083
  __nh.__release_ptr();
1930
2084
  return iterator(__ptr);
1931
2085
  }
1932
2086
 
1933
2087
  template <class _Tp, class _Compare, class _Allocator>
1934
- template <class _Tree>
1935
- _LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source) {
1936
- static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
1937
-
1938
- for (typename _Tree::iterator __i = __source.begin(); __i != __source.end();) {
2088
+ template <class _Comp2>
2089
+ _LIBCPP_HIDE_FROM_ABI void
2090
+ __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(__tree<_Tp, _Comp2, _Allocator>& __source) {
2091
+ for (iterator __i = __source.begin(); __i != __source.end();) {
1939
2092
  __node_pointer __src_ptr = __i.__get_np();
1940
2093
  __end_node_pointer __parent;
1941
- __node_base_pointer& __child = __find_leaf_high(__parent, __src_ptr->__value_);
2094
+ __node_base_pointer& __child = __find_leaf_high(__parent, __src_ptr->__get_value());
1942
2095
  ++__i;
1943
2096
  __source.__remove_node_pointer(__src_ptr);
1944
2097
  __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__src_ptr));
@@ -1987,34 +2140,17 @@ __tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k) {
1987
2140
  return __r;
1988
2141
  }
1989
2142
 
1990
- template <class _Tp, class _Compare, class _Allocator>
1991
- template <class _Key>
1992
- typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) {
1993
- iterator __p = __lower_bound(__v, __root(), __end_node());
1994
- if (__p != end() && !value_comp()(__v, *__p))
1995
- return __p;
1996
- return end();
1997
- }
1998
-
1999
- template <class _Tp, class _Compare, class _Allocator>
2000
- template <class _Key>
2001
- typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2002
- __tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const {
2003
- const_iterator __p = __lower_bound(__v, __root(), __end_node());
2004
- if (__p != end() && !value_comp()(__v, *__p))
2005
- return __p;
2006
- return end();
2007
- }
2008
-
2009
2143
  template <class _Tp, class _Compare, class _Allocator>
2010
2144
  template <class _Key>
2011
2145
  typename __tree<_Tp, _Compare, _Allocator>::size_type
2012
2146
  __tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const {
2013
2147
  __node_pointer __rt = __root();
2148
+ auto __comp = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
2014
2149
  while (__rt != nullptr) {
2015
- if (value_comp()(__k, __rt->__value_)) {
2150
+ auto __comp_res = __comp(__k, __rt->__get_value());
2151
+ if (__comp_res.__less()) {
2016
2152
  __rt = static_cast<__node_pointer>(__rt->__left_);
2017
- } else if (value_comp()(__rt->__value_, __k))
2153
+ } else if (__comp_res.__greater())
2018
2154
  __rt = static_cast<__node_pointer>(__rt->__right_);
2019
2155
  else
2020
2156
  return 1;
@@ -2028,26 +2164,28 @@ typename __tree<_Tp, _Compare, _Allocator>::size_type
2028
2164
  __tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const {
2029
2165
  __end_node_pointer __result = __end_node();
2030
2166
  __node_pointer __rt = __root();
2167
+ auto __comp = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
2031
2168
  while (__rt != nullptr) {
2032
- if (value_comp()(__k, __rt->__value_)) {
2169
+ auto __comp_res = __comp(__k, __rt->__get_value());
2170
+ if (__comp_res.__less()) {
2033
2171
  __result = static_cast<__end_node_pointer>(__rt);
2034
2172
  __rt = static_cast<__node_pointer>(__rt->__left_);
2035
- } else if (value_comp()(__rt->__value_, __k))
2173
+ } else if (__comp_res.__greater())
2036
2174
  __rt = static_cast<__node_pointer>(__rt->__right_);
2037
2175
  else
2038
2176
  return std::distance(
2039
- __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
2040
- __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2177
+ __lower_bound_multi(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
2178
+ __upper_bound_multi(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2041
2179
  }
2042
2180
  return 0;
2043
2181
  }
2044
2182
 
2045
2183
  template <class _Tp, class _Compare, class _Allocator>
2046
2184
  template <class _Key>
2047
- typename __tree<_Tp, _Compare, _Allocator>::iterator
2048
- __tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
2185
+ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound_multi(
2186
+ const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
2049
2187
  while (__root != nullptr) {
2050
- if (!value_comp()(__root->__value_, __v)) {
2188
+ if (!value_comp()(__root->__get_value(), __v)) {
2051
2189
  __result = static_cast<__end_node_pointer>(__root);
2052
2190
  __root = static_cast<__node_pointer>(__root->__left_);
2053
2191
  } else
@@ -2058,10 +2196,10 @@ __tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, __node_pointer
2058
2196
 
2059
2197
  template <class _Tp, class _Compare, class _Allocator>
2060
2198
  template <class _Key>
2061
- typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound(
2199
+ typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound_multi(
2062
2200
  const _Key& __v, __node_pointer __root, __end_node_pointer __result) const {
2063
2201
  while (__root != nullptr) {
2064
- if (!value_comp()(__root->__value_, __v)) {
2202
+ if (!value_comp()(__root->__get_value(), __v)) {
2065
2203
  __result = static_cast<__end_node_pointer>(__root);
2066
2204
  __root = static_cast<__node_pointer>(__root->__left_);
2067
2205
  } else
@@ -2072,10 +2210,10 @@ typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare,
2072
2210
 
2073
2211
  template <class _Tp, class _Compare, class _Allocator>
2074
2212
  template <class _Key>
2075
- typename __tree<_Tp, _Compare, _Allocator>::iterator
2076
- __tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
2213
+ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound_multi(
2214
+ const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
2077
2215
  while (__root != nullptr) {
2078
- if (value_comp()(__v, __root->__value_)) {
2216
+ if (value_comp()(__v, __root->__get_value())) {
2079
2217
  __result = static_cast<__end_node_pointer>(__root);
2080
2218
  __root = static_cast<__node_pointer>(__root->__left_);
2081
2219
  } else
@@ -2086,10 +2224,10 @@ __tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, __node_pointer
2086
2224
 
2087
2225
  template <class _Tp, class _Compare, class _Allocator>
2088
2226
  template <class _Key>
2089
- typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound(
2227
+ typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound_multi(
2090
2228
  const _Key& __v, __node_pointer __root, __end_node_pointer __result) const {
2091
2229
  while (__root != nullptr) {
2092
- if (value_comp()(__v, __root->__value_)) {
2230
+ if (value_comp()(__v, __root->__get_value())) {
2093
2231
  __result = static_cast<__end_node_pointer>(__root);
2094
2232
  __root = static_cast<__node_pointer>(__root->__left_);
2095
2233
  } else
@@ -2102,14 +2240,16 @@ template <class _Tp, class _Compare, class _Allocator>
2102
2240
  template <class _Key>
2103
2241
  pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator>
2104
2242
  __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) {
2105
- typedef pair<iterator, iterator> _Pp;
2243
+ using _Pp = pair<iterator, iterator>;
2106
2244
  __end_node_pointer __result = __end_node();
2107
2245
  __node_pointer __rt = __root();
2246
+ auto __comp = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
2108
2247
  while (__rt != nullptr) {
2109
- if (value_comp()(__k, __rt->__value_)) {
2248
+ auto __comp_res = __comp(__k, __rt->__get_value());
2249
+ if (__comp_res.__less()) {
2110
2250
  __result = static_cast<__end_node_pointer>(__rt);
2111
2251
  __rt = static_cast<__node_pointer>(__rt->__left_);
2112
- } else if (value_comp()(__rt->__value_, __k))
2252
+ } else if (__comp_res.__greater())
2113
2253
  __rt = static_cast<__node_pointer>(__rt->__right_);
2114
2254
  else
2115
2255
  return _Pp(iterator(__rt),
@@ -2124,14 +2264,16 @@ template <class _Key>
2124
2264
  pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2125
2265
  typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2126
2266
  __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const {
2127
- typedef pair<const_iterator, const_iterator> _Pp;
2267
+ using _Pp = pair<const_iterator, const_iterator>;
2128
2268
  __end_node_pointer __result = __end_node();
2129
2269
  __node_pointer __rt = __root();
2270
+ auto __comp = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
2130
2271
  while (__rt != nullptr) {
2131
- if (value_comp()(__k, __rt->__value_)) {
2272
+ auto __comp_res = __comp(__k, __rt->__get_value());
2273
+ if (__comp_res.__less()) {
2132
2274
  __result = static_cast<__end_node_pointer>(__rt);
2133
2275
  __rt = static_cast<__node_pointer>(__rt->__left_);
2134
- } else if (value_comp()(__rt->__value_, __k))
2276
+ } else if (__comp_res.__greater())
2135
2277
  __rt = static_cast<__node_pointer>(__rt->__right_);
2136
2278
  else
2137
2279
  return _Pp(
@@ -2146,18 +2288,21 @@ template <class _Tp, class _Compare, class _Allocator>
2146
2288
  template <class _Key>
2147
2289
  pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator>
2148
2290
  __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) {
2149
- typedef pair<iterator, iterator> _Pp;
2291
+ using _Pp = pair<iterator, iterator>;
2150
2292
  __end_node_pointer __result = __end_node();
2151
- __node_pointer __rt = __root();
2293
+ __node_pointer __rt = __root();
2294
+ auto __comp = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
2152
2295
  while (__rt != nullptr) {
2153
- if (value_comp()(__k, __rt->__value_)) {
2296
+ auto __comp_res = __comp(__k, __rt->__get_value());
2297
+ if (__comp_res.__less()) {
2154
2298
  __result = static_cast<__end_node_pointer>(__rt);
2155
2299
  __rt = static_cast<__node_pointer>(__rt->__left_);
2156
- } else if (value_comp()(__rt->__value_, __k))
2300
+ } else if (__comp_res.__greater())
2157
2301
  __rt = static_cast<__node_pointer>(__rt->__right_);
2158
2302
  else
2159
- return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
2160
- __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2303
+ return _Pp(
2304
+ __lower_bound_multi(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
2305
+ __upper_bound_multi(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2161
2306
  }
2162
2307
  return _Pp(iterator(__result), iterator(__result));
2163
2308
  }
@@ -2167,18 +2312,21 @@ template <class _Key>
2167
2312
  pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2168
2313
  typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2169
2314
  __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const {
2170
- typedef pair<const_iterator, const_iterator> _Pp;
2315
+ using _Pp = pair<const_iterator, const_iterator>;
2171
2316
  __end_node_pointer __result = __end_node();
2172
- __node_pointer __rt = __root();
2317
+ __node_pointer __rt = __root();
2318
+ auto __comp = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
2173
2319
  while (__rt != nullptr) {
2174
- if (value_comp()(__k, __rt->__value_)) {
2320
+ auto __comp_res = __comp(__k, __rt->__get_value());
2321
+ if (__comp_res.__less()) {
2175
2322
  __result = static_cast<__end_node_pointer>(__rt);
2176
2323
  __rt = static_cast<__node_pointer>(__rt->__left_);
2177
- } else if (value_comp()(__rt->__value_, __k))
2324
+ } else if (__comp_res.__greater())
2178
2325
  __rt = static_cast<__node_pointer>(__rt->__right_);
2179
2326
  else
2180
- return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
2181
- __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2327
+ return _Pp(
2328
+ __lower_bound_multi(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
2329
+ __upper_bound_multi(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2182
2330
  }
2183
2331
  return _Pp(const_iterator(__result), const_iterator(__result));
2184
2332
  }
@@ -2187,13 +2335,13 @@ template <class _Tp, class _Compare, class _Allocator>
2187
2335
  typename __tree<_Tp, _Compare, _Allocator>::__node_holder
2188
2336
  __tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT {
2189
2337
  __node_pointer __np = __p.__get_np();
2190
- if (__begin_node() == __p.__ptr_) {
2338
+ if (__begin_node_ == __p.__ptr_) {
2191
2339
  if (__np->__right_ != nullptr)
2192
- __begin_node() = static_cast<__end_node_pointer>(__np->__right_);
2340
+ __begin_node_ = static_cast<__end_node_pointer>(__np->__right_);
2193
2341
  else
2194
- __begin_node() = static_cast<__end_node_pointer>(__np->__parent_);
2342
+ __begin_node_ = static_cast<__end_node_pointer>(__np->__parent_);
2195
2343
  }
2196
- --size();
2344
+ --__size_;
2197
2345
  std::__tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__np));
2198
2346
  return __node_holder(__np, _Dp(__node_alloc(), true));
2199
2347
  }