authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-19 14:37:46-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-09-19 14:37:46-07:00
loga63a1c5cb9fd31a57e8371e6cba5f316bd3f2a65
tree86c229e453d1f09734d6c89d172a471675aa7478
parentee4ced96833470f9432e6a5dc5b31534457280c0
parentf9f9c4a083b4e268caac3feff3a848df7a4f17cb
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #17202 from ziglang/llvm17

Update to LLVM 17

1155 files changed, 61378 insertions(+), 25992 deletions(-)

.github/workflows/ci.yaml+1-1
......@@ -4,7 +4,7 @@ on:
44 push:
55 branches:
66 - master
7 - llvm16
7 - llvm17
88concurrency:
99 # Cancels pending runs when a PR gets updated.
1010 group: ${{ github.head_ref || github.run_id }}-${{ github.actor }}
CMakeLists.txt+3-3
......@@ -131,9 +131,9 @@ else()
131131 set(ZIG_SYSTEM_LIBCXX "stdc++" CACHE STRING "system libcxx name for build.zig")
132132endif()
133133
134find_package(llvm 16)
135find_package(clang 16)
136find_package(lld 16)
134find_package(llvm 17)
135find_package(clang 17)
136find_package(lld 17)
137137
138138if(ZIG_STATIC_ZLIB)
139139 if (MSVC)
build.zig+4-2
......@@ -998,8 +998,8 @@ const llvm_libs = [_][]const u8{
998998 "LLVMWebAssemblyDisassembler",
999999 "LLVMWebAssemblyAsmParser",
10001000 "LLVMWebAssemblyCodeGen",
1001 "LLVMWebAssemblyDesc",
10021001 "LLVMWebAssemblyUtils",
1002 "LLVMWebAssemblyDesc",
10031003 "LLVMWebAssemblyInfo",
10041004 "LLVMVEDisassembler",
10051005 "LLVMVEAsmParser",
......@@ -1120,12 +1120,13 @@ const llvm_libs = [_][]const u8{
11201120 "LLVMAsmPrinter",
11211121 "LLVMSelectionDAG",
11221122 "LLVMCodeGen",
1123 "LLVMTarget",
11231124 "LLVMObjCARCOpts",
1125 "LLVMCodeGenTypes",
11241126 "LLVMIRPrinter",
11251127 "LLVMInterfaceStub",
11261128 "LLVMFileCheck",
11271129 "LLVMFuzzMutate",
1128 "LLVMTarget",
11291130 "LLVMScalarOpts",
11301131 "LLVMInstCombine",
11311132 "LLVMAggressiveInstCombine",
......@@ -1134,6 +1135,7 @@ const llvm_libs = [_][]const u8{
11341135 "LLVMAnalysis",
11351136 "LLVMProfileData",
11361137 "LLVMSymbolize",
1138 "LLVMDebugInfoBTF",
11371139 "LLVMDebugInfoPDB",
11381140 "LLVMDebugInfoMSF",
11391141 "LLVMDebugInfoDWARF",
ci/aarch64-linux-debug.sh+1-1
......@@ -8,7 +8,7 @@ set -e
88ARCH="$(uname -m)"
99TARGET="$ARCH-linux-musl"
1010MCPU="baseline"
11CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.11.0-dev.1869+df4cfc2ec"
11CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.12.0-dev.203+d3bc1cfc4"
1212PREFIX="$HOME/deps/$CACHE_BASENAME"
1313ZIG="$PREFIX/bin/zig"
1414
ci/aarch64-linux-release.sh+1-1
......@@ -8,7 +8,7 @@ set -e
88ARCH="$(uname -m)"
99TARGET="$ARCH-linux-musl"
1010MCPU="baseline"
11CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.11.0-dev.1869+df4cfc2ec"
11CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.12.0-dev.203+d3bc1cfc4"
1212PREFIX="$HOME/deps/$CACHE_BASENAME"
1313ZIG="$PREFIX/bin/zig"
1414
ci/aarch64-macos-debug.sh+1-1
......@@ -9,7 +9,7 @@ set -e
99ZIGDIR="$(pwd)"
1010TARGET="$ARCH-macos-none"
1111MCPU="baseline"
12CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.11.0-dev.2441+eb19f73af"
12CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.12.0-dev.203+d3bc1cfc4"
1313PREFIX="$HOME/$CACHE_BASENAME"
1414ZIG="$PREFIX/bin/zig"
1515
ci/aarch64-macos-release.sh+1-1
......@@ -9,7 +9,7 @@ set -e
99ZIGDIR="$(pwd)"
1010TARGET="$ARCH-macos-none"
1111MCPU="baseline"
12CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.11.0-dev.2441+eb19f73af"
12CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.12.0-dev.203+d3bc1cfc4"
1313PREFIX="$HOME/$CACHE_BASENAME"
1414ZIG="$PREFIX/bin/zig"
1515
ci/aarch64-windows.ps1+1-1
......@@ -1,5 +1,5 @@
11$TARGET = "$($Env:ARCH)-windows-gnu"
2$ZIG_LLVM_CLANG_LLD_NAME = "zig+llvm+lld+clang-$TARGET-0.11.0-dev.1869+df4cfc2ec"
2$ZIG_LLVM_CLANG_LLD_NAME = "zig+llvm+lld+clang-$TARGET-0.12.0-dev.203+d3bc1cfc4"
33$MCPU = "baseline"
44$ZIG_LLVM_CLANG_LLD_URL = "https://ziglang.org/deps/$ZIG_LLVM_CLANG_LLD_NAME.zip"
55$PREFIX_PATH = "$(Get-Location)\..\$ZIG_LLVM_CLANG_LLD_NAME"
ci/x86_64-linux-debug.sh+1-1
......@@ -8,7 +8,7 @@ set -e
88ARCH="$(uname -m)"
99TARGET="$ARCH-linux-musl"
1010MCPU="baseline"
11CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.11.0-dev.1869+df4cfc2ec"
11CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.12.0-dev.203+d3bc1cfc4"
1212PREFIX="$HOME/deps/$CACHE_BASENAME"
1313ZIG="$PREFIX/bin/zig"
1414
ci/x86_64-linux-release.sh+1-1
......@@ -8,7 +8,7 @@ set -e
88ARCH="$(uname -m)"
99TARGET="$ARCH-linux-musl"
1010MCPU="baseline"
11CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.11.0-dev.1869+df4cfc2ec"
11CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.12.0-dev.203+d3bc1cfc4"
1212PREFIX="$HOME/deps/$CACHE_BASENAME"
1313ZIG="$PREFIX/bin/zig"
1414
ci/x86_64-macos-release.sh+1-1
......@@ -6,7 +6,7 @@ set -e
66ZIGDIR="$(pwd)"
77TARGET="$ARCH-macos-none"
88MCPU="baseline"
9CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.11.0-dev.2441+eb19f73af"
9CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.12.0-dev.203+d3bc1cfc4"
1010PREFIX="$HOME/$CACHE_BASENAME"
1111JOBS="-j3"
1212
ci/x86_64-windows-debug.ps1+1-1
......@@ -1,5 +1,5 @@
11$TARGET = "$($Env:ARCH)-windows-gnu"
2$ZIG_LLVM_CLANG_LLD_NAME = "zig+llvm+lld+clang-$TARGET-0.11.0-dev.1869+df4cfc2ec"
2$ZIG_LLVM_CLANG_LLD_NAME = "zig+llvm+lld+clang-$TARGET-0.12.0-dev.203+d3bc1cfc4"
33$MCPU = "baseline"
44$ZIG_LLVM_CLANG_LLD_URL = "https://ziglang.org/deps/$ZIG_LLVM_CLANG_LLD_NAME.zip"
55$PREFIX_PATH = "$(Get-Location)\$ZIG_LLVM_CLANG_LLD_NAME"
ci/x86_64-windows-release.ps1+1-1
......@@ -1,5 +1,5 @@
11$TARGET = "$($Env:ARCH)-windows-gnu"
2$ZIG_LLVM_CLANG_LLD_NAME = "zig+llvm+lld+clang-$TARGET-0.11.0-dev.1869+df4cfc2ec"
2$ZIG_LLVM_CLANG_LLD_NAME = "zig+llvm+lld+clang-$TARGET-0.12.0-dev.203+d3bc1cfc4"
33$MCPU = "baseline"
44$ZIG_LLVM_CLANG_LLD_URL = "https://ziglang.org/deps/$ZIG_LLVM_CLANG_LLD_NAME.zip"
55$PREFIX_PATH = "$(Get-Location)\$ZIG_LLVM_CLANG_LLD_NAME"
cmake/Findclang.cmake+3-3
......@@ -17,9 +17,9 @@ find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h
1717if(${LLVM_LINK_MODE} STREQUAL "shared")
1818 find_library(CLANG_LIBRARIES
1919 NAMES
20 libclang-cpp.so.16
21 clang-cpp-16.0
22 clang-cpp160
20 libclang-cpp.so.17
21 clang-cpp-17.0
22 clang-cpp170
2323 clang-cpp
2424 NAMES_PER_DIR
2525 HINTS "${LLVM_LIBDIRS}"
cmake/Findlld.cmake+16-16
......@@ -9,21 +9,21 @@
99find_path(LLD_INCLUDE_DIRS NAMES lld/Common/Driver.h
1010 HINTS ${LLVM_INCLUDE_DIRS}
1111 PATHS
12 /usr/lib/llvm-16/include
13 /usr/local/llvm160/include
14 /usr/local/llvm16/include
15 /usr/local/opt/llvm@16/include
16 /opt/homebrew/opt/llvm@16/include
12 /usr/lib/llvm-17/include
13 /usr/local/llvm170/include
14 /usr/local/llvm17/include
15 /usr/local/opt/llvm@17/include
16 /opt/homebrew/opt/llvm@17/include
1717 /mingw64/include)
1818
19find_library(LLD_LIBRARY NAMES lld-16.0 lld160 lld NAMES_PER_DIR
19find_library(LLD_LIBRARY NAMES lld-17.0 lld170 lld NAMES_PER_DIR
2020 HINTS ${LLVM_LIBDIRS}
2121 PATHS
22 /usr/lib/llvm-16/lib
23 /usr/local/llvm160/lib
24 /usr/local/llvm16/lib
25 /usr/local/opt/llvm@16/lib
26 /opt/homebrew/opt/llvm@16/lib
22 /usr/lib/llvm-17/lib
23 /usr/local/llvm170/lib
24 /usr/local/llvm17/lib
25 /usr/local/opt/llvm@17/lib
26 /opt/homebrew/opt/llvm@17/lib
2727)
2828if(EXISTS ${LLD_LIBRARY})
2929 set(LLD_LIBRARIES ${LLD_LIBRARY})
......@@ -34,11 +34,11 @@ else()
3434 HINTS ${LLVM_LIBDIRS}
3535 PATHS
3636 ${LLD_LIBDIRS}
37 /usr/lib/llvm-16/lib
38 /usr/local/llvm160/lib
39 /usr/local/llvm16/lib
40 /usr/local/opt/llvm@16/lib
41 /opt/homebrew/opt/llvm@16/lib
37 /usr/lib/llvm-17/lib
38 /usr/local/llvm170/lib
39 /usr/local/llvm17/lib
40 /usr/local/opt/llvm@17/lib
41 /opt/homebrew/opt/llvm@17/lib
4242 /mingw64/lib
4343 /c/msys64/mingw64/lib
4444 c:/msys64/mingw64/lib)
cmake/Findllvm.cmake+10-8
......@@ -14,12 +14,12 @@ if(ZIG_USE_LLVM_CONFIG)
1414 while(1)
1515 unset(LLVM_CONFIG_EXE CACHE)
1616 find_program(LLVM_CONFIG_EXE
17 NAMES llvm-config-16 llvm-config-16.0 llvm-config160 llvm-config16 llvm-config NAMES_PER_DIR
17 NAMES llvm-config-17 llvm-config-17.0 llvm-config170 llvm-config17 llvm-config NAMES_PER_DIR
1818 PATHS
1919 "/mingw64/bin"
2020 "/c/msys64/mingw64/bin"
2121 "c:/msys64/mingw64/bin"
22 "C:/Libraries/llvm-16.0.0/bin")
22 "C:/Libraries/llvm-17.0.0/bin")
2323
2424 if ("${LLVM_CONFIG_EXE}" STREQUAL "LLVM_CONFIG_EXE-NOTFOUND")
2525 if (NOT LLVM_CONFIG_ERROR_MESSAGES STREQUAL "")
......@@ -37,9 +37,9 @@ if(ZIG_USE_LLVM_CONFIG)
3737 OUTPUT_STRIP_TRAILING_WHITESPACE)
3838
3939 get_filename_component(LLVM_CONFIG_DIR "${LLVM_CONFIG_EXE}" DIRECTORY)
40 if("${LLVM_CONFIG_VERSION}" VERSION_LESS 16 OR "${LLVM_CONFIG_VERSION}" VERSION_EQUAL 17 OR "${LLVM_CONFIG_VERSION}" VERSION_GREATER 17)
40 if("${LLVM_CONFIG_VERSION}" VERSION_LESS 17 OR "${LLVM_CONFIG_VERSION}" VERSION_EQUAL 18 OR "${LLVM_CONFIG_VERSION}" VERSION_GREATER 18)
4141 # Save the error message, in case this is the last llvm-config we find
42 list(APPEND LLVM_CONFIG_ERROR_MESSAGES "expected LLVM 16.x but found ${LLVM_CONFIG_VERSION} using ${LLVM_CONFIG_EXE}")
42 list(APPEND LLVM_CONFIG_ERROR_MESSAGES "expected LLVM 17.x but found ${LLVM_CONFIG_VERSION} using ${LLVM_CONFIG_EXE}")
4343
4444 # Ignore this directory and try the search again
4545 list(APPEND CMAKE_IGNORE_PATH "${LLVM_CONFIG_DIR}")
......@@ -63,9 +63,9 @@ if(ZIG_USE_LLVM_CONFIG)
6363 if (LLVM_CONFIG_ERROR)
6464 # Save the error message, in case this is the last llvm-config we find
6565 if (ZIG_SHARED_LLVM)
66 list(APPEND LLVM_CONFIG_ERROR_MESSAGES "LLVM 16.x found at ${LLVM_CONFIG_EXE} does not support linking as a shared library")
66 list(APPEND LLVM_CONFIG_ERROR_MESSAGES "LLVM 17.x found at ${LLVM_CONFIG_EXE} does not support linking as a shared library")
6767 else()
68 list(APPEND LLVM_CONFIG_ERROR_MESSAGES "LLVM 16.x found at ${LLVM_CONFIG_EXE} does not support linking as a static library")
68 list(APPEND LLVM_CONFIG_ERROR_MESSAGES "LLVM 17.x found at ${LLVM_CONFIG_EXE} does not support linking as a static library")
6969 endif()
7070
7171 # Ignore this directory and try the search again
......@@ -210,8 +210,8 @@ else()
210210 FIND_AND_ADD_LLVM_LIB(LLVMWebAssemblyDisassembler)
211211 FIND_AND_ADD_LLVM_LIB(LLVMWebAssemblyAsmParser)
212212 FIND_AND_ADD_LLVM_LIB(LLVMWebAssemblyCodeGen)
213 FIND_AND_ADD_LLVM_LIB(LLVMWebAssemblyDesc)
214213 FIND_AND_ADD_LLVM_LIB(LLVMWebAssemblyUtils)
214 FIND_AND_ADD_LLVM_LIB(LLVMWebAssemblyDesc)
215215 FIND_AND_ADD_LLVM_LIB(LLVMWebAssemblyInfo)
216216 FIND_AND_ADD_LLVM_LIB(LLVMVEDisassembler)
217217 FIND_AND_ADD_LLVM_LIB(LLVMVEAsmParser)
......@@ -332,12 +332,13 @@ else()
332332 FIND_AND_ADD_LLVM_LIB(LLVMAsmPrinter)
333333 FIND_AND_ADD_LLVM_LIB(LLVMSelectionDAG)
334334 FIND_AND_ADD_LLVM_LIB(LLVMCodeGen)
335 FIND_AND_ADD_LLVM_LIB(LLVMTarget)
335336 FIND_AND_ADD_LLVM_LIB(LLVMObjCARCOpts)
337 FIND_AND_ADD_LLVM_LIB(LLVMCodeGenTypes)
336338 FIND_AND_ADD_LLVM_LIB(LLVMIRPrinter)
337339 FIND_AND_ADD_LLVM_LIB(LLVMInterfaceStub)
338340 FIND_AND_ADD_LLVM_LIB(LLVMFileCheck)
339341 FIND_AND_ADD_LLVM_LIB(LLVMFuzzMutate)
340 FIND_AND_ADD_LLVM_LIB(LLVMTarget)
341342 FIND_AND_ADD_LLVM_LIB(LLVMScalarOpts)
342343 FIND_AND_ADD_LLVM_LIB(LLVMInstCombine)
343344 FIND_AND_ADD_LLVM_LIB(LLVMAggressiveInstCombine)
......@@ -346,6 +347,7 @@ else()
346347 FIND_AND_ADD_LLVM_LIB(LLVMAnalysis)
347348 FIND_AND_ADD_LLVM_LIB(LLVMProfileData)
348349 FIND_AND_ADD_LLVM_LIB(LLVMSymbolize)
350 FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoBTF)
349351 FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoPDB)
350352 FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoMSF)
351353 FIND_AND_ADD_LLVM_LIB(LLVMDebugInfoDWARF)
doc/langref.html.in+8-3
......@@ -11133,9 +11133,14 @@ fn add(count: c_int, ...) callconv(.C) c_int {
1113311133}
1113411134
1113511135test "defining a variadic function" {
11136 // Variadic functions are currently disabled on some targets due to miscompilations.
11137 if (builtin.cpu.arch == .aarch64 and builtin.os.tag != .windows and builtin.os.tag != .macos) return error.SkipZigTest;
11138 if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) return error.SkipZigTest;
11136 if (builtin.cpu.arch == .aarch64 and builtin.os.tag != .macos) {
11137 // https://github.com/ziglang/zig/issues/14096
11138 return error.SkipZigTest;
11139 }
11140 if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) {
11141 // https://github.com/ziglang/zig/issues/16961
11142 return error.SkipZigTest;
11143 }
1113911144
1114011145 try std.testing.expectEqual(@as(c_int, 0), add(0));
1114111146 try std.testing.expectEqual(@as(c_int, 1), add(1, @as(c_int, 1)));
lib/compiler_rt/addf3.zig+7-8
......@@ -9,7 +9,6 @@ const normalize = common.normalize;
99pub inline fn addf3(comptime T: type, a: T, b: T) T {
1010 const bits = @typeInfo(T).Float.bits;
1111 const Z = std.meta.Int(.unsigned, bits);
12 const S = std.meta.Int(.unsigned, bits - @clz(@as(Z, bits) - 1));
1312
1413 const typeWidth = bits;
1514 const significandBits = math.floatMantissaBits(T);
......@@ -26,12 +25,12 @@ pub inline fn addf3(comptime T: type, a: T, b: T) T {
2625 const absMask = signBit - 1;
2726 const qnanRep = @as(Z, @bitCast(math.nan(T))) | quietBit;
2827
29 var aRep = @as(Z, @bitCast(a));
30 var bRep = @as(Z, @bitCast(b));
28 var aRep: Z = @bitCast(a);
29 var bRep: Z = @bitCast(b);
3130 const aAbs = aRep & absMask;
3231 const bAbs = bRep & absMask;
3332
34 const infRep = @as(Z, @bitCast(math.inf(T)));
33 const infRep: Z = @bitCast(math.inf(T));
3534
3635 // Detect if a or b is zero, infinity, or NaN.
3736 if (aAbs -% @as(Z, 1) >= infRep - @as(Z, 1) or
......@@ -104,8 +103,8 @@ pub inline fn addf3(comptime T: type, a: T, b: T) T {
104103 const @"align": u32 = @intCast(aExponent - bExponent);
105104 if (@"align" != 0) {
106105 if (@"align" < typeWidth) {
107 const sticky = if (bSignificand << @as(S, @intCast(typeWidth - @"align")) != 0) @as(Z, 1) else 0;
108 bSignificand = (bSignificand >> @as(S, @truncate(@"align"))) | sticky;
106 const sticky = if (bSignificand << @intCast(typeWidth - @"align") != 0) @as(Z, 1) else 0;
107 bSignificand = (bSignificand >> @truncate(@"align")) | sticky;
109108 } else {
110109 bSignificand = 1; // sticky; b is known to be non-zero.
111110 }
......@@ -119,7 +118,7 @@ pub inline fn addf3(comptime T: type, a: T, b: T) T {
119118 // and adjust the exponent:
120119 if (aSignificand < integerBit << 3) {
121120 const shift = @as(i32, @intCast(@clz(aSignificand))) - @as(i32, @intCast(@clz(integerBit << 3)));
122 aSignificand <<= @as(S, @intCast(shift));
121 aSignificand <<= @intCast(shift);
123122 aExponent -= shift;
124123 }
125124 } else { // addition
......@@ -140,7 +139,7 @@ pub inline fn addf3(comptime T: type, a: T, b: T) T {
140139 if (aExponent <= 0) {
141140 // Result is denormal; the exponent and round/sticky bits are zero.
142141 // All we need to do is shift the significand and apply the correct sign.
143 aSignificand >>= @as(S, @intCast(4 - aExponent));
142 aSignificand >>= @intCast(4 - aExponent);
144143 return @bitCast(resultSign | aSignificand);
145144 }
146145
lib/compiler_rt/ceil.zig+1-1
......@@ -43,7 +43,7 @@ pub fn ceilf(x: f32) callconv(.C) f32 {
4343 if (e >= 23) {
4444 return x;
4545 } else if (e >= 0) {
46 m = @as(u32, 0x007FFFFF) >> @as(u5, @intCast(e));
46 m = @as(u32, 0x007FFFFF) >> @intCast(e);
4747 if (u & m == 0) {
4848 return x;
4949 }
lib/compiler_rt/clear_cache.zig+2-2
......@@ -102,7 +102,7 @@ fn clear_cache(start: usize, end: usize) callconv(.C) void {
102102 // If CTR_EL0.IDC is set, data cache cleaning to the point of unification
103103 // is not required for instruction to data coherence.
104104 if (((ctr_el0 >> 28) & 0x1) == 0x0) {
105 const dcache_line_size: usize = @as(usize, 4) << @as(u6, @intCast((ctr_el0 >> 16) & 15));
105 const dcache_line_size = @as(usize, 4) << @intCast((ctr_el0 >> 16) & 15);
106106 addr = start & ~(dcache_line_size - 1);
107107 while (addr < end) : (addr += dcache_line_size) {
108108 asm volatile ("dc cvau, %[addr]"
......@@ -115,7 +115,7 @@ fn clear_cache(start: usize, end: usize) callconv(.C) void {
115115 // If CTR_EL0.DIC is set, instruction cache invalidation to the point of
116116 // unification is not required for instruction to data coherence.
117117 if (((ctr_el0 >> 29) & 0x1) == 0x0) {
118 const icache_line_size: usize = @as(usize, 4) << @as(u6, @intCast((ctr_el0 >> 0) & 15));
118 const icache_line_size = @as(usize, 4) << @intCast((ctr_el0 >> 0) & 15);
119119 addr = start & ~(icache_line_size - 1);
120120 while (addr < end) : (addr += icache_line_size) {
121121 asm volatile ("ic ivau, %[addr]"
lib/compiler_rt/common.zig+15-8
......@@ -84,6 +84,13 @@ pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, _: ?
8484/// here in compiler-rt.
8585pub fn F16T(comptime other_type: type) type {
8686 return switch (builtin.cpu.arch) {
87 .arm, .armeb, .thumb, .thumbeb => if (std.Target.arm.featureSetHas(builtin.cpu.features, .has_v8))
88 switch (builtin.abi.floatAbi()) {
89 .soft => u16,
90 .hard => f16,
91 }
92 else
93 u16,
8794 .aarch64, .aarch64_be, .aarch64_32 => f16,
8895 .riscv64 => if (builtin.zig_backend == .stage1) u16 else f16,
8996 .x86, .x86_64 => if (builtin.target.isDarwin()) switch (other_type) {
......@@ -102,14 +109,14 @@ pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
102109 u16 => {
103110 // 16x16 --> 32 bit multiply
104111 const product = @as(u32, a) * @as(u32, b);
105 hi.* = @as(u16, @intCast(product >> 16));
106 lo.* = @as(u16, @truncate(product));
112 hi.* = @intCast(product >> 16);
113 lo.* = @truncate(product);
107114 },
108115 u32 => {
109116 // 32x32 --> 64 bit multiply
110117 const product = @as(u64, a) * @as(u64, b);
111 hi.* = @as(u32, @truncate(product >> 32));
112 lo.* = @as(u32, @truncate(product));
118 hi.* = @truncate(product >> 32);
119 lo.* = @truncate(product);
113120 },
114121 u64 => {
115122 const S = struct {
......@@ -136,9 +143,9 @@ pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
136143 hi.* = S.hiWord(plohi) +% S.hiWord(philo) +% S.hiWord(r1) +% phihi;
137144 },
138145 u128 => {
139 const Word_LoMask = @as(u64, 0x00000000ffffffff);
140 const Word_HiMask = @as(u64, 0xffffffff00000000);
141 const Word_FullMask = @as(u64, 0xffffffffffffffff);
146 const Word_LoMask: u64 = 0x00000000ffffffff;
147 const Word_HiMask: u64 = 0xffffffff00000000;
148 const Word_FullMask: u64 = 0xffffffffffffffff;
142149 const S = struct {
143150 fn Word_1(x: u128) u64 {
144151 return @as(u32, @truncate(x >> 96));
......@@ -229,7 +236,7 @@ pub inline fn fneg(a: anytype) @TypeOf(a) {
229236 } });
230237 const sign_bit_mask = @as(U, 1) << (bits - 1);
231238 const negated = @as(U, @bitCast(a)) ^ sign_bit_mask;
232 return @as(F, @bitCast(negated));
239 return @bitCast(negated);
233240}
234241
235242/// Allows to access underlying bits as two equally sized lower and higher
lib/compiler_rt/cos.zig+1-1
......@@ -25,7 +25,7 @@ comptime {
2525
2626pub fn __cosh(a: f16) callconv(.C) f16 {
2727 // TODO: more efficient implementation
28 return @as(f16, @floatCast(cosf(a)));
28 return @floatCast(cosf(a));
2929}
3030
3131pub fn cosf(x: f32) callconv(.C) f32 {
lib/compiler_rt/count0bits.zig+1-6
......@@ -203,12 +203,7 @@ pub fn __ctzti2(a: i128) callconv(.C) i32 {
203203}
204204
205205inline fn ffsXi2(comptime T: type, a: T) i32 {
206 var x = switch (@bitSizeOf(T)) {
207 32 => @as(u32, @bitCast(a)),
208 64 => @as(u64, @bitCast(a)),
209 128 => @as(u128, @bitCast(a)),
210 else => unreachable,
211 };
206 var x: std.meta.Int(.unsigned, @typeInfo(T).Int.bits) = @bitCast(a);
212207 var n: T = 1;
213208 // adapted from Number of trailing zeroes (see ctzXi2)
214209 var mask: @TypeOf(x) = std.math.maxInt(@TypeOf(x));
lib/compiler_rt/divti3.zig+2-2
......@@ -21,7 +21,7 @@ pub fn __divti3(a: i128, b: i128) callconv(.C) i128 {
2121const v128 = @Vector(2, u64);
2222
2323fn __divti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 {
24 return @as(v128, @bitCast(div(@as(i128, @bitCast(a)), @as(i128, @bitCast(b)))));
24 return @bitCast(div(@bitCast(a), @bitCast(b)));
2525}
2626
2727inline fn div(a: i128, b: i128) i128 {
......@@ -31,7 +31,7 @@ inline fn div(a: i128, b: i128) i128 {
3131 const an = (a ^ s_a) -% s_a;
3232 const bn = (b ^ s_b) -% s_b;
3333
34 const r = udivmod(u128, @as(u128, @bitCast(an)), @as(u128, @bitCast(bn)), null);
34 const r = udivmod(u128, @bitCast(an), @bitCast(bn), null);
3535 const s = s_a ^ s_b;
3636 return (@as(i128, @bitCast(r)) ^ s) -% s;
3737}
lib/compiler_rt/divxf3.zig+6-6
......@@ -164,8 +164,8 @@ pub fn __divxf3(a: f80, b: f80) callconv(.C) f80 {
164164 // exponent accordingly.
165165 var quotient: u64 = if (quotient128 < (integerBit << 1)) b: {
166166 quotientExponent -= 1;
167 break :b @as(u64, @intCast(quotient128));
168 } else @as(u64, @intCast(quotient128 >> 1));
167 break :b @intCast(quotient128);
168 } else @intCast(quotient128 >> 1);
169169
170170 // We are going to compute a residual of the form
171171 //
......@@ -182,18 +182,18 @@ pub fn __divxf3(a: f80, b: f80) callconv(.C) f80 {
182182 const writtenExponent = quotientExponent + exponentBias;
183183 if (writtenExponent >= maxExponent) {
184184 // If we have overflowed the exponent, return infinity.
185 return @as(T, @bitCast(infRep | quotientSign));
185 return @bitCast(infRep | quotientSign);
186186 } else if (writtenExponent < 1) {
187187 if (writtenExponent == 0) {
188188 // Check whether the rounded result is normal.
189189 if (residual > (bSignificand >> 1)) { // round
190190 if (quotient == (integerBit - 1)) // If the rounded result is normal, return it
191 return @as(T, @bitCast(@as(Z, @bitCast(std.math.floatMin(T))) | quotientSign));
191 return @bitCast(@as(Z, @bitCast(std.math.floatMin(T))) | quotientSign);
192192 }
193193 }
194194 // Flush denormals to zero. In the future, it would be nice to add
195195 // code to round them correctly.
196 return @as(T, @bitCast(quotientSign));
196 return @bitCast(quotientSign);
197197 } else {
198198 const round = @intFromBool(residual > (bSignificand >> 1));
199199 // Insert the exponent
......@@ -201,7 +201,7 @@ pub fn __divxf3(a: f80, b: f80) callconv(.C) f80 {
201201 // Round
202202 absResult +%= round;
203203 // Insert the sign and return
204 return @as(T, @bitCast(absResult | quotientSign | integerBit));
204 return @bitCast(absResult | quotientSign | integerBit);
205205 }
206206}
207207
lib/compiler_rt/emutls.zig+6-6
......@@ -52,19 +52,19 @@ const simple_allocator = struct {
5252 abort();
5353 }
5454
55 return @as([*]u8, @ptrCast(aligned_ptr));
55 return @ptrCast(aligned_ptr);
5656 }
5757
5858 /// Resize a slice.
5959 pub fn reallocSlice(comptime T: type, slice: []T, len: usize) []T {
60 var c_ptr: *anyopaque = @as(*anyopaque, @ptrCast(slice.ptr));
60 var c_ptr: *anyopaque = @ptrCast(slice.ptr);
6161 var new_array: [*]T = @ptrCast(@alignCast(std.c.realloc(c_ptr, @sizeOf(T) * len) orelse abort()));
6262 return new_array[0..len];
6363 }
6464
6565 /// Free a memory chunk allocated with simple_allocator.
6666 pub fn free(ptr: anytype) void {
67 std.c.free(@as(*anyopaque, @ptrCast(ptr)));
67 std.c.free(@ptrCast(ptr));
6868 }
6969};
7070
......@@ -138,7 +138,7 @@ const ObjectArray = struct {
138138 @memset(data[0..size], 0);
139139 }
140140
141 self.slots[index] = @as(*anyopaque, @ptrCast(data));
141 self.slots[index] = @ptrCast(data);
142142 }
143143
144144 return self.slots[index].?;
......@@ -178,7 +178,7 @@ const current_thread_storage = struct {
178178
179179 /// Set casted thread specific value.
180180 fn setspecific(new: ?*ObjectArray) void {
181 if (std.c.pthread_setspecific(current_thread_storage.key, @as(*anyopaque, @ptrCast(new))) != 0) {
181 if (std.c.pthread_setspecific(current_thread_storage.key, @ptrCast(new)) != 0) {
182182 abort();
183183 }
184184 }
......@@ -278,7 +278,7 @@ const emutls_control = extern struct {
278278 .size = @sizeOf(T),
279279 .alignment = @alignOf(T),
280280 .object = .{ .index = 0 },
281 .default_value = @as(?*const anyopaque, @ptrCast(default_value)),
281 .default_value = @ptrCast(default_value),
282282 };
283283 }
284284
lib/compiler_rt/exp.zig+3-3
......@@ -27,7 +27,7 @@ comptime {
2727
2828pub fn __exph(a: f16) callconv(.C) f16 {
2929 // TODO: more efficient implementation
30 return @as(f16, @floatCast(expf(a)));
30 return @floatCast(expf(a));
3131}
3232
3333pub fn expf(x_: f32) callconv(.C) f32 {
......@@ -74,7 +74,7 @@ pub fn expf(x_: f32) callconv(.C) f32 {
7474 if (hx > 0x3EB17218) {
7575 // |x| > 1.5 * ln2
7676 if (hx > 0x3F851592) {
77 k = @intFromFloat(invln2 * x + half[@as(usize, @intCast(sign))]);
77 k = @intFromFloat(invln2 * x + half[@intCast(sign)]);
7878 } else {
7979 k = 1 - sign - sign;
8080 }
......@@ -157,7 +157,7 @@ pub fn exp(x_: f64) callconv(.C) f64 {
157157 if (hx > 0x3FD62E42) {
158158 // |x| >= 1.5 * ln2
159159 if (hx > 0x3FF0A2B2) {
160 k = @intFromFloat(invln2 * x + half[@as(usize, @intCast(sign))]);
160 k = @intFromFloat(invln2 * x + half[@intCast(sign)]);
161161 } else {
162162 k = 1 - sign - sign;
163163 }
lib/compiler_rt/exp2.zig+4-4
......@@ -27,7 +27,7 @@ comptime {
2727
2828pub fn __exp2h(x: f16) callconv(.C) f16 {
2929 // TODO: more efficient implementation
30 return @as(f16, @floatCast(exp2f(x)));
30 return @floatCast(exp2f(x));
3131}
3232
3333pub fn exp2f(x: f32) callconv(.C) f32 {
......@@ -81,7 +81,7 @@ pub fn exp2f(x: f32) callconv(.C) f32 {
8181 uf -= redux;
8282
8383 const z: f64 = x - uf;
84 var r: f64 = exp2ft[@as(usize, @intCast(i_0))];
84 var r: f64 = exp2ft[@intCast(i_0)];
8585 const t: f64 = r * z;
8686 r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4);
8787 return @floatCast(r * uk);
......@@ -149,8 +149,8 @@ pub fn exp2(x: f64) callconv(.C) f64 {
149149
150150 // r = exp2(y) = exp2t[i_0] * p(z - eps[i])
151151 var z: f64 = x - uf;
152 const t: f64 = exp2dt[@as(usize, @intCast(2 * i_0))];
153 z -= exp2dt[@as(usize, @intCast(2 * i_0 + 1))];
152 const t: f64 = exp2dt[@intCast(2 * i_0)];
153 z -= exp2dt[@intCast(2 * i_0 + 1)];
154154 const r: f64 = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
155155
156156 return math.scalbn(r, ik);
lib/compiler_rt/extendf.zig+6-11
......@@ -9,7 +9,6 @@ pub inline fn extendf(
99 const dst_rep_t = std.meta.Int(.unsigned, @typeInfo(dst_t).Float.bits);
1010 const srcSigBits = std.math.floatMantissaBits(src_t);
1111 const dstSigBits = std.math.floatMantissaBits(dst_t);
12 const DstShift = std.math.Log2Int(dst_rep_t);
1312
1413 // Various constants whose values follow from the type parameters.
1514 // Any reasonable optimizer will fold and propagate all of these.
......@@ -56,9 +55,8 @@ pub inline fn extendf(
5655 // a is denormal.
5756 // renormalize the significand and clear the leading bit, then insert
5857 // the correct adjusted exponent in the destination type.
59 const scale: u32 = @clz(aAbs) -
60 @clz(@as(src_rep_t, srcMinNormal));
61 absResult = @as(dst_rep_t, aAbs) << @as(DstShift, @intCast(dstSigBits - srcSigBits + scale));
58 const scale: u32 = @clz(aAbs) - @clz(@as(src_rep_t, srcMinNormal));
59 absResult = @as(dst_rep_t, aAbs) << @intCast(dstSigBits - srcSigBits + scale);
6260 absResult ^= dstMinNormal;
6361 const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1;
6462 absResult |= @as(dst_rep_t, @intCast(resultExponent)) << dstSigBits;
......@@ -69,7 +67,7 @@ pub inline fn extendf(
6967
7068 // Apply the signbit to (dst_t)abs(a).
7169 const result: dst_rep_t align(@alignOf(dst_t)) = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits);
72 return @as(dst_t, @bitCast(result));
70 return @bitCast(result);
7371}
7472
7573pub inline fn extend_f80(comptime src_t: type, a: std.meta.Int(.unsigned, @typeInfo(src_t).Float.bits)) f80 {
......@@ -92,8 +90,6 @@ pub inline fn extend_f80(comptime src_t: type, a: std.meta.Int(.unsigned, @typeI
9290 const src_qnan = 1 << (src_sig_bits - 1);
9391 const src_nan_code = src_qnan - 1;
9492
95 const SrcShift = std.math.Log2Int(src_rep_t);
96
9793 var dst: std.math.F80 = undefined;
9894
9995 // Break a into a sign and representation of the absolute value
......@@ -121,12 +117,11 @@ pub inline fn extend_f80(comptime src_t: type, a: std.meta.Int(.unsigned, @typeI
121117 // a is denormal.
122118 // renormalize the significand and clear the leading bit, then insert
123119 // the correct adjusted exponent in the destination type.
124 const scale: u16 = @clz(a_abs) -
125 @clz(@as(src_rep_t, src_min_normal));
120 const scale: u16 = @clz(a_abs) - @clz(@as(src_rep_t, src_min_normal));
126121
127 dst.fraction = @as(u64, a_abs) << @as(u6, @intCast(dst_sig_bits - src_sig_bits + scale));
122 dst.fraction = @as(u64, a_abs) << @intCast(dst_sig_bits - src_sig_bits + scale);
128123 dst.fraction |= dst_int_bit; // bit 64 is always set for normal numbers
129 dst.exp = @truncate(a_abs >> @as(SrcShift, @intCast(src_sig_bits - scale)));
124 dst.exp = @truncate(a_abs >> @intCast(src_sig_bits - scale));
130125 dst.exp ^= 1;
131126 dst.exp |= dst_exp_bias - src_exp_bias - scale + 1;
132127 } else {
lib/compiler_rt/extendxftf2.zig+2-2
......@@ -39,12 +39,12 @@ fn __extendxftf2(a: f80) callconv(.C) f128 {
3939 // renormalize the significand and clear the leading bit and integer part,
4040 // then insert the correct adjusted exponent in the destination type.
4141 const scale: u32 = @clz(a_rep.fraction);
42 abs_result = @as(u128, a_rep.fraction) << @as(u7, @intCast(dst_sig_bits - src_sig_bits + scale + 1));
42 abs_result = @as(u128, a_rep.fraction) << @intCast(dst_sig_bits - src_sig_bits + scale + 1);
4343 abs_result ^= dst_min_normal;
4444 abs_result |= @as(u128, scale + 1) << dst_sig_bits;
4545 }
4646
4747 // Apply the signbit to (dst_t)abs(a).
4848 const result: u128 align(@alignOf(f128)) = abs_result | @as(u128, sign) << (dst_bits - 16);
49 return @as(f128, @bitCast(result));
49 return @bitCast(result);
5050}
lib/compiler_rt/fabs.zig+2-2
......@@ -51,7 +51,7 @@ pub fn fabsl(x: c_longdouble) callconv(.C) c_longdouble {
5151inline fn generic_fabs(x: anytype) @TypeOf(x) {
5252 const T = @TypeOf(x);
5353 const TBits = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
54 const float_bits = @as(TBits, @bitCast(x));
54 const float_bits: TBits = @bitCast(x);
5555 const remove_sign = ~@as(TBits, 0) >> 1;
56 return @as(T, @bitCast(float_bits & remove_sign));
56 return @bitCast(float_bits & remove_sign);
5757}
lib/compiler_rt/fixdfti.zig+1-1
......@@ -19,5 +19,5 @@ pub fn __fixdfti(a: f64) callconv(.C) i128 {
1919const v2u64 = @Vector(2, u64);
2020
2121fn __fixdfti_windows_x86_64(a: f64) callconv(.C) v2u64 {
22 return @as(v2u64, @bitCast(intFromFloat(i128, a)));
22 return @bitCast(intFromFloat(i128, a));
2323}
lib/compiler_rt/fixhfti.zig+1-1
......@@ -19,5 +19,5 @@ pub fn __fixhfti(a: f16) callconv(.C) i128 {
1919const v2u64 = @Vector(2, u64);
2020
2121fn __fixhfti_windows_x86_64(a: f16) callconv(.C) v2u64 {
22 return @as(v2u64, @bitCast(intFromFloat(i128, a)));
22 return @bitCast(intFromFloat(i128, a));
2323}
lib/compiler_rt/fixsfti.zig+1-1
......@@ -19,5 +19,5 @@ pub fn __fixsfti(a: f32) callconv(.C) i128 {
1919const v2u64 = @Vector(2, u64);
2020
2121fn __fixsfti_windows_x86_64(a: f32) callconv(.C) v2u64 {
22 return @as(v2u64, @bitCast(intFromFloat(i128, a)));
22 return @bitCast(intFromFloat(i128, a));
2323}
lib/compiler_rt/fixtfti.zig+1-1
......@@ -21,5 +21,5 @@ pub fn __fixtfti(a: f128) callconv(.C) i128 {
2121const v2u64 = @Vector(2, u64);
2222
2323fn __fixtfti_windows_x86_64(a: f128) callconv(.C) v2u64 {
24 return @as(v2u64, @bitCast(intFromFloat(i128, a)));
24 return @bitCast(intFromFloat(i128, a));
2525}
lib/compiler_rt/fixunsdfti.zig+1-1
......@@ -19,5 +19,5 @@ pub fn __fixunsdfti(a: f64) callconv(.C) u128 {
1919const v2u64 = @Vector(2, u64);
2020
2121fn __fixunsdfti_windows_x86_64(a: f64) callconv(.C) v2u64 {
22 return @as(v2u64, @bitCast(intFromFloat(u128, a)));
22 return @bitCast(intFromFloat(u128, a));
2323}
lib/compiler_rt/fixunshfti.zig+1-1
......@@ -19,5 +19,5 @@ pub fn __fixunshfti(a: f16) callconv(.C) u128 {
1919const v2u64 = @Vector(2, u64);
2020
2121fn __fixunshfti_windows_x86_64(a: f16) callconv(.C) v2u64 {
22 return @as(v2u64, @bitCast(intFromFloat(u128, a)));
22 return @bitCast(intFromFloat(u128, a));
2323}
lib/compiler_rt/fixunssfti.zig+1-1
......@@ -19,5 +19,5 @@ pub fn __fixunssfti(a: f32) callconv(.C) u128 {
1919const v2u64 = @Vector(2, u64);
2020
2121fn __fixunssfti_windows_x86_64(a: f32) callconv(.C) v2u64 {
22 return @as(v2u64, @bitCast(intFromFloat(u128, a)));
22 return @bitCast(intFromFloat(u128, a));
2323}
lib/compiler_rt/fixunstfti.zig+1-1
......@@ -21,5 +21,5 @@ pub fn __fixunstfti(a: f128) callconv(.C) u128 {
2121const v2u64 = @Vector(2, u64);
2222
2323fn __fixunstfti_windows_x86_64(a: f128) callconv(.C) v2u64 {
24 return @as(v2u64, @bitCast(intFromFloat(u128, a)));
24 return @bitCast(intFromFloat(u128, a));
2525}
lib/compiler_rt/fixunsxfti.zig+1-1
......@@ -19,5 +19,5 @@ pub fn __fixunsxfti(a: f80) callconv(.C) u128 {
1919const v2u64 = @Vector(2, u64);
2020
2121fn __fixunsxfti_windows_x86_64(a: f80) callconv(.C) v2u64 {
22 return @as(v2u64, @bitCast(intFromFloat(u128, a)));
22 return @bitCast(intFromFloat(u128, a));
2323}
lib/compiler_rt/fixxfti.zig+1-1
......@@ -19,5 +19,5 @@ pub fn __fixxfti(a: f80) callconv(.C) i128 {
1919const v2u64 = @Vector(2, u64);
2020
2121fn __fixxfti_windows_x86_64(a: f80) callconv(.C) v2u64 {
22 return @as(v2u64, @bitCast(intFromFloat(i128, a)));
22 return @bitCast(intFromFloat(i128, a));
2323}
lib/compiler_rt/float_from_int.zig+4-4
......@@ -28,10 +28,10 @@ pub fn floatFromInt(comptime T: type, x: anytype) T {
2828 const shift_amt = fractional_bits - @as(math.Log2Int(uT), @intCast(exp));
2929
3030 // Shift up result to line up with the significand - no rounding required
31 result = (@as(uT, @intCast(abs_val)) << shift_amt);
31 result = @as(uT, @intCast(abs_val)) << shift_amt;
3232 result ^= implicit_bit; // Remove implicit integer bit
3333 } else {
34 var shift_amt = @as(math.Log2Int(Z), @intCast(exp - fractional_bits));
34 var shift_amt: math.Log2Int(Z) = @intCast(exp - fractional_bits);
3535 const exact_tie: bool = @ctz(abs_val) == shift_amt - 1;
3636
3737 // Shift down result and remove implicit integer bit
......@@ -43,14 +43,14 @@ pub fn floatFromInt(comptime T: type, x: anytype) T {
4343
4444 // Compute exponent
4545 if ((int_bits > max_exp) and (exp > max_exp)) // If exponent too large, overflow to infinity
46 return @as(T, @bitCast(sign_bit | @as(uT, @bitCast(inf))));
46 return @bitCast(sign_bit | @as(uT, @bitCast(inf)));
4747
4848 result += (@as(uT, exp) + exp_bias) << math.floatMantissaBits(T);
4949
5050 // If the result included a carry, we need to restore the explicit integer bit
5151 if (T == f80) result |= 1 << fractional_bits;
5252
53 return @as(T, @bitCast(sign_bit | result));
53 return @bitCast(sign_bit | result);
5454}
5555
5656test {
lib/compiler_rt/float_from_int_test.zig+22-22
......@@ -43,7 +43,7 @@ test "floatsisf" {
4343 try test__floatsisf(1, 0x3f800000);
4444 try test__floatsisf(-1, 0xbf800000);
4545 try test__floatsisf(0x7FFFFFFF, 0x4f000000);
46 try test__floatsisf(@as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 0xcf000000);
46 try test__floatsisf(@bitCast(@as(u32, @intCast(0x80000000))), 0xcf000000);
4747}
4848
4949test "floatunsisf" {
......@@ -72,10 +72,10 @@ test "floatdisf" {
7272 try test__floatdisf(-2, -2.0);
7373 try test__floatdisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
7474 try test__floatdisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
75 try test__floatdisf(@as(i64, @bitCast(@as(u64, 0x8000008000000000))), -0x1.FFFFFEp+62);
76 try test__floatdisf(@as(i64, @bitCast(@as(u64, 0x8000010000000000))), -0x1.FFFFFCp+62);
77 try test__floatdisf(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), -0x1.000000p+63);
78 try test__floatdisf(@as(i64, @bitCast(@as(u64, 0x8000000000000001))), -0x1.000000p+63);
75 try test__floatdisf(@bitCast(@as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62);
76 try test__floatdisf(@bitCast(@as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62);
77 try test__floatdisf(@bitCast(@as(u64, 0x8000000000000000)), -0x1.000000p+63);
78 try test__floatdisf(@bitCast(@as(u64, 0x8000000000000001)), -0x1.000000p+63);
7979 try test__floatdisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
8080 try test__floatdisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);
8181 try test__floatdisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);
......@@ -228,7 +228,7 @@ test "floatuntisf" {
228228 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76);
229229
230230 // Test overflow to infinity
231 try test__floatuntisf(@as(u128, math.maxInt(u128)), @as(f32, @bitCast(math.inf(f32))));
231 try test__floatuntisf(math.maxInt(u128), @bitCast(math.inf(f32)));
232232}
233233
234234fn test_one_floatsidf(a: i32, expected: u64) !void {
......@@ -246,15 +246,15 @@ test "floatsidf" {
246246 try test_one_floatsidf(1, 0x3ff0000000000000);
247247 try test_one_floatsidf(-1, 0xbff0000000000000);
248248 try test_one_floatsidf(0x7FFFFFFF, 0x41dfffffffc00000);
249 try test_one_floatsidf(@as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 0xc1e0000000000000);
249 try test_one_floatsidf(@bitCast(@as(u32, @intCast(0x80000000))), 0xc1e0000000000000);
250250}
251251
252252test "floatunsidf" {
253253 try test_one_floatunsidf(0, 0x0000000000000000);
254254 try test_one_floatunsidf(1, 0x3ff0000000000000);
255255 try test_one_floatunsidf(0x7FFFFFFF, 0x41dfffffffc00000);
256 try test_one_floatunsidf(@as(u32, @intCast(0x80000000)), 0x41e0000000000000);
257 try test_one_floatunsidf(@as(u32, @intCast(0xFFFFFFFF)), 0x41efffffffe00000);
256 try test_one_floatunsidf(@intCast(0x80000000), 0x41e0000000000000);
257 try test_one_floatunsidf(@intCast(0xFFFFFFFF), 0x41efffffffe00000);
258258}
259259
260260fn test__floatdidf(a: i64, expected: f64) !void {
......@@ -279,12 +279,12 @@ test "floatdidf" {
279279 try test__floatdidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
280280 try test__floatdidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
281281 try test__floatdidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
282 try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000008000000000)))), -0x1.FFFFFEp+62);
283 try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000000000000800)))), -0x1.FFFFFFFFFFFFEp+62);
284 try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000010000000000)))), -0x1.FFFFFCp+62);
285 try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000000000001000)))), -0x1.FFFFFFFFFFFFCp+62);
286 try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000000000000000)))), -0x1.000000p+63);
287 try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000000000000001)))), -0x1.000000p+63); // 0x8000000000000001
282 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000008000000000))), -0x1.FFFFFEp+62);
283 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000800))), -0x1.FFFFFFFFFFFFEp+62);
284 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000010000000000))), -0x1.FFFFFCp+62);
285 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000001000))), -0x1.FFFFFFFFFFFFCp+62);
286 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000000))), -0x1.000000p+63);
287 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000001))), -0x1.000000p+63); // 0x8000000000000001
288288 try test__floatdidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
289289 try test__floatdidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
290290 try test__floatdidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);
......@@ -513,8 +513,8 @@ test "floatsitf" {
513513 try test__floatsitf(0x7FFFFFFF, 0x401dfffffffc00000000000000000000);
514514 try test__floatsitf(0x12345678, 0x401b2345678000000000000000000000);
515515 try test__floatsitf(-0x12345678, 0xc01b2345678000000000000000000000);
516 try test__floatsitf(@as(i32, @bitCast(@as(u32, @intCast(0xffffffff)))), 0xbfff0000000000000000000000000000);
517 try test__floatsitf(@as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 0xc01e0000000000000000000000000000);
516 try test__floatsitf(@bitCast(@as(u32, @intCast(0xffffffff))), 0xbfff0000000000000000000000000000);
517 try test__floatsitf(@bitCast(@as(u32, @intCast(0x80000000))), 0xc01e0000000000000000000000000000);
518518}
519519
520520fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void {
......@@ -575,10 +575,10 @@ test "floatditf" {
575575 try test__floatditf(0x2, make_tf(0x4000000000000000, 0x0));
576576 try test__floatditf(0x1, make_tf(0x3fff000000000000, 0x0));
577577 try test__floatditf(0x0, make_tf(0x0, 0x0));
578 try test__floatditf(@as(i64, @bitCast(@as(u64, 0xffffffffffffffff))), make_tf(0xbfff000000000000, 0x0));
579 try test__floatditf(@as(i64, @bitCast(@as(u64, 0xfffffffffffffffe))), make_tf(0xc000000000000000, 0x0));
578 try test__floatditf(@bitCast(@as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0));
579 try test__floatditf(@bitCast(@as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0));
580580 try test__floatditf(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000));
581 try test__floatditf(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), make_tf(0xc03e000000000000, 0x0));
581 try test__floatditf(@bitCast(@as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0));
582582}
583583
584584test "floatunditf" {
......@@ -773,7 +773,7 @@ fn make_ti(high: u64, low: u64) i128 {
773773 var result: u128 = high;
774774 result <<= 64;
775775 result |= low;
776 return @as(i128, @bitCast(result));
776 return @bitCast(result);
777777}
778778
779779fn make_uti(high: u64, low: u64) u128 {
......@@ -787,7 +787,7 @@ fn make_tf(high: u64, low: u64) f128 {
787787 var result: u128 = high;
788788 result <<= 64;
789789 result |= low;
790 return @as(f128, @bitCast(result));
790 return @bitCast(result);
791791}
792792
793793test "conversion to f16" {
lib/compiler_rt/floor.zig+7-7
......@@ -40,7 +40,7 @@ pub fn __floorh(x: f16) callconv(.C) f16 {
4040 }
4141
4242 if (e >= 0) {
43 m = @as(u16, 1023) >> @as(u4, @intCast(e));
43 m = @as(u16, 1023) >> @intCast(e);
4444 if (u & m == 0) {
4545 return x;
4646 }
......@@ -48,7 +48,7 @@ pub fn __floorh(x: f16) callconv(.C) f16 {
4848 if (u >> 15 != 0) {
4949 u += m;
5050 }
51 return @as(f16, @bitCast(u & ~m));
51 return @bitCast(u & ~m);
5252 } else {
5353 math.doNotOptimizeAway(x + 0x1.0p120);
5454 if (u >> 15 == 0) {
......@@ -60,7 +60,7 @@ pub fn __floorh(x: f16) callconv(.C) f16 {
6060}
6161
6262pub fn floorf(x: f32) callconv(.C) f32 {
63 var u = @as(u32, @bitCast(x));
63 var u: u32 = @bitCast(x);
6464 const e = @as(i32, @intCast((u >> 23) & 0xFF)) - 0x7F;
6565 var m: u32 = undefined;
6666
......@@ -74,7 +74,7 @@ pub fn floorf(x: f32) callconv(.C) f32 {
7474 }
7575
7676 if (e >= 0) {
77 m = @as(u32, 0x007FFFFF) >> @as(u5, @intCast(e));
77 m = @as(u32, 0x007FFFFF) >> @intCast(e);
7878 if (u & m == 0) {
7979 return x;
8080 }
......@@ -82,7 +82,7 @@ pub fn floorf(x: f32) callconv(.C) f32 {
8282 if (u >> 31 != 0) {
8383 u += m;
8484 }
85 return @as(f32, @bitCast(u & ~m));
85 return @bitCast(u & ~m);
8686 } else {
8787 math.doNotOptimizeAway(x + 0x1.0p120);
8888 if (u >> 31 == 0) {
......@@ -96,7 +96,7 @@ pub fn floorf(x: f32) callconv(.C) f32 {
9696pub fn floor(x: f64) callconv(.C) f64 {
9797 const f64_toint = 1.0 / math.floatEps(f64);
9898
99 const u = @as(u64, @bitCast(x));
99 const u: u64 = @bitCast(x);
100100 const e = (u >> 52) & 0x7FF;
101101 var y: f64 = undefined;
102102
......@@ -126,7 +126,7 @@ pub fn floor(x: f64) callconv(.C) f64 {
126126
127127pub fn __floorx(x: f80) callconv(.C) f80 {
128128 // TODO: more efficient implementation
129 return @as(f80, @floatCast(floorq(x)));
129 return @floatCast(floorq(x));
130130}
131131
132132pub fn floorq(x: f128) callconv(.C) f128 {
lib/compiler_rt/fma.zig+16-16
......@@ -28,7 +28,7 @@ comptime {
2828
2929pub fn __fmah(x: f16, y: f16, z: f16) callconv(.C) f16 {
3030 // TODO: more efficient implementation
31 return @as(f16, @floatCast(fmaf(x, y, z)));
31 return @floatCast(fmaf(x, y, z));
3232}
3333
3434pub fn fmaf(x: f32, y: f32, z: f32) callconv(.C) f32 {
......@@ -38,10 +38,10 @@ pub fn fmaf(x: f32, y: f32, z: f32) callconv(.C) f32 {
3838 const e = (u >> 52) & 0x7FF;
3939
4040 if ((u & 0x1FFFFFFF) != 0x10000000 or e == 0x7FF or (xy_z - xy == z and xy_z - z == xy)) {
41 return @as(f32, @floatCast(xy_z));
41 return @floatCast(xy_z);
4242 } else {
4343 // TODO: Handle inexact case with double-rounding
44 return @as(f32, @floatCast(xy_z));
44 return @floatCast(xy_z);
4545 }
4646}
4747
......@@ -95,7 +95,7 @@ pub fn fma(x: f64, y: f64, z: f64) callconv(.C) f64 {
9595
9696pub fn __fmax(a: f80, b: f80, c: f80) callconv(.C) f80 {
9797 // TODO: more efficient implementation
98 return @as(f80, @floatCast(fmaq(a, b, c)));
98 return @floatCast(fmaq(a, b, c));
9999}
100100
101101/// Fused multiply-add: Compute x * y + z with a single rounding error.
......@@ -201,12 +201,12 @@ fn dd_mul(a: f64, b: f64) dd {
201201fn add_adjusted(a: f64, b: f64) f64 {
202202 var sum = dd_add(a, b);
203203 if (sum.lo != 0) {
204 var uhii = @as(u64, @bitCast(sum.hi));
204 var uhii: u64 = @bitCast(sum.hi);
205205 if (uhii & 1 == 0) {
206206 // hibits += copysign(1.0, sum.hi, sum.lo)
207 const uloi = @as(u64, @bitCast(sum.lo));
207 const uloi: u64 = @bitCast(sum.lo);
208208 uhii += 1 - ((uhii ^ uloi) >> 62);
209 sum.hi = @as(f64, @bitCast(uhii));
209 sum.hi = @bitCast(uhii);
210210 }
211211 }
212212 return sum.hi;
......@@ -215,12 +215,12 @@ fn add_adjusted(a: f64, b: f64) f64 {
215215fn add_and_denorm(a: f64, b: f64, scale: i32) f64 {
216216 var sum = dd_add(a, b);
217217 if (sum.lo != 0) {
218 var uhii = @as(u64, @bitCast(sum.hi));
218 var uhii: u64 = @bitCast(sum.hi);
219219 const bits_lost = -@as(i32, @intCast((uhii >> 52) & 0x7FF)) - scale + 1;
220220 if ((bits_lost != 1) == (uhii & 1 != 0)) {
221 const uloi = @as(u64, @bitCast(sum.lo));
221 const uloi: u64 = @bitCast(sum.lo);
222222 uhii += 1 - (((uhii ^ uloi) >> 62) & 2);
223 sum.hi = @as(f64, @bitCast(uhii));
223 sum.hi = @bitCast(uhii);
224224 }
225225 }
226226 return math.scalbn(sum.hi, scale);
......@@ -257,12 +257,12 @@ fn dd_add128(a: f128, b: f128) dd128 {
257257fn add_adjusted128(a: f128, b: f128) f128 {
258258 var sum = dd_add128(a, b);
259259 if (sum.lo != 0) {
260 var uhii = @as(u128, @bitCast(sum.hi));
260 var uhii: u128 = @bitCast(sum.hi);
261261 if (uhii & 1 == 0) {
262262 // hibits += copysign(1.0, sum.hi, sum.lo)
263 const uloi = @as(u128, @bitCast(sum.lo));
263 const uloi: u128 = @bitCast(sum.lo);
264264 uhii += 1 - ((uhii ^ uloi) >> 126);
265 sum.hi = @as(f128, @bitCast(uhii));
265 sum.hi = @bitCast(uhii);
266266 }
267267 }
268268 return sum.hi;
......@@ -282,12 +282,12 @@ fn add_and_denorm128(a: f128, b: f128, scale: i32) f128 {
282282 // If we are losing only one bit to denormalization, however, we must
283283 // break the ties manually.
284284 if (sum.lo != 0) {
285 var uhii = @as(u128, @bitCast(sum.hi));
285 var uhii: u128 = @bitCast(sum.hi);
286286 const bits_lost = -@as(i32, @intCast((uhii >> 112) & 0x7FFF)) - scale + 1;
287287 if ((bits_lost != 1) == (uhii & 1 != 0)) {
288 const uloi = @as(u128, @bitCast(sum.lo));
288 const uloi: u128 = @bitCast(sum.lo);
289289 uhii += 1 - (((uhii ^ uloi) >> 126) & 2);
290 sum.hi = @as(f128, @bitCast(uhii));
290 sum.hi = @bitCast(uhii);
291291 }
292292 }
293293 return math.scalbn(sum.hi, scale);
lib/compiler_rt/fmod.zig+12-13
......@@ -82,8 +82,8 @@ pub fn __fmodx(a: f80, b: f80) callconv(.C) f80 {
8282
8383 var highA: u64 = 0;
8484 var highB: u64 = 0;
85 var lowA: u64 = @as(u64, @truncate(aRep));
86 var lowB: u64 = @as(u64, @truncate(bRep));
85 var lowA: u64 = @truncate(aRep);
86 var lowB: u64 = @truncate(bRep);
8787
8888 while (expA > expB) : (expA -= 1) {
8989 var high = highA -% highB;
......@@ -125,7 +125,7 @@ pub fn __fmodx(a: f80, b: f80) callconv(.C) f80 {
125125 if (expA < -fractionalBits) {
126126 return @bitCast(signA);
127127 } else if (expA <= 0) {
128 return @bitCast((lowA >> @as(math.Log2Int(u64), @intCast(1 - expA))) | signA);
128 return @bitCast((lowA >> @intCast(1 - expA)) | signA);
129129 } else {
130130 return @bitCast(lowA | (@as(Z, @as(u16, @intCast(expA))) << significandBits) | signA);
131131 }
......@@ -136,10 +136,10 @@ pub fn __fmodx(a: f80, b: f80) callconv(.C) f80 {
136136pub fn fmodq(a: f128, b: f128) callconv(.C) f128 {
137137 var amod = a;
138138 var bmod = b;
139 const aPtr_u64 = @as([*]u64, @ptrCast(&amod));
140 const bPtr_u64 = @as([*]u64, @ptrCast(&bmod));
141 const aPtr_u16 = @as([*]u16, @ptrCast(&amod));
142 const bPtr_u16 = @as([*]u16, @ptrCast(&bmod));
139 const aPtr_u64: [*]u64 = @ptrCast(&amod);
140 const bPtr_u64: [*]u64 = @ptrCast(&bmod);
141 const aPtr_u16: [*]u16 = @ptrCast(&amod);
142 const bPtr_u16: [*]u16 = @ptrCast(&bmod);
143143
144144 const exp_and_sign_index = comptime switch (builtin.target.cpu.arch.endian()) {
145145 .Little => 7,
......@@ -173,8 +173,8 @@ pub fn fmodq(a: f128, b: f128) callconv(.C) f128 {
173173 }
174174
175175 // Remove the sign from both
176 aPtr_u16[exp_and_sign_index] = @as(u16, @bitCast(@as(i16, @intCast(expA))));
177 bPtr_u16[exp_and_sign_index] = @as(u16, @bitCast(@as(i16, @intCast(expB))));
176 aPtr_u16[exp_and_sign_index] = @bitCast(@as(i16, @intCast(expA)));
177 bPtr_u16[exp_and_sign_index] = @bitCast(@as(i16, @intCast(expB)));
178178 if (amod <= bmod) {
179179 if (amod == bmod) {
180180 return 0 * a;
......@@ -264,7 +264,6 @@ pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.C) c_longdouble {
264264inline fn generic_fmod(comptime T: type, x: T, y: T) T {
265265 const bits = @typeInfo(T).Float.bits;
266266 const uint = std.meta.Int(.unsigned, bits);
267 const log2uint = math.Log2Int(uint);
268267 comptime assert(T == f32 or T == f64);
269268 const digits = if (T == f32) 23 else 52;
270269 const exp_bits = if (T == f32) 9 else 12;
......@@ -293,7 +292,7 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {
293292 ex -= 1;
294293 i <<= 1;
295294 }) {}
296 ux <<= @as(log2uint, @intCast(@as(u32, @bitCast(-ex + 1))));
295 ux <<= @intCast(@as(u32, @bitCast(-ex + 1)));
297296 } else {
298297 ux &= math.maxInt(uint) >> exp_bits;
299298 ux |= 1 << digits;
......@@ -304,7 +303,7 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {
304303 ey -= 1;
305304 i <<= 1;
306305 }) {}
307 uy <<= @as(log2uint, @intCast(@as(u32, @bitCast(-ey + 1))));
306 uy <<= @intCast(@as(u32, @bitCast(-ey + 1)));
308307 } else {
309308 uy &= math.maxInt(uint) >> exp_bits;
310309 uy |= 1 << digits;
......@@ -336,7 +335,7 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {
336335 ux -%= 1 << digits;
337336 ux |= @as(uint, @as(u32, @bitCast(ex))) << digits;
338337 } else {
339 ux >>= @as(log2uint, @intCast(@as(u32, @bitCast(-ex + 1))));
338 ux >>= @intCast(@as(u32, @bitCast(-ex + 1)));
340339 }
341340 if (T == f32) {
342341 ux |= sx;
lib/compiler_rt/int.zig+33-33
......@@ -52,8 +52,8 @@ test "test_divmodti4" {
5252 [_]i128{ -7, 5, -1, -2 },
5353 [_]i128{ 19, 5, 3, 4 },
5454 [_]i128{ 19, -5, -3, 4 },
55 [_]i128{ @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 8, @as(i128, @bitCast(@as(u128, 0xf0000000000000000000000000000000))), 0 },
56 [_]i128{ @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000007))), 8, @as(i128, @bitCast(@as(u128, 0xf0000000000000000000000000000001))), -1 },
55 [_]i128{ @bitCast(@as(u128, 0x80000000000000000000000000000000)), 8, @bitCast(@as(u128, 0xf0000000000000000000000000000000)), 0 },
56 [_]i128{ @bitCast(@as(u128, 0x80000000000000000000000000000007)), 8, @bitCast(@as(u128, 0xf0000000000000000000000000000001)), -1 },
5757 };
5858
5959 for (cases) |case| {
......@@ -85,8 +85,8 @@ test "test_divmoddi4" {
8585 [_]i64{ -7, 5, -1, -2 },
8686 [_]i64{ 19, 5, 3, 4 },
8787 [_]i64{ 19, -5, -3, 4 },
88 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 },
89 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 },
88 [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), 8, @bitCast(@as(u64, 0xf000000000000000)), 0 },
89 [_]i64{ @bitCast(@as(u64, 0x8000000000000007)), 8, @bitCast(@as(u64, 0xf000000000000001)), -1 },
9090 };
9191
9292 for (cases) |case| {
......@@ -110,14 +110,14 @@ test "test_udivmoddi4" {
110110
111111pub fn __divdi3(a: i64, b: i64) callconv(.C) i64 {
112112 // Set aside the sign of the quotient.
113 const sign = @as(u64, @bitCast((a ^ b) >> 63));
113 const sign: u64 = @bitCast((a ^ b) >> 63);
114114 // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63).
115115 const abs_a = (a ^ (a >> 63)) -% (a >> 63);
116116 const abs_b = (b ^ (b >> 63)) -% (b >> 63);
117117 // Unsigned division
118 const res = __udivmoddi4(@as(u64, @bitCast(abs_a)), @as(u64, @bitCast(abs_b)), null);
118 const res = __udivmoddi4(@bitCast(abs_a), @bitCast(abs_b), null);
119119 // Apply sign of quotient to result and return.
120 return @as(i64, @bitCast((res ^ sign) -% sign));
120 return @bitCast((res ^ sign) -% sign);
121121}
122122
123123test "test_divdi3" {
......@@ -151,7 +151,7 @@ pub fn __moddi3(a: i64, b: i64) callconv(.C) i64 {
151151 const abs_b = (b ^ (b >> 63)) -% (b >> 63);
152152 // Unsigned division
153153 var r: u64 = undefined;
154 _ = __udivmoddi4(@as(u64, @bitCast(abs_a)), @as(u64, @bitCast(abs_b)), &r);
154 _ = __udivmoddi4(@bitCast(abs_a), @bitCast(abs_b), &r);
155155 // Apply the sign of the dividend and return.
156156 return (@as(i64, @bitCast(r)) ^ (a >> 63)) -% (a >> 63);
157157}
......@@ -165,12 +165,12 @@ test "test_moddi3" {
165165 [_]i64{ -5, 3, -2 },
166166 [_]i64{ -5, -3, -2 },
167167
168 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1, 0 },
169 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -1, 0 },
170 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 2, 0 },
171 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -2, 0 },
172 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 3, -2 },
173 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -3, -2 },
168 [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), 1, 0 },
169 [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), -1, 0 },
170 [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), 2, 0 },
171 [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), -2, 0 },
172 [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), 3, -2 },
173 [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), -3, -2 },
174174 };
175175
176176 for (cases) |case| {
......@@ -225,8 +225,8 @@ test "test_divmodsi4" {
225225 [_]i32{ 19, 5, 3, 4 },
226226 [_]i32{ 19, -5, -3, 4 },
227227
228 [_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), 8, @as(i32, @bitCast(@as(u32, 0xf0000000))), 0 },
229 [_]i32{ @as(i32, @bitCast(@as(u32, 0x80000007))), 8, @as(i32, @bitCast(@as(u32, 0xf0000001))), -1 },
228 [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 },
229 [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 },
230230 };
231231
232232 for (cases) |case| {
......@@ -242,7 +242,7 @@ fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void {
242242
243243pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.C) u32 {
244244 const d = __udivsi3(a, b);
245 rem.* = @as(u32, @bitCast(@as(i32, @bitCast(a)) -% (@as(i32, @bitCast(d)) * @as(i32, @bitCast(b)))));
245 rem.* = @bitCast(@as(i32, @bitCast(a)) -% (@as(i32, @bitCast(d)) * @as(i32, @bitCast(b))));
246246 return d;
247247}
248248
......@@ -256,14 +256,14 @@ fn __aeabi_idiv(n: i32, d: i32) callconv(.AAPCS) i32 {
256256
257257inline fn div_i32(n: i32, d: i32) i32 {
258258 // Set aside the sign of the quotient.
259 const sign = @as(u32, @bitCast((n ^ d) >> 31));
259 const sign: u32 = @bitCast((n ^ d) >> 31);
260260 // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
261261 const abs_n = (n ^ (n >> 31)) -% (n >> 31);
262262 const abs_d = (d ^ (d >> 31)) -% (d >> 31);
263263 // abs(a) / abs(b)
264264 const res = @as(u32, @bitCast(abs_n)) / @as(u32, @bitCast(abs_d));
265265 // Apply sign of quotient to result and return.
266 return @as(i32, @bitCast((res ^ sign) -% sign));
266 return @bitCast((res ^ sign) -% sign);
267267}
268268
269269test "test_divsi3" {
......@@ -275,10 +275,10 @@ test "test_divsi3" {
275275 [_]i32{ -2, 1, -2 },
276276 [_]i32{ -2, -1, 2 },
277277
278 [_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), 1, @as(i32, @bitCast(@as(u32, 0x80000000))) },
279 [_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), -1, @as(i32, @bitCast(@as(u32, 0x80000000))) },
280 [_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), -2, 0x40000000 },
281 [_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), 2, @as(i32, @bitCast(@as(u32, 0xC0000000))) },
278 [_]i32{ @bitCast(@as(u32, 0x80000000)), 1, @bitCast(@as(u32, 0x80000000)) },
279 [_]i32{ @bitCast(@as(u32, 0x80000000)), -1, @bitCast(@as(u32, 0x80000000)) },
280 [_]i32{ @bitCast(@as(u32, 0x80000000)), -2, 0x40000000 },
281 [_]i32{ @bitCast(@as(u32, 0x80000000)), 2, @bitCast(@as(u32, 0xC0000000)) },
282282 };
283283
284284 for (cases) |case| {
......@@ -317,12 +317,12 @@ inline fn div_u32(n: u32, d: u32) u32 {
317317 sr += 1;
318318 // 1 <= sr <= n_uword_bits - 1
319319 // Not a special case
320 var q: u32 = n << @as(u5, @intCast(n_uword_bits - sr));
321 var r: u32 = n >> @as(u5, @intCast(sr));
320 var q: u32 = n << @intCast(n_uword_bits - sr);
321 var r: u32 = n >> @intCast(sr);
322322 var carry: u32 = 0;
323323 while (sr > 0) : (sr -= 1) {
324324 // r:q = ((r:q) << 1) | carry
325 r = (r << 1) | (q >> @as(u5, @intCast(n_uword_bits - 1)));
325 r = (r << 1) | (q >> @intCast(n_uword_bits - 1));
326326 q = (q << 1) | carry;
327327 // carry = 0;
328328 // if (r.all >= d.all)
......@@ -330,8 +330,8 @@ inline fn div_u32(n: u32, d: u32) u32 {
330330 // r.all -= d.all;
331331 // carry = 1;
332332 // }
333 const s = @as(i32, @bitCast(d -% r -% 1)) >> @as(u5, @intCast(n_uword_bits - 1));
334 carry = @as(u32, @intCast(s & 1));
333 const s = @as(i32, @bitCast(d -% r -% 1)) >> @intCast(n_uword_bits - 1);
334 carry = @intCast(s & 1);
335335 r -= d & @as(u32, @bitCast(s));
336336 }
337337 q = (q << 1) | carry;
......@@ -496,11 +496,11 @@ test "test_modsi3" {
496496 [_]i32{ 5, -3, 2 },
497497 [_]i32{ -5, 3, -2 },
498498 [_]i32{ -5, -3, -2 },
499 [_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 1, 0x0 },
500 [_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 2, 0x0 },
501 [_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), -2, 0x0 },
502 [_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 3, -2 },
503 [_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), -3, -2 },
499 [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), 1, 0x0 },
500 [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), 2, 0x0 },
501 [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), -2, 0x0 },
502 [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), 3, -2 },
503 [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), -3, -2 },
504504 };
505505
506506 for (cases) |case| {
lib/compiler_rt/int_from_float.zig+3-3
......@@ -17,7 +17,7 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I {
1717 const sig_mask = (@as(rep_t, 1) << sig_bits) - 1;
1818
1919 // Break a into sign, exponent, significand
20 const a_rep: rep_t = @as(rep_t, @bitCast(a));
20 const a_rep: rep_t = @bitCast(a);
2121 const negative = (a_rep >> (float_bits - 1)) != 0;
2222 const exponent = @as(i32, @intCast((a_rep << 1) >> (sig_bits + 1))) - exp_bias;
2323 const significand: rep_t = (a_rep & sig_mask) | implicit_bit;
......@@ -40,9 +40,9 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I {
4040 // Otherwise, shift left.
4141 var result: I = undefined;
4242 if (exponent < fractional_bits) {
43 result = @as(I, @intCast(significand >> @as(Log2Int(rep_t), @intCast(fractional_bits - exponent))));
43 result = @intCast(significand >> @intCast(fractional_bits - exponent));
4444 } else {
45 result = @as(I, @intCast(significand)) << @as(Log2Int(I), @intCast(exponent - fractional_bits));
45 result = @as(I, @intCast(significand)) << @intCast(exponent - fractional_bits);
4646 }
4747
4848 if ((@typeInfo(I).Int.signedness == .signed) and negative)
lib/compiler_rt/log10.zig+6-6
......@@ -28,7 +28,7 @@ comptime {
2828
2929pub fn __log10h(a: f16) callconv(.C) f16 {
3030 // TODO: more efficient implementation
31 return @as(f16, @floatCast(log10f(a)));
31 return @floatCast(log10f(a));
3232}
3333
3434pub fn log10f(x_: f32) callconv(.C) f32 {
......@@ -42,7 +42,7 @@ pub fn log10f(x_: f32) callconv(.C) f32 {
4242 const Lg4: f32 = 0xf89e26.0p-26;
4343
4444 var x = x_;
45 var u = @as(u32, @bitCast(x));
45 var u: u32 = @bitCast(x);
4646 var ix = u;
4747 var k: i32 = 0;
4848
......@@ -59,7 +59,7 @@ pub fn log10f(x_: f32) callconv(.C) f32 {
5959
6060 k -= 25;
6161 x *= 0x1.0p25;
62 ix = @as(u32, @bitCast(x));
62 ix = @bitCast(x);
6363 } else if (ix >= 0x7F800000) {
6464 return x;
6565 } else if (ix == 0x3F800000) {
......@@ -70,7 +70,7 @@ pub fn log10f(x_: f32) callconv(.C) f32 {
7070 ix += 0x3F800000 - 0x3F3504F3;
7171 k += @as(i32, @intCast(ix >> 23)) - 0x7F;
7272 ix = (ix & 0x007FFFFF) + 0x3F3504F3;
73 x = @as(f32, @bitCast(ix));
73 x = @bitCast(ix);
7474
7575 const f = x - 1.0;
7676 const s = f / (2.0 + f);
......@@ -168,12 +168,12 @@ pub fn log10(x_: f64) callconv(.C) f64 {
168168
169169pub fn __log10x(a: f80) callconv(.C) f80 {
170170 // TODO: more efficient implementation
171 return @as(f80, @floatCast(log10q(a)));
171 return @floatCast(log10q(a));
172172}
173173
174174pub fn log10q(a: f128) callconv(.C) f128 {
175175 // TODO: more correct implementation
176 return log10(@as(f64, @floatCast(a)));
176 return log10(@floatCast(a));
177177}
178178
179179pub fn log10l(x: c_longdouble) callconv(.C) c_longdouble {
lib/compiler_rt/modti3_test.zig+1-1
......@@ -33,5 +33,5 @@ fn make_ti(high: u64, low: u64) i128 {
3333 var result: u128 = high;
3434 result <<= 64;
3535 result |= low;
36 return @as(i128, @bitCast(result));
36 return @bitCast(result);
3737}
lib/compiler_rt/mulf3.zig+18-19
......@@ -29,16 +29,16 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
2929
3030 const absMask = signBit - 1;
3131 const qnanRep = @as(Z, @bitCast(math.nan(T))) | quietBit;
32 const infRep = @as(Z, @bitCast(math.inf(T)));
33 const minNormalRep = @as(Z, @bitCast(math.floatMin(T)));
32 const infRep: Z = @bitCast(math.inf(T));
33 const minNormalRep: Z = @bitCast(math.floatMin(T));
3434
3535 const ZExp = if (typeWidth >= 32) u32 else Z;
36 const aExponent = @as(ZExp, @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent));
37 const bExponent = @as(ZExp, @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent));
36 const aExponent: ZExp = @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent);
37 const bExponent: ZExp = @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent);
3838 const productSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit;
3939
40 var aSignificand: ZSignificand = @as(ZSignificand, @intCast(@as(Z, @bitCast(a)) & significandMask));
41 var bSignificand: ZSignificand = @as(ZSignificand, @intCast(@as(Z, @bitCast(b)) & significandMask));
40 var aSignificand: ZSignificand = @intCast(@as(Z, @bitCast(a)) & significandMask);
41 var bSignificand: ZSignificand = @intCast(@as(Z, @bitCast(b)) & significandMask);
4242 var scale: i32 = 0;
4343
4444 // Detect if a or b is zero, denormal, infinity, or NaN.
......@@ -47,9 +47,9 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
4747 const bAbs: Z = @as(Z, @bitCast(b)) & absMask;
4848
4949 // NaN * anything = qNaN
50 if (aAbs > infRep) return @as(T, @bitCast(@as(Z, @bitCast(a)) | quietBit));
50 if (aAbs > infRep) return @bitCast(@as(Z, @bitCast(a)) | quietBit);
5151 // anything * NaN = qNaN
52 if (bAbs > infRep) return @as(T, @bitCast(@as(Z, @bitCast(b)) | quietBit));
52 if (bAbs > infRep) return @bitCast(@as(Z, @bitCast(b)) | quietBit);
5353
5454 if (aAbs == infRep) {
5555 // infinity * non-zero = +/- infinity
......@@ -110,7 +110,7 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
110110 }
111111
112112 // If we have overflowed the type, return +/- infinity.
113 if (productExponent >= maxExponent) return @as(T, @bitCast(infRep | productSign));
113 if (productExponent >= maxExponent) return @bitCast(infRep | productSign);
114114
115115 var result: Z = undefined;
116116 if (productExponent <= 0) {
......@@ -120,8 +120,8 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
120120 // a zero of the appropriate sign. Mathematically there is no need to
121121 // handle this case separately, but we make it a special case to
122122 // simplify the shift logic.
123 const shift: u32 = @as(u32, @truncate(@as(Z, 1) -% @as(u32, @bitCast(productExponent))));
124 if (shift >= ZSignificandBits) return @as(T, @bitCast(productSign));
123 const shift: u32 = @truncate(@as(Z, 1) -% @as(u32, @bitCast(productExponent)));
124 if (shift >= ZSignificandBits) return @bitCast(productSign);
125125
126126 // Otherwise, shift the significand of the result so that the round
127127 // bit is the high bit of productLo.
......@@ -156,7 +156,7 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
156156 // Insert the sign of the result:
157157 result |= productSign;
158158
159 return @as(T, @bitCast(result));
159 return @bitCast(result);
160160}
161161
162162/// Returns `true` if the right shift is inexact (i.e. any bit shifted out is non-zero)
......@@ -165,15 +165,14 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
165165fn wideShrWithTruncation(comptime Z: type, hi: *Z, lo: *Z, count: u32) bool {
166166 @setRuntimeSafety(builtin.is_test);
167167 const typeWidth = @typeInfo(Z).Int.bits;
168 const S = math.Log2Int(Z);
169168 var inexact = false;
170169 if (count < typeWidth) {
171 inexact = (lo.* << @as(S, @intCast(typeWidth -% count))) != 0;
172 lo.* = (hi.* << @as(S, @intCast(typeWidth -% count))) | (lo.* >> @as(S, @intCast(count)));
173 hi.* = hi.* >> @as(S, @intCast(count));
170 inexact = (lo.* << @intCast(typeWidth -% count)) != 0;
171 lo.* = (hi.* << @intCast(typeWidth -% count)) | (lo.* >> @intCast(count));
172 hi.* = hi.* >> @intCast(count);
174173 } else if (count < 2 * typeWidth) {
175 inexact = (hi.* << @as(S, @intCast(2 * typeWidth -% count)) | lo.*) != 0;
176 lo.* = hi.* >> @as(S, @intCast(count -% typeWidth));
174 inexact = (hi.* << @intCast(2 * typeWidth -% count) | lo.*) != 0;
175 lo.* = hi.* >> @intCast(count -% typeWidth);
177176 hi.* = 0;
178177 } else {
179178 inexact = (hi.* | lo.*) != 0;
......@@ -188,7 +187,7 @@ fn normalize(comptime T: type, significand: *PowerOfTwoSignificandZ(T)) i32 {
188187 const integerBit = @as(Z, 1) << math.floatFractionalBits(T);
189188
190189 const shift = @clz(significand.*) - @clz(integerBit);
191 significand.* <<= @as(math.Log2Int(Z), @intCast(shift));
190 significand.* <<= @intCast(shift);
192191 return @as(i32, 1) - shift;
193192}
194193
lib/compiler_rt/parity.zig+2-7
......@@ -26,12 +26,7 @@ pub fn __parityti2(a: i128) callconv(.C) i32 {
2626}
2727
2828inline fn parityXi2(comptime T: type, a: T) i32 {
29 var x = switch (@bitSizeOf(T)) {
30 32 => @as(u32, @bitCast(a)),
31 64 => @as(u64, @bitCast(a)),
32 128 => @as(u128, @bitCast(a)),
33 else => unreachable,
34 };
29 var x: std.meta.Int(.unsigned, @typeInfo(T).Int.bits) = @bitCast(a);
3530 // Bit Twiddling Hacks: Compute parity in parallel
3631 comptime var shift: u8 = @bitSizeOf(T) / 2;
3732 inline while (shift > 2) {
......@@ -39,7 +34,7 @@ inline fn parityXi2(comptime T: type, a: T) i32 {
3934 shift = shift >> 1;
4035 }
4136 x &= 0xf;
42 return (@as(u16, @intCast(0x6996)) >> @as(u4, @intCast(x))) & 1; // optimization for >>2 and >>1
37 return (@as(u16, 0x6996) >> @intCast(x)) & 1; // optimization for >>2 and >>1
4338}
4439
4540test {
lib/compiler_rt/paritydi2_test.zig+5-5
......@@ -3,13 +3,13 @@ const parity = @import("parity.zig");
33const testing = std.testing;
44
55fn paritydi2Naive(a: i64) i32 {
6 var x = @as(u64, @bitCast(a));
6 var x: u64 = @bitCast(a);
77 var has_parity: bool = false;
88 while (x > 0) {
99 has_parity = !has_parity;
1010 x = x & (x - 1);
1111 }
12 return @as(i32, @intCast(@intFromBool(has_parity)));
12 return @intCast(@intFromBool(has_parity));
1313}
1414
1515fn test__paritydi2(a: i64) !void {
......@@ -22,9 +22,9 @@ test "paritydi2" {
2222 try test__paritydi2(0);
2323 try test__paritydi2(1);
2424 try test__paritydi2(2);
25 try test__paritydi2(@as(i64, @bitCast(@as(u64, 0xffffffff_fffffffd))));
26 try test__paritydi2(@as(i64, @bitCast(@as(u64, 0xffffffff_fffffffe))));
27 try test__paritydi2(@as(i64, @bitCast(@as(u64, 0xffffffff_ffffffff))));
25 try test__paritydi2(@bitCast(@as(u64, 0xffffffff_fffffffd)));
26 try test__paritydi2(@bitCast(@as(u64, 0xffffffff_fffffffe)));
27 try test__paritydi2(@bitCast(@as(u64, 0xffffffff_ffffffff)));
2828
2929 const RndGen = std.rand.DefaultPrng;
3030 var rnd = RndGen.init(42);
lib/compiler_rt/paritysi2_test.zig+5-5
......@@ -3,13 +3,13 @@ const parity = @import("parity.zig");
33const testing = std.testing;
44
55fn paritysi2Naive(a: i32) i32 {
6 var x = @as(u32, @bitCast(a));
6 var x: u32 = @bitCast(a);
77 var has_parity: bool = false;
88 while (x > 0) {
99 has_parity = !has_parity;
1010 x = x & (x - 1);
1111 }
12 return @as(i32, @intCast(@intFromBool(has_parity)));
12 return @intCast(@intFromBool(has_parity));
1313}
1414
1515fn test__paritysi2(a: i32) !void {
......@@ -22,9 +22,9 @@ test "paritysi2" {
2222 try test__paritysi2(0);
2323 try test__paritysi2(1);
2424 try test__paritysi2(2);
25 try test__paritysi2(@as(i32, @bitCast(@as(u32, 0xfffffffd))));
26 try test__paritysi2(@as(i32, @bitCast(@as(u32, 0xfffffffe))));
27 try test__paritysi2(@as(i32, @bitCast(@as(u32, 0xffffffff))));
25 try test__paritysi2(@bitCast(@as(u32, 0xfffffffd)));
26 try test__paritysi2(@bitCast(@as(u32, 0xfffffffe)));
27 try test__paritysi2(@bitCast(@as(u32, 0xffffffff)));
2828
2929 const RndGen = std.rand.DefaultPrng;
3030 var rnd = RndGen.init(42);
lib/compiler_rt/parityti2_test.zig+4-4
......@@ -9,7 +9,7 @@ fn parityti2Naive(a: i128) i32 {
99 has_parity = !has_parity;
1010 x = x & (x - 1);
1111 }
12 return @as(i32, @intCast(@intFromBool(has_parity)));
12 return @intCast(@intFromBool(has_parity));
1313}
1414
1515fn test__parityti2(a: i128) !void {
......@@ -22,9 +22,9 @@ test "parityti2" {
2222 try test__parityti2(0);
2323 try test__parityti2(1);
2424 try test__parityti2(2);
25 try test__parityti2(@as(i128, @bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_fffffffd))));
26 try test__parityti2(@as(i128, @bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_fffffffe))));
27 try test__parityti2(@as(i128, @bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_ffffffff))));
25 try test__parityti2(@bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_fffffffd)));
26 try test__parityti2(@bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_fffffffe)));
27 try test__parityti2(@bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_ffffffff)));
2828
2929 const RndGen = std.rand.DefaultPrng;
3030 var rnd = RndGen.init(42);
lib/compiler_rt/popcount.zig+2-2
......@@ -37,7 +37,7 @@ inline fn popcountXi2(comptime ST: type, a: ST) i32 {
3737 i128 => u128,
3838 else => unreachable,
3939 };
40 var x = @as(UT, @bitCast(a));
40 var x: UT = @bitCast(a);
4141 x -= (x >> 1) & (~@as(UT, 0) / 3); // 0x55...55, aggregate duos
4242 x = ((x >> 2) & (~@as(UT, 0) / 5)) // 0x33...33, aggregate nibbles
4343 + (x & (~@as(UT, 0) / 5));
......@@ -46,7 +46,7 @@ inline fn popcountXi2(comptime ST: type, a: ST) i32 {
4646 // 8 most significant bits of x + (x<<8) + (x<<16) + ..
4747 x *%= ~@as(UT, 0) / 255; // 0x01...01
4848 x >>= (@bitSizeOf(ST) - 8);
49 return @as(i32, @intCast(x));
49 return @intCast(x);
5050}
5151
5252test {
lib/compiler_rt/rem_pio2.zig+6-10
......@@ -25,10 +25,6 @@ const pio2_3 = 2.02226624871116645580e-21; // 0x3BA3198A, 0x2E000000
2525// pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
2626const pio2_3t = 8.47842766036889956997e-32; // 0x397B839A, 0x252049C1
2727
28fn U(x: anytype) usize {
29 return @as(usize, @intCast(x));
30}
31
3228fn medium(ix: u32, x: f64, y: *[2]f64) i32 {
3329 var w: f64 = undefined;
3430 var t: f64 = undefined;
......@@ -41,7 +37,7 @@ fn medium(ix: u32, x: f64, y: *[2]f64) i32 {
4137
4238 // rint(x/(pi/2))
4339 @"fn" = x * invpio2 + toint - toint;
44 n = @as(i32, @intFromFloat(@"fn"));
40 n = @intFromFloat(@"fn");
4541 r = x - @"fn" * pio2_1;
4642 w = @"fn" * pio2_1t; // 1st round, good to 85 bits
4743 // Matters with directed rounding.
......@@ -174,16 +170,16 @@ pub fn rem_pio2(x: f64, y: *[2]f64) i32 {
174170 ui = @bitCast(x);
175171 ui &= std.math.maxInt(u64) >> 12;
176172 ui |= @as(u64, 0x3ff + 23) << 52;
177 z = @as(f64, @bitCast(ui));
173 z = @bitCast(ui);
178174
179175 i = 0;
180176 while (i < 2) : (i += 1) {
181 tx[U(i)] = @as(f64, @floatFromInt(@as(i32, @intFromFloat(z))));
182 z = (z - tx[U(i)]) * 0x1p24;
177 tx[@intCast(i)] = @floatFromInt(@as(i32, @intFromFloat(z)));
178 z = (z - tx[@intCast(i)]) * 0x1p24;
183179 }
184 tx[U(i)] = z;
180 tx[@intCast(i)] = z;
185181 // skip zero terms, first term is non-zero
186 while (tx[U(i)] == 0.0) {
182 while (tx[@intCast(i)] == 0.0) {
187183 i -= 1;
188184 }
189185 n = rem_pio2_large(tx[0..], ty[0..], @as(i32, @intCast((ix >> 20))) - (0x3ff + 23), i + 1, 1);
lib/compiler_rt/rem_pio2_large.zig+38-42
......@@ -149,10 +149,6 @@ const PIo2 = [_]f64{
149149 2.16741683877804819444e-51, // 0x3569F31D, 0x00000000
150150};
151151
152fn U(x: anytype) usize {
153 return @as(usize, @intCast(x));
154}
155
156152/// Returns the last three digits of N with y = x - N*pi/2 so that |y| < pi/2.
157153///
158154/// The method is to compute the integer (mod 8) and fraction parts of
......@@ -295,7 +291,7 @@ pub fn rem_pio2_large(x: []f64, y: []f64, e0: i32, nx: i32, prec: usize) i32 {
295291 i += 1;
296292 j += 1;
297293 }) {
298 f[U(i)] = if (j < 0) 0.0 else @as(f64, @floatFromInt(ipio2[U(j)]));
294 f[@intCast(i)] = if (j < 0) 0.0 else @floatFromInt(ipio2[@intCast(j)]);
299295 }
300296
301297 // compute q[0],q[1],...q[jk]
......@@ -304,9 +300,9 @@ pub fn rem_pio2_large(x: []f64, y: []f64, e0: i32, nx: i32, prec: usize) i32 {
304300 j = 0;
305301 fw = 0;
306302 while (j <= jx) : (j += 1) {
307 fw += x[U(j)] * f[U(jx + i - j)];
303 fw += x[@intCast(j)] * f[@intCast(jx + i - j)];
308304 }
309 q[U(i)] = fw;
305 q[@intCast(i)] = fw;
310306 }
311307
312308 jz = jk;
......@@ -317,29 +313,29 @@ pub fn rem_pio2_large(x: []f64, y: []f64, e0: i32, nx: i32, prec: usize) i32 {
317313 // distill q[] into iq[] reversingly
318314 i = 0;
319315 j = jz;
320 z = q[U(jz)];
316 z = q[@intCast(jz)];
321317 while (j > 0) : ({
322318 i += 1;
323319 j -= 1;
324320 }) {
325321 fw = @floatFromInt(@as(i32, @intFromFloat(0x1p-24 * z)));
326 iq[U(i)] = @as(i32, @intFromFloat(z - 0x1p24 * fw));
327 z = q[U(j - 1)] + fw;
322 iq[@intCast(i)] = @intFromFloat(z - 0x1p24 * fw);
323 z = q[@intCast(j - 1)] + fw;
328324 }
329325
330326 // compute n
331327 z = math.scalbn(z, q0); // actual value of z
332328 z -= 8.0 * @floor(z * 0.125); // trim off integer >= 8
333329 n = @intFromFloat(z);
334 z -= @as(f64, @floatFromInt(n));
330 z -= @floatFromInt(n);
335331 ih = 0;
336332 if (q0 > 0) { // need iq[jz-1] to determine n
337 i = iq[U(jz - 1)] >> @as(u5, @intCast(24 - q0));
333 i = iq[@intCast(jz - 1)] >> @intCast(24 - q0);
338334 n += i;
339 iq[U(jz - 1)] -= i << @as(u5, @intCast(24 - q0));
340 ih = iq[U(jz - 1)] >> @as(u5, @intCast(23 - q0));
335 iq[@intCast(jz - 1)] -= i << @intCast(24 - q0);
336 ih = iq[@intCast(jz - 1)] >> @intCast(23 - q0);
341337 } else if (q0 == 0) {
342 ih = iq[U(jz - 1)] >> 23;
338 ih = iq[@intCast(jz - 1)] >> 23;
343339 } else if (z >= 0.5) {
344340 ih = 2;
345341 }
......@@ -349,20 +345,20 @@ pub fn rem_pio2_large(x: []f64, y: []f64, e0: i32, nx: i32, prec: usize) i32 {
349345 carry = 0;
350346 i = 0;
351347 while (i < jz) : (i += 1) { // compute 1-q
352 j = iq[U(i)];
348 j = iq[@intCast(i)];
353349 if (carry == 0) {
354350 if (j != 0) {
355351 carry = 1;
356 iq[U(i)] = 0x1000000 - j;
352 iq[@intCast(i)] = 0x1000000 - j;
357353 }
358354 } else {
359 iq[U(i)] = 0xffffff - j;
355 iq[@intCast(i)] = 0xffffff - j;
360356 }
361357 }
362358 if (q0 > 0) { // rare case: chance is 1 in 12
363359 switch (q0) {
364 1 => iq[U(jz - 1)] &= 0x7fffff,
365 2 => iq[U(jz - 1)] &= 0x3fffff,
360 1 => iq[@intCast(jz - 1)] &= 0x7fffff,
361 2 => iq[@intCast(jz - 1)] &= 0x3fffff,
366362 else => unreachable,
367363 }
368364 }
......@@ -379,24 +375,24 @@ pub fn rem_pio2_large(x: []f64, y: []f64, e0: i32, nx: i32, prec: usize) i32 {
379375 j = 0;
380376 i = jz - 1;
381377 while (i >= jk) : (i -= 1) {
382 j |= iq[U(i)];
378 j |= iq[@intCast(i)];
383379 }
384380
385381 if (j == 0) { // need recomputation
386382 k = 1;
387 while (iq[U(jk - k)] == 0) : (k += 1) {
383 while (iq[@intCast(jk - k)] == 0) : (k += 1) {
388384 // k = no. of terms needed
389385 }
390386
391387 i = jz + 1;
392388 while (i <= jz + k) : (i += 1) { // add q[jz+1] to q[jz+k]
393 f[U(jx + i)] = @as(f64, @floatFromInt(ipio2[U(jv + i)]));
389 f[@intCast(jx + i)] = @floatFromInt(ipio2[@intCast(jv + i)]);
394390 j = 0;
395391 fw = 0;
396392 while (j <= jx) : (j += 1) {
397 fw += x[U(j)] * f[U(jx + i - j)];
393 fw += x[@intCast(j)] * f[@intCast(jx + i - j)];
398394 }
399 q[U(i)] = fw;
395 q[@intCast(i)] = fw;
400396 }
401397 jz += k;
402398 continue :recompute; // mimic goto recompute
......@@ -407,7 +403,7 @@ pub fn rem_pio2_large(x: []f64, y: []f64, e0: i32, nx: i32, prec: usize) i32 {
407403 if (z == 0.0) {
408404 jz -= 1;
409405 q0 -= 24;
410 while (iq[U(jz)] == 0) {
406 while (iq[@intCast(jz)] == 0) {
411407 jz -= 1;
412408 q0 -= 24;
413409 }
......@@ -415,12 +411,12 @@ pub fn rem_pio2_large(x: []f64, y: []f64, e0: i32, nx: i32, prec: usize) i32 {
415411 z = math.scalbn(z, -q0);
416412 if (z >= 0x1p24) {
417413 fw = @floatFromInt(@as(i32, @intFromFloat(0x1p-24 * z)));
418 iq[U(jz)] = @as(i32, @intFromFloat(z - 0x1p24 * fw));
414 iq[@intCast(jz)] = @intFromFloat(z - 0x1p24 * fw);
419415 jz += 1;
420416 q0 += 24;
421 iq[U(jz)] = @as(i32, @intFromFloat(fw));
417 iq[@intCast(jz)] = @intFromFloat(fw);
422418 } else {
423 iq[U(jz)] = @as(i32, @intFromFloat(z));
419 iq[@intCast(jz)] = @intFromFloat(z);
424420 }
425421 }
426422
......@@ -428,7 +424,7 @@ pub fn rem_pio2_large(x: []f64, y: []f64, e0: i32, nx: i32, prec: usize) i32 {
428424 fw = math.scalbn(@as(f64, 1.0), q0);
429425 i = jz;
430426 while (i >= 0) : (i -= 1) {
431 q[U(i)] = fw * @as(f64, @floatFromInt(iq[U(i)]));
427 q[@intCast(i)] = fw * @as(f64, @floatFromInt(iq[@intCast(i)]));
432428 fw *= 0x1p-24;
433429 }
434430
......@@ -438,9 +434,9 @@ pub fn rem_pio2_large(x: []f64, y: []f64, e0: i32, nx: i32, prec: usize) i32 {
438434 fw = 0;
439435 k = 0;
440436 while (k <= jp and k <= jz - i) : (k += 1) {
441 fw += PIo2[U(k)] * q[U(i + k)];
437 fw += PIo2[@intCast(k)] * q[@intCast(i + k)];
442438 }
443 fq[U(jz - i)] = fw;
439 fq[@intCast(jz - i)] = fw;
444440 }
445441
446442 // compress fq[] into y[]
......@@ -449,7 +445,7 @@ pub fn rem_pio2_large(x: []f64, y: []f64, e0: i32, nx: i32, prec: usize) i32 {
449445 fw = 0.0;
450446 i = jz;
451447 while (i >= 0) : (i -= 1) {
452 fw += fq[U(i)];
448 fw += fq[@intCast(i)];
453449 }
454450 y[0] = if (ih == 0) fw else -fw;
455451 },
......@@ -458,7 +454,7 @@ pub fn rem_pio2_large(x: []f64, y: []f64, e0: i32, nx: i32, prec: usize) i32 {
458454 fw = 0.0;
459455 i = jz;
460456 while (i >= 0) : (i -= 1) {
461 fw += fq[U(i)];
457 fw += fq[@intCast(i)];
462458 }
463459 // TODO: drop excess precision here once double_t is used
464460 fw = fw;
......@@ -466,27 +462,27 @@ pub fn rem_pio2_large(x: []f64, y: []f64, e0: i32, nx: i32, prec: usize) i32 {
466462 fw = fq[0] - fw;
467463 i = 1;
468464 while (i <= jz) : (i += 1) {
469 fw += fq[U(i)];
465 fw += fq[@intCast(i)];
470466 }
471467 y[1] = if (ih == 0) fw else -fw;
472468 },
473469 3 => { // painful
474470 i = jz;
475471 while (i > 0) : (i -= 1) {
476 fw = fq[U(i - 1)] + fq[U(i)];
477 fq[U(i)] += fq[U(i - 1)] - fw;
478 fq[U(i - 1)] = fw;
472 fw = fq[@intCast(i - 1)] + fq[@intCast(i)];
473 fq[@intCast(i)] += fq[@intCast(i - 1)] - fw;
474 fq[@intCast(i - 1)] = fw;
479475 }
480476 i = jz;
481477 while (i > 1) : (i -= 1) {
482 fw = fq[U(i - 1)] + fq[U(i)];
483 fq[U(i)] += fq[U(i - 1)] - fw;
484 fq[U(i - 1)] = fw;
478 fw = fq[@intCast(i - 1)] + fq[@intCast(i)];
479 fq[@intCast(i)] += fq[@intCast(i - 1)] - fw;
480 fq[@intCast(i - 1)] = fw;
485481 }
486482 fw = 0;
487483 i = jz;
488484 while (i >= 2) : (i -= 1) {
489 fw += fq[U(i)];
485 fw += fq[@intCast(i)];
490486 }
491487 if (ih == 0) {
492488 y[0] = fq[0];
lib/compiler_rt/shift.zig+12-18
......@@ -30,20 +30,19 @@ comptime {
3030// Precondition: 0 <= b < bits_in_dword
3131inline fn ashlXi3(comptime T: type, a: T, b: i32) T {
3232 const word_t = common.HalveInt(T, false);
33 const S = Log2Int(word_t.HalfT);
3433
3534 const input = word_t{ .all = a };
3635 var output: word_t = undefined;
3736
3837 if (b >= word_t.bits) {
3938 output.s.low = 0;
40 output.s.high = input.s.low << @as(S, @intCast(b - word_t.bits));
39 output.s.high = input.s.low << @intCast(b - word_t.bits);
4140 } else if (b == 0) {
4241 return a;
4342 } else {
44 output.s.low = input.s.low << @as(S, @intCast(b));
45 output.s.high = input.s.high << @as(S, @intCast(b));
46 output.s.high |= input.s.low >> @as(S, @intCast(word_t.bits - b));
43 output.s.low = input.s.low << @intCast(b);
44 output.s.high = input.s.high << @intCast(b);
45 output.s.high |= input.s.low >> @intCast(word_t.bits - b);
4746 }
4847
4948 return output.all;
......@@ -53,24 +52,20 @@ inline fn ashlXi3(comptime T: type, a: T, b: i32) T {
5352// Precondition: 0 <= b < T.bit_count
5453inline fn ashrXi3(comptime T: type, a: T, b: i32) T {
5554 const word_t = common.HalveInt(T, true);
56 const S = Log2Int(word_t.HalfT);
5755
5856 const input = word_t{ .all = a };
5957 var output: word_t = undefined;
6058
6159 if (b >= word_t.bits) {
6260 output.s.high = input.s.high >> (word_t.bits - 1);
63 output.s.low = input.s.high >> @as(S, @intCast(b - word_t.bits));
61 output.s.low = input.s.high >> @intCast(b - word_t.bits);
6462 } else if (b == 0) {
6563 return a;
6664 } else {
67 output.s.high = input.s.high >> @as(S, @intCast(b));
68 output.s.low = input.s.high << @as(S, @intCast(word_t.bits - b));
65 output.s.high = input.s.high >> @intCast(b);
66 output.s.low = input.s.high << @intCast(word_t.bits - b);
6967 // Avoid sign-extension here
70 output.s.low |= @as(
71 word_t.HalfT,
72 @bitCast(@as(word_t.HalfTU, @bitCast(input.s.low)) >> @as(S, @intCast(b))),
73 );
68 output.s.low |= @bitCast(@as(word_t.HalfTU, @bitCast(input.s.low)) >> @intCast(b));
7469 }
7570
7671 return output.all;
......@@ -80,20 +75,19 @@ inline fn ashrXi3(comptime T: type, a: T, b: i32) T {
8075// Precondition: 0 <= b < T.bit_count
8176inline fn lshrXi3(comptime T: type, a: T, b: i32) T {
8277 const word_t = common.HalveInt(T, false);
83 const S = Log2Int(word_t.HalfT);
8478
8579 const input = word_t{ .all = a };
8680 var output: word_t = undefined;
8781
8882 if (b >= word_t.bits) {
8983 output.s.high = 0;
90 output.s.low = input.s.high >> @as(S, @intCast(b - word_t.bits));
84 output.s.low = input.s.high >> @intCast(b - word_t.bits);
9185 } else if (b == 0) {
9286 return a;
9387 } else {
94 output.s.high = input.s.high >> @as(S, @intCast(b));
95 output.s.low = input.s.high << @as(S, @intCast(word_t.bits - b));
96 output.s.low |= input.s.low >> @as(S, @intCast(b));
88 output.s.high = input.s.high >> @intCast(b);
89 output.s.low = input.s.high << @intCast(word_t.bits - b);
90 output.s.low |= input.s.low >> @intCast(b);
9791 }
9892
9993 return output.all;
lib/compiler_rt/sin.zig+6-6
......@@ -31,7 +31,7 @@ comptime {
3131
3232pub fn __sinh(x: f16) callconv(.C) f16 {
3333 // TODO: more efficient implementation
34 return @as(f16, @floatCast(sinf(x)));
34 return @floatCast(sinf(x));
3535}
3636
3737pub fn sinf(x: f32) callconv(.C) f32 {
......@@ -41,7 +41,7 @@ pub fn sinf(x: f32) callconv(.C) f32 {
4141 const s3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2
4242 const s4pio2: f64 = 4.0 * math.pi / 2.0; // 0x401921FB, 0x54442D18
4343
44 var ix = @as(u32, @bitCast(x));
44 var ix: u32 = @bitCast(x);
4545 const sign = ix >> 31 != 0;
4646 ix &= 0x7fffffff;
4747
......@@ -120,12 +120,12 @@ pub fn sin(x: f64) callconv(.C) f64 {
120120
121121pub fn __sinx(x: f80) callconv(.C) f80 {
122122 // TODO: more efficient implementation
123 return @as(f80, @floatCast(sinq(x)));
123 return @floatCast(sinq(x));
124124}
125125
126126pub fn sinq(x: f128) callconv(.C) f128 {
127127 // TODO: more correct implementation
128 return sin(@as(f64, @floatCast(x)));
128 return sin(@floatCast(x));
129129}
130130
131131pub fn sinl(x: c_longdouble) callconv(.C) c_longdouble {
......@@ -180,11 +180,11 @@ test "sin64.special" {
180180}
181181
182182test "sin32 #9901" {
183 const float = @as(f32, @bitCast(@as(u32, 0b11100011111111110000000000000000)));
183 const float: f32 = @bitCast(@as(u32, 0b11100011111111110000000000000000));
184184 _ = sinf(float);
185185}
186186
187187test "sin64 #9901" {
188 const float = @as(f64, @bitCast(@as(u64, 0b1111111101000001000000001111110111111111100000000000000000000001)));
188 const float: f64 = @bitCast(@as(u64, 0b1111111101000001000000001111110111111111100000000000000000000001));
189189 _ = sin(float);
190190}
lib/compiler_rt/sqrt.zig+13-13
......@@ -20,13 +20,13 @@ comptime {
2020
2121pub fn __sqrth(x: f16) callconv(.C) f16 {
2222 // TODO: more efficient implementation
23 return @as(f16, @floatCast(sqrtf(x)));
23 return @floatCast(sqrtf(x));
2424}
2525
2626pub fn sqrtf(x: f32) callconv(.C) f32 {
2727 const tiny: f32 = 1.0e-30;
28 const sign: i32 = @as(i32, @bitCast(@as(u32, 0x80000000)));
29 var ix: i32 = @as(i32, @bitCast(x));
28 const sign: i32 = @bitCast(@as(u32, 0x80000000));
29 var ix: i32 = @bitCast(x);
3030
3131 if ((ix & 0x7F800000) == 0x7F800000) {
3232 return x * x + x; // sqrt(nan) = nan, sqrt(+inf) = +inf, sqrt(-inf) = nan
......@@ -96,7 +96,7 @@ pub fn sqrtf(x: f32) callconv(.C) f32 {
9696
9797 ix = (q >> 1) + 0x3f000000;
9898 ix += m << 23;
99 return @as(f32, @bitCast(ix));
99 return @bitCast(ix);
100100}
101101
102102/// NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound
......@@ -105,10 +105,10 @@ pub fn sqrtf(x: f32) callconv(.C) f32 {
105105pub fn sqrt(x: f64) callconv(.C) f64 {
106106 const tiny: f64 = 1.0e-300;
107107 const sign: u32 = 0x80000000;
108 const u = @as(u64, @bitCast(x));
108 const u: u64 = @bitCast(x);
109109
110 var ix0 = @as(u32, @intCast(u >> 32));
111 var ix1 = @as(u32, @intCast(u & 0xFFFFFFFF));
110 var ix0: u32 = @intCast(u >> 32);
111 var ix1: u32 = @intCast(u & 0xFFFFFFFF);
112112
113113 // sqrt(nan) = nan, sqrt(+inf) = +inf, sqrt(-inf) = nan
114114 if (ix0 & 0x7FF00000 == 0x7FF00000) {
......@@ -140,8 +140,8 @@ pub fn sqrt(x: f64) callconv(.C) f64 {
140140 ix0 <<= 1;
141141 }
142142 m -= @as(i32, @intCast(i)) - 1;
143 ix0 |= ix1 >> @as(u5, @intCast(32 - i));
144 ix1 <<= @as(u5, @intCast(i));
143 ix0 |= ix1 >> @intCast(32 - i);
144 ix1 <<= @intCast(i);
145145 }
146146
147147 // unbias exponent
......@@ -225,21 +225,21 @@ pub fn sqrt(x: f64) callconv(.C) f64 {
225225
226226 // NOTE: musl here appears to rely on signed twos-complement wraparound. +% has the same
227227 // behaviour at least.
228 var iix0 = @as(i32, @intCast(ix0));
228 var iix0: i32 = @intCast(ix0);
229229 iix0 = iix0 +% (m << 20);
230230
231231 const uz = (@as(u64, @intCast(iix0)) << 32) | ix1;
232 return @as(f64, @bitCast(uz));
232 return @bitCast(uz);
233233}
234234
235235pub fn __sqrtx(x: f80) callconv(.C) f80 {
236236 // TODO: more efficient implementation
237 return @as(f80, @floatCast(sqrtq(x)));
237 return @floatCast(sqrtq(x));
238238}
239239
240240pub fn sqrtq(x: f128) callconv(.C) f128 {
241241 // TODO: more correct implementation
242 return sqrt(@as(f64, @floatCast(x)));
242 return sqrt(@floatCast(x));
243243}
244244
245245pub fn sqrtl(x: c_longdouble) callconv(.C) c_longdouble {
lib/compiler_rt/subdf3.zig+7-3
......@@ -1,4 +1,5 @@
11const common = @import("./common.zig");
2const addf3 = @import("./addf3.zig").addf3;
23
34pub const panic = common.panic;
45
......@@ -11,11 +12,14 @@ comptime {
1112}
1213
1314fn __subdf3(a: f64, b: f64) callconv(.C) f64 {
14 const neg_b = @as(f64, @bitCast(@as(u64, @bitCast(b)) ^ (@as(u64, 1) << 63)));
15 return a + neg_b;
15 return sub(a, b);
1616}
1717
1818fn __aeabi_dsub(a: f64, b: f64) callconv(.AAPCS) f64 {
19 return sub(a, b);
20}
21
22inline fn sub(a: f64, b: f64) f64 {
1923 const neg_b = @as(f64, @bitCast(@as(u64, @bitCast(b)) ^ (@as(u64, 1) << 63)));
20 return a + neg_b;
24 return addf3(f64, a, neg_b);
2125}
lib/compiler_rt/subhf3.zig+2-1
......@@ -1,4 +1,5 @@
11const common = @import("./common.zig");
2const addf3 = @import("./addf3.zig").addf3;
23
34pub const panic = common.panic;
45
......@@ -8,5 +9,5 @@ comptime {
89
910fn __subhf3(a: f16, b: f16) callconv(.C) f16 {
1011 const neg_b = @as(f16, @bitCast(@as(u16, @bitCast(b)) ^ (@as(u16, 1) << 15)));
11 return a + neg_b;
12 return addf3(f16, a, neg_b);
1213}
lib/compiler_rt/subsf3.zig+7-3
......@@ -1,4 +1,5 @@
11const common = @import("./common.zig");
2const addf3 = @import("./addf3.zig").addf3;
23
34pub const panic = common.panic;
45
......@@ -11,11 +12,14 @@ comptime {
1112}
1213
1314fn __subsf3(a: f32, b: f32) callconv(.C) f32 {
14 const neg_b = @as(f32, @bitCast(@as(u32, @bitCast(b)) ^ (@as(u32, 1) << 31)));
15 return a + neg_b;
15 return sub(a, b);
1616}
1717
1818fn __aeabi_fsub(a: f32, b: f32) callconv(.AAPCS) f32 {
19 return sub(a, b);
20}
21
22inline fn sub(a: f32, b: f32) f32 {
1923 const neg_b = @as(f32, @bitCast(@as(u32, @bitCast(b)) ^ (@as(u32, 1) << 31)));
20 return a + neg_b;
24 return addf3(f32, a, neg_b);
2125}
lib/compiler_rt/subtf3.zig+2-1
......@@ -1,4 +1,5 @@
11const common = @import("./common.zig");
2const addf3 = @import("./addf3.zig").addf3;
23
34pub const panic = common.panic;
45
......@@ -21,5 +22,5 @@ fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.C) void {
2122
2223inline fn sub(a: f128, b: f128) f128 {
2324 const neg_b = @as(f128, @bitCast(@as(u128, @bitCast(b)) ^ (@as(u128, 1) << 127)));
24 return a + neg_b;
25 return addf3(f128, a, neg_b);
2526}
lib/compiler_rt/tan.zig+2-2
......@@ -106,12 +106,12 @@ pub fn tan(x: f64) callconv(.C) f64 {
106106
107107pub fn __tanx(x: f80) callconv(.C) f80 {
108108 // TODO: more efficient implementation
109 return @as(f80, @floatCast(tanq(x)));
109 return @floatCast(tanq(x));
110110}
111111
112112pub fn tanq(x: f128) callconv(.C) f128 {
113113 // TODO: more correct implementation
114 return tan(@as(f64, @floatCast(x)));
114 return tan(@floatCast(x));
115115}
116116
117117pub fn tanl(x: c_longdouble) callconv(.C) c_longdouble {
lib/compiler_rt/trig.zig+5-5
......@@ -70,7 +70,7 @@ pub fn __cosdf(x: f64) f32 {
7070 const z = x * x;
7171 const w = z * z;
7272 const r = C2 + z * C3;
73 return @as(f32, @floatCast(((1.0 + z * C0) + w * C1) + (w * z) * r));
73 return @floatCast(((1.0 + z * C0) + w * C1) + (w * z) * r);
7474}
7575
7676/// kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
......@@ -131,7 +131,7 @@ pub fn __sindf(x: f64) f32 {
131131 const w = z * z;
132132 const r = S3 + z * S4;
133133 const s = z * x;
134 return @as(f32, @floatCast((x + s * (S1 + z * S2)) + s * w * r));
134 return @floatCast((x + s * (S1 + z * S2)) + s * w * r);
135135}
136136
137137/// kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
......@@ -231,11 +231,11 @@ pub fn __tan(x_: f64, y_: f64, odd: bool) f64 {
231231 }
232232 // -1.0/(x+r) has up to 2ulp error, so compute it accurately
233233 w0 = w;
234 w0 = @as(f64, @bitCast(@as(u64, @bitCast(w0)) & 0xffffffff00000000));
234 w0 = @bitCast(@as(u64, @bitCast(w0)) & 0xffffffff00000000);
235235 v = r - (w0 - x); // w0+v = r+x
236236 a = -1.0 / w;
237237 a0 = a;
238 a0 = @as(f64, @bitCast(@as(u64, @bitCast(a0)) & 0xffffffff00000000));
238 a0 = @bitCast(@as(u64, @bitCast(a0)) & 0xffffffff00000000);
239239 return a0 + a * (1.0 + a0 * w0 + a0 * v);
240240}
241241
......@@ -269,5 +269,5 @@ pub fn __tandf(x: f64, odd: bool) f32 {
269269 const s = z * x;
270270 const u = T[0] + z * T[1];
271271 const r0 = (x + s * u) + (s * w) * (t + w * r);
272 return @as(f32, @floatCast(if (odd) -1.0 / r0 else r0));
272 return @floatCast(if (odd) -1.0 / r0 else r0);
273273}
lib/compiler_rt/trunc.zig+6-6
......@@ -42,7 +42,7 @@ pub fn truncf(x: f32) callconv(.C) f32 {
4242 e = 1;
4343 }
4444
45 m = @as(u32, math.maxInt(u32)) >> @as(u5, @intCast(e));
45 m = @as(u32, math.maxInt(u32)) >> @intCast(e);
4646 if (u & m == 0) {
4747 return x;
4848 } else {
......@@ -63,7 +63,7 @@ pub fn trunc(x: f64) callconv(.C) f64 {
6363 e = 1;
6464 }
6565
66 m = @as(u64, math.maxInt(u64)) >> @as(u6, @intCast(e));
66 m = @as(u64, math.maxInt(u64)) >> @intCast(e);
6767 if (u & m == 0) {
6868 return x;
6969 } else {
......@@ -74,11 +74,11 @@ pub fn trunc(x: f64) callconv(.C) f64 {
7474
7575pub fn __truncx(x: f80) callconv(.C) f80 {
7676 // TODO: more efficient implementation
77 return @as(f80, @floatCast(truncq(x)));
77 return @floatCast(truncq(x));
7878}
7979
8080pub fn truncq(x: f128) callconv(.C) f128 {
81 const u = @as(u128, @bitCast(x));
81 const u: u128 = @bitCast(x);
8282 var e = @as(i32, @intCast(((u >> 112) & 0x7FFF))) - 0x3FFF + 16;
8383 var m: u128 = undefined;
8484
......@@ -89,12 +89,12 @@ pub fn truncq(x: f128) callconv(.C) f128 {
8989 e = 1;
9090 }
9191
92 m = @as(u128, math.maxInt(u128)) >> @as(u7, @intCast(e));
92 m = @as(u128, math.maxInt(u128)) >> @intCast(e);
9393 if (u & m == 0) {
9494 return x;
9595 } else {
9696 math.doNotOptimizeAway(x + 0x1p120);
97 return @as(f128, @bitCast(u & ~m));
97 return @bitCast(u & ~m);
9898 }
9999}
100100
lib/compiler_rt/truncdfhf2.zig+2-2
......@@ -12,9 +12,9 @@ comptime {
1212}
1313
1414pub fn __truncdfhf2(a: f64) callconv(.C) common.F16T(f64) {
15 return @as(common.F16T(f64), @bitCast(truncf(f16, f64, a)));
15 return @bitCast(truncf(f16, f64, a));
1616}
1717
1818fn __aeabi_d2h(a: f64) callconv(.AAPCS) u16 {
19 return @as(common.F16T(f64), @bitCast(truncf(f16, f64, a)));
19 return @bitCast(truncf(f16, f64, a));
2020}
lib/compiler_rt/truncf.zig+14-15
......@@ -5,7 +5,6 @@ pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t
55 const dst_rep_t = std.meta.Int(.unsigned, @typeInfo(dst_t).Float.bits);
66 const srcSigBits = std.math.floatMantissaBits(src_t);
77 const dstSigBits = std.math.floatMantissaBits(dst_t);
8 const SrcShift = std.math.Log2Int(src_rep_t);
98
109 // Various constants whose values follow from the type parameters.
1110 // Any reasonable optimizer will fold and propagate all of these.
......@@ -38,7 +37,7 @@ pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t
3837 const dstNaNCode = dstQNaN - 1;
3938
4039 // Break a into a sign and representation of the absolute value
41 const aRep: src_rep_t = @as(src_rep_t, @bitCast(a));
40 const aRep: src_rep_t = @bitCast(a);
4241 const aAbs: src_rep_t = aRep & srcAbsMask;
4342 const sign: src_rep_t = aRep & srcSignMask;
4443 var absResult: dst_rep_t = undefined;
......@@ -47,7 +46,7 @@ pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t
4746 // The exponent of a is within the range of normal numbers in the
4847 // destination format. We can convert by simply right-shifting with
4948 // rounding and adjusting the exponent.
50 absResult = @as(dst_rep_t, @truncate(aAbs >> (srcSigBits - dstSigBits)));
49 absResult = @truncate(aAbs >> (srcSigBits - dstSigBits));
5150 absResult -%= @as(dst_rep_t, srcExpBias - dstExpBias) << dstSigBits;
5251
5352 const roundBits: src_rep_t = aAbs & roundMask;
......@@ -64,7 +63,7 @@ pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t
6463 // bit and inserting the (truncated) trailing NaN field.
6564 absResult = @as(dst_rep_t, @intCast(dstInfExp)) << dstSigBits;
6665 absResult |= dstQNaN;
67 absResult |= @as(dst_rep_t, @intCast(((aAbs & srcNaNCode) >> (srcSigBits - dstSigBits)) & dstNaNCode));
66 absResult |= @intCast(((aAbs & srcNaNCode) >> (srcSigBits - dstSigBits)) & dstNaNCode);
6867 } else if (aAbs >= overflow) {
6968 // a overflows to infinity.
7069 absResult = @as(dst_rep_t, @intCast(dstInfExp)) << dstSigBits;
......@@ -81,9 +80,9 @@ pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t
8180 if (shift > srcSigBits) {
8281 absResult = 0;
8382 } else {
84 const sticky: src_rep_t = @intFromBool(significand << @as(SrcShift, @intCast(srcBits - shift)) != 0);
85 const denormalizedSignificand: src_rep_t = significand >> @as(SrcShift, @intCast(shift)) | sticky;
86 absResult = @as(dst_rep_t, @intCast(denormalizedSignificand >> (srcSigBits - dstSigBits)));
83 const sticky: src_rep_t = @intFromBool(significand << @intCast(srcBits - shift) != 0);
84 const denormalizedSignificand: src_rep_t = significand >> @intCast(shift) | sticky;
85 absResult = @intCast(denormalizedSignificand >> (srcSigBits - dstSigBits));
8786 const roundBits: src_rep_t = denormalizedSignificand & roundMask;
8887 if (roundBits > halfway) {
8988 // Round to nearest
......@@ -96,8 +95,8 @@ pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t
9695 }
9796
9897 const result: dst_rep_t align(@alignOf(dst_t)) = absResult |
99 @as(dst_rep_t, @truncate(sign >> @as(SrcShift, @intCast(srcBits - dstBits))));
100 return @as(dst_t, @bitCast(result));
98 @as(dst_rep_t, @truncate(sign >> @intCast(srcBits - dstBits)));
99 return @bitCast(result);
101100}
102101
103102pub inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t {
......@@ -133,7 +132,7 @@ pub inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t {
133132 // destination format. We can convert by simply right-shifting with
134133 // rounding and adjusting the exponent.
135134 abs_result = @as(dst_rep_t, a_rep.exp) << dst_sig_bits;
136 abs_result |= @as(dst_rep_t, @truncate(a_rep.fraction >> (src_sig_bits - dst_sig_bits)));
135 abs_result |= @truncate(a_rep.fraction >> (src_sig_bits - dst_sig_bits));
137136 abs_result -%= @as(dst_rep_t, src_exp_bias - dst_exp_bias) << dst_sig_bits;
138137
139138 const round_bits = a_rep.fraction & round_mask;
......@@ -150,7 +149,7 @@ pub inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t {
150149 // bit and inserting the (truncated) trailing NaN field.
151150 abs_result = @as(dst_rep_t, @intCast(dst_inf_exp)) << dst_sig_bits;
152151 abs_result |= dst_qnan;
153 abs_result |= @as(dst_rep_t, @intCast((a_rep.fraction >> (src_sig_bits - dst_sig_bits)) & dst_nan_mask));
152 abs_result |= @intCast((a_rep.fraction >> (src_sig_bits - dst_sig_bits)) & dst_nan_mask);
154153 } else if (a_rep.exp >= overflow) {
155154 // a overflows to infinity.
156155 abs_result = @as(dst_rep_t, @intCast(dst_inf_exp)) << dst_sig_bits;
......@@ -164,9 +163,9 @@ pub inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t {
164163 if (shift > src_sig_bits) {
165164 abs_result = 0;
166165 } else {
167 const sticky = @intFromBool(a_rep.fraction << @as(u6, @intCast(shift)) != 0);
168 const denormalized_significand = a_rep.fraction >> @as(u6, @intCast(shift)) | sticky;
169 abs_result = @as(dst_rep_t, @intCast(denormalized_significand >> (src_sig_bits - dst_sig_bits)));
166 const sticky = @intFromBool(a_rep.fraction << @intCast(shift) != 0);
167 const denormalized_significand = a_rep.fraction >> @intCast(shift) | sticky;
168 abs_result = @intCast(denormalized_significand >> (src_sig_bits - dst_sig_bits));
170169 const round_bits = denormalized_significand & round_mask;
171170 if (round_bits > halfway) {
172171 // Round to nearest
......@@ -179,7 +178,7 @@ pub inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t {
179178 }
180179
181180 const result align(@alignOf(dst_t)) = abs_result | @as(dst_rep_t, sign) << dst_bits - 16;
182 return @as(dst_t, @bitCast(result));
181 return @bitCast(result);
183182}
184183
185184test {
lib/compiler_rt/truncsfhf2.zig+3-3
......@@ -13,13 +13,13 @@ comptime {
1313}
1414
1515pub fn __truncsfhf2(a: f32) callconv(.C) common.F16T(f32) {
16 return @as(common.F16T(f32), @bitCast(truncf(f16, f32, a)));
16 return @bitCast(truncf(f16, f32, a));
1717}
1818
1919fn __gnu_f2h_ieee(a: f32) callconv(.C) common.F16T(f32) {
20 return @as(common.F16T(f32), @bitCast(truncf(f16, f32, a)));
20 return @bitCast(truncf(f16, f32, a));
2121}
2222
2323fn __aeabi_f2h(a: f32) callconv(.AAPCS) u16 {
24 return @as(common.F16T(f32), @bitCast(truncf(f16, f32, a)));
24 return @bitCast(truncf(f16, f32, a));
2525}
lib/compiler_rt/trunctfhf2.zig+1-1
......@@ -8,5 +8,5 @@ comptime {
88}
99
1010pub fn __trunctfhf2(a: f128) callconv(.C) common.F16T(f128) {
11 return @as(common.F16T(f128), @bitCast(truncf(f16, f128, a)));
11 return @bitCast(truncf(f16, f128, a));
1212}
lib/compiler_rt/truncxfhf2.zig+1-1
......@@ -8,5 +8,5 @@ comptime {
88}
99
1010fn __truncxfhf2(a: f80) callconv(.C) common.F16T(f80) {
11 return @as(common.F16T(f80), @bitCast(trunc_f80(f16, a)));
11 return @bitCast(trunc_f80(f16, a));
1212}
lib/compiler_rt/udivmod.zig+11-11
......@@ -21,11 +21,11 @@ fn divwide_generic(comptime T: type, _u1: T, _u0: T, v_: T, r: *T) T {
2121 var un64: T = undefined;
2222 var un10: T = undefined;
2323
24 const s = @as(Log2Int(T), @intCast(@clz(v)));
24 const s: Log2Int(T) = @intCast(@clz(v));
2525 if (s > 0) {
2626 // Normalize divisor
2727 v <<= s;
28 un64 = (_u1 << s) | (_u0 >> @as(Log2Int(T), @intCast((@bitSizeOf(T) - @as(T, @intCast(s))))));
28 un64 = (_u1 << s) | (_u0 >> @intCast((@bitSizeOf(T) - @as(T, @intCast(s)))));
2929 un10 = _u0 << s;
3030 } else {
3131 // Avoid undefined behavior of (u0 >> @bitSizeOf(T))
......@@ -101,8 +101,8 @@ pub fn udivmod(comptime T: type, a_: T, b_: T, maybe_rem: ?*T) T {
101101 return 0;
102102 }
103103
104 var a = @as([2]HalfT, @bitCast(a_));
105 var b = @as([2]HalfT, @bitCast(b_));
104 var a: [2]HalfT = @bitCast(a_);
105 var b: [2]HalfT = @bitCast(b_);
106106 var q: [2]HalfT = undefined;
107107 var r: [2]HalfT = undefined;
108108
......@@ -119,16 +119,16 @@ pub fn udivmod(comptime T: type, a_: T, b_: T, maybe_rem: ?*T) T {
119119 q[lo] = divwide(HalfT, a[hi] % b[lo], a[lo], b[lo], &r[lo]);
120120 }
121121 if (maybe_rem) |rem| {
122 rem.* = @as(T, @bitCast(r));
122 rem.* = @bitCast(r);
123123 }
124 return @as(T, @bitCast(q));
124 return @bitCast(q);
125125 }
126126
127127 // 0 <= shift <= 63
128128 var shift: Log2Int(T) = @clz(b[hi]) - @clz(a[hi]);
129 var af = @as(T, @bitCast(a));
129 var af: T = @bitCast(a);
130130 var bf = @as(T, @bitCast(b)) << shift;
131 q = @as([2]HalfT, @bitCast(@as(T, 0)));
131 q = @bitCast(@as(T, 0));
132132
133133 for (0..shift + 1) |_| {
134134 q[lo] <<= 1;
......@@ -138,12 +138,12 @@ pub fn udivmod(comptime T: type, a_: T, b_: T, maybe_rem: ?*T) T {
138138 // q[lo] |= 1;
139139 // }
140140 const s = @as(SignedT, @bitCast(bf -% af -% 1)) >> (@bitSizeOf(T) - 1);
141 q[lo] |= @as(HalfT, @intCast(s & 1));
141 q[lo] |= @intCast(s & 1);
142142 af -= bf & @as(T, @bitCast(s));
143143 bf >>= 1;
144144 }
145145 if (maybe_rem) |rem| {
146 rem.* = @as(T, @bitCast(af));
146 rem.* = @bitCast(af);
147147 }
148 return @as(T, @bitCast(q));
148 return @bitCast(q);
149149}
lib/compiler_rt/udivmodti4.zig+1-1
......@@ -20,7 +20,7 @@ pub fn __udivmodti4(a: u128, b: u128, maybe_rem: ?*u128) callconv(.C) u128 {
2020const v2u64 = @Vector(2, u64);
2121
2222fn __udivmodti4_windows_x86_64(a: v2u64, b: v2u64, maybe_rem: ?*u128) callconv(.C) v2u64 {
23 return @as(v2u64, @bitCast(udivmod(u128, @as(u128, @bitCast(a)), @as(u128, @bitCast(b)), maybe_rem)));
23 return @bitCast(udivmod(u128, @bitCast(a), @bitCast(b), maybe_rem));
2424}
2525
2626test {
lib/compiler_rt/udivti3.zig+1-1
......@@ -20,5 +20,5 @@ pub fn __udivti3(a: u128, b: u128) callconv(.C) u128 {
2020const v2u64 = @Vector(2, u64);
2121
2222fn __udivti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 {
23 return @as(v2u64, @bitCast(udivmod(u128, @as(u128, @bitCast(a)), @as(u128, @bitCast(b)), null)));
23 return @bitCast(udivmod(u128, @bitCast(a), @bitCast(b), null));
2424}
lib/compiler_rt/umodti3.zig+2-2
......@@ -23,6 +23,6 @@ const v2u64 = @Vector(2, u64);
2323
2424fn __umodti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 {
2525 var r: u128 = undefined;
26 _ = udivmod(u128, @as(u128, @bitCast(a)), @as(u128, @bitCast(b)), &r);
27 return @as(v2u64, @bitCast(r));
26 _ = udivmod(u128, @bitCast(a), @bitCast(b), &r);
27 return @bitCast(r);
2828}
lib/include/__clang_cuda_intrinsics.h+191
......@@ -513,6 +513,197 @@ __device__ inline cuuint32_t __nvvm_get_smem_pointer(void *__ptr) {
513513 return __nv_cvta_generic_to_shared_impl(__ptr);
514514}
515515} // extern "C"
516
517#if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 800
518__device__ inline unsigned __reduce_add_sync(unsigned __mask,
519 unsigned __value) {
520 return __nvvm_redux_sync_add(__mask, __value);
521}
522__device__ inline unsigned __reduce_min_sync(unsigned __mask,
523 unsigned __value) {
524 return __nvvm_redux_sync_umin(__mask, __value);
525}
526__device__ inline unsigned __reduce_max_sync(unsigned __mask,
527 unsigned __value) {
528 return __nvvm_redux_sync_umax(__mask, __value);
529}
530__device__ inline int __reduce_min_sync(unsigned __mask, int __value) {
531 return __nvvm_redux_sync_min(__mask, __value);
532}
533__device__ inline int __reduce_max_sync(unsigned __mask, int __value) {
534 return __nvvm_redux_sync_max(__mask, __value);
535}
536__device__ inline unsigned __reduce_or_sync(unsigned __mask, unsigned __value) {
537 return __nvvm_redux_sync_or(__mask, __value);
538}
539__device__ inline unsigned __reduce_and_sync(unsigned __mask,
540 unsigned __value) {
541 return __nvvm_redux_sync_and(__mask, __value);
542}
543__device__ inline unsigned __reduce_xor_sync(unsigned __mask,
544 unsigned __value) {
545 return __nvvm_redux_sync_xor(__mask, __value);
546}
547
548__device__ inline void __nv_memcpy_async_shared_global_4(void *__dst,
549 const void *__src,
550 unsigned __src_size) {
551 __nvvm_cp_async_ca_shared_global_4(
552 (void __attribute__((address_space(3))) *)__dst,
553 (const void __attribute__((address_space(1))) *)__src, __src_size);
554}
555__device__ inline void __nv_memcpy_async_shared_global_8(void *__dst,
556 const void *__src,
557 unsigned __src_size) {
558 __nvvm_cp_async_ca_shared_global_8(
559 (void __attribute__((address_space(3))) *)__dst,
560 (const void __attribute__((address_space(1))) *)__src, __src_size);
561}
562__device__ inline void __nv_memcpy_async_shared_global_16(void *__dst,
563 const void *__src,
564 unsigned __src_size) {
565 __nvvm_cp_async_ca_shared_global_16(
566 (void __attribute__((address_space(3))) *)__dst,
567 (const void __attribute__((address_space(1))) *)__src, __src_size);
568}
569
570__device__ inline void *
571__nv_associate_access_property(const void *__ptr, unsigned long long __prop) {
572 // TODO: it appears to provide compiler with some sort of a hint. We do not
573 // know what exactly it is supposed to do. However, CUDA headers suggest that
574 // just passing through __ptr should not affect correctness. They do so on
575 // pre-sm80 GPUs where this builtin is not available.
576 return (void*)__ptr;
577}
578#endif // !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 800
579
580#if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 900
581__device__ inline unsigned __isCtaShared(const void *ptr) {
582 return __isShared(ptr);
583}
584
585__device__ inline unsigned __isClusterShared(const void *__ptr) {
586 return __nvvm_isspacep_shared_cluster(__ptr);
587}
588
589__device__ inline void *__cluster_map_shared_rank(const void *__ptr,
590 unsigned __rank) {
591 return __nvvm_mapa((void *)__ptr, __rank);
592}
593
594__device__ inline unsigned __cluster_query_shared_rank(const void *__ptr) {
595 return __nvvm_getctarank((void *)__ptr);
596}
597
598__device__ inline uint2
599__cluster_map_shared_multicast(const void *__ptr,
600 unsigned int __cluster_cta_mask) {
601 return make_uint2((unsigned)__cvta_generic_to_shared(__ptr),
602 __cluster_cta_mask);
603}
604
605__device__ inline unsigned __clusterDimIsSpecified() {
606 return __nvvm_is_explicit_cluster();
607}
608
609__device__ inline dim3 __clusterDim() {
610 return dim3(__nvvm_read_ptx_sreg_cluster_nctaid_x(),
611 __nvvm_read_ptx_sreg_cluster_nctaid_y(),
612 __nvvm_read_ptx_sreg_cluster_nctaid_z());
613}
614
615__device__ inline dim3 __clusterRelativeBlockIdx() {
616 return dim3(__nvvm_read_ptx_sreg_cluster_ctaid_x(),
617 __nvvm_read_ptx_sreg_cluster_ctaid_y(),
618 __nvvm_read_ptx_sreg_cluster_ctaid_z());
619}
620
621__device__ inline dim3 __clusterGridDimInClusters() {
622 return dim3(__nvvm_read_ptx_sreg_nclusterid_x(),
623 __nvvm_read_ptx_sreg_nclusterid_y(),
624 __nvvm_read_ptx_sreg_nclusterid_z());
625}
626
627__device__ inline dim3 __clusterIdx() {
628 return dim3(__nvvm_read_ptx_sreg_clusterid_x(),
629 __nvvm_read_ptx_sreg_clusterid_y(),
630 __nvvm_read_ptx_sreg_clusterid_z());
631}
632
633__device__ inline unsigned __clusterRelativeBlockRank() {
634 return __nvvm_read_ptx_sreg_cluster_ctarank();
635}
636
637__device__ inline unsigned __clusterSizeInBlocks() {
638 return __nvvm_read_ptx_sreg_cluster_nctarank();
639}
640
641__device__ inline void __cluster_barrier_arrive() {
642 __nvvm_barrier_cluster_arrive();
643}
644
645__device__ inline void __cluster_barrier_arrive_relaxed() {
646 __nvvm_barrier_cluster_arrive_relaxed();
647}
648
649__device__ inline void __cluster_barrier_wait() {
650 __nvvm_barrier_cluster_wait();
651}
652
653__device__ inline void __threadfence_cluster() { __nvvm_fence_sc_cluster(); }
654
655__device__ inline float2 atomicAdd(float2 *__ptr, float2 __val) {
656 float2 __ret;
657 __asm__("atom.add.v2.f32 {%0, %1}, [%2], {%3, %4};"
658 : "=f"(__ret.x), "=f"(__ret.y)
659 : "l"(__ptr), "f"(__val.x), "f"(__val.y));
660 return __ret;
661}
662
663__device__ inline float2 atomicAdd_block(float2 *__ptr, float2 __val) {
664 float2 __ret;
665 __asm__("atom.cta.add.v2.f32 {%0, %1}, [%2], {%3, %4};"
666 : "=f"(__ret.x), "=f"(__ret.y)
667 : "l"(__ptr), "f"(__val.x), "f"(__val.y));
668 return __ret;
669}
670
671__device__ inline float2 atomicAdd_system(float2 *__ptr, float2 __val) {
672 float2 __ret;
673 __asm__("atom.sys.add.v2.f32 {%0, %1}, [%2], {%3, %4};"
674 : "=f"(__ret.x), "=f"(__ret.y)
675 : "l"(__ptr), "f"(__val.x), "f"(__val.y));
676 return __ret;
677}
678
679__device__ inline float4 atomicAdd(float4 *__ptr, float4 __val) {
680 float4 __ret;
681 __asm__("atom.add.v4.f32 {%0, %1, %2, %3}, [%4], {%5, %6, %7, %8};"
682 : "=f"(__ret.x), "=f"(__ret.y), "=f"(__ret.z), "=f"(__ret.w)
683 : "l"(__ptr), "f"(__val.x), "f"(__val.y), "f"(__val.z), "f"(__val.w));
684 return __ret;
685}
686
687__device__ inline float4 atomicAdd_block(float4 *__ptr, float4 __val) {
688 float4 __ret;
689 __asm__(
690 "atom.cta.add.v4.f32 {%0, %1, %2, %3}, [%4], {%5, %6, %7, %8};"
691 : "=f"(__ret.x), "=f"(__ret.y), "=f"(__ret.z), "=f"(__ret.w)
692 : "l"(__ptr), "f"(__val.x), "f"(__val.y), "f"(__val.z), "f"(__val.w));
693 return __ret;
694}
695
696__device__ inline float4 atomicAdd_system(float4 *__ptr, float4 __val) {
697 float4 __ret;
698 __asm__(
699 "atom.sys.add.v4.f32 {%0, %1, %2, %3}, [%4], {%5, %6, %7, %8};"
700 : "=f"(__ret.x), "=f"(__ret.y), "=f"(__ret.z), "=f"(__ret.w)
701 : "l"(__ptr), "f"(__val.x), "f"(__val.y), "f"(__val.z), "f"(__val.w)
702 :);
703 return __ret;
704}
705
706#endif // !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 900
516707#endif // CUDA_VERSION >= 11000
517708
518709#endif // defined(__CLANG_CUDA_INTRINSICS_H__)
lib/include/__clang_hip_cmath.h+1-1
......@@ -171,7 +171,7 @@ __DEVICE__ __CONSTEXPR__ bool signbit(double __x) { return ::__signbit(__x); }
171171// Other functions.
172172__DEVICE__ __CONSTEXPR__ _Float16 fma(_Float16 __x, _Float16 __y,
173173 _Float16 __z) {
174 return __ocml_fma_f16(__x, __y, __z);
174 return __builtin_fmaf16(__x, __y, __z);
175175}
176176__DEVICE__ __CONSTEXPR__ _Float16 pow(_Float16 __base, int __iexp) {
177177 return __ocml_pown_f16(__base, __iexp);
lib/include/__clang_hip_libdevice_declares.h+32-30
......@@ -10,6 +10,10 @@
1010#ifndef __CLANG_HIP_LIBDEVICE_DECLARES_H__
1111#define __CLANG_HIP_LIBDEVICE_DECLARES_H__
1212
13#if !defined(__HIPCC_RTC__) && __has_include("hip/hip_version.h")
14#include "hip/hip_version.h"
15#endif // __has_include("hip/hip_version.h")
16
1317#ifdef __cplusplus
1418extern "C" {
1519#endif
......@@ -137,23 +141,6 @@ __device__ __attribute__((const)) float __ocml_fma_rte_f32(float, float, float);
137141__device__ __attribute__((const)) float __ocml_fma_rtn_f32(float, float, float);
138142__device__ __attribute__((const)) float __ocml_fma_rtp_f32(float, float, float);
139143__device__ __attribute__((const)) float __ocml_fma_rtz_f32(float, float, float);
140
141__device__ inline __attribute__((const)) float
142__llvm_amdgcn_cos_f32(float __x) {
143 return __builtin_amdgcn_cosf(__x);
144}
145__device__ inline __attribute__((const)) float
146__llvm_amdgcn_rcp_f32(float __x) {
147 return __builtin_amdgcn_rcpf(__x);
148}
149__device__ inline __attribute__((const)) float
150__llvm_amdgcn_rsq_f32(float __x) {
151 return __builtin_amdgcn_rsqf(__x);
152}
153__device__ inline __attribute__((const)) float
154__llvm_amdgcn_sin_f32(float __x) {
155 return __builtin_amdgcn_sinf(__x);
156}
157144// END INTRINSICS
158145// END FLOAT
159146
......@@ -277,15 +264,6 @@ __device__ __attribute__((const)) double __ocml_fma_rtp_f64(double, double,
277264__device__ __attribute__((const)) double __ocml_fma_rtz_f64(double, double,
278265 double);
279266
280__device__ inline __attribute__((const)) double
281__llvm_amdgcn_rcp_f64(double __x) {
282 return __builtin_amdgcn_rcp(__x);
283}
284__device__ inline __attribute__((const)) double
285__llvm_amdgcn_rsq_f64(double __x) {
286 return __builtin_amdgcn_rsq(__x);
287}
288
289267__device__ __attribute__((const)) _Float16 __ocml_ceil_f16(_Float16);
290268__device__ _Float16 __ocml_cos_f16(_Float16);
291269__device__ __attribute__((const)) _Float16 __ocml_cvtrtn_f16_f32(float);
......@@ -305,7 +283,6 @@ __device__ __attribute__((const)) int __ocml_isnan_f16(_Float16);
305283__device__ __attribute__((pure)) _Float16 __ocml_log_f16(_Float16);
306284__device__ __attribute__((pure)) _Float16 __ocml_log10_f16(_Float16);
307285__device__ __attribute__((pure)) _Float16 __ocml_log2_f16(_Float16);
308__device__ __attribute__((const)) _Float16 __llvm_amdgcn_rcp_f16(_Float16);
309286__device__ __attribute__((const)) _Float16 __ocml_rint_f16(_Float16);
310287__device__ __attribute__((const)) _Float16 __ocml_rsqrt_f16(_Float16);
311288__device__ _Float16 __ocml_sin_f16(_Float16);
......@@ -316,8 +293,15 @@ __device__ __attribute__((pure)) _Float16 __ocml_pown_f16(_Float16, int);
316293typedef _Float16 __2f16 __attribute__((ext_vector_type(2)));
317294typedef short __2i16 __attribute__((ext_vector_type(2)));
318295
296// We need to match C99's bool and get an i1 in the IR.
297#ifdef __cplusplus
298typedef bool __ockl_bool;
299#else
300typedef _Bool __ockl_bool;
301#endif
302
319303__device__ __attribute__((const)) float __ockl_fdot2(__2f16 a, __2f16 b,
320 float c, bool s);
304 float c, __ockl_bool s);
321305__device__ __attribute__((const)) __2f16 __ocml_ceil_2f16(__2f16);
322306__device__ __attribute__((const)) __2f16 __ocml_fabs_2f16(__2f16);
323307__device__ __2f16 __ocml_cos_2f16(__2f16);
......@@ -332,11 +316,29 @@ __device__ __attribute__((const)) __2i16 __ocml_isnan_2f16(__2f16);
332316__device__ __attribute__((pure)) __2f16 __ocml_log_2f16(__2f16);
333317__device__ __attribute__((pure)) __2f16 __ocml_log10_2f16(__2f16);
334318__device__ __attribute__((pure)) __2f16 __ocml_log2_2f16(__2f16);
319
320#if HIP_VERSION_MAJOR * 100 + HIP_VERSION_MINOR >= 560
321#define __DEPRECATED_SINCE_HIP_560(X) __attribute__((deprecated(X)))
322#else
323#define __DEPRECATED_SINCE_HIP_560(X)
324#endif
325
326// Deprecated, should be removed when rocm releases using it are no longer
327// relevant.
328__DEPRECATED_SINCE_HIP_560("use ((_Float16)1.0) / ")
329__device__ inline _Float16 __llvm_amdgcn_rcp_f16(_Float16 x) {
330 return ((_Float16)1.0f) / x;
331}
332
333__DEPRECATED_SINCE_HIP_560("use ((__2f16)1.0) / ")
335334__device__ inline __2f16
336__llvm_amdgcn_rcp_2f16(__2f16 __x) // Not currently exposed by ROCDL.
335__llvm_amdgcn_rcp_2f16(__2f16 __x)
337336{
338 return (__2f16)(__llvm_amdgcn_rcp_f16(__x.x), __llvm_amdgcn_rcp_f16(__x.y));
337 return ((__2f16)1.0f) / __x;
339338}
339
340#undef __DEPRECATED_SINCE_HIP_560
341
340342__device__ __attribute__((const)) __2f16 __ocml_rint_2f16(__2f16);
341343__device__ __attribute__((const)) __2f16 __ocml_rsqrt_2f16(__2f16);
342344__device__ __2f16 __ocml_sin_2f16(__2f16);
lib/include/__clang_hip_math.h+56-71
......@@ -182,10 +182,10 @@ __DEVICE__
182182float cbrtf(float __x) { return __ocml_cbrt_f32(__x); }
183183
184184__DEVICE__
185float ceilf(float __x) { return __ocml_ceil_f32(__x); }
185float ceilf(float __x) { return __builtin_ceilf(__x); }
186186
187187__DEVICE__
188float copysignf(float __x, float __y) { return __ocml_copysign_f32(__x, __y); }
188float copysignf(float __x, float __y) { return __builtin_copysignf(__x, __y); }
189189
190190__DEVICE__
191191float cosf(float __x) { return __ocml_cos_f32(__x); }
......@@ -221,10 +221,10 @@ __DEVICE__
221221float exp10f(float __x) { return __ocml_exp10_f32(__x); }
222222
223223__DEVICE__
224float exp2f(float __x) { return __ocml_exp2_f32(__x); }
224float exp2f(float __x) { return __builtin_exp2f(__x); }
225225
226226__DEVICE__
227float expf(float __x) { return __ocml_exp_f32(__x); }
227float expf(float __x) { return __builtin_expf(__x); }
228228
229229__DEVICE__
230230float expm1f(float __x) { return __ocml_expm1_f32(__x); }
......@@ -239,33 +239,25 @@ __DEVICE__
239239float fdividef(float __x, float __y) { return __x / __y; }
240240
241241__DEVICE__
242float floorf(float __x) { return __ocml_floor_f32(__x); }
242float floorf(float __x) { return __builtin_floorf(__x); }
243243
244244__DEVICE__
245245float fmaf(float __x, float __y, float __z) {
246 return __ocml_fma_f32(__x, __y, __z);
246 return __builtin_fmaf(__x, __y, __z);
247247}
248248
249249__DEVICE__
250float fmaxf(float __x, float __y) { return __ocml_fmax_f32(__x, __y); }
250float fmaxf(float __x, float __y) { return __builtin_fmaxf(__x, __y); }
251251
252252__DEVICE__
253float fminf(float __x, float __y) { return __ocml_fmin_f32(__x, __y); }
253float fminf(float __x, float __y) { return __builtin_fminf(__x, __y); }
254254
255255__DEVICE__
256256float fmodf(float __x, float __y) { return __ocml_fmod_f32(__x, __y); }
257257
258258__DEVICE__
259259float frexpf(float __x, int *__nptr) {
260 int __tmp;
261#ifdef __OPENMP_AMDGCN__
262#pragma omp allocate(__tmp) allocator(omp_thread_mem_alloc)
263#endif
264 float __r =
265 __ocml_frexp_f32(__x, (__attribute__((address_space(5))) int *)&__tmp);
266 *__nptr = __tmp;
267
268 return __r;
260 return __builtin_frexpf(__x, __nptr);
269261}
270262
271263__DEVICE__
......@@ -275,13 +267,13 @@ __DEVICE__
275267int ilogbf(float __x) { return __ocml_ilogb_f32(__x); }
276268
277269__DEVICE__
278__RETURN_TYPE __finitef(float __x) { return __ocml_isfinite_f32(__x); }
270__RETURN_TYPE __finitef(float __x) { return __builtin_isfinite(__x); }
279271
280272__DEVICE__
281__RETURN_TYPE __isinff(float __x) { return __ocml_isinf_f32(__x); }
273__RETURN_TYPE __isinff(float __x) { return __builtin_isinf(__x); }
282274
283275__DEVICE__
284__RETURN_TYPE __isnanf(float __x) { return __ocml_isnan_f32(__x); }
276__RETURN_TYPE __isnanf(float __x) { return __builtin_isnan(__x); }
285277
286278__DEVICE__
287279float j0f(float __x) { return __ocml_j0_f32(__x); }
......@@ -311,37 +303,37 @@ float jnf(int __n, float __x) { // TODO: we could use Ahmes multiplication
311303}
312304
313305__DEVICE__
314float ldexpf(float __x, int __e) { return __ocml_ldexp_f32(__x, __e); }
306float ldexpf(float __x, int __e) { return __builtin_amdgcn_ldexpf(__x, __e); }
315307
316308__DEVICE__
317309float lgammaf(float __x) { return __ocml_lgamma_f32(__x); }
318310
319311__DEVICE__
320long long int llrintf(float __x) { return __ocml_rint_f32(__x); }
312long long int llrintf(float __x) { return __builtin_rintf(__x); }
321313
322314__DEVICE__
323long long int llroundf(float __x) { return __ocml_round_f32(__x); }
315long long int llroundf(float __x) { return __builtin_roundf(__x); }
324316
325317__DEVICE__
326float log10f(float __x) { return __ocml_log10_f32(__x); }
318float log10f(float __x) { return __builtin_log10f(__x); }
327319
328320__DEVICE__
329321float log1pf(float __x) { return __ocml_log1p_f32(__x); }
330322
331323__DEVICE__
332float log2f(float __x) { return __ocml_log2_f32(__x); }
324float log2f(float __x) { return __builtin_log2f(__x); }
333325
334326__DEVICE__
335327float logbf(float __x) { return __ocml_logb_f32(__x); }
336328
337329__DEVICE__
338float logf(float __x) { return __ocml_log_f32(__x); }
330float logf(float __x) { return __builtin_logf(__x); }
339331
340332__DEVICE__
341long int lrintf(float __x) { return __ocml_rint_f32(__x); }
333long int lrintf(float __x) { return __builtin_rintf(__x); }
342334
343335__DEVICE__
344long int lroundf(float __x) { return __ocml_round_f32(__x); }
336long int lroundf(float __x) { return __builtin_roundf(__x); }
345337
346338__DEVICE__
347339float modff(float __x, float *__iptr) {
......@@ -377,7 +369,7 @@ float nanf(const char *__tagp __attribute__((nonnull))) {
377369}
378370
379371__DEVICE__
380float nearbyintf(float __x) { return __ocml_nearbyint_f32(__x); }
372float nearbyintf(float __x) { return __builtin_nearbyintf(__x); }
381373
382374__DEVICE__
383375float nextafterf(float __x, float __y) {
......@@ -443,7 +435,7 @@ __DEVICE__
443435float rhypotf(float __x, float __y) { return __ocml_rhypot_f32(__x, __y); }
444436
445437__DEVICE__
446float rintf(float __x) { return __ocml_rint_f32(__x); }
438float rintf(float __x) { return __builtin_rintf(__x); }
447439
448440__DEVICE__
449441float rnorm3df(float __x, float __y, float __z) {
......@@ -468,22 +460,22 @@ float rnormf(int __dim,
468460}
469461
470462__DEVICE__
471float roundf(float __x) { return __ocml_round_f32(__x); }
463float roundf(float __x) { return __builtin_roundf(__x); }
472464
473465__DEVICE__
474466float rsqrtf(float __x) { return __ocml_rsqrt_f32(__x); }
475467
476468__DEVICE__
477469float scalblnf(float __x, long int __n) {
478 return (__n < INT_MAX) ? __ocml_scalbn_f32(__x, __n)
470 return (__n < INT_MAX) ? __builtin_amdgcn_ldexpf(__x, __n)
479471 : __ocml_scalb_f32(__x, __n);
480472}
481473
482474__DEVICE__
483float scalbnf(float __x, int __n) { return __ocml_scalbn_f32(__x, __n); }
475float scalbnf(float __x, int __n) { return __builtin_amdgcn_ldexpf(__x, __n); }
484476
485477__DEVICE__
486__RETURN_TYPE __signbitf(float __x) { return __ocml_signbit_f32(__x); }
478__RETURN_TYPE __signbitf(float __x) { return __builtin_signbitf(__x); }
487479
488480__DEVICE__
489481void sincosf(float __x, float *__sinptr, float *__cosptr) {
......@@ -529,7 +521,7 @@ __DEVICE__
529521float tgammaf(float __x) { return __ocml_tgamma_f32(__x); }
530522
531523__DEVICE__
532float truncf(float __x) { return __ocml_trunc_f32(__x); }
524float truncf(float __x) { return __builtin_truncf(__x); }
533525
534526__DEVICE__
535527float y0f(float __x) { return __ocml_y0_f32(__x); }
......@@ -621,7 +613,7 @@ float __fmaf_rz(float __x, float __y, float __z) {
621613#else
622614__DEVICE__
623615float __fmaf_rn(float __x, float __y, float __z) {
624 return __ocml_fma_f32(__x, __y, __z);
616 return __builtin_fmaf(__x, __y, __z);
625617}
626618#endif
627619
......@@ -654,7 +646,7 @@ float __frcp_rn(float __x) { return 1.0f / __x; }
654646#endif
655647
656648__DEVICE__
657float __frsqrt_rn(float __x) { return __llvm_amdgcn_rsq_f32(__x); }
649float __frsqrt_rn(float __x) { return __builtin_amdgcn_rsqf(__x); }
658650
659651#if defined OCML_BASIC_ROUNDED_OPERATIONS
660652__DEVICE__
......@@ -739,11 +731,11 @@ __DEVICE__
739731double cbrt(double __x) { return __ocml_cbrt_f64(__x); }
740732
741733__DEVICE__
742double ceil(double __x) { return __ocml_ceil_f64(__x); }
734double ceil(double __x) { return __builtin_ceil(__x); }
743735
744736__DEVICE__
745737double copysign(double __x, double __y) {
746 return __ocml_copysign_f64(__x, __y);
738 return __builtin_copysign(__x, __y);
747739}
748740
749741__DEVICE__
......@@ -795,32 +787,25 @@ __DEVICE__
795787double fdim(double __x, double __y) { return __ocml_fdim_f64(__x, __y); }
796788
797789__DEVICE__
798double floor(double __x) { return __ocml_floor_f64(__x); }
790double floor(double __x) { return __builtin_floor(__x); }
799791
800792__DEVICE__
801793double fma(double __x, double __y, double __z) {
802 return __ocml_fma_f64(__x, __y, __z);
794 return __builtin_fma(__x, __y, __z);
803795}
804796
805797__DEVICE__
806double fmax(double __x, double __y) { return __ocml_fmax_f64(__x, __y); }
798double fmax(double __x, double __y) { return __builtin_fmax(__x, __y); }
807799
808800__DEVICE__
809double fmin(double __x, double __y) { return __ocml_fmin_f64(__x, __y); }
801double fmin(double __x, double __y) { return __builtin_fmin(__x, __y); }
810802
811803__DEVICE__
812804double fmod(double __x, double __y) { return __ocml_fmod_f64(__x, __y); }
813805
814806__DEVICE__
815807double frexp(double __x, int *__nptr) {
816 int __tmp;
817#ifdef __OPENMP_AMDGCN__
818#pragma omp allocate(__tmp) allocator(omp_thread_mem_alloc)
819#endif
820 double __r =
821 __ocml_frexp_f64(__x, (__attribute__((address_space(5))) int *)&__tmp);
822 *__nptr = __tmp;
823 return __r;
808 return __builtin_frexp(__x, __nptr);
824809}
825810
826811__DEVICE__
......@@ -830,13 +815,13 @@ __DEVICE__
830815int ilogb(double __x) { return __ocml_ilogb_f64(__x); }
831816
832817__DEVICE__
833__RETURN_TYPE __finite(double __x) { return __ocml_isfinite_f64(__x); }
818__RETURN_TYPE __finite(double __x) { return __builtin_isfinite(__x); }
834819
835820__DEVICE__
836__RETURN_TYPE __isinf(double __x) { return __ocml_isinf_f64(__x); }
821__RETURN_TYPE __isinf(double __x) { return __builtin_isinf(__x); }
837822
838823__DEVICE__
839__RETURN_TYPE __isnan(double __x) { return __ocml_isnan_f64(__x); }
824__RETURN_TYPE __isnan(double __x) { return __builtin_isnan(__x); }
840825
841826__DEVICE__
842827double j0(double __x) { return __ocml_j0_f64(__x); }
......@@ -866,16 +851,16 @@ double jn(int __n, double __x) { // TODO: we could use Ahmes multiplication
866851}
867852
868853__DEVICE__
869double ldexp(double __x, int __e) { return __ocml_ldexp_f64(__x, __e); }
854double ldexp(double __x, int __e) { return __builtin_amdgcn_ldexp(__x, __e); }
870855
871856__DEVICE__
872857double lgamma(double __x) { return __ocml_lgamma_f64(__x); }
873858
874859__DEVICE__
875long long int llrint(double __x) { return __ocml_rint_f64(__x); }
860long long int llrint(double __x) { return __builtin_rint(__x); }
876861
877862__DEVICE__
878long long int llround(double __x) { return __ocml_round_f64(__x); }
863long long int llround(double __x) { return __builtin_round(__x); }
879864
880865__DEVICE__
881866double log(double __x) { return __ocml_log_f64(__x); }
......@@ -893,10 +878,10 @@ __DEVICE__
893878double logb(double __x) { return __ocml_logb_f64(__x); }
894879
895880__DEVICE__
896long int lrint(double __x) { return __ocml_rint_f64(__x); }
881long int lrint(double __x) { return __builtin_rint(__x); }
897882
898883__DEVICE__
899long int lround(double __x) { return __ocml_round_f64(__x); }
884long int lround(double __x) { return __builtin_round(__x); }
900885
901886__DEVICE__
902887double modf(double __x, double *__iptr) {
......@@ -940,7 +925,7 @@ double nan(const char *__tagp) {
940925}
941926
942927__DEVICE__
943double nearbyint(double __x) { return __ocml_nearbyint_f64(__x); }
928double nearbyint(double __x) { return __builtin_nearbyint(__x); }
944929
945930__DEVICE__
946931double nextafter(double __x, double __y) {
......@@ -1006,7 +991,7 @@ __DEVICE__
1006991double rhypot(double __x, double __y) { return __ocml_rhypot_f64(__x, __y); }
1007992
1008993__DEVICE__
1009double rint(double __x) { return __ocml_rint_f64(__x); }
994double rint(double __x) { return __builtin_rint(__x); }
1010995
1011996__DEVICE__
1012997double rnorm(int __dim,
......@@ -1031,21 +1016,21 @@ double rnorm4d(double __x, double __y, double __z, double __w) {
10311016}
10321017
10331018__DEVICE__
1034double round(double __x) { return __ocml_round_f64(__x); }
1019double round(double __x) { return __builtin_round(__x); }
10351020
10361021__DEVICE__
10371022double rsqrt(double __x) { return __ocml_rsqrt_f64(__x); }
10381023
10391024__DEVICE__
10401025double scalbln(double __x, long int __n) {
1041 return (__n < INT_MAX) ? __ocml_scalbn_f64(__x, __n)
1026 return (__n < INT_MAX) ? __builtin_amdgcn_ldexp(__x, __n)
10421027 : __ocml_scalb_f64(__x, __n);
10431028}
10441029__DEVICE__
1045double scalbn(double __x, int __n) { return __ocml_scalbn_f64(__x, __n); }
1030double scalbn(double __x, int __n) { return __builtin_amdgcn_ldexp(__x, __n); }
10461031
10471032__DEVICE__
1048__RETURN_TYPE __signbit(double __x) { return __ocml_signbit_f64(__x); }
1033__RETURN_TYPE __signbit(double __x) { return __builtin_signbit(__x); }
10491034
10501035__DEVICE__
10511036double sin(double __x) { return __ocml_sin_f64(__x); }
......@@ -1091,7 +1076,7 @@ __DEVICE__
10911076double tgamma(double __x) { return __ocml_tgamma_f64(__x); }
10921077
10931078__DEVICE__
1094double trunc(double __x) { return __ocml_trunc_f64(__x); }
1079double trunc(double __x) { return __builtin_trunc(__x); }
10951080
10961081__DEVICE__
10971082double y0(double __x) { return __ocml_y0_f64(__x); }
......@@ -1258,7 +1243,7 @@ double __fma_rz(double __x, double __y, double __z) {
12581243#else
12591244__DEVICE__
12601245double __fma_rn(double __x, double __y, double __z) {
1261 return __ocml_fma_f64(__x, __y, __z);
1246 return __builtin_fma(__x, __y, __z);
12621247}
12631248#endif
12641249// END INTRINSICS
......@@ -1290,16 +1275,16 @@ __DEVICE__ int max(int __arg1, int __arg2) {
12901275}
12911276
12921277__DEVICE__
1293float max(float __x, float __y) { return fmaxf(__x, __y); }
1278float max(float __x, float __y) { return __builtin_fmaxf(__x, __y); }
12941279
12951280__DEVICE__
1296double max(double __x, double __y) { return fmax(__x, __y); }
1281double max(double __x, double __y) { return __builtin_fmax(__x, __y); }
12971282
12981283__DEVICE__
1299float min(float __x, float __y) { return fminf(__x, __y); }
1284float min(float __x, float __y) { return __builtin_fminf(__x, __y); }
13001285
13011286__DEVICE__
1302double min(double __x, double __y) { return fmin(__x, __y); }
1287double min(double __x, double __y) { return __builtin_fmin(__x, __y); }
13031288
13041289#if !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__)
13051290__host__ inline static int min(int __arg1, int __arg2) {
lib/include/__clang_hip_runtime_wrapper.h+13
......@@ -80,12 +80,25 @@ extern "C" {
8080#if HIP_VERSION_MAJOR * 100 + HIP_VERSION_MINOR >= 405
8181extern "C" __device__ unsigned long long __ockl_dm_alloc(unsigned long long __size);
8282extern "C" __device__ void __ockl_dm_dealloc(unsigned long long __addr);
83#if __has_feature(address_sanitizer)
84extern "C" __device__ unsigned long long __asan_malloc_impl(unsigned long long __size, unsigned long long __pc);
85extern "C" __device__ void __asan_free_impl(unsigned long long __addr, unsigned long long __pc);
86__attribute__((noinline, weak)) __device__ void *malloc(__hip_size_t __size) {
87 unsigned long long __pc = (unsigned long long)__builtin_return_address(0);
88 return (void *)__asan_malloc_impl(__size, __pc);
89}
90__attribute__((noinline, weak)) __device__ void free(void *__ptr) {
91 unsigned long long __pc = (unsigned long long)__builtin_return_address(0);
92 __asan_free_impl((unsigned long long)__ptr, __pc);
93}
94#else
8395__attribute__((weak)) inline __device__ void *malloc(__hip_size_t __size) {
8496 return (void *) __ockl_dm_alloc(__size);
8597}
8698__attribute__((weak)) inline __device__ void free(void *__ptr) {
8799 __ockl_dm_dealloc((unsigned long long)__ptr);
88100}
101#endif // __has_feature(address_sanitizer)
89102#else // HIP version check
90103#if __HIP_ENABLE_DEVICE_MALLOC__
91104__device__ void *__hip_malloc(__hip_size_t __size);
lib/include/adxintrin.h+179-24
......@@ -17,56 +17,211 @@
1717/* Define the default attributes for the functions in this file. */
1818#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
1919
20/* Intrinsics that are available only if __ADX__ defined */
21static __inline unsigned char __attribute__((__always_inline__, __nodebug__, __target__("adx")))
22_addcarryx_u32(unsigned char __cf, unsigned int __x, unsigned int __y,
23 unsigned int *__p)
24{
20/* Use C++ inline semantics in C++, GNU inline for C mode. */
21#if defined(__cplusplus)
22#define __INLINE __inline
23#else
24#define __INLINE static __inline
25#endif
26
27#if defined(__cplusplus)
28extern "C" {
29#endif
30
31/* Intrinsics that are available only if __ADX__ is defined. */
32
33/// Adds unsigned 32-bit integers \a __x and \a __y, plus 0 or 1 as indicated
34/// by the carry flag \a __cf. Stores the unsigned 32-bit sum in the memory
35/// at \a __p, and returns the 8-bit carry-out (carry flag).
36///
37/// \code{.operation}
38/// temp := (__cf == 0) ? 0 : 1
39/// Store32(__p, __x + __y + temp)
40/// result := CF
41/// \endcode
42///
43/// \headerfile <immintrin.h>
44///
45/// This intrinsic corresponds to the \c ADCX instruction.
46///
47/// \param __cf
48/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
49/// \param __x
50/// A 32-bit unsigned addend.
51/// \param __y
52/// A 32-bit unsigned addend.
53/// \param __p
54/// Pointer to memory for storing the sum.
55/// \returns The 8-bit unsigned carry-out value.
56__INLINE unsigned char
57 __attribute__((__always_inline__, __nodebug__, __target__("adx")))
58 _addcarryx_u32(unsigned char __cf, unsigned int __x, unsigned int __y,
59 unsigned int *__p) {
2560 return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p);
2661}
2762
2863#ifdef __x86_64__
29static __inline unsigned char __attribute__((__always_inline__, __nodebug__, __target__("adx")))
30_addcarryx_u64(unsigned char __cf, unsigned long long __x,
31 unsigned long long __y, unsigned long long *__p)
32{
64/// Adds unsigned 64-bit integers \a __x and \a __y, plus 0 or 1 as indicated
65/// by the carry flag \a __cf. Stores the unsigned 64-bit sum in the memory
66/// at \a __p, and returns the 8-bit carry-out (carry flag).
67///
68/// \code{.operation}
69/// temp := (__cf == 0) ? 0 : 1
70/// Store64(__p, __x + __y + temp)
71/// result := CF
72/// \endcode
73///
74/// \headerfile <immintrin.h>
75///
76/// This intrinsic corresponds to the \c ADCX instruction.
77///
78/// \param __cf
79/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
80/// \param __x
81/// A 64-bit unsigned addend.
82/// \param __y
83/// A 64-bit unsigned addend.
84/// \param __p
85/// Pointer to memory for storing the sum.
86/// \returns The 8-bit unsigned carry-out value.
87__INLINE unsigned char
88 __attribute__((__always_inline__, __nodebug__, __target__("adx")))
89 _addcarryx_u64(unsigned char __cf, unsigned long long __x,
90 unsigned long long __y, unsigned long long *__p) {
3391 return __builtin_ia32_addcarryx_u64(__cf, __x, __y, __p);
3492}
3593#endif
3694
37/* Intrinsics that are also available if __ADX__ undefined */
38static __inline unsigned char __DEFAULT_FN_ATTRS
39_addcarry_u32(unsigned char __cf, unsigned int __x, unsigned int __y,
40 unsigned int *__p)
41{
95/* Intrinsics that are also available if __ADX__ is undefined. */
96
97/// Adds unsigned 32-bit integers \a __x and \a __y, plus 0 or 1 as indicated
98/// by the carry flag \a __cf. Stores the unsigned 32-bit sum in the memory
99/// at \a __p, and returns the 8-bit carry-out (carry flag).
100///
101/// \code{.operation}
102/// temp := (__cf == 0) ? 0 : 1
103/// Store32(__p, __x + __y + temp)
104/// result := CF
105/// \endcode
106///
107/// \headerfile <immintrin.h>
108///
109/// This intrinsic corresponds to the \c ADC instruction.
110///
111/// \param __cf
112/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
113/// \param __x
114/// A 32-bit unsigned addend.
115/// \param __y
116/// A 32-bit unsigned addend.
117/// \param __p
118/// Pointer to memory for storing the sum.
119/// \returns The 8-bit unsigned carry-out value.
120__INLINE unsigned char __DEFAULT_FN_ATTRS _addcarry_u32(unsigned char __cf,
121 unsigned int __x,
122 unsigned int __y,
123 unsigned int *__p) {
42124 return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p);
43125}
44126
45127#ifdef __x86_64__
46static __inline unsigned char __DEFAULT_FN_ATTRS
128/// Adds unsigned 64-bit integers \a __x and \a __y, plus 0 or 1 as indicated
129/// by the carry flag \a __cf. Stores the unsigned 64-bit sum in the memory
130/// at \a __p, and returns the 8-bit carry-out (carry flag).
131///
132/// \code{.operation}
133/// temp := (__cf == 0) ? 0 : 1
134/// Store64(__p, __x + __y + temp)
135/// result := CF
136/// \endcode
137///
138/// \headerfile <immintrin.h>
139///
140/// This intrinsic corresponds to the \c ADC instruction.
141///
142/// \param __cf
143/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
144/// \param __x
145/// A 64-bit unsigned addend.
146/// \param __y
147/// A 64-bit unsigned addend.
148/// \param __p
149/// Pointer to memory for storing the sum.
150/// \returns The 8-bit unsigned carry-out value.
151__INLINE unsigned char __DEFAULT_FN_ATTRS
47152_addcarry_u64(unsigned char __cf, unsigned long long __x,
48 unsigned long long __y, unsigned long long *__p)
49{
153 unsigned long long __y, unsigned long long *__p) {
50154 return __builtin_ia32_addcarryx_u64(__cf, __x, __y, __p);
51155}
52156#endif
53157
54static __inline unsigned char __DEFAULT_FN_ATTRS
55_subborrow_u32(unsigned char __cf, unsigned int __x, unsigned int __y,
56 unsigned int *__p)
57{
158/// Adds unsigned 32-bit integer \a __y to 0 or 1 as indicated by the carry
159/// flag \a __cf, and subtracts the result from unsigned 32-bit integer
160/// \a __x. Stores the unsigned 32-bit difference in the memory at \a __p,
161/// and returns the 8-bit carry-out (carry or overflow flag).
162///
163/// \code{.operation}
164/// temp := (__cf == 0) ? 0 : 1
165/// Store32(__p, __x - (__y + temp))
166/// result := CF
167/// \endcode
168///
169/// \headerfile <immintrin.h>
170///
171/// This intrinsic corresponds to the \c SBB instruction.
172///
173/// \param __cf
174/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
175/// \param __x
176/// The 32-bit unsigned minuend.
177/// \param __y
178/// The 32-bit unsigned subtrahend.
179/// \param __p
180/// Pointer to memory for storing the difference.
181/// \returns The 8-bit unsigned carry-out value.
182__INLINE unsigned char __DEFAULT_FN_ATTRS _subborrow_u32(unsigned char __cf,
183 unsigned int __x,
184 unsigned int __y,
185 unsigned int *__p) {
58186 return __builtin_ia32_subborrow_u32(__cf, __x, __y, __p);
59187}
60188
61189#ifdef __x86_64__
62static __inline unsigned char __DEFAULT_FN_ATTRS
190/// Adds unsigned 64-bit integer \a __y to 0 or 1 as indicated by the carry
191/// flag \a __cf, and subtracts the result from unsigned 64-bit integer
192/// \a __x. Stores the unsigned 64-bit difference in the memory at \a __p,
193/// and returns the 8-bit carry-out (carry or overflow flag).
194///
195/// \code{.operation}
196/// temp := (__cf == 0) ? 0 : 1
197/// Store64(__p, __x - (__y + temp))
198/// result := CF
199/// \endcode
200///
201/// \headerfile <immintrin.h>
202///
203/// This intrinsic corresponds to the \c ADC instruction.
204///
205/// \param __cf
206/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
207/// \param __x
208/// The 64-bit unsigned minuend.
209/// \param __y
210/// The 64-bit unsigned subtrahend.
211/// \param __p
212/// Pointer to memory for storing the difference.
213/// \returns The 8-bit unsigned carry-out value.
214__INLINE unsigned char __DEFAULT_FN_ATTRS
63215_subborrow_u64(unsigned char __cf, unsigned long long __x,
64 unsigned long long __y, unsigned long long *__p)
65{
216 unsigned long long __y, unsigned long long *__p) {
66217 return __builtin_ia32_subborrow_u64(__cf, __x, __y, __p);
67218}
68219#endif
69220
221#if defined(__cplusplus)
222}
223#endif
224
70225#undef __DEFAULT_FN_ATTRS
71226
72227#endif /* __ADXINTRIN_H */
lib/include/altivec.h+136-124
......@@ -3202,71 +3202,79 @@ static __inline__ vector double __ATTRS_o_ai vec_cpsgn(vector double __a,
32023202// the XL-compatible signatures are used for those functions.
32033203#ifdef __XL_COMPAT_ALTIVEC__
32043204#define vec_ctf(__a, __b) \
3205 _Generic( \
3206 (__a), vector int \
3207 : (vector float)__builtin_altivec_vcfsx((vector int)(__a), (__b)), \
3208 vector unsigned int \
3209 : (vector float)__builtin_altivec_vcfux((vector unsigned int)(__a), \
3210 (__b)), \
3211 vector unsigned long long \
3212 : (vector float)(__builtin_vsx_xvcvuxdsp( \
3213 (vector unsigned long long)(__a)) * \
3214 (vector float)(vector unsigned)((0x7f - (__b)) << 23)), \
3215 vector signed long long \
3216 : (vector float)(__builtin_vsx_xvcvsxdsp( \
3217 (vector signed long long)(__a)) * \
3218 (vector float)(vector unsigned)((0x7f - (__b)) << 23)))
3205 _Generic((__a), \
3206 vector int: (vector float)__builtin_altivec_vcfsx((vector int)(__a), \
3207 ((__b)&0x1F)), \
3208 vector unsigned int: (vector float)__builtin_altivec_vcfux( \
3209 (vector unsigned int)(__a), ((__b)&0x1F)), \
3210 vector unsigned long long: ( \
3211 vector float)(__builtin_vsx_xvcvuxdsp( \
3212 (vector unsigned long long)(__a)) * \
3213 (vector float)(vector unsigned)((0x7f - \
3214 ((__b)&0x1F)) \
3215 << 23)), \
3216 vector signed long long: ( \
3217 vector float)(__builtin_vsx_xvcvsxdsp( \
3218 (vector signed long long)(__a)) * \
3219 (vector float)(vector unsigned)((0x7f - \
3220 ((__b)&0x1F)) \
3221 << 23)))
32193222#else // __XL_COMPAT_ALTIVEC__
3220#define vec_ctf(__a, __b) \
3221 _Generic( \
3222 (__a), vector int \
3223 : (vector float)__builtin_altivec_vcfsx((vector int)(__a), (__b)), \
3224 vector unsigned int \
3225 : (vector float)__builtin_altivec_vcfux((vector unsigned int)(__a), \
3226 (__b)), \
3227 vector unsigned long long \
3228 : (vector float)(__builtin_convertvector( \
3229 (vector unsigned long long)(__a), vector double) * \
3230 (vector double)(vector unsigned long long)((0x3ffULL - \
3231 (__b)) \
3232 << 52)), \
3233 vector signed long long \
3234 : (vector float)(__builtin_convertvector((vector signed long long)(__a), \
3235 vector double) * \
3236 (vector double)(vector unsigned long long)((0x3ffULL - \
3237 (__b)) \
3238 << 52)))
3223#define vec_ctf(__a, __b) \
3224 _Generic( \
3225 (__a), \
3226 vector int: (vector float)__builtin_altivec_vcfsx((vector int)(__a), \
3227 ((__b)&0x1F)), \
3228 vector unsigned int: (vector float)__builtin_altivec_vcfux( \
3229 (vector unsigned int)(__a), ((__b)&0x1F)), \
3230 vector unsigned long long: ( \
3231 vector float)(__builtin_convertvector( \
3232 (vector unsigned long long)(__a), vector double) * \
3233 (vector double)(vector unsigned long long)((0x3ffULL - \
3234 ((__b)&0x1F)) \
3235 << 52)), \
3236 vector signed long long: ( \
3237 vector float)(__builtin_convertvector( \
3238 (vector signed long long)(__a), vector double) * \
3239 (vector double)(vector unsigned long long)((0x3ffULL - \
3240 ((__b)&0x1F)) \
3241 << 52)))
32393242#endif // __XL_COMPAT_ALTIVEC__
32403243#else
32413244#define vec_ctf(__a, __b) \
3242 _Generic((__a), vector int \
3243 : (vector float)__builtin_altivec_vcfsx((vector int)(__a), (__b)), \
3244 vector unsigned int \
3245 : (vector float)__builtin_altivec_vcfux((vector unsigned int)(__a), \
3246 (__b)))
3245 _Generic((__a), \
3246 vector int: (vector float)__builtin_altivec_vcfsx((vector int)(__a), \
3247 ((__b)&0x1F)), \
3248 vector unsigned int: (vector float)__builtin_altivec_vcfux( \
3249 (vector unsigned int)(__a), ((__b)&0x1F)))
32473250#endif
32483251
32493252/* vec_ctd */
32503253#ifdef __VSX__
32513254#define vec_ctd(__a, __b) \
3252 _Generic((__a), vector signed int \
3253 : (vec_doublee((vector signed int)(__a)) * \
3254 (vector double)(vector unsigned long long)((0x3ffULL - (__b)) \
3255 << 52)), \
3256 vector unsigned int \
3257 : (vec_doublee((vector unsigned int)(__a)) * \
3258 (vector double)(vector unsigned long long)((0x3ffULL - (__b)) \
3259 << 52)), \
3260 vector unsigned long long \
3261 : (__builtin_convertvector((vector unsigned long long)(__a), \
3262 vector double) * \
3263 (vector double)(vector unsigned long long)((0x3ffULL - (__b)) \
3264 << 52)), \
3265 vector signed long long \
3266 : (__builtin_convertvector((vector signed long long)(__a), \
3267 vector double) * \
3268 (vector double)(vector unsigned long long)((0x3ffULL - (__b)) \
3269 << 52)))
3255 _Generic((__a), \
3256 vector signed int: ( \
3257 vec_doublee((vector signed int)(__a)) * \
3258 (vector double)(vector unsigned long long)((0x3ffULL - \
3259 ((__b)&0x1F)) \
3260 << 52)), \
3261 vector unsigned int: ( \
3262 vec_doublee((vector unsigned int)(__a)) * \
3263 (vector double)(vector unsigned long long)((0x3ffULL - \
3264 ((__b)&0x1F)) \
3265 << 52)), \
3266 vector unsigned long long: ( \
3267 __builtin_convertvector((vector unsigned long long)(__a), \
3268 vector double) * \
3269 (vector double)(vector unsigned long long)((0x3ffULL - \
3270 ((__b)&0x1F)) \
3271 << 52)), \
3272 vector signed long long: ( \
3273 __builtin_convertvector((vector signed long long)(__a), \
3274 vector double) * \
3275 (vector double)(vector unsigned long long)((0x3ffULL - \
3276 ((__b)&0x1F)) \
3277 << 52)))
32703278#endif // __VSX__
32713279
32723280/* vec_vcfsx */
......@@ -3281,27 +3289,27 @@ static __inline__ vector double __ATTRS_o_ai vec_cpsgn(vector double __a,
32813289#ifdef __VSX__
32823290#ifdef __XL_COMPAT_ALTIVEC__
32833291#define vec_cts(__a, __b) \
3284 _Generic((__a), vector float \
3285 : (vector signed int)__builtin_altivec_vctsxs((vector float)(__a), \
3286 (__b)), \
3287 vector double \
3288 : __extension__({ \
3292 _Generic((__a), \
3293 vector float: (vector signed int)__builtin_altivec_vctsxs( \
3294 (vector float)(__a), ((__b)&0x1F)), \
3295 vector double: __extension__({ \
32893296 vector double __ret = \
32903297 (vector double)(__a) * \
3291 (vector double)(vector unsigned long long)((0x3ffULL + (__b)) \
3298 (vector double)(vector unsigned long long)((0x3ffULL + \
3299 ((__b)&0x1F)) \
32923300 << 52); \
32933301 (vector signed long long)__builtin_vsx_xvcvdpsxws(__ret); \
32943302 }))
32953303#else // __XL_COMPAT_ALTIVEC__
32963304#define vec_cts(__a, __b) \
3297 _Generic((__a), vector float \
3298 : (vector signed int)__builtin_altivec_vctsxs((vector float)(__a), \
3299 (__b)), \
3300 vector double \
3301 : __extension__({ \
3305 _Generic((__a), \
3306 vector float: (vector signed int)__builtin_altivec_vctsxs( \
3307 (vector float)(__a), ((__b)&0x1F)), \
3308 vector double: __extension__({ \
33023309 vector double __ret = \
33033310 (vector double)(__a) * \
3304 (vector double)(vector unsigned long long)((0x3ffULL + (__b)) \
3311 (vector double)(vector unsigned long long)((0x3ffULL + \
3312 ((__b)&0x1F)) \
33053313 << 52); \
33063314 (vector signed long long)__builtin_convertvector( \
33073315 __ret, vector signed long long); \
......@@ -3320,27 +3328,27 @@ static __inline__ vector double __ATTRS_o_ai vec_cpsgn(vector double __a,
33203328#ifdef __VSX__
33213329#ifdef __XL_COMPAT_ALTIVEC__
33223330#define vec_ctu(__a, __b) \
3323 _Generic((__a), vector float \
3324 : (vector unsigned int)__builtin_altivec_vctuxs( \
3325 (vector float)(__a), (__b)), \
3326 vector double \
3327 : __extension__({ \
3331 _Generic((__a), \
3332 vector float: (vector unsigned int)__builtin_altivec_vctuxs( \
3333 (vector float)(__a), ((__b)&0x1F)), \
3334 vector double: __extension__({ \
33283335 vector double __ret = \
33293336 (vector double)(__a) * \
3330 (vector double)(vector unsigned long long)((0x3ffULL + __b) \
3337 (vector double)(vector unsigned long long)((0x3ffULL + \
3338 ((__b)&0x1F)) \
33313339 << 52); \
33323340 (vector unsigned long long)__builtin_vsx_xvcvdpuxws(__ret); \
33333341 }))
33343342#else // __XL_COMPAT_ALTIVEC__
33353343#define vec_ctu(__a, __b) \
3336 _Generic((__a), vector float \
3337 : (vector unsigned int)__builtin_altivec_vctuxs( \
3338 (vector float)(__a), (__b)), \
3339 vector double \
3340 : __extension__({ \
3344 _Generic((__a), \
3345 vector float: (vector unsigned int)__builtin_altivec_vctuxs( \
3346 (vector float)(__a), ((__b)&0x1F)), \
3347 vector double: __extension__({ \
33413348 vector double __ret = \
33423349 (vector double)(__a) * \
3343 (vector double)(vector unsigned long long)((0x3ffULL + __b) \
3350 (vector double)(vector unsigned long long)((0x3ffULL + \
3351 ((__b)&0x1F)) \
33443352 << 52); \
33453353 (vector unsigned long long)__builtin_convertvector( \
33463354 __ret, vector unsigned long long); \
......@@ -3355,60 +3363,62 @@ static __inline__ vector double __ATTRS_o_ai vec_cpsgn(vector double __a,
33553363
33563364#ifdef __VSX__
33573365#define vec_ctsl(__a, __b) \
3358 _Generic((__a), vector float \
3359 : __extension__({ \
3360 vector float __ret = \
3361 (vector float)(__a) * \
3362 (vector float)(vector unsigned)((0x7f + (__b)) << 23); \
3363 __builtin_vsx_xvcvspsxds( \
3364 __builtin_vsx_xxsldwi(__ret, __ret, 1)); \
3365 }), \
3366 vector double \
3367 : __extension__({ \
3368 vector double __ret = \
3369 (vector double)(__a) * \
3370 (vector double)(vector unsigned long long)((0x3ffULL + __b) \
3371 << 52); \
3372 __builtin_convertvector(__ret, vector signed long long); \
3373 }))
3366 _Generic( \
3367 (__a), vector float \
3368 : __extension__({ \
3369 vector float __ret = \
3370 (vector float)(__a) * \
3371 (vector float)(vector unsigned)((0x7f + ((__b)&0x1F)) << 23); \
3372 __builtin_vsx_xvcvspsxds(__builtin_vsx_xxsldwi(__ret, __ret, 1)); \
3373 }), \
3374 vector double \
3375 : __extension__({ \
3376 vector double __ret = \
3377 (vector double)(__a) * \
3378 (vector double)(vector unsigned long long)((0x3ffULL + \
3379 ((__b)&0x1F)) \
3380 << 52); \
3381 __builtin_convertvector(__ret, vector signed long long); \
3382 }))
33743383
33753384/* vec_ctul */
33763385
33773386#define vec_ctul(__a, __b) \
3378 _Generic((__a), vector float \
3379 : __extension__({ \
3380 vector float __ret = \
3381 (vector float)(__a) * \
3382 (vector float)(vector unsigned)((0x7f + (__b)) << 23); \
3383 __builtin_vsx_xvcvspuxds( \
3384 __builtin_vsx_xxsldwi(__ret, __ret, 1)); \
3385 }), \
3386 vector double \
3387 : __extension__({ \
3388 vector double __ret = \
3389 (vector double)(__a) * \
3390 (vector double)(vector unsigned long long)((0x3ffULL + __b) \
3391 << 52); \
3392 __builtin_convertvector(__ret, vector unsigned long long); \
3393 }))
3387 _Generic( \
3388 (__a), vector float \
3389 : __extension__({ \
3390 vector float __ret = \
3391 (vector float)(__a) * \
3392 (vector float)(vector unsigned)((0x7f + ((__b)&0x1F)) << 23); \
3393 __builtin_vsx_xvcvspuxds(__builtin_vsx_xxsldwi(__ret, __ret, 1)); \
3394 }), \
3395 vector double \
3396 : __extension__({ \
3397 vector double __ret = \
3398 (vector double)(__a) * \
3399 (vector double)(vector unsigned long long)((0x3ffULL + \
3400 ((__b)&0x1F)) \
3401 << 52); \
3402 __builtin_convertvector(__ret, vector unsigned long long); \
3403 }))
33943404#endif
33953405#else // __LITTLE_ENDIAN__
33963406/* vec_ctsl */
33973407
33983408#ifdef __VSX__
33993409#define vec_ctsl(__a, __b) \
3400 _Generic((__a), vector float \
3401 : __extension__({ \
3402 vector float __ret = \
3403 (vector float)(__a) * \
3404 (vector float)(vector unsigned)((0x7f + (__b)) << 23); \
3405 __builtin_vsx_xvcvspsxds(__ret); \
3406 }), \
3407 vector double \
3408 : __extension__({ \
3410 _Generic((__a), \
3411 vector float: __extension__({ \
3412 vector float __ret = \
3413 (vector float)(__a) * \
3414 (vector float)(vector unsigned)((0x7f + ((__b)&0x1F)) << 23); \
3415 __builtin_vsx_xvcvspsxds(__ret); \
3416 }), \
3417 vector double: __extension__({ \
34093418 vector double __ret = \
34103419 (vector double)(__a) * \
3411 (vector double)(vector unsigned long long)((0x3ffULL + __b) \
3420 (vector double)(vector unsigned long long)((0x3ffULL + \
3421 ((__b)&0x1F)) \
34123422 << 52); \
34133423 __builtin_convertvector(__ret, vector signed long long); \
34143424 }))
......@@ -3420,14 +3430,16 @@ static __inline__ vector double __ATTRS_o_ai vec_cpsgn(vector double __a,
34203430 : __extension__({ \
34213431 vector float __ret = \
34223432 (vector float)(__a) * \
3423 (vector float)(vector unsigned)((0x7f + (__b)) << 23); \
3433 (vector float)(vector unsigned)((0x7f + ((__b)&0x1F)) \
3434 << 23); \
34243435 __builtin_vsx_xvcvspuxds(__ret); \
34253436 }), \
34263437 vector double \
34273438 : __extension__({ \
34283439 vector double __ret = \
34293440 (vector double)(__a) * \
3430 (vector double)(vector unsigned long long)((0x3ffULL + __b) \
3441 (vector double)(vector unsigned long long)((0x3ffULL + \
3442 ((__b)&0x1F)) \
34313443 << 52); \
34323444 __builtin_convertvector(__ret, vector unsigned long long); \
34333445 }))
lib/include/amxcomplexintrin.h created+169
......@@ -0,0 +1,169 @@
1/*===--------- amxcomplexintrin.h - AMXCOMPLEX intrinsics -*- C++ -*---------===
2 *
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 * See https://llvm.org/LICENSE.txt for license information.
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 *
7 *===------------------------------------------------------------------------===
8 */
9
10#ifndef __IMMINTRIN_H
11#error "Never use <amxcomplexintrin.h> directly; include <immintrin.h> instead."
12#endif // __IMMINTRIN_H
13
14#ifndef __AMX_COMPLEXINTRIN_H
15#define __AMX_COMPLEXINTRIN_H
16#ifdef __x86_64__
17
18#define __DEFAULT_FN_ATTRS_COMPLEX \
19 __attribute__((__always_inline__, __nodebug__, __target__("amx-complex")))
20
21/// Perform matrix multiplication of two tiles containing complex elements and
22/// accumulate the results into a packed single precision tile. Each dword
23/// element in input tiles \a a and \a b is interpreted as a complex number
24/// with FP16 real part and FP16 imaginary part.
25/// Calculates the imaginary part of the result. For each possible combination
26/// of (row of \a a, column of \a b), it performs a set of multiplication
27/// and accumulations on all corresponding complex numbers (one from \a a
28/// and one from \a b). The imaginary part of the \a a element is multiplied
29/// with the real part of the corresponding \a b element, and the real part
30/// of the \a a element is multiplied with the imaginary part of the
31/// corresponding \a b elements. The two accumulated results are added, and
32/// then accumulated into the corresponding row and column of \a dst.
33///
34/// \headerfile <x86intrin.h>
35///
36/// \code
37/// void _tile_cmmimfp16ps(__tile dst, __tile a, __tile b);
38/// \endcode
39///
40/// \code{.operation}
41/// FOR m := 0 TO dst.rows - 1
42/// tmp := dst.row[m]
43/// FOR k := 0 TO (a.colsb / 4) - 1
44/// FOR n := 0 TO (dst.colsb / 4) - 1
45/// tmp.fp32[n] += FP32(a.row[m].fp16[2*k+0]) * FP32(b.row[k].fp16[2*n+1])
46/// tmp.fp32[n] += FP32(a.row[m].fp16[2*k+1]) * FP32(b.row[k].fp16[2*n+0])
47/// ENDFOR
48/// ENDFOR
49/// write_row_and_zero(dst, m, tmp, dst.colsb)
50/// ENDFOR
51/// zero_upper_rows(dst, dst.rows)
52/// zero_tileconfig_start()
53/// \endcode
54///
55/// This intrinsic corresponds to the \c TCMMIMFP16PS instruction.
56///
57/// \param dst
58/// The destination tile. Max size is 1024 Bytes.
59/// \param a
60/// The 1st source tile. Max size is 1024 Bytes.
61/// \param b
62/// The 2nd source tile. Max size is 1024 Bytes.
63#define _tile_cmmimfp16ps(dst, a, b) __builtin_ia32_tcmmimfp16ps(dst, a, b)
64
65/// Perform matrix multiplication of two tiles containing complex elements and
66/// accumulate the results into a packed single precision tile. Each dword
67/// element in input tiles \a a and \a b is interpreted as a complex number
68/// with FP16 real part and FP16 imaginary part.
69/// Calculates the real part of the result. For each possible combination
70/// of (row of \a a, column of \a b), it performs a set of multiplication
71/// and accumulations on all corresponding complex numbers (one from \a a
72/// and one from \a b). The real part of the \a a element is multiplied
73/// with the real part of the corresponding \a b element, and the negated
74/// imaginary part of the \a a element is multiplied with the imaginary
75/// part of the corresponding \a b elements. The two accumulated results
76/// are added, and then accumulated into the corresponding row and column
77/// of \a dst.
78///
79/// \headerfile <x86intrin.h>
80///
81/// \code
82/// void _tile_cmmrlfp16ps(__tile dst, __tile a, __tile b);
83/// \endcode
84///
85/// \code{.operation}
86/// FOR m := 0 TO dst.rows - 1
87/// tmp := dst.row[m]
88/// FOR k := 0 TO (a.colsb / 4) - 1
89/// FOR n := 0 TO (dst.colsb / 4) - 1
90/// tmp.fp32[n] += FP32(a.row[m].fp16[2*k+0]) * FP32(b.row[k].fp16[2*n+0])
91/// tmp.fp32[n] += FP32(-a.row[m].fp16[2*k+1]) * FP32(b.row[k].fp16[2*n+1])
92/// ENDFOR
93/// ENDFOR
94/// write_row_and_zero(dst, m, tmp, dst.colsb)
95/// ENDFOR
96/// zero_upper_rows(dst, dst.rows)
97/// zero_tileconfig_start()
98/// \endcode
99///
100/// This intrinsic corresponds to the \c TCMMIMFP16PS instruction.
101///
102/// \param dst
103/// The destination tile. Max size is 1024 Bytes.
104/// \param a
105/// The 1st source tile. Max size is 1024 Bytes.
106/// \param b
107/// The 2nd source tile. Max size is 1024 Bytes.
108#define _tile_cmmrlfp16ps(dst, a, b) __builtin_ia32_tcmmrlfp16ps(dst, a, b)
109
110static __inline__ _tile1024i __DEFAULT_FN_ATTRS_COMPLEX
111_tile_cmmimfp16ps_internal(unsigned short m, unsigned short n, unsigned short k,
112 _tile1024i dst, _tile1024i src1, _tile1024i src2) {
113 return __builtin_ia32_tcmmimfp16ps_internal(m, n, k, dst, src1, src2);
114}
115
116static __inline__ _tile1024i __DEFAULT_FN_ATTRS_COMPLEX
117_tile_cmmrlfp16ps_internal(unsigned short m, unsigned short n, unsigned short k,
118 _tile1024i dst, _tile1024i src1, _tile1024i src2) {
119 return __builtin_ia32_tcmmrlfp16ps_internal(m, n, k, dst, src1, src2);
120}
121
122/// Perform matrix multiplication of two tiles containing complex elements and
123/// accumulate the results into a packed single precision tile. Each dword
124/// element in input tiles src0 and src1 is interpreted as a complex number with
125/// FP16 real part and FP16 imaginary part.
126/// This function calculates the imaginary part of the result.
127///
128/// \headerfile <immintrin.h>
129///
130/// This intrinsic corresponds to the <c> TCMMIMFP16PS </c> instruction.
131///
132/// \param dst
133/// The destination tile. Max size is 1024 Bytes.
134/// \param src0
135/// The 1st source tile. Max size is 1024 Bytes.
136/// \param src1
137/// The 2nd source tile. Max size is 1024 Bytes.
138__DEFAULT_FN_ATTRS_COMPLEX
139static void __tile_cmmimfp16ps(__tile1024i *dst, __tile1024i src0,
140 __tile1024i src1) {
141 dst->tile = _tile_cmmimfp16ps_internal(src0.row, src1.col, src0.col,
142 dst->tile, src0.tile, src1.tile);
143}
144
145/// Perform matrix multiplication of two tiles containing complex elements and
146/// accumulate the results into a packed single precision tile. Each dword
147/// element in input tiles src0 and src1 is interpreted as a complex number with
148/// FP16 real part and FP16 imaginary part.
149/// This function calculates the real part of the result.
150///
151/// \headerfile <immintrin.h>
152///
153/// This intrinsic corresponds to the <c> TCMMRLFP16PS </c> instruction.
154///
155/// \param dst
156/// The destination tile. Max size is 1024 Bytes.
157/// \param src0
158/// The 1st source tile. Max size is 1024 Bytes.
159/// \param src1
160/// The 2nd source tile. Max size is 1024 Bytes.
161__DEFAULT_FN_ATTRS_COMPLEX
162static void __tile_cmmrlfp16ps(__tile1024i *dst, __tile1024i src0,
163 __tile1024i src1) {
164 dst->tile = _tile_cmmrlfp16ps_internal(src0.row, src1.col, src0.col,
165 dst->tile, src0.tile, src1.tile);
166}
167
168#endif // __x86_64__
169#endif // __AMX_COMPLEXINTRIN_H
lib/include/arm_acle.h+13-9
......@@ -138,28 +138,32 @@ __rorl(unsigned long __x, uint32_t __y) {
138138
139139
140140/* CLZ */
141static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
141static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
142142__clz(uint32_t __t) {
143 return (uint32_t)__builtin_clz(__t);
143 return __builtin_arm_clz(__t);
144144}
145145
146static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
146static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
147147__clzl(unsigned long __t) {
148 return (unsigned long)__builtin_clzl(__t);
148#if __SIZEOF_LONG__ == 4
149 return __builtin_arm_clz(__t);
150#else
151 return __builtin_arm_clz64(__t);
152#endif
149153}
150154
151static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
155static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
152156__clzll(uint64_t __t) {
153 return (uint64_t)__builtin_clzll(__t);
157 return __builtin_arm_clz64(__t);
154158}
155159
156160/* CLS */
157static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
161static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
158162__cls(uint32_t __t) {
159163 return __builtin_arm_cls(__t);
160164}
161165
162static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
166static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
163167__clsl(unsigned long __t) {
164168#if __SIZEOF_LONG__ == 4
165169 return __builtin_arm_cls(__t);
......@@ -168,7 +172,7 @@ __clsl(unsigned long __t) {
168172#endif
169173}
170174
171static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
175static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
172176__clsll(uint64_t __t) {
173177 return __builtin_arm_cls64(__t);
174178}
lib/include/arm_neon.h+164-1
......@@ -35,7 +35,6 @@
3535#include <stdint.h>
3636
3737#include <arm_bf16.h>
38typedef __bf16 bfloat16_t;
3938typedef float float32_t;
4039typedef __fp16 float16_t;
4140#ifdef __aarch64__
......@@ -64938,6 +64937,170 @@ int8x16_t __reint_786 = __rev2_786; \
6493864937})
6493964938#endif
6494064939
64940#define vldap1_lane_p64(__p0, __p1, __p2) __extension__ ({ \
64941 poly64x1_t __ret; \
64942 poly64x1_t __s1 = __p1; \
64943 __ret = (poly64x1_t) __builtin_neon_vldap1_lane_p64(__p0, (int8x8_t)__s1, __p2, 6); \
64944 __ret; \
64945})
64946#ifdef __LITTLE_ENDIAN__
64947#define vldap1q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
64948 poly64x2_t __ret; \
64949 poly64x2_t __s1 = __p1; \
64950 __ret = (poly64x2_t) __builtin_neon_vldap1q_lane_p64(__p0, (int8x16_t)__s1, __p2, 38); \
64951 __ret; \
64952})
64953#else
64954#define vldap1q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
64955 poly64x2_t __ret; \
64956 poly64x2_t __s1 = __p1; \
64957 poly64x2_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
64958 __ret = (poly64x2_t) __builtin_neon_vldap1q_lane_p64(__p0, (int8x16_t)__rev1, __p2, 38); \
64959 __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
64960 __ret; \
64961})
64962#endif
64963
64964#ifdef __LITTLE_ENDIAN__
64965#define vldap1q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
64966 uint64x2_t __ret; \
64967 uint64x2_t __s1 = __p1; \
64968 __ret = (uint64x2_t) __builtin_neon_vldap1q_lane_u64(__p0, (int8x16_t)__s1, __p2, 51); \
64969 __ret; \
64970})
64971#else
64972#define vldap1q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
64973 uint64x2_t __ret; \
64974 uint64x2_t __s1 = __p1; \
64975 uint64x2_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
64976 __ret = (uint64x2_t) __builtin_neon_vldap1q_lane_u64(__p0, (int8x16_t)__rev1, __p2, 51); \
64977 __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
64978 __ret; \
64979})
64980#endif
64981
64982#ifdef __LITTLE_ENDIAN__
64983#define vldap1q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
64984 float64x2_t __ret; \
64985 float64x2_t __s1 = __p1; \
64986 __ret = (float64x2_t) __builtin_neon_vldap1q_lane_f64(__p0, (int8x16_t)__s1, __p2, 42); \
64987 __ret; \
64988})
64989#else
64990#define vldap1q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
64991 float64x2_t __ret; \
64992 float64x2_t __s1 = __p1; \
64993 float64x2_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
64994 __ret = (float64x2_t) __builtin_neon_vldap1q_lane_f64(__p0, (int8x16_t)__rev1, __p2, 42); \
64995 __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
64996 __ret; \
64997})
64998#endif
64999
65000#ifdef __LITTLE_ENDIAN__
65001#define vldap1q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
65002 int64x2_t __ret; \
65003 int64x2_t __s1 = __p1; \
65004 __ret = (int64x2_t) __builtin_neon_vldap1q_lane_s64(__p0, (int8x16_t)__s1, __p2, 35); \
65005 __ret; \
65006})
65007#else
65008#define vldap1q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
65009 int64x2_t __ret; \
65010 int64x2_t __s1 = __p1; \
65011 int64x2_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
65012 __ret = (int64x2_t) __builtin_neon_vldap1q_lane_s64(__p0, (int8x16_t)__rev1, __p2, 35); \
65013 __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
65014 __ret; \
65015})
65016#endif
65017
65018#define vldap1_lane_u64(__p0, __p1, __p2) __extension__ ({ \
65019 uint64x1_t __ret; \
65020 uint64x1_t __s1 = __p1; \
65021 __ret = (uint64x1_t) __builtin_neon_vldap1_lane_u64(__p0, (int8x8_t)__s1, __p2, 19); \
65022 __ret; \
65023})
65024#define vldap1_lane_f64(__p0, __p1, __p2) __extension__ ({ \
65025 float64x1_t __ret; \
65026 float64x1_t __s1 = __p1; \
65027 __ret = (float64x1_t) __builtin_neon_vldap1_lane_f64(__p0, (int8x8_t)__s1, __p2, 10); \
65028 __ret; \
65029})
65030#define vldap1_lane_s64(__p0, __p1, __p2) __extension__ ({ \
65031 int64x1_t __ret; \
65032 int64x1_t __s1 = __p1; \
65033 __ret = (int64x1_t) __builtin_neon_vldap1_lane_s64(__p0, (int8x8_t)__s1, __p2, 3); \
65034 __ret; \
65035})
65036#define vstl1_lane_p64(__p0, __p1, __p2) __extension__ ({ \
65037 poly64x1_t __s1 = __p1; \
65038 __builtin_neon_vstl1_lane_p64(__p0, (int8x8_t)__s1, __p2, 6); \
65039})
65040#ifdef __LITTLE_ENDIAN__
65041#define vstl1q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
65042 poly64x2_t __s1 = __p1; \
65043 __builtin_neon_vstl1q_lane_p64(__p0, (int8x16_t)__s1, __p2, 38); \
65044})
65045#else
65046#define vstl1q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
65047 poly64x2_t __s1 = __p1; \
65048 poly64x2_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
65049 __builtin_neon_vstl1q_lane_p64(__p0, (int8x16_t)__rev1, __p2, 38); \
65050})
65051#endif
65052
65053#ifdef __LITTLE_ENDIAN__
65054#define vstl1q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
65055 uint64x2_t __s1 = __p1; \
65056 __builtin_neon_vstl1q_lane_u64(__p0, (int8x16_t)__s1, __p2, 51); \
65057})
65058#else
65059#define vstl1q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
65060 uint64x2_t __s1 = __p1; \
65061 uint64x2_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
65062 __builtin_neon_vstl1q_lane_u64(__p0, (int8x16_t)__rev1, __p2, 51); \
65063})
65064#endif
65065
65066#ifdef __LITTLE_ENDIAN__
65067#define vstl1q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
65068 float64x2_t __s1 = __p1; \
65069 __builtin_neon_vstl1q_lane_f64(__p0, (int8x16_t)__s1, __p2, 42); \
65070})
65071#else
65072#define vstl1q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
65073 float64x2_t __s1 = __p1; \
65074 float64x2_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
65075 __builtin_neon_vstl1q_lane_f64(__p0, (int8x16_t)__rev1, __p2, 42); \
65076})
65077#endif
65078
65079#ifdef __LITTLE_ENDIAN__
65080#define vstl1q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
65081 int64x2_t __s1 = __p1; \
65082 __builtin_neon_vstl1q_lane_s64(__p0, (int8x16_t)__s1, __p2, 35); \
65083})
65084#else
65085#define vstl1q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
65086 int64x2_t __s1 = __p1; \
65087 int64x2_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
65088 __builtin_neon_vstl1q_lane_s64(__p0, (int8x16_t)__rev1, __p2, 35); \
65089})
65090#endif
65091
65092#define vstl1_lane_u64(__p0, __p1, __p2) __extension__ ({ \
65093 uint64x1_t __s1 = __p1; \
65094 __builtin_neon_vstl1_lane_u64(__p0, (int8x8_t)__s1, __p2, 19); \
65095})
65096#define vstl1_lane_f64(__p0, __p1, __p2) __extension__ ({ \
65097 float64x1_t __s1 = __p1; \
65098 __builtin_neon_vstl1_lane_f64(__p0, (int8x8_t)__s1, __p2, 10); \
65099})
65100#define vstl1_lane_s64(__p0, __p1, __p2) __extension__ ({ \
65101 int64x1_t __s1 = __p1; \
65102 __builtin_neon_vstl1_lane_s64(__p0, (int8x8_t)__s1, __p2, 3); \
65103})
6494165104#ifdef __LITTLE_ENDIAN__
6494265105__ai __attribute__((target("sha3"))) uint8x16_t vbcaxq_u8(uint8x16_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
6494365106 uint8x16_t __ret;
lib/include/arm_sme_draft_spec_subject_to_change.h created+642
......@@ -0,0 +1,642 @@
1/*===---- arm_sme_draft_spec_subject_to_change.h - ARM SME intrinsics ------===
2 *
3 *
4 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 * See https://llvm.org/LICENSE.txt for license information.
6 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 *
8 *===-----------------------------------------------------------------------===
9 */
10
11#ifndef __ARM_SME_H
12#define __ARM_SME_H
13
14#if !defined(__LITTLE_ENDIAN__)
15#error "Big endian is currently not supported for arm_sme_draft_spec_subject_to_change.h"
16#endif
17#include <arm_sve.h>
18
19/* Function attributes */
20#define __ai static __inline__ __attribute__((__always_inline__, __nodebug__))
21
22#define __aio static __inline__ __attribute__((__always_inline__, __nodebug__, __overloadable__))
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddha_za32_u32_m), arm_streaming, arm_shared_za))
29void svaddha_za32_u32_m(uint64_t, svbool_t, svbool_t, svuint32_t);
30__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddha_za32_s32_m), arm_streaming, arm_shared_za))
31void svaddha_za32_s32_m(uint64_t, svbool_t, svbool_t, svint32_t);
32__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddva_za32_u32_m), arm_streaming, arm_shared_za))
33void svaddva_za32_u32_m(uint64_t, svbool_t, svbool_t, svuint32_t);
34__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddva_za32_s32_m), arm_streaming, arm_shared_za))
35void svaddva_za32_s32_m(uint64_t, svbool_t, svbool_t, svint32_t);
36__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svcntsb), arm_streaming_compatible, arm_preserves_za))
37uint64_t svcntsb(void);
38__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svcntsd), arm_streaming_compatible, arm_preserves_za))
39uint64_t svcntsd(void);
40__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svcntsh), arm_streaming_compatible, arm_preserves_za))
41uint64_t svcntsh(void);
42__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svcntsw), arm_streaming_compatible, arm_preserves_za))
43uint64_t svcntsw(void);
44__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_hor_vnum_za128), arm_streaming, arm_shared_za))
45void svld1_hor_vnum_za128(uint64_t, uint32_t, uint64_t, svbool_t, void const *, int64_t);
46__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_hor_vnum_za16), arm_streaming, arm_shared_za))
47void svld1_hor_vnum_za16(uint64_t, uint32_t, uint64_t, svbool_t, void const *, int64_t);
48__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_hor_vnum_za32), arm_streaming, arm_shared_za))
49void svld1_hor_vnum_za32(uint64_t, uint32_t, uint64_t, svbool_t, void const *, int64_t);
50__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_hor_vnum_za64), arm_streaming, arm_shared_za))
51void svld1_hor_vnum_za64(uint64_t, uint32_t, uint64_t, svbool_t, void const *, int64_t);
52__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_hor_vnum_za8), arm_streaming, arm_shared_za))
53void svld1_hor_vnum_za8(uint64_t, uint32_t, uint64_t, svbool_t, void const *, int64_t);
54__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_hor_za128), arm_streaming, arm_shared_za))
55void svld1_hor_za128(uint64_t, uint32_t, uint64_t, svbool_t, void const *);
56__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_hor_za16), arm_streaming, arm_shared_za))
57void svld1_hor_za16(uint64_t, uint32_t, uint64_t, svbool_t, void const *);
58__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_hor_za32), arm_streaming, arm_shared_za))
59void svld1_hor_za32(uint64_t, uint32_t, uint64_t, svbool_t, void const *);
60__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_hor_za64), arm_streaming, arm_shared_za))
61void svld1_hor_za64(uint64_t, uint32_t, uint64_t, svbool_t, void const *);
62__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_hor_za8), arm_streaming, arm_shared_za))
63void svld1_hor_za8(uint64_t, uint32_t, uint64_t, svbool_t, void const *);
64__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_ver_vnum_za128), arm_streaming, arm_shared_za))
65void svld1_ver_vnum_za128(uint64_t, uint32_t, uint64_t, svbool_t, void const *, int64_t);
66__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_ver_vnum_za16), arm_streaming, arm_shared_za))
67void svld1_ver_vnum_za16(uint64_t, uint32_t, uint64_t, svbool_t, void const *, int64_t);
68__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_ver_vnum_za32), arm_streaming, arm_shared_za))
69void svld1_ver_vnum_za32(uint64_t, uint32_t, uint64_t, svbool_t, void const *, int64_t);
70__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_ver_vnum_za64), arm_streaming, arm_shared_za))
71void svld1_ver_vnum_za64(uint64_t, uint32_t, uint64_t, svbool_t, void const *, int64_t);
72__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_ver_vnum_za8), arm_streaming, arm_shared_za))
73void svld1_ver_vnum_za8(uint64_t, uint32_t, uint64_t, svbool_t, void const *, int64_t);
74__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_ver_za128), arm_streaming, arm_shared_za))
75void svld1_ver_za128(uint64_t, uint32_t, uint64_t, svbool_t, void const *);
76__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_ver_za16), arm_streaming, arm_shared_za))
77void svld1_ver_za16(uint64_t, uint32_t, uint64_t, svbool_t, void const *);
78__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_ver_za32), arm_streaming, arm_shared_za))
79void svld1_ver_za32(uint64_t, uint32_t, uint64_t, svbool_t, void const *);
80__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_ver_za64), arm_streaming, arm_shared_za))
81void svld1_ver_za64(uint64_t, uint32_t, uint64_t, svbool_t, void const *);
82__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svld1_ver_za8), arm_streaming, arm_shared_za))
83void svld1_ver_za8(uint64_t, uint32_t, uint64_t, svbool_t, void const *);
84__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za32_f16_m), arm_streaming, arm_shared_za))
85void svmopa_za32_f16_m(uint64_t, svbool_t, svbool_t, svfloat16_t, svfloat16_t);
86__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za32_bf16_m), arm_streaming, arm_shared_za))
87void svmopa_za32_bf16_m(uint64_t, svbool_t, svbool_t, svbfloat16_t, svbfloat16_t);
88__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za32_f32_m), arm_streaming, arm_shared_za))
89void svmopa_za32_f32_m(uint64_t, svbool_t, svbool_t, svfloat32_t, svfloat32_t);
90__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za32_s8_m), arm_streaming, arm_shared_za))
91void svmopa_za32_s8_m(uint64_t, svbool_t, svbool_t, svint8_t, svint8_t);
92__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za32_u8_m), arm_streaming, arm_shared_za))
93void svmopa_za32_u8_m(uint64_t, svbool_t, svbool_t, svuint8_t, svuint8_t);
94__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za32_f16_m), arm_streaming, arm_shared_za))
95void svmops_za32_f16_m(uint64_t, svbool_t, svbool_t, svfloat16_t, svfloat16_t);
96__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za32_bf16_m), arm_streaming, arm_shared_za))
97void svmops_za32_bf16_m(uint64_t, svbool_t, svbool_t, svbfloat16_t, svbfloat16_t);
98__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za32_f32_m), arm_streaming, arm_shared_za))
99void svmops_za32_f32_m(uint64_t, svbool_t, svbool_t, svfloat32_t, svfloat32_t);
100__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za32_s8_m), arm_streaming, arm_shared_za))
101void svmops_za32_s8_m(uint64_t, svbool_t, svbool_t, svint8_t, svint8_t);
102__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za32_u8_m), arm_streaming, arm_shared_za))
103void svmops_za32_u8_m(uint64_t, svbool_t, svbool_t, svuint8_t, svuint8_t);
104__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_u8_m), arm_streaming, arm_shared_za, arm_preserves_za))
105svuint8_t svread_hor_za128_u8_m(svuint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
106__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_u32_m), arm_streaming, arm_shared_za, arm_preserves_za))
107svuint32_t svread_hor_za128_u32_m(svuint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
108__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_u64_m), arm_streaming, arm_shared_za, arm_preserves_za))
109svuint64_t svread_hor_za128_u64_m(svuint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
110__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_u16_m), arm_streaming, arm_shared_za, arm_preserves_za))
111svuint16_t svread_hor_za128_u16_m(svuint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
112__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_bf16_m), arm_streaming, arm_shared_za, arm_preserves_za))
113svbfloat16_t svread_hor_za128_bf16_m(svbfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
114__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_s8_m), arm_streaming, arm_shared_za, arm_preserves_za))
115svint8_t svread_hor_za128_s8_m(svint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
116__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_f64_m), arm_streaming, arm_shared_za, arm_preserves_za))
117svfloat64_t svread_hor_za128_f64_m(svfloat64_t, svbool_t, uint64_t, uint32_t, uint64_t);
118__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_f32_m), arm_streaming, arm_shared_za, arm_preserves_za))
119svfloat32_t svread_hor_za128_f32_m(svfloat32_t, svbool_t, uint64_t, uint32_t, uint64_t);
120__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_f16_m), arm_streaming, arm_shared_za, arm_preserves_za))
121svfloat16_t svread_hor_za128_f16_m(svfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
122__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_s32_m), arm_streaming, arm_shared_za, arm_preserves_za))
123svint32_t svread_hor_za128_s32_m(svint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
124__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_s64_m), arm_streaming, arm_shared_za, arm_preserves_za))
125svint64_t svread_hor_za128_s64_m(svint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
126__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_s16_m), arm_streaming, arm_shared_za, arm_preserves_za))
127svint16_t svread_hor_za128_s16_m(svint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
128__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za16_u16_m), arm_streaming, arm_shared_za, arm_preserves_za))
129svuint16_t svread_hor_za16_u16_m(svuint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
130__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za16_bf16_m), arm_streaming, arm_shared_za, arm_preserves_za))
131svbfloat16_t svread_hor_za16_bf16_m(svbfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
132__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za16_f16_m), arm_streaming, arm_shared_za, arm_preserves_za))
133svfloat16_t svread_hor_za16_f16_m(svfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
134__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za16_s16_m), arm_streaming, arm_shared_za, arm_preserves_za))
135svint16_t svread_hor_za16_s16_m(svint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
136__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za32_u32_m), arm_streaming, arm_shared_za, arm_preserves_za))
137svuint32_t svread_hor_za32_u32_m(svuint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
138__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za32_f32_m), arm_streaming, arm_shared_za, arm_preserves_za))
139svfloat32_t svread_hor_za32_f32_m(svfloat32_t, svbool_t, uint64_t, uint32_t, uint64_t);
140__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za32_s32_m), arm_streaming, arm_shared_za, arm_preserves_za))
141svint32_t svread_hor_za32_s32_m(svint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
142__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za64_u64_m), arm_streaming, arm_shared_za, arm_preserves_za))
143svuint64_t svread_hor_za64_u64_m(svuint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
144__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za64_f64_m), arm_streaming, arm_shared_za, arm_preserves_za))
145svfloat64_t svread_hor_za64_f64_m(svfloat64_t, svbool_t, uint64_t, uint32_t, uint64_t);
146__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za64_s64_m), arm_streaming, arm_shared_za, arm_preserves_za))
147svint64_t svread_hor_za64_s64_m(svint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
148__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za8_u8_m), arm_streaming, arm_shared_za, arm_preserves_za))
149svuint8_t svread_hor_za8_u8_m(svuint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
150__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za8_s8_m), arm_streaming, arm_shared_za, arm_preserves_za))
151svint8_t svread_hor_za8_s8_m(svint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
152__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_u8_m), arm_streaming, arm_shared_za, arm_preserves_za))
153svuint8_t svread_ver_za128_u8_m(svuint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
154__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_u32_m), arm_streaming, arm_shared_za, arm_preserves_za))
155svuint32_t svread_ver_za128_u32_m(svuint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
156__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_u64_m), arm_streaming, arm_shared_za, arm_preserves_za))
157svuint64_t svread_ver_za128_u64_m(svuint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
158__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_u16_m), arm_streaming, arm_shared_za, arm_preserves_za))
159svuint16_t svread_ver_za128_u16_m(svuint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
160__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_bf16_m), arm_streaming, arm_shared_za, arm_preserves_za))
161svbfloat16_t svread_ver_za128_bf16_m(svbfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
162__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_s8_m), arm_streaming, arm_shared_za, arm_preserves_za))
163svint8_t svread_ver_za128_s8_m(svint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
164__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_f64_m), arm_streaming, arm_shared_za, arm_preserves_za))
165svfloat64_t svread_ver_za128_f64_m(svfloat64_t, svbool_t, uint64_t, uint32_t, uint64_t);
166__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_f32_m), arm_streaming, arm_shared_za, arm_preserves_za))
167svfloat32_t svread_ver_za128_f32_m(svfloat32_t, svbool_t, uint64_t, uint32_t, uint64_t);
168__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_f16_m), arm_streaming, arm_shared_za, arm_preserves_za))
169svfloat16_t svread_ver_za128_f16_m(svfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
170__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_s32_m), arm_streaming, arm_shared_za, arm_preserves_za))
171svint32_t svread_ver_za128_s32_m(svint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
172__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_s64_m), arm_streaming, arm_shared_za, arm_preserves_za))
173svint64_t svread_ver_za128_s64_m(svint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
174__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_s16_m), arm_streaming, arm_shared_za, arm_preserves_za))
175svint16_t svread_ver_za128_s16_m(svint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
176__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za16_u16_m), arm_streaming, arm_shared_za, arm_preserves_za))
177svuint16_t svread_ver_za16_u16_m(svuint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
178__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za16_bf16_m), arm_streaming, arm_shared_za, arm_preserves_za))
179svbfloat16_t svread_ver_za16_bf16_m(svbfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
180__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za16_f16_m), arm_streaming, arm_shared_za, arm_preserves_za))
181svfloat16_t svread_ver_za16_f16_m(svfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
182__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za16_s16_m), arm_streaming, arm_shared_za, arm_preserves_za))
183svint16_t svread_ver_za16_s16_m(svint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
184__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za32_u32_m), arm_streaming, arm_shared_za, arm_preserves_za))
185svuint32_t svread_ver_za32_u32_m(svuint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
186__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za32_f32_m), arm_streaming, arm_shared_za, arm_preserves_za))
187svfloat32_t svread_ver_za32_f32_m(svfloat32_t, svbool_t, uint64_t, uint32_t, uint64_t);
188__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za32_s32_m), arm_streaming, arm_shared_za, arm_preserves_za))
189svint32_t svread_ver_za32_s32_m(svint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
190__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za64_u64_m), arm_streaming, arm_shared_za, arm_preserves_za))
191svuint64_t svread_ver_za64_u64_m(svuint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
192__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za64_f64_m), arm_streaming, arm_shared_za, arm_preserves_za))
193svfloat64_t svread_ver_za64_f64_m(svfloat64_t, svbool_t, uint64_t, uint32_t, uint64_t);
194__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za64_s64_m), arm_streaming, arm_shared_za, arm_preserves_za))
195svint64_t svread_ver_za64_s64_m(svint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
196__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za8_u8_m), arm_streaming, arm_shared_za, arm_preserves_za))
197svuint8_t svread_ver_za8_u8_m(svuint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
198__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za8_s8_m), arm_streaming, arm_shared_za, arm_preserves_za))
199svint8_t svread_ver_za8_s8_m(svint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
200__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_hor_vnum_za128), arm_streaming, arm_shared_za, arm_preserves_za))
201void svst1_hor_vnum_za128(uint64_t, uint32_t, uint64_t, svbool_t, void *, int64_t);
202__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_hor_vnum_za16), arm_streaming, arm_shared_za, arm_preserves_za))
203void svst1_hor_vnum_za16(uint64_t, uint32_t, uint64_t, svbool_t, void *, int64_t);
204__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_hor_vnum_za32), arm_streaming, arm_shared_za, arm_preserves_za))
205void svst1_hor_vnum_za32(uint64_t, uint32_t, uint64_t, svbool_t, void *, int64_t);
206__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_hor_vnum_za64), arm_streaming, arm_shared_za, arm_preserves_za))
207void svst1_hor_vnum_za64(uint64_t, uint32_t, uint64_t, svbool_t, void *, int64_t);
208__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_hor_vnum_za8), arm_streaming, arm_shared_za, arm_preserves_za))
209void svst1_hor_vnum_za8(uint64_t, uint32_t, uint64_t, svbool_t, void *, int64_t);
210__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_hor_za128), arm_streaming, arm_shared_za, arm_preserves_za))
211void svst1_hor_za128(uint64_t, uint32_t, uint64_t, svbool_t, void *);
212__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_hor_za16), arm_streaming, arm_shared_za, arm_preserves_za))
213void svst1_hor_za16(uint64_t, uint32_t, uint64_t, svbool_t, void *);
214__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_hor_za32), arm_streaming, arm_shared_za, arm_preserves_za))
215void svst1_hor_za32(uint64_t, uint32_t, uint64_t, svbool_t, void *);
216__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_hor_za64), arm_streaming, arm_shared_za, arm_preserves_za))
217void svst1_hor_za64(uint64_t, uint32_t, uint64_t, svbool_t, void *);
218__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_hor_za8), arm_streaming, arm_shared_za, arm_preserves_za))
219void svst1_hor_za8(uint64_t, uint32_t, uint64_t, svbool_t, void *);
220__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_ver_vnum_za128), arm_streaming, arm_shared_za, arm_preserves_za))
221void svst1_ver_vnum_za128(uint64_t, uint32_t, uint64_t, svbool_t, void *, int64_t);
222__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_ver_vnum_za16), arm_streaming, arm_shared_za, arm_preserves_za))
223void svst1_ver_vnum_za16(uint64_t, uint32_t, uint64_t, svbool_t, void *, int64_t);
224__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_ver_vnum_za32), arm_streaming, arm_shared_za, arm_preserves_za))
225void svst1_ver_vnum_za32(uint64_t, uint32_t, uint64_t, svbool_t, void *, int64_t);
226__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_ver_vnum_za64), arm_streaming, arm_shared_za, arm_preserves_za))
227void svst1_ver_vnum_za64(uint64_t, uint32_t, uint64_t, svbool_t, void *, int64_t);
228__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_ver_vnum_za8), arm_streaming, arm_shared_za, arm_preserves_za))
229void svst1_ver_vnum_za8(uint64_t, uint32_t, uint64_t, svbool_t, void *, int64_t);
230__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_ver_za128), arm_streaming, arm_shared_za, arm_preserves_za))
231void svst1_ver_za128(uint64_t, uint32_t, uint64_t, svbool_t, void *);
232__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_ver_za16), arm_streaming, arm_shared_za, arm_preserves_za))
233void svst1_ver_za16(uint64_t, uint32_t, uint64_t, svbool_t, void *);
234__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_ver_za32), arm_streaming, arm_shared_za, arm_preserves_za))
235void svst1_ver_za32(uint64_t, uint32_t, uint64_t, svbool_t, void *);
236__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_ver_za64), arm_streaming, arm_shared_za, arm_preserves_za))
237void svst1_ver_za64(uint64_t, uint32_t, uint64_t, svbool_t, void *);
238__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svst1_ver_za8), arm_streaming, arm_shared_za, arm_preserves_za))
239void svst1_ver_za8(uint64_t, uint32_t, uint64_t, svbool_t, void *);
240__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svsumopa_za32_s8_m), arm_streaming, arm_shared_za))
241void svsumopa_za32_s8_m(uint64_t, svbool_t, svbool_t, svint8_t, svuint8_t);
242__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svsumops_za32_s8_m), arm_streaming, arm_shared_za))
243void svsumops_za32_s8_m(uint64_t, svbool_t, svbool_t, svint8_t, svuint8_t);
244__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svusmopa_za32_u8_m), arm_streaming, arm_shared_za))
245void svusmopa_za32_u8_m(uint64_t, svbool_t, svbool_t, svuint8_t, svint8_t);
246__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svusmops_za32_u8_m), arm_streaming, arm_shared_za))
247void svusmops_za32_u8_m(uint64_t, svbool_t, svbool_t, svuint8_t, svint8_t);
248__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_u8_m), arm_streaming, arm_shared_za))
249void svwrite_hor_za128_u8_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint8_t);
250__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_u32_m), arm_streaming, arm_shared_za))
251void svwrite_hor_za128_u32_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint32_t);
252__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_u64_m), arm_streaming, arm_shared_za))
253void svwrite_hor_za128_u64_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint64_t);
254__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_u16_m), arm_streaming, arm_shared_za))
255void svwrite_hor_za128_u16_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint16_t);
256__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_bf16_m), arm_streaming, arm_shared_za))
257void svwrite_hor_za128_bf16_m(uint64_t, uint32_t, uint64_t, svbool_t, svbfloat16_t);
258__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_s8_m), arm_streaming, arm_shared_za))
259void svwrite_hor_za128_s8_m(uint64_t, uint32_t, uint64_t, svbool_t, svint8_t);
260__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_f64_m), arm_streaming, arm_shared_za))
261void svwrite_hor_za128_f64_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat64_t);
262__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_f32_m), arm_streaming, arm_shared_za))
263void svwrite_hor_za128_f32_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat32_t);
264__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_f16_m), arm_streaming, arm_shared_za))
265void svwrite_hor_za128_f16_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat16_t);
266__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_s32_m), arm_streaming, arm_shared_za))
267void svwrite_hor_za128_s32_m(uint64_t, uint32_t, uint64_t, svbool_t, svint32_t);
268__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_s64_m), arm_streaming, arm_shared_za))
269void svwrite_hor_za128_s64_m(uint64_t, uint32_t, uint64_t, svbool_t, svint64_t);
270__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_s16_m), arm_streaming, arm_shared_za))
271void svwrite_hor_za128_s16_m(uint64_t, uint32_t, uint64_t, svbool_t, svint16_t);
272__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za16_u16_m), arm_streaming, arm_shared_za))
273void svwrite_hor_za16_u16_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint16_t);
274__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za16_bf16_m), arm_streaming, arm_shared_za))
275void svwrite_hor_za16_bf16_m(uint64_t, uint32_t, uint64_t, svbool_t, svbfloat16_t);
276__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za16_f16_m), arm_streaming, arm_shared_za))
277void svwrite_hor_za16_f16_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat16_t);
278__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za16_s16_m), arm_streaming, arm_shared_za))
279void svwrite_hor_za16_s16_m(uint64_t, uint32_t, uint64_t, svbool_t, svint16_t);
280__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za32_u32_m), arm_streaming, arm_shared_za))
281void svwrite_hor_za32_u32_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint32_t);
282__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za32_f32_m), arm_streaming, arm_shared_za))
283void svwrite_hor_za32_f32_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat32_t);
284__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za32_s32_m), arm_streaming, arm_shared_za))
285void svwrite_hor_za32_s32_m(uint64_t, uint32_t, uint64_t, svbool_t, svint32_t);
286__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za64_u64_m), arm_streaming, arm_shared_za))
287void svwrite_hor_za64_u64_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint64_t);
288__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za64_f64_m), arm_streaming, arm_shared_za))
289void svwrite_hor_za64_f64_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat64_t);
290__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za64_s64_m), arm_streaming, arm_shared_za))
291void svwrite_hor_za64_s64_m(uint64_t, uint32_t, uint64_t, svbool_t, svint64_t);
292__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za8_u8_m), arm_streaming, arm_shared_za))
293void svwrite_hor_za8_u8_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint8_t);
294__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za8_s8_m), arm_streaming, arm_shared_za))
295void svwrite_hor_za8_s8_m(uint64_t, uint32_t, uint64_t, svbool_t, svint8_t);
296__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_u8_m), arm_streaming, arm_shared_za))
297void svwrite_ver_za128_u8_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint8_t);
298__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_u32_m), arm_streaming, arm_shared_za))
299void svwrite_ver_za128_u32_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint32_t);
300__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_u64_m), arm_streaming, arm_shared_za))
301void svwrite_ver_za128_u64_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint64_t);
302__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_u16_m), arm_streaming, arm_shared_za))
303void svwrite_ver_za128_u16_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint16_t);
304__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_bf16_m), arm_streaming, arm_shared_za))
305void svwrite_ver_za128_bf16_m(uint64_t, uint32_t, uint64_t, svbool_t, svbfloat16_t);
306__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_s8_m), arm_streaming, arm_shared_za))
307void svwrite_ver_za128_s8_m(uint64_t, uint32_t, uint64_t, svbool_t, svint8_t);
308__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_f64_m), arm_streaming, arm_shared_za))
309void svwrite_ver_za128_f64_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat64_t);
310__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_f32_m), arm_streaming, arm_shared_za))
311void svwrite_ver_za128_f32_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat32_t);
312__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_f16_m), arm_streaming, arm_shared_za))
313void svwrite_ver_za128_f16_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat16_t);
314__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_s32_m), arm_streaming, arm_shared_za))
315void svwrite_ver_za128_s32_m(uint64_t, uint32_t, uint64_t, svbool_t, svint32_t);
316__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_s64_m), arm_streaming, arm_shared_za))
317void svwrite_ver_za128_s64_m(uint64_t, uint32_t, uint64_t, svbool_t, svint64_t);
318__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_s16_m), arm_streaming, arm_shared_za))
319void svwrite_ver_za128_s16_m(uint64_t, uint32_t, uint64_t, svbool_t, svint16_t);
320__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za16_u16_m), arm_streaming, arm_shared_za))
321void svwrite_ver_za16_u16_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint16_t);
322__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za16_bf16_m), arm_streaming, arm_shared_za))
323void svwrite_ver_za16_bf16_m(uint64_t, uint32_t, uint64_t, svbool_t, svbfloat16_t);
324__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za16_f16_m), arm_streaming, arm_shared_za))
325void svwrite_ver_za16_f16_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat16_t);
326__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za16_s16_m), arm_streaming, arm_shared_za))
327void svwrite_ver_za16_s16_m(uint64_t, uint32_t, uint64_t, svbool_t, svint16_t);
328__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za32_u32_m), arm_streaming, arm_shared_za))
329void svwrite_ver_za32_u32_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint32_t);
330__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za32_f32_m), arm_streaming, arm_shared_za))
331void svwrite_ver_za32_f32_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat32_t);
332__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za32_s32_m), arm_streaming, arm_shared_za))
333void svwrite_ver_za32_s32_m(uint64_t, uint32_t, uint64_t, svbool_t, svint32_t);
334__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za64_u64_m), arm_streaming, arm_shared_za))
335void svwrite_ver_za64_u64_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint64_t);
336__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za64_f64_m), arm_streaming, arm_shared_za))
337void svwrite_ver_za64_f64_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat64_t);
338__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za64_s64_m), arm_streaming, arm_shared_za))
339void svwrite_ver_za64_s64_m(uint64_t, uint32_t, uint64_t, svbool_t, svint64_t);
340__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za8_u8_m), arm_streaming, arm_shared_za))
341void svwrite_ver_za8_u8_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint8_t);
342__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za8_s8_m), arm_streaming, arm_shared_za))
343void svwrite_ver_za8_s8_m(uint64_t, uint32_t, uint64_t, svbool_t, svint8_t);
344__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svzero_mask_za), arm_streaming_compatible, arm_shared_za))
345void svzero_mask_za(uint64_t);
346__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svzero_za), arm_streaming_compatible, arm_shared_za))
347void svzero_za();
348__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddha_za32_u32_m), arm_streaming, arm_shared_za))
349void svaddha_za32_m(uint64_t, svbool_t, svbool_t, svuint32_t);
350__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddha_za32_s32_m), arm_streaming, arm_shared_za))
351void svaddha_za32_m(uint64_t, svbool_t, svbool_t, svint32_t);
352__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddva_za32_u32_m), arm_streaming, arm_shared_za))
353void svaddva_za32_m(uint64_t, svbool_t, svbool_t, svuint32_t);
354__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddva_za32_s32_m), arm_streaming, arm_shared_za))
355void svaddva_za32_m(uint64_t, svbool_t, svbool_t, svint32_t);
356__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za32_f16_m), arm_streaming, arm_shared_za))
357void svmopa_za32_m(uint64_t, svbool_t, svbool_t, svfloat16_t, svfloat16_t);
358__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za32_bf16_m), arm_streaming, arm_shared_za))
359void svmopa_za32_m(uint64_t, svbool_t, svbool_t, svbfloat16_t, svbfloat16_t);
360__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za32_f32_m), arm_streaming, arm_shared_za))
361void svmopa_za32_m(uint64_t, svbool_t, svbool_t, svfloat32_t, svfloat32_t);
362__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za32_s8_m), arm_streaming, arm_shared_za))
363void svmopa_za32_m(uint64_t, svbool_t, svbool_t, svint8_t, svint8_t);
364__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za32_u8_m), arm_streaming, arm_shared_za))
365void svmopa_za32_m(uint64_t, svbool_t, svbool_t, svuint8_t, svuint8_t);
366__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za32_f16_m), arm_streaming, arm_shared_za))
367void svmops_za32_m(uint64_t, svbool_t, svbool_t, svfloat16_t, svfloat16_t);
368__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za32_bf16_m), arm_streaming, arm_shared_za))
369void svmops_za32_m(uint64_t, svbool_t, svbool_t, svbfloat16_t, svbfloat16_t);
370__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za32_f32_m), arm_streaming, arm_shared_za))
371void svmops_za32_m(uint64_t, svbool_t, svbool_t, svfloat32_t, svfloat32_t);
372__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za32_s8_m), arm_streaming, arm_shared_za))
373void svmops_za32_m(uint64_t, svbool_t, svbool_t, svint8_t, svint8_t);
374__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za32_u8_m), arm_streaming, arm_shared_za))
375void svmops_za32_m(uint64_t, svbool_t, svbool_t, svuint8_t, svuint8_t);
376__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_u8_m), arm_streaming, arm_shared_za, arm_preserves_za))
377svuint8_t svread_hor_za128_m(svuint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
378__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_u32_m), arm_streaming, arm_shared_za, arm_preserves_za))
379svuint32_t svread_hor_za128_m(svuint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
380__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_u64_m), arm_streaming, arm_shared_za, arm_preserves_za))
381svuint64_t svread_hor_za128_m(svuint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
382__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_u16_m), arm_streaming, arm_shared_za, arm_preserves_za))
383svuint16_t svread_hor_za128_m(svuint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
384__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_bf16_m), arm_streaming, arm_shared_za, arm_preserves_za))
385svbfloat16_t svread_hor_za128_m(svbfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
386__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_s8_m), arm_streaming, arm_shared_za, arm_preserves_za))
387svint8_t svread_hor_za128_m(svint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
388__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_f64_m), arm_streaming, arm_shared_za, arm_preserves_za))
389svfloat64_t svread_hor_za128_m(svfloat64_t, svbool_t, uint64_t, uint32_t, uint64_t);
390__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_f32_m), arm_streaming, arm_shared_za, arm_preserves_za))
391svfloat32_t svread_hor_za128_m(svfloat32_t, svbool_t, uint64_t, uint32_t, uint64_t);
392__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_f16_m), arm_streaming, arm_shared_za, arm_preserves_za))
393svfloat16_t svread_hor_za128_m(svfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
394__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_s32_m), arm_streaming, arm_shared_za, arm_preserves_za))
395svint32_t svread_hor_za128_m(svint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
396__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_s64_m), arm_streaming, arm_shared_za, arm_preserves_za))
397svint64_t svread_hor_za128_m(svint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
398__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za128_s16_m), arm_streaming, arm_shared_za, arm_preserves_za))
399svint16_t svread_hor_za128_m(svint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
400__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za16_u16_m), arm_streaming, arm_shared_za, arm_preserves_za))
401svuint16_t svread_hor_za16_m(svuint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
402__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za16_bf16_m), arm_streaming, arm_shared_za, arm_preserves_za))
403svbfloat16_t svread_hor_za16_m(svbfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
404__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za16_f16_m), arm_streaming, arm_shared_za, arm_preserves_za))
405svfloat16_t svread_hor_za16_m(svfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
406__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za16_s16_m), arm_streaming, arm_shared_za, arm_preserves_za))
407svint16_t svread_hor_za16_m(svint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
408__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za32_u32_m), arm_streaming, arm_shared_za, arm_preserves_za))
409svuint32_t svread_hor_za32_m(svuint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
410__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za32_f32_m), arm_streaming, arm_shared_za, arm_preserves_za))
411svfloat32_t svread_hor_za32_m(svfloat32_t, svbool_t, uint64_t, uint32_t, uint64_t);
412__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za32_s32_m), arm_streaming, arm_shared_za, arm_preserves_za))
413svint32_t svread_hor_za32_m(svint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
414__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za64_u64_m), arm_streaming, arm_shared_za, arm_preserves_za))
415svuint64_t svread_hor_za64_m(svuint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
416__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za64_f64_m), arm_streaming, arm_shared_za, arm_preserves_za))
417svfloat64_t svread_hor_za64_m(svfloat64_t, svbool_t, uint64_t, uint32_t, uint64_t);
418__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za64_s64_m), arm_streaming, arm_shared_za, arm_preserves_za))
419svint64_t svread_hor_za64_m(svint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
420__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za8_u8_m), arm_streaming, arm_shared_za, arm_preserves_za))
421svuint8_t svread_hor_za8_m(svuint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
422__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_hor_za8_s8_m), arm_streaming, arm_shared_za, arm_preserves_za))
423svint8_t svread_hor_za8_m(svint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
424__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_u8_m), arm_streaming, arm_shared_za, arm_preserves_za))
425svuint8_t svread_ver_za128_m(svuint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
426__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_u32_m), arm_streaming, arm_shared_za, arm_preserves_za))
427svuint32_t svread_ver_za128_m(svuint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
428__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_u64_m), arm_streaming, arm_shared_za, arm_preserves_za))
429svuint64_t svread_ver_za128_m(svuint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
430__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_u16_m), arm_streaming, arm_shared_za, arm_preserves_za))
431svuint16_t svread_ver_za128_m(svuint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
432__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_bf16_m), arm_streaming, arm_shared_za, arm_preserves_za))
433svbfloat16_t svread_ver_za128_m(svbfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
434__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_s8_m), arm_streaming, arm_shared_za, arm_preserves_za))
435svint8_t svread_ver_za128_m(svint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
436__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_f64_m), arm_streaming, arm_shared_za, arm_preserves_za))
437svfloat64_t svread_ver_za128_m(svfloat64_t, svbool_t, uint64_t, uint32_t, uint64_t);
438__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_f32_m), arm_streaming, arm_shared_za, arm_preserves_za))
439svfloat32_t svread_ver_za128_m(svfloat32_t, svbool_t, uint64_t, uint32_t, uint64_t);
440__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_f16_m), arm_streaming, arm_shared_za, arm_preserves_za))
441svfloat16_t svread_ver_za128_m(svfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
442__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_s32_m), arm_streaming, arm_shared_za, arm_preserves_za))
443svint32_t svread_ver_za128_m(svint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
444__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_s64_m), arm_streaming, arm_shared_za, arm_preserves_za))
445svint64_t svread_ver_za128_m(svint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
446__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za128_s16_m), arm_streaming, arm_shared_za, arm_preserves_za))
447svint16_t svread_ver_za128_m(svint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
448__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za16_u16_m), arm_streaming, arm_shared_za, arm_preserves_za))
449svuint16_t svread_ver_za16_m(svuint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
450__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za16_bf16_m), arm_streaming, arm_shared_za, arm_preserves_za))
451svbfloat16_t svread_ver_za16_m(svbfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
452__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za16_f16_m), arm_streaming, arm_shared_za, arm_preserves_za))
453svfloat16_t svread_ver_za16_m(svfloat16_t, svbool_t, uint64_t, uint32_t, uint64_t);
454__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za16_s16_m), arm_streaming, arm_shared_za, arm_preserves_za))
455svint16_t svread_ver_za16_m(svint16_t, svbool_t, uint64_t, uint32_t, uint64_t);
456__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za32_u32_m), arm_streaming, arm_shared_za, arm_preserves_za))
457svuint32_t svread_ver_za32_m(svuint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
458__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za32_f32_m), arm_streaming, arm_shared_za, arm_preserves_za))
459svfloat32_t svread_ver_za32_m(svfloat32_t, svbool_t, uint64_t, uint32_t, uint64_t);
460__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za32_s32_m), arm_streaming, arm_shared_za, arm_preserves_za))
461svint32_t svread_ver_za32_m(svint32_t, svbool_t, uint64_t, uint32_t, uint64_t);
462__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za64_u64_m), arm_streaming, arm_shared_za, arm_preserves_za))
463svuint64_t svread_ver_za64_m(svuint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
464__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za64_f64_m), arm_streaming, arm_shared_za, arm_preserves_za))
465svfloat64_t svread_ver_za64_m(svfloat64_t, svbool_t, uint64_t, uint32_t, uint64_t);
466__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za64_s64_m), arm_streaming, arm_shared_za, arm_preserves_za))
467svint64_t svread_ver_za64_m(svint64_t, svbool_t, uint64_t, uint32_t, uint64_t);
468__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za8_u8_m), arm_streaming, arm_shared_za, arm_preserves_za))
469svuint8_t svread_ver_za8_m(svuint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
470__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svread_ver_za8_s8_m), arm_streaming, arm_shared_za, arm_preserves_za))
471svint8_t svread_ver_za8_m(svint8_t, svbool_t, uint64_t, uint32_t, uint64_t);
472__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svsumopa_za32_s8_m), arm_streaming, arm_shared_za))
473void svsumopa_za32_m(uint64_t, svbool_t, svbool_t, svint8_t, svuint8_t);
474__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svsumops_za32_s8_m), arm_streaming, arm_shared_za))
475void svsumops_za32_m(uint64_t, svbool_t, svbool_t, svint8_t, svuint8_t);
476__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svusmopa_za32_u8_m), arm_streaming, arm_shared_za))
477void svusmopa_za32_m(uint64_t, svbool_t, svbool_t, svuint8_t, svint8_t);
478__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svusmops_za32_u8_m), arm_streaming, arm_shared_za))
479void svusmops_za32_m(uint64_t, svbool_t, svbool_t, svuint8_t, svint8_t);
480__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_u8_m), arm_streaming, arm_shared_za))
481void svwrite_hor_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint8_t);
482__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_u32_m), arm_streaming, arm_shared_za))
483void svwrite_hor_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint32_t);
484__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_u64_m), arm_streaming, arm_shared_za))
485void svwrite_hor_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint64_t);
486__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_u16_m), arm_streaming, arm_shared_za))
487void svwrite_hor_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint16_t);
488__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_bf16_m), arm_streaming, arm_shared_za))
489void svwrite_hor_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svbfloat16_t);
490__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_s8_m), arm_streaming, arm_shared_za))
491void svwrite_hor_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svint8_t);
492__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_f64_m), arm_streaming, arm_shared_za))
493void svwrite_hor_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat64_t);
494__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_f32_m), arm_streaming, arm_shared_za))
495void svwrite_hor_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat32_t);
496__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_f16_m), arm_streaming, arm_shared_za))
497void svwrite_hor_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat16_t);
498__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_s32_m), arm_streaming, arm_shared_za))
499void svwrite_hor_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svint32_t);
500__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_s64_m), arm_streaming, arm_shared_za))
501void svwrite_hor_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svint64_t);
502__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za128_s16_m), arm_streaming, arm_shared_za))
503void svwrite_hor_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svint16_t);
504__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za16_u16_m), arm_streaming, arm_shared_za))
505void svwrite_hor_za16_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint16_t);
506__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za16_bf16_m), arm_streaming, arm_shared_za))
507void svwrite_hor_za16_m(uint64_t, uint32_t, uint64_t, svbool_t, svbfloat16_t);
508__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za16_f16_m), arm_streaming, arm_shared_za))
509void svwrite_hor_za16_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat16_t);
510__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za16_s16_m), arm_streaming, arm_shared_za))
511void svwrite_hor_za16_m(uint64_t, uint32_t, uint64_t, svbool_t, svint16_t);
512__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za32_u32_m), arm_streaming, arm_shared_za))
513void svwrite_hor_za32_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint32_t);
514__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za32_f32_m), arm_streaming, arm_shared_za))
515void svwrite_hor_za32_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat32_t);
516__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za32_s32_m), arm_streaming, arm_shared_za))
517void svwrite_hor_za32_m(uint64_t, uint32_t, uint64_t, svbool_t, svint32_t);
518__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za64_u64_m), arm_streaming, arm_shared_za))
519void svwrite_hor_za64_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint64_t);
520__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za64_f64_m), arm_streaming, arm_shared_za))
521void svwrite_hor_za64_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat64_t);
522__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za64_s64_m), arm_streaming, arm_shared_za))
523void svwrite_hor_za64_m(uint64_t, uint32_t, uint64_t, svbool_t, svint64_t);
524__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za8_u8_m), arm_streaming, arm_shared_za))
525void svwrite_hor_za8_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint8_t);
526__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_hor_za8_s8_m), arm_streaming, arm_shared_za))
527void svwrite_hor_za8_m(uint64_t, uint32_t, uint64_t, svbool_t, svint8_t);
528__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_u8_m), arm_streaming, arm_shared_za))
529void svwrite_ver_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint8_t);
530__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_u32_m), arm_streaming, arm_shared_za))
531void svwrite_ver_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint32_t);
532__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_u64_m), arm_streaming, arm_shared_za))
533void svwrite_ver_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint64_t);
534__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_u16_m), arm_streaming, arm_shared_za))
535void svwrite_ver_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint16_t);
536__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_bf16_m), arm_streaming, arm_shared_za))
537void svwrite_ver_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svbfloat16_t);
538__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_s8_m), arm_streaming, arm_shared_za))
539void svwrite_ver_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svint8_t);
540__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_f64_m), arm_streaming, arm_shared_za))
541void svwrite_ver_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat64_t);
542__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_f32_m), arm_streaming, arm_shared_za))
543void svwrite_ver_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat32_t);
544__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_f16_m), arm_streaming, arm_shared_za))
545void svwrite_ver_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat16_t);
546__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_s32_m), arm_streaming, arm_shared_za))
547void svwrite_ver_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svint32_t);
548__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_s64_m), arm_streaming, arm_shared_za))
549void svwrite_ver_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svint64_t);
550__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za128_s16_m), arm_streaming, arm_shared_za))
551void svwrite_ver_za128_m(uint64_t, uint32_t, uint64_t, svbool_t, svint16_t);
552__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za16_u16_m), arm_streaming, arm_shared_za))
553void svwrite_ver_za16_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint16_t);
554__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za16_bf16_m), arm_streaming, arm_shared_za))
555void svwrite_ver_za16_m(uint64_t, uint32_t, uint64_t, svbool_t, svbfloat16_t);
556__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za16_f16_m), arm_streaming, arm_shared_za))
557void svwrite_ver_za16_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat16_t);
558__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za16_s16_m), arm_streaming, arm_shared_za))
559void svwrite_ver_za16_m(uint64_t, uint32_t, uint64_t, svbool_t, svint16_t);
560__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za32_u32_m), arm_streaming, arm_shared_za))
561void svwrite_ver_za32_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint32_t);
562__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za32_f32_m), arm_streaming, arm_shared_za))
563void svwrite_ver_za32_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat32_t);
564__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za32_s32_m), arm_streaming, arm_shared_za))
565void svwrite_ver_za32_m(uint64_t, uint32_t, uint64_t, svbool_t, svint32_t);
566__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za64_u64_m), arm_streaming, arm_shared_za))
567void svwrite_ver_za64_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint64_t);
568__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za64_f64_m), arm_streaming, arm_shared_za))
569void svwrite_ver_za64_m(uint64_t, uint32_t, uint64_t, svbool_t, svfloat64_t);
570__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za64_s64_m), arm_streaming, arm_shared_za))
571void svwrite_ver_za64_m(uint64_t, uint32_t, uint64_t, svbool_t, svint64_t);
572__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za8_u8_m), arm_streaming, arm_shared_za))
573void svwrite_ver_za8_m(uint64_t, uint32_t, uint64_t, svbool_t, svuint8_t);
574__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svwrite_ver_za8_s8_m), arm_streaming, arm_shared_za))
575void svwrite_ver_za8_m(uint64_t, uint32_t, uint64_t, svbool_t, svint8_t);
576__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za64_f64_m), arm_streaming, arm_shared_za))
577void svmopa_za64_f64_m(uint64_t, svbool_t, svbool_t, svfloat64_t, svfloat64_t);
578__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za64_f64_m), arm_streaming, arm_shared_za))
579void svmops_za64_f64_m(uint64_t, svbool_t, svbool_t, svfloat64_t, svfloat64_t);
580__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za64_f64_m), arm_streaming, arm_shared_za))
581void svmopa_za64_m(uint64_t, svbool_t, svbool_t, svfloat64_t, svfloat64_t);
582__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za64_f64_m), arm_streaming, arm_shared_za))
583void svmops_za64_m(uint64_t, svbool_t, svbool_t, svfloat64_t, svfloat64_t);
584__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddha_za64_u64_m), arm_streaming, arm_shared_za))
585void svaddha_za64_u64_m(uint64_t, svbool_t, svbool_t, svuint64_t);
586__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddha_za64_s64_m), arm_streaming, arm_shared_za))
587void svaddha_za64_s64_m(uint64_t, svbool_t, svbool_t, svint64_t);
588__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddva_za64_u64_m), arm_streaming, arm_shared_za))
589void svaddva_za64_u64_m(uint64_t, svbool_t, svbool_t, svuint64_t);
590__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddva_za64_s64_m), arm_streaming, arm_shared_za))
591void svaddva_za64_s64_m(uint64_t, svbool_t, svbool_t, svint64_t);
592__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za64_s16_m), arm_streaming, arm_shared_za))
593void svmopa_za64_s16_m(uint64_t, svbool_t, svbool_t, svint16_t, svint16_t);
594__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za64_u16_m), arm_streaming, arm_shared_za))
595void svmopa_za64_u16_m(uint64_t, svbool_t, svbool_t, svuint16_t, svuint16_t);
596__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za64_s16_m), arm_streaming, arm_shared_za))
597void svmops_za64_s16_m(uint64_t, svbool_t, svbool_t, svint16_t, svint16_t);
598__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za64_u16_m), arm_streaming, arm_shared_za))
599void svmops_za64_u16_m(uint64_t, svbool_t, svbool_t, svuint16_t, svuint16_t);
600__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svsumopa_za64_s16_m), arm_streaming, arm_shared_za))
601void svsumopa_za64_s16_m(uint64_t, svbool_t, svbool_t, svint16_t, svuint16_t);
602__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svsumops_za64_s16_m), arm_streaming, arm_shared_za))
603void svsumops_za64_s16_m(uint64_t, svbool_t, svbool_t, svint16_t, svuint16_t);
604__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svusmopa_za64_u16_m), arm_streaming, arm_shared_za))
605void svusmopa_za64_u16_m(uint64_t, svbool_t, svbool_t, svuint16_t, svint16_t);
606__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svusmops_za64_u16_m), arm_streaming, arm_shared_za))
607void svusmops_za64_u16_m(uint64_t, svbool_t, svbool_t, svuint16_t, svint16_t);
608__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddha_za64_u64_m), arm_streaming, arm_shared_za))
609void svaddha_za64_m(uint64_t, svbool_t, svbool_t, svuint64_t);
610__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddha_za64_s64_m), arm_streaming, arm_shared_za))
611void svaddha_za64_m(uint64_t, svbool_t, svbool_t, svint64_t);
612__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddva_za64_u64_m), arm_streaming, arm_shared_za))
613void svaddva_za64_m(uint64_t, svbool_t, svbool_t, svuint64_t);
614__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svaddva_za64_s64_m), arm_streaming, arm_shared_za))
615void svaddva_za64_m(uint64_t, svbool_t, svbool_t, svint64_t);
616__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za64_s16_m), arm_streaming, arm_shared_za))
617void svmopa_za64_m(uint64_t, svbool_t, svbool_t, svint16_t, svint16_t);
618__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmopa_za64_u16_m), arm_streaming, arm_shared_za))
619void svmopa_za64_m(uint64_t, svbool_t, svbool_t, svuint16_t, svuint16_t);
620__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za64_s16_m), arm_streaming, arm_shared_za))
621void svmops_za64_m(uint64_t, svbool_t, svbool_t, svint16_t, svint16_t);
622__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svmops_za64_u16_m), arm_streaming, arm_shared_za))
623void svmops_za64_m(uint64_t, svbool_t, svbool_t, svuint16_t, svuint16_t);
624__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svsumopa_za64_s16_m), arm_streaming, arm_shared_za))
625void svsumopa_za64_m(uint64_t, svbool_t, svbool_t, svint16_t, svuint16_t);
626__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svsumops_za64_s16_m), arm_streaming, arm_shared_za))
627void svsumops_za64_m(uint64_t, svbool_t, svbool_t, svint16_t, svuint16_t);
628__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svusmopa_za64_u16_m), arm_streaming, arm_shared_za))
629void svusmopa_za64_m(uint64_t, svbool_t, svbool_t, svuint16_t, svint16_t);
630__aio __attribute__((__clang_arm_builtin_alias(__builtin_sme_svusmops_za64_u16_m), arm_streaming, arm_shared_za))
631void svusmops_za64_m(uint64_t, svbool_t, svbool_t, svuint16_t, svint16_t);
632__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svldr_vnum_za), arm_streaming_compatible, arm_shared_za))
633void svldr_vnum_za(uint32_t, uint64_t, void const *);
634__ai __attribute__((__clang_arm_builtin_alias(__builtin_sme_svstr_vnum_za), arm_streaming_compatible, arm_shared_za, arm_preserves_za))
635void svstr_vnum_za(uint32_t, uint64_t, void *);
636#ifdef __cplusplus
637} // extern "C"
638#endif
639
640#undef __ai
641
642#endif /* __ARM_SME_H */
lib/include/arm_sve.h+68-13
......@@ -37,7 +37,6 @@ typedef __SVFloat16_t svfloat16_t;
3737
3838typedef __SVBFloat16_t svbfloat16_t;
3939#include <arm_bf16.h>
40typedef __bf16 bfloat16_t;
4140typedef __SVFloat32_t svfloat32_t;
4241typedef __SVFloat64_t svfloat64_t;
4342typedef __clang_svint8x2_t svint8x2_t;
......@@ -74,10 +73,14 @@ typedef __clang_svfloat16x4_t svfloat16x4_t;
7473typedef __clang_svfloat32x4_t svfloat32x4_t;
7574typedef __clang_svfloat64x4_t svfloat64x4_t;
7675typedef __SVBool_t svbool_t;
76typedef __clang_svboolx2_t svboolx2_t;
77typedef __clang_svboolx4_t svboolx4_t;
7778
7879typedef __clang_svbfloat16x2_t svbfloat16x2_t;
7980typedef __clang_svbfloat16x3_t svbfloat16x3_t;
8081typedef __clang_svbfloat16x4_t svbfloat16x4_t;
82typedef __SVCount_t svcount_t;
83
8184enum svpattern
8285{
8386 SV_POW2 = 0,
......@@ -2914,6 +2917,10 @@ __ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdup_lane_s64)))
29142917svint64_t svdup_lane_s64(svint64_t, uint64_t);
29152918__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdup_lane_s16)))
29162919svint16_t svdup_lane_s16(svint16_t, uint16_t);
2920__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_u8)))
2921svuint8_t svdupq_n_u8(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t);
2922__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_s8)))
2923svint8_t svdupq_n_s8(int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t);
29172924__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_u16)))
29182925svuint16_t svdupq_n_u16(uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t);
29192926__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_f16)))
......@@ -2932,18 +2939,14 @@ __ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_f64)))
29322939svfloat64_t svdupq_n_f64(float64_t, float64_t);
29332940__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_s64)))
29342941svint64_t svdupq_n_s64(int64_t, int64_t);
2935__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_u8)))
2936svuint8_t svdupq_n_u8(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t);
2937__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_s8)))
2938svint8_t svdupq_n_s8(int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t);
2942__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_b8)))
2943svbool_t svdupq_n_b8(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool);
29392944__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_b16)))
29402945svbool_t svdupq_n_b16(bool, bool, bool, bool, bool, bool, bool, bool);
29412946__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_b32)))
29422947svbool_t svdupq_n_b32(bool, bool, bool, bool);
29432948__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_b64)))
29442949svbool_t svdupq_n_b64(bool, bool);
2945__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_b8)))
2946svbool_t svdupq_n_b8(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool);
29472950__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_lane_u8)))
29482951svuint8_t svdupq_lane_u8(svuint8_t, uint64_t);
29492952__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_lane_u32)))
......@@ -10528,6 +10531,10 @@ __aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdup_lane_s64)))
1052810531svint64_t svdup_lane(svint64_t, uint64_t);
1052910532__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdup_lane_s16)))
1053010533svint16_t svdup_lane(svint16_t, uint16_t);
10534__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_u8)))
10535svuint8_t svdupq_u8(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t);
10536__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_s8)))
10537svint8_t svdupq_s8(int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t);
1053110538__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_u16)))
1053210539svuint16_t svdupq_u16(uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t);
1053310540__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_f16)))
......@@ -10546,18 +10553,14 @@ __aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_f64)))
1054610553svfloat64_t svdupq_f64(float64_t, float64_t);
1054710554__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_s64)))
1054810555svint64_t svdupq_s64(int64_t, int64_t);
10549__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_u8)))
10550svuint8_t svdupq_u8(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t);
10551__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_s8)))
10552svint8_t svdupq_s8(int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t, int8_t);
10556__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_b8)))
10557svbool_t svdupq_b8(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool);
1055310558__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_b16)))
1055410559svbool_t svdupq_b16(bool, bool, bool, bool, bool, bool, bool, bool);
1055510560__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_b32)))
1055610561svbool_t svdupq_b32(bool, bool, bool, bool);
1055710562__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_b64)))
1055810563svbool_t svdupq_b64(bool, bool);
10559__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_n_b8)))
10560svbool_t svdupq_b8(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool);
1056110564__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_lane_u8)))
1056210565svuint8_t svdupq_lane(svuint8_t, uint64_t);
1056310566__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svdupq_lane_u32)))
......@@ -23874,6 +23877,58 @@ __aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svsm4e_u32)))
2387423877svuint32_t svsm4e(svuint32_t, svuint32_t);
2387523878__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svsm4ekey_u32)))
2387623879svuint32_t svsm4ekey(svuint32_t, svuint32_t);
23880__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_f64)))
23881svfloat64_t svclamp_f64(svfloat64_t, svfloat64_t, svfloat64_t);
23882__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_f32)))
23883svfloat32_t svclamp_f32(svfloat32_t, svfloat32_t, svfloat32_t);
23884__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_f16)))
23885svfloat16_t svclamp_f16(svfloat16_t, svfloat16_t, svfloat16_t);
23886__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_s8)))
23887svint8_t svclamp_s8(svint8_t, svint8_t, svint8_t);
23888__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_s32)))
23889svint32_t svclamp_s32(svint32_t, svint32_t, svint32_t);
23890__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_s64)))
23891svint64_t svclamp_s64(svint64_t, svint64_t, svint64_t);
23892__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_s16)))
23893svint16_t svclamp_s16(svint16_t, svint16_t, svint16_t);
23894__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_u8)))
23895svuint8_t svclamp_u8(svuint8_t, svuint8_t, svuint8_t);
23896__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_u32)))
23897svuint32_t svclamp_u32(svuint32_t, svuint32_t, svuint32_t);
23898__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_u64)))
23899svuint64_t svclamp_u64(svuint64_t, svuint64_t, svuint64_t);
23900__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_u16)))
23901svuint16_t svclamp_u16(svuint16_t, svuint16_t, svuint16_t);
23902__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svptrue_c8)))
23903svcount_t svptrue_c8(void);
23904__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svptrue_c32)))
23905svcount_t svptrue_c32(void);
23906__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svptrue_c64)))
23907svcount_t svptrue_c64(void);
23908__ai __attribute__((__clang_arm_builtin_alias(__builtin_sve_svptrue_c16)))
23909svcount_t svptrue_c16(void);
23910__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_f64)))
23911svfloat64_t svclamp(svfloat64_t, svfloat64_t, svfloat64_t);
23912__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_f32)))
23913svfloat32_t svclamp(svfloat32_t, svfloat32_t, svfloat32_t);
23914__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_f16)))
23915svfloat16_t svclamp(svfloat16_t, svfloat16_t, svfloat16_t);
23916__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_s8)))
23917svint8_t svclamp(svint8_t, svint8_t, svint8_t);
23918__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_s32)))
23919svint32_t svclamp(svint32_t, svint32_t, svint32_t);
23920__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_s64)))
23921svint64_t svclamp(svint64_t, svint64_t, svint64_t);
23922__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_s16)))
23923svint16_t svclamp(svint16_t, svint16_t, svint16_t);
23924__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_u8)))
23925svuint8_t svclamp(svuint8_t, svuint8_t, svuint8_t);
23926__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_u32)))
23927svuint32_t svclamp(svuint32_t, svuint32_t, svuint32_t);
23928__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_u64)))
23929svuint64_t svclamp(svuint64_t, svuint64_t, svuint64_t);
23930__aio __attribute__((__clang_arm_builtin_alias(__builtin_sve_svclamp_u16)))
23931svuint16_t svclamp(svuint16_t, svuint16_t, svuint16_t);
2387723932#define svcvtnt_bf16_x svcvtnt_bf16_m
2387823933#define svcvtnt_bf16_f32_x svcvtnt_bf16_f32_m
2387923934#define svcvtnt_f16_x svcvtnt_f16_m
lib/include/avx2intrin.h+4116-1
......@@ -19,128 +19,539 @@
1919#define __DEFAULT_FN_ATTRS128 __attribute__((__always_inline__, __nodebug__, __target__("avx2"), __min_vector_width__(128)))
2020
2121/* SSE4 Multiple Packed Sums of Absolute Difference. */
22/// Computes sixteen sum of absolute difference (SAD) operations on sets of
23/// four unsigned 8-bit integers from the 256-bit integer vectors \a X and
24/// \a Y.
25///
26/// Eight SAD results are computed using the lower half of the input
27/// vectors, and another eight using the upper half. These 16-bit values
28/// are returned in the lower and upper halves of the 256-bit result,
29/// respectively.
30///
31/// A single SAD operation selects four bytes from \a X and four bytes from
32/// \a Y as input. It computes the differences between each \a X byte and
33/// the corresponding \a Y byte, takes the absolute value of each
34/// difference, and sums these four values to form one 16-bit result. The
35/// intrinsic computes 16 of these results with different sets of input
36/// bytes.
37///
38/// For each set of eight results, the SAD operations use the same four
39/// bytes from \a Y; the starting bit position for these four bytes is
40/// specified by \a M[1:0] times 32. The eight operations use successive
41/// sets of four bytes from \a X; the starting bit position for the first
42/// set of four bytes is specified by \a M[2] times 32. These bit positions
43/// are all relative to the 128-bit lane for each set of eight operations.
44///
45/// \code{.operation}
46/// r := 0
47/// FOR i := 0 TO 1
48/// j := i*3
49/// Ybase := M[j+1:j]*32 + i*128
50/// Xbase := M[j+2]*32 + i*128
51/// FOR k := 0 TO 3
52/// temp0 := ABS(X[Xbase+7:Xbase] - Y[Ybase+7:Ybase])
53/// temp1 := ABS(X[Xbase+15:Xbase+8] - Y[Ybase+15:Ybase+8])
54/// temp2 := ABS(X[Xbase+23:Xbase+16] - Y[Ybase+23:Ybase+16])
55/// temp3 := ABS(X[Xbase+31:Xbase+24] - Y[Ybase+31:Ybase+24])
56/// result[r+15:r] := temp0 + temp1 + temp2 + temp3
57/// Xbase := Xbase + 8
58/// r := r + 16
59/// ENDFOR
60/// ENDFOR
61/// \endcode
62///
63/// \headerfile <immintrin.h>
64///
65/// \code
66/// __m256i _mm256_mpsadbw_epu8(__m256i X, __m256i Y, const int M);
67/// \endcode
68///
69/// This intrinsic corresponds to the \c VMPSADBW instruction.
70///
71/// \param X
72/// A 256-bit integer vector containing one of the inputs.
73/// \param Y
74/// A 256-bit integer vector containing one of the inputs.
75/// \param M
76/// An unsigned immediate value specifying the starting positions of the
77/// bytes to operate on.
78/// \returns A 256-bit vector of [16 x i16] containing the result.
2279#define _mm256_mpsadbw_epu8(X, Y, M) \
2380 ((__m256i)__builtin_ia32_mpsadbw256((__v32qi)(__m256i)(X), \
2481 (__v32qi)(__m256i)(Y), (int)(M)))
2582
83/// Computes the absolute value of each signed byte in the 256-bit integer
84/// vector \a __a and returns each value in the corresponding byte of
85/// the result.
86///
87/// \headerfile <immintrin.h>
88///
89/// This intrinsic corresponds to the \c VPABSB instruction.
90///
91/// \param __a
92/// A 256-bit integer vector.
93/// \returns A 256-bit integer vector containing the result.
2694static __inline__ __m256i __DEFAULT_FN_ATTRS256
2795_mm256_abs_epi8(__m256i __a)
2896{
2997 return (__m256i)__builtin_elementwise_abs((__v32qs)__a);
3098}
3199
100/// Computes the absolute value of each signed 16-bit element in the 256-bit
101/// vector of [16 x i16] in \a __a and returns each value in the
102/// corresponding element of the result.
103///
104/// \headerfile <immintrin.h>
105///
106/// This intrinsic corresponds to the \c VPABSW instruction.
107///
108/// \param __a
109/// A 256-bit vector of [16 x i16].
110/// \returns A 256-bit vector of [16 x i16] containing the result.
32111static __inline__ __m256i __DEFAULT_FN_ATTRS256
33112_mm256_abs_epi16(__m256i __a)
34113{
35114 return (__m256i)__builtin_elementwise_abs((__v16hi)__a);
36115}
37116
117/// Computes the absolute value of each signed 32-bit element in the 256-bit
118/// vector of [8 x i32] in \a __a and returns each value in the
119/// corresponding element of the result.
120///
121/// \headerfile <immintrin.h>
122///
123/// This intrinsic corresponds to the \c VPABSD instruction.
124///
125/// \param __a
126/// A 256-bit vector of [8 x i32].
127/// \returns A 256-bit vector of [8 x i32] containing the result.
38128static __inline__ __m256i __DEFAULT_FN_ATTRS256
39129_mm256_abs_epi32(__m256i __a)
40130{
41131 return (__m256i)__builtin_elementwise_abs((__v8si)__a);
42132}
43133
134/// Converts the elements of two 256-bit vectors of [16 x i16] to 8-bit
135/// integers using signed saturation, and returns the 256-bit result.
136///
137/// \code{.operation}
138/// FOR i := 0 TO 7
139/// j := i*16
140/// k := i*8
141/// result[7+k:k] := SATURATE8(__a[15+j:j])
142/// result[71+k:64+k] := SATURATE8(__b[15+j:j])
143/// result[135+k:128+k] := SATURATE8(__a[143+j:128+j])
144/// result[199+k:192+k] := SATURATE8(__b[143+j:128+j])
145/// ENDFOR
146/// \endcode
147///
148/// \headerfile <immintrin.h>
149///
150/// This intrinsic corresponds to the \c VPACKSSWB instruction.
151///
152/// \param __a
153/// A 256-bit vector of [16 x i16] used to generate result[63:0] and
154/// result[191:128].
155/// \param __b
156/// A 256-bit vector of [16 x i16] used to generate result[127:64] and
157/// result[255:192].
158/// \returns A 256-bit integer vector containing the result.
44159static __inline__ __m256i __DEFAULT_FN_ATTRS256
45160_mm256_packs_epi16(__m256i __a, __m256i __b)
46161{
47162 return (__m256i)__builtin_ia32_packsswb256((__v16hi)__a, (__v16hi)__b);
48163}
49164
165/// Converts the elements of two 256-bit vectors of [8 x i32] to 16-bit
166/// integers using signed saturation, and returns the resulting 256-bit
167/// vector of [16 x i16].
168///
169/// \code{.operation}
170/// FOR i := 0 TO 3
171/// j := i*32
172/// k := i*16
173/// result[15+k:k] := SATURATE16(__a[31+j:j])
174/// result[79+k:64+k] := SATURATE16(__b[31+j:j])
175/// result[143+k:128+k] := SATURATE16(__a[159+j:128+j])
176/// result[207+k:192+k] := SATURATE16(__b[159+j:128+j])
177/// ENDFOR
178/// \endcode
179///
180/// \headerfile <immintrin.h>
181///
182/// This intrinsic corresponds to the \c VPACKSSDW instruction.
183///
184/// \param __a
185/// A 256-bit vector of [8 x i32] used to generate result[63:0] and
186/// result[191:128].
187/// \param __b
188/// A 256-bit vector of [8 x i32] used to generate result[127:64] and
189/// result[255:192].
190/// \returns A 256-bit vector of [16 x i16] containing the result.
50191static __inline__ __m256i __DEFAULT_FN_ATTRS256
51192_mm256_packs_epi32(__m256i __a, __m256i __b)
52193{
53194 return (__m256i)__builtin_ia32_packssdw256((__v8si)__a, (__v8si)__b);
54195}
55196
197/// Converts elements from two 256-bit vectors of [16 x i16] to 8-bit integers
198/// using unsigned saturation, and returns the 256-bit result.
199///
200/// \code{.operation}
201/// FOR i := 0 TO 7
202/// j := i*16
203/// k := i*8
204/// result[7+k:k] := SATURATE8U(__a[15+j:j])
205/// result[71+k:64+k] := SATURATE8U(__b[15+j:j])
206/// result[135+k:128+k] := SATURATE8U(__a[143+j:128+j])
207/// result[199+k:192+k] := SATURATE8U(__b[143+j:128+j])
208/// ENDFOR
209/// \endcode
210///
211/// \headerfile <immintrin.h>
212///
213/// This intrinsic corresponds to the \c VPACKUSWB instruction.
214///
215/// \param __a
216/// A 256-bit vector of [16 x i16] used to generate result[63:0] and
217/// result[191:128].
218/// \param __b
219/// A 256-bit vector of [16 x i16] used to generate result[127:64] and
220/// result[255:192].
221/// \returns A 256-bit integer vector containing the result.
56222static __inline__ __m256i __DEFAULT_FN_ATTRS256
57223_mm256_packus_epi16(__m256i __a, __m256i __b)
58224{
59225 return (__m256i)__builtin_ia32_packuswb256((__v16hi)__a, (__v16hi)__b);
60226}
61227
228/// Converts elements from two 256-bit vectors of [8 x i32] to 16-bit integers
229/// using unsigned saturation, and returns the resulting 256-bit vector of
230/// [16 x i16].
231///
232/// \code{.operation}
233/// FOR i := 0 TO 3
234/// j := i*32
235/// k := i*16
236/// result[15+k:k] := SATURATE16U(__V1[31+j:j])
237/// result[79+k:64+k] := SATURATE16U(__V2[31+j:j])
238/// result[143+k:128+k] := SATURATE16U(__V1[159+j:128+j])
239/// result[207+k:192+k] := SATURATE16U(__V2[159+j:128+j])
240/// ENDFOR
241/// \endcode
242///
243/// \headerfile <immintrin.h>
244///
245/// This intrinsic corresponds to the \c VPACKUSDW instruction.
246///
247/// \param __V1
248/// A 256-bit vector of [8 x i32] used to generate result[63:0] and
249/// result[191:128].
250/// \param __V2
251/// A 256-bit vector of [8 x i32] used to generate result[127:64] and
252/// result[255:192].
253/// \returns A 256-bit vector of [16 x i16] containing the result.
62254static __inline__ __m256i __DEFAULT_FN_ATTRS256
63255_mm256_packus_epi32(__m256i __V1, __m256i __V2)
64256{
65257 return (__m256i) __builtin_ia32_packusdw256((__v8si)__V1, (__v8si)__V2);
66258}
67259
260/// Adds 8-bit integers from corresponding bytes of two 256-bit integer
261/// vectors and returns the lower 8 bits of each sum in the corresponding
262/// byte of the 256-bit integer vector result (overflow is ignored).
263///
264/// \headerfile <immintrin.h>
265///
266/// This intrinsic corresponds to the \c VPADDB instruction.
267///
268/// \param __a
269/// A 256-bit integer vector containing one of the source operands.
270/// \param __b
271/// A 256-bit integer vector containing one of the source operands.
272/// \returns A 256-bit integer vector containing the sums.
68273static __inline__ __m256i __DEFAULT_FN_ATTRS256
69274_mm256_add_epi8(__m256i __a, __m256i __b)
70275{
71276 return (__m256i)((__v32qu)__a + (__v32qu)__b);
72277}
73278
279/// Adds 16-bit integers from corresponding elements of two 256-bit vectors of
280/// [16 x i16] and returns the lower 16 bits of each sum in the
281/// corresponding element of the [16 x i16] result (overflow is ignored).
282///
283/// \headerfile <immintrin.h>
284///
285/// This intrinsic corresponds to the \c VPADDW instruction.
286///
287/// \param __a
288/// A 256-bit vector of [16 x i16] containing one of the source operands.
289/// \param __b
290/// A 256-bit vector of [16 x i16] containing one of the source operands.
291/// \returns A 256-bit vector of [16 x i16] containing the sums.
74292static __inline__ __m256i __DEFAULT_FN_ATTRS256
75293_mm256_add_epi16(__m256i __a, __m256i __b)
76294{
77295 return (__m256i)((__v16hu)__a + (__v16hu)__b);
78296}
79297
298/// Adds 32-bit integers from corresponding elements of two 256-bit vectors of
299/// [8 x i32] and returns the lower 32 bits of each sum in the corresponding
300/// element of the [8 x i32] result (overflow is ignored).
301///
302/// \headerfile <immintrin.h>
303///
304/// This intrinsic corresponds to the \c VPADDD instruction.
305///
306/// \param __a
307/// A 256-bit vector of [8 x i32] containing one of the source operands.
308/// \param __b
309/// A 256-bit vector of [8 x i32] containing one of the source operands.
310/// \returns A 256-bit vector of [8 x i32] containing the sums.
80311static __inline__ __m256i __DEFAULT_FN_ATTRS256
81312_mm256_add_epi32(__m256i __a, __m256i __b)
82313{
83314 return (__m256i)((__v8su)__a + (__v8su)__b);
84315}
85316
317/// Adds 64-bit integers from corresponding elements of two 256-bit vectors of
318/// [4 x i64] and returns the lower 64 bits of each sum in the corresponding
319/// element of the [4 x i64] result (overflow is ignored).
320///
321/// \headerfile <immintrin.h>
322///
323/// This intrinsic corresponds to the \c VPADDQ instruction.
324///
325/// \param __a
326/// A 256-bit vector of [4 x i64] containing one of the source operands.
327/// \param __b
328/// A 256-bit vector of [4 x i64] containing one of the source operands.
329/// \returns A 256-bit vector of [4 x i64] containing the sums.
86330static __inline__ __m256i __DEFAULT_FN_ATTRS256
87331_mm256_add_epi64(__m256i __a, __m256i __b)
88332{
89333 return (__m256i)((__v4du)__a + (__v4du)__b);
90334}
91335
336/// Adds 8-bit integers from corresponding bytes of two 256-bit integer
337/// vectors using signed saturation, and returns each sum in the
338/// corresponding byte of the 256-bit integer vector result.
339///
340/// \headerfile <immintrin.h>
341///
342/// This intrinsic corresponds to the \c VPADDSB instruction.
343///
344/// \param __a
345/// A 256-bit integer vector containing one of the source operands.
346/// \param __b
347/// A 256-bit integer vector containing one of the source operands.
348/// \returns A 256-bit integer vector containing the sums.
92349static __inline__ __m256i __DEFAULT_FN_ATTRS256
93350_mm256_adds_epi8(__m256i __a, __m256i __b)
94351{
95352 return (__m256i)__builtin_elementwise_add_sat((__v32qs)__a, (__v32qs)__b);
96353}
97354
355/// Adds 16-bit integers from corresponding elements of two 256-bit vectors of
356/// [16 x i16] using signed saturation, and returns the [16 x i16] result.
357///
358/// \headerfile <immintrin.h>
359///
360/// This intrinsic corresponds to the \c VPADDSW instruction.
361///
362/// \param __a
363/// A 256-bit vector of [16 x i16] containing one of the source operands.
364/// \param __b
365/// A 256-bit vector of [16 x i16] containing one of the source operands.
366/// \returns A 256-bit vector of [16 x i16] containing the sums.
98367static __inline__ __m256i __DEFAULT_FN_ATTRS256
99368_mm256_adds_epi16(__m256i __a, __m256i __b)
100369{
101370 return (__m256i)__builtin_elementwise_add_sat((__v16hi)__a, (__v16hi)__b);
102371}
103372
373/// Adds 8-bit integers from corresponding bytes of two 256-bit integer
374/// vectors using unsigned saturation, and returns each sum in the
375/// corresponding byte of the 256-bit integer vector result.
376///
377/// \headerfile <immintrin.h>
378///
379/// This intrinsic corresponds to the \c VPADDUSB instruction.
380///
381/// \param __a
382/// A 256-bit integer vector containing one of the source operands.
383/// \param __b
384/// A 256-bit integer vector containing one of the source operands.
385/// \returns A 256-bit integer vector containing the sums.
104386static __inline__ __m256i __DEFAULT_FN_ATTRS256
105387_mm256_adds_epu8(__m256i __a, __m256i __b)
106388{
107389 return (__m256i)__builtin_elementwise_add_sat((__v32qu)__a, (__v32qu)__b);
108390}
109391
392/// Adds 16-bit integers from corresponding elements of two 256-bit vectors of
393/// [16 x i16] using unsigned saturation, and returns the [16 x i16] result.
394///
395/// \headerfile <immintrin.h>
396///
397/// This intrinsic corresponds to the \c VPADDUSW instruction.
398///
399/// \param __a
400/// A 256-bit vector of [16 x i16] containing one of the source operands.
401/// \param __b
402/// A 256-bit vector of [16 x i16] containing one of the source operands.
403/// \returns A 256-bit vector of [16 x i16] containing the sums.
110404static __inline__ __m256i __DEFAULT_FN_ATTRS256
111405_mm256_adds_epu16(__m256i __a, __m256i __b)
112406{
113407 return (__m256i)__builtin_elementwise_add_sat((__v16hu)__a, (__v16hu)__b);
114408}
115409
410/// Uses the lower half of the 256-bit vector \a a as the upper half of a
411/// temporary 256-bit value, and the lower half of the 256-bit vector \a b
412/// as the lower half of the temporary value. Right-shifts the temporary
413/// value by \a n bytes, and uses the lower 16 bytes of the shifted value
414/// as the lower 16 bytes of the result. Uses the upper halves of \a a and
415/// \a b to make another temporary value, right shifts by \a n, and uses
416/// the lower 16 bytes of the shifted value as the upper 16 bytes of the
417/// result.
418///
419/// \headerfile <immintrin.h>
420///
421/// \code
422/// __m256i _mm256_alignr_epi8(__m256i a, __m256i b, const int n);
423/// \endcode
424///
425/// This intrinsic corresponds to the \c VPALIGNR instruction.
426///
427/// \param a
428/// A 256-bit integer vector containing source values.
429/// \param b
430/// A 256-bit integer vector containing source values.
431/// \param n
432/// An immediate value specifying the number of bytes to shift.
433/// \returns A 256-bit integer vector containing the result.
116434#define _mm256_alignr_epi8(a, b, n) \
117435 ((__m256i)__builtin_ia32_palignr256((__v32qi)(__m256i)(a), \
118436 (__v32qi)(__m256i)(b), (n)))
119437
438/// Computes the bitwise AND of the 256-bit integer vectors in \a __a and
439/// \a __b.
440///
441/// \headerfile <immintrin.h>
442///
443/// This intrinsic corresponds to the \c VPAND instruction.
444///
445/// \param __a
446/// A 256-bit integer vector.
447/// \param __b
448/// A 256-bit integer vector.
449/// \returns A 256-bit integer vector containing the result.
120450static __inline__ __m256i __DEFAULT_FN_ATTRS256
121451_mm256_and_si256(__m256i __a, __m256i __b)
122452{
123453 return (__m256i)((__v4du)__a & (__v4du)__b);
124454}
125455
456/// Computes the bitwise AND of the 256-bit integer vector in \a __b with
457/// the bitwise NOT of the 256-bit integer vector in \a __a.
458///
459/// \headerfile <immintrin.h>
460///
461/// This intrinsic corresponds to the \c VPANDN instruction.
462///
463/// \param __a
464/// A 256-bit integer vector.
465/// \param __b
466/// A 256-bit integer vector.
467/// \returns A 256-bit integer vector containing the result.
126468static __inline__ __m256i __DEFAULT_FN_ATTRS256
127469_mm256_andnot_si256(__m256i __a, __m256i __b)
128470{
129471 return (__m256i)(~(__v4du)__a & (__v4du)__b);
130472}
131473
474/// Computes the averages of the corresponding unsigned bytes in the two
475/// 256-bit integer vectors in \a __a and \a __b and returns each
476/// average in the corresponding byte of the 256-bit result.
477///
478/// \code{.operation}
479/// FOR i := 0 TO 31
480/// j := i*8
481/// result[j+7:j] := (__a[j+7:j] + __b[j+7:j] + 1) >> 1
482/// ENDFOR
483/// \endcode
484///
485/// \headerfile <immintrin.h>
486///
487/// This intrinsic corresponds to the \c VPAVGB instruction.
488///
489/// \param __a
490/// A 256-bit integer vector.
491/// \param __b
492/// A 256-bit integer vector.
493/// \returns A 256-bit integer vector containing the result.
132494static __inline__ __m256i __DEFAULT_FN_ATTRS256
133495_mm256_avg_epu8(__m256i __a, __m256i __b)
134496{
135497 return (__m256i)__builtin_ia32_pavgb256((__v32qi)__a, (__v32qi)__b);
136498}
137499
500/// Computes the averages of the corresponding unsigned 16-bit integers in
501/// the two 256-bit vectors of [16 x i16] in \a __a and \a __b and returns
502/// each average in the corresponding element of the 256-bit result.
503///
504/// \code{.operation}
505/// FOR i := 0 TO 15
506/// j := i*16
507/// result[j+15:j] := (__a[j+15:j] + __b[j+15:j] + 1) >> 1
508/// ENDFOR
509/// \endcode
510///
511/// \headerfile <immintrin.h>
512///
513/// This intrinsic corresponds to the \c VPAVGW instruction.
514///
515/// \param __a
516/// A 256-bit vector of [16 x i16].
517/// \param __b
518/// A 256-bit vector of [16 x i16].
519/// \returns A 256-bit vector of [16 x i16] containing the result.
138520static __inline__ __m256i __DEFAULT_FN_ATTRS256
139521_mm256_avg_epu16(__m256i __a, __m256i __b)
140522{
141523 return (__m256i)__builtin_ia32_pavgw256((__v16hi)__a, (__v16hi)__b);
142524}
143525
526/// Merges 8-bit integer values from either of the two 256-bit vectors
527/// \a __V1 or \a __V2, as specified by the 256-bit mask \a __M and returns
528/// the resulting 256-bit integer vector.
529///
530/// \code{.operation}
531/// FOR i := 0 TO 31
532/// j := i*8
533/// IF __M[7+i] == 0
534/// result[7+j:j] := __V1[7+j:j]
535/// ELSE
536/// result[7+j:j] := __V2[7+j:j]
537/// FI
538/// ENDFOR
539/// \endcode
540///
541/// \headerfile <immintrin.h>
542///
543/// This intrinsic corresponds to the \c VPBLENDVB instruction.
544///
545/// \param __V1
546/// A 256-bit integer vector containing source values.
547/// \param __V2
548/// A 256-bit integer vector containing source values.
549/// \param __M
550/// A 256-bit integer vector, with bit [7] of each byte specifying the
551/// source for each corresponding byte of the result. When the mask bit
552/// is 0, the byte is copied from \a __V1; otherwise, it is copied from
553/// \a __V2.
554/// \returns A 256-bit integer vector containing the result.
144555static __inline__ __m256i __DEFAULT_FN_ATTRS256
145556_mm256_blendv_epi8(__m256i __V1, __m256i __V2, __m256i __M)
146557{
......@@ -148,34 +559,171 @@ _mm256_blendv_epi8(__m256i __V1, __m256i __V2, __m256i __M)
148559 (__v32qi)__M);
149560}
150561
562/// Merges 16-bit integer values from either of the two 256-bit vectors
563/// \a V1 or \a V2, as specified by the immediate integer operand \a M,
564/// and returns the resulting 256-bit vector of [16 x i16].
565///
566/// \code{.operation}
567/// FOR i := 0 TO 7
568/// j := i*16
569/// IF M[i] == 0
570/// result[7+j:j] := V1[7+j:j]
571/// result[135+j:128+j] := V1[135+j:128+j]
572/// ELSE
573/// result[7+j:j] := V2[7+j:j]
574/// result[135+j:128+j] := V2[135+j:128+j]
575/// FI
576/// ENDFOR
577/// \endcode
578///
579/// \headerfile <immintrin.h>
580///
581/// \code
582/// __m256i _mm256_blend_epi16(__m256i V1, __m256i V2, const int M);
583/// \endcode
584///
585/// This intrinsic corresponds to the \c VPBLENDW instruction.
586///
587/// \param V1
588/// A 256-bit vector of [16 x i16] containing source values.
589/// \param V2
590/// A 256-bit vector of [16 x i16] containing source values.
591/// \param M
592/// An immediate 8-bit integer operand, with bits [7:0] specifying the
593/// source for each element of the result. The position of the mask bit
594/// corresponds to the index of a copied value. When a mask bit is 0, the
595/// element is copied from \a V1; otherwise, it is copied from \a V2.
596/// \a M[0] determines the source for elements 0 and 8, \a M[1] for
597/// elements 1 and 9, and so forth.
598/// \returns A 256-bit vector of [16 x i16] containing the result.
151599#define _mm256_blend_epi16(V1, V2, M) \
152600 ((__m256i)__builtin_ia32_pblendw256((__v16hi)(__m256i)(V1), \
153601 (__v16hi)(__m256i)(V2), (int)(M)))
154602
603/// Compares corresponding bytes in the 256-bit integer vectors in \a __a and
604/// \a __b for equality and returns the outcomes in the corresponding
605/// bytes of the 256-bit result.
606///
607/// \code{.operation}
608/// FOR i := 0 TO 31
609/// j := i*8
610/// result[j+7:j] := (__a[j+7:j] == __b[j+7:j]) ? 0xFF : 0
611/// ENDFOR
612/// \endcode
613///
614/// \headerfile <immintrin.h>
615///
616/// This intrinsic corresponds to the \c VPCMPEQB instruction.
617///
618/// \param __a
619/// A 256-bit integer vector containing one of the inputs.
620/// \param __b
621/// A 256-bit integer vector containing one of the inputs.
622/// \returns A 256-bit integer vector containing the result.
155623static __inline__ __m256i __DEFAULT_FN_ATTRS256
156624_mm256_cmpeq_epi8(__m256i __a, __m256i __b)
157625{
158626 return (__m256i)((__v32qi)__a == (__v32qi)__b);
159627}
160628
629/// Compares corresponding elements in the 256-bit vectors of [16 x i16] in
630/// \a __a and \a __b for equality and returns the outcomes in the
631/// corresponding elements of the 256-bit result.
632///
633/// \code{.operation}
634/// FOR i := 0 TO 15
635/// j := i*16
636/// result[j+15:j] := (__a[j+15:j] == __b[j+15:j]) ? 0xFFFF : 0
637/// ENDFOR
638/// \endcode
639///
640/// \headerfile <immintrin.h>
641///
642/// This intrinsic corresponds to the \c VPCMPEQW instruction.
643///
644/// \param __a
645/// A 256-bit vector of [16 x i16] containing one of the inputs.
646/// \param __b
647/// A 256-bit vector of [16 x i16] containing one of the inputs.
648/// \returns A 256-bit vector of [16 x i16] containing the result.
161649static __inline__ __m256i __DEFAULT_FN_ATTRS256
162650_mm256_cmpeq_epi16(__m256i __a, __m256i __b)
163651{
164652 return (__m256i)((__v16hi)__a == (__v16hi)__b);
165653}
166654
655/// Compares corresponding elements in the 256-bit vectors of [8 x i32] in
656/// \a __a and \a __b for equality and returns the outcomes in the
657/// corresponding elements of the 256-bit result.
658///
659/// \code{.operation}
660/// FOR i := 0 TO 7
661/// j := i*32
662/// result[j+31:j] := (__a[j+31:j] == __b[j+31:j]) ? 0xFFFFFFFF : 0
663/// ENDFOR
664/// \endcode
665///
666/// \headerfile <immintrin.h>
667///
668/// This intrinsic corresponds to the \c VPCMPEQD instruction.
669///
670/// \param __a
671/// A 256-bit vector of [8 x i32] containing one of the inputs.
672/// \param __b
673/// A 256-bit vector of [8 x i32] containing one of the inputs.
674/// \returns A 256-bit vector of [8 x i32] containing the result.
167675static __inline__ __m256i __DEFAULT_FN_ATTRS256
168676_mm256_cmpeq_epi32(__m256i __a, __m256i __b)
169677{
170678 return (__m256i)((__v8si)__a == (__v8si)__b);
171679}
172680
681/// Compares corresponding elements in the 256-bit vectors of [4 x i64] in
682/// \a __a and \a __b for equality and returns the outcomes in the
683/// corresponding elements of the 256-bit result.
684///
685/// \code{.operation}
686/// FOR i := 0 TO 3
687/// j := i*64
688/// result[j+63:j] := (__a[j+63:j] == __b[j+63:j]) ? 0xFFFFFFFFFFFFFFFF : 0
689/// ENDFOR
690/// \endcode
691///
692/// \headerfile <immintrin.h>
693///
694/// This intrinsic corresponds to the \c VPCMPEQQ instruction.
695///
696/// \param __a
697/// A 256-bit vector of [4 x i64] containing one of the inputs.
698/// \param __b
699/// A 256-bit vector of [4 x i64] containing one of the inputs.
700/// \returns A 256-bit vector of [4 x i64] containing the result.
173701static __inline__ __m256i __DEFAULT_FN_ATTRS256
174702_mm256_cmpeq_epi64(__m256i __a, __m256i __b)
175703{
176704 return (__m256i)((__v4di)__a == (__v4di)__b);
177705}
178706
707/// Compares corresponding signed bytes in the 256-bit integer vectors in
708/// \a __a and \a __b for greater-than and returns the outcomes in the
709/// corresponding bytes of the 256-bit result.
710///
711/// \code{.operation}
712/// FOR i := 0 TO 31
713/// j := i*8
714/// result[j+7:j] := (__a[j+7:j] > __b[j+7:j]) ? 0xFF : 0
715/// ENDFOR
716/// \endcode
717///
718/// \headerfile <immintrin.h>
719///
720/// This intrinsic corresponds to the \c VPCMPGTB instruction.
721///
722/// \param __a
723/// A 256-bit integer vector containing one of the inputs.
724/// \param __b
725/// A 256-bit integer vector containing one of the inputs.
726/// \returns A 256-bit integer vector containing the result.
179727static __inline__ __m256i __DEFAULT_FN_ATTRS256
180728_mm256_cmpgt_epi8(__m256i __a, __m256i __b)
181729{
......@@ -184,138 +732,575 @@ _mm256_cmpgt_epi8(__m256i __a, __m256i __b)
184732 return (__m256i)((__v32qs)__a > (__v32qs)__b);
185733}
186734
735/// Compares corresponding signed elements in the 256-bit vectors of
736/// [16 x i16] in \a __a and \a __b for greater-than and returns the
737/// outcomes in the corresponding elements of the 256-bit result.
738///
739/// \code{.operation}
740/// FOR i := 0 TO 15
741/// j := i*16
742/// result[j+15:j] := (__a[j+15:j] > __b[j+15:j]) ? 0xFFFF : 0
743/// ENDFOR
744/// \endcode
745///
746/// \headerfile <immintrin.h>
747///
748/// This intrinsic corresponds to the \c VPCMPGTW instruction.
749///
750/// \param __a
751/// A 256-bit vector of [16 x i16] containing one of the inputs.
752/// \param __b
753/// A 256-bit vector of [16 x i16] containing one of the inputs.
754/// \returns A 256-bit vector of [16 x i16] containing the result.
187755static __inline__ __m256i __DEFAULT_FN_ATTRS256
188756_mm256_cmpgt_epi16(__m256i __a, __m256i __b)
189757{
190758 return (__m256i)((__v16hi)__a > (__v16hi)__b);
191759}
192760
761/// Compares corresponding signed elements in the 256-bit vectors of
762/// [8 x i32] in \a __a and \a __b for greater-than and returns the
763/// outcomes in the corresponding elements of the 256-bit result.
764///
765/// \code{.operation}
766/// FOR i := 0 TO 7
767/// j := i*32
768/// result[j+31:j] := (__a[j+31:j] > __b[j+31:j]) ? 0xFFFFFFFF : 0
769/// ENDFOR
770/// \endcode
771///
772/// \headerfile <immintrin.h>
773///
774/// This intrinsic corresponds to the \c VPCMPGTD instruction.
775///
776/// \param __a
777/// A 256-bit vector of [8 x i32] containing one of the inputs.
778/// \param __b
779/// A 256-bit vector of [8 x i32] containing one of the inputs.
780/// \returns A 256-bit vector of [8 x i32] containing the result.
193781static __inline__ __m256i __DEFAULT_FN_ATTRS256
194782_mm256_cmpgt_epi32(__m256i __a, __m256i __b)
195783{
196784 return (__m256i)((__v8si)__a > (__v8si)__b);
197785}
198786
787/// Compares corresponding signed elements in the 256-bit vectors of
788/// [4 x i64] in \a __a and \a __b for greater-than and returns the
789/// outcomes in the corresponding elements of the 256-bit result.
790///
791/// \code{.operation}
792/// FOR i := 0 TO 3
793/// j := i*64
794/// result[j+63:j] := (__a[j+63:j] > __b[j+63:j]) ? 0xFFFFFFFFFFFFFFFF : 0
795/// ENDFOR
796/// \endcode
797///
798/// \headerfile <immintrin.h>
799///
800/// This intrinsic corresponds to the \c VPCMPGTQ instruction.
801///
802/// \param __a
803/// A 256-bit vector of [4 x i64] containing one of the inputs.
804/// \param __b
805/// A 256-bit vector of [4 x i64] containing one of the inputs.
806/// \returns A 256-bit vector of [4 x i64] containing the result.
199807static __inline__ __m256i __DEFAULT_FN_ATTRS256
200808_mm256_cmpgt_epi64(__m256i __a, __m256i __b)
201809{
202810 return (__m256i)((__v4di)__a > (__v4di)__b);
203811}
204812
813/// Horizontally adds the adjacent pairs of 16-bit integers from two 256-bit
814/// vectors of [16 x i16] and returns the lower 16 bits of each sum in an
815/// element of the [16 x i16] result (overflow is ignored). Sums from
816/// \a __a are returned in the lower 64 bits of each 128-bit half of the
817/// result; sums from \a __b are returned in the upper 64 bits of each
818/// 128-bit half of the result.
819///
820/// \code{.operation}
821/// FOR i := 0 TO 1
822/// j := i*128
823/// result[j+15:j] := __a[j+15:j] + __a[j+31:j+16]
824/// result[j+31:j+16] := __a[j+47:j+32] + __a[j+63:j+48]
825/// result[j+47:j+32] := __a[j+79:j+64] + __a[j+95:j+80]
826/// result[j+63:j+48] := __a[j+111:j+96] + __a[j+127:j+112]
827/// result[j+79:j+64] := __b[j+15:j] + __b[j+31:j+16]
828/// result[j+95:j+80] := __b[j+47:j+32] + __b[j+63:j+48]
829/// result[j+111:j+96] := __b[j+79:j+64] + __b[j+95:j+80]
830/// result[j+127:j+112] := __b[j+111:j+96] + __b[j+127:j+112]
831/// ENDFOR
832/// \endcode
833///
834/// \headerfile <immintrin.h>
835///
836/// This intrinsic corresponds to the \c VPHADDW instruction.
837///
838/// \param __a
839/// A 256-bit vector of [16 x i16] containing one of the source operands.
840/// \param __b
841/// A 256-bit vector of [16 x i16] containing one of the source operands.
842/// \returns A 256-bit vector of [16 x i16] containing the sums.
205843static __inline__ __m256i __DEFAULT_FN_ATTRS256
206844_mm256_hadd_epi16(__m256i __a, __m256i __b)
207845{
208846 return (__m256i)__builtin_ia32_phaddw256((__v16hi)__a, (__v16hi)__b);
209847}
210848
849/// Horizontally adds the adjacent pairs of 32-bit integers from two 256-bit
850/// vectors of [8 x i32] and returns the lower 32 bits of each sum in an
851/// element of the [8 x i32] result (overflow is ignored). Sums from \a __a
852/// are returned in the lower 64 bits of each 128-bit half of the result;
853/// sums from \a __b are returned in the upper 64 bits of each 128-bit half
854/// of the result.
855///
856/// \code{.operation}
857/// FOR i := 0 TO 1
858/// j := i*128
859/// result[j+31:j] := __a[j+31:j] + __a[j+63:j+32]
860/// result[j+63:j+32] := __a[j+95:j+64] + __a[j+127:j+96]
861/// result[j+95:j+64] := __b[j+31:j] + __b[j+63:j+32]
862/// result[j+127:j+96] := __b[j+95:j+64] + __b[j+127:j+96]
863/// ENDFOR
864/// \endcode
865///
866/// \headerfile <immintrin.h>
867///
868/// This intrinsic corresponds to the \c VPHADDD instruction.
869///
870/// \param __a
871/// A 256-bit vector of [8 x i32] containing one of the source operands.
872/// \param __b
873/// A 256-bit vector of [8 x i32] containing one of the source operands.
874/// \returns A 256-bit vector of [8 x i32] containing the sums.
211875static __inline__ __m256i __DEFAULT_FN_ATTRS256
212876_mm256_hadd_epi32(__m256i __a, __m256i __b)
213877{
214878 return (__m256i)__builtin_ia32_phaddd256((__v8si)__a, (__v8si)__b);
215879}
216880
881/// Horizontally adds the adjacent pairs of 16-bit integers from two 256-bit
882/// vectors of [16 x i16] using signed saturation and returns each sum in
883/// an element of the [16 x i16] result. Sums from \a __a are returned in
884/// the lower 64 bits of each 128-bit half of the result; sums from \a __b
885/// are returned in the upper 64 bits of each 128-bit half of the result.
886///
887/// \code{.operation}
888/// FOR i := 0 TO 1
889/// j := i*128
890/// result[j+15:j] := SATURATE16(__a[j+15:j] + __a[j+31:j+16])
891/// result[j+31:j+16] := SATURATE16(__a[j+47:j+32] + __a[j+63:j+48])
892/// result[j+47:j+32] := SATURATE16(__a[j+79:j+64] + __a[j+95:j+80])
893/// result[j+63:j+48] := SATURATE16(__a[j+111:j+96] + __a[j+127:j+112])
894/// result[j+79:j+64] := SATURATE16(__b[j+15:j] + __b[j+31:j+16])
895/// result[j+95:j+80] := SATURATE16(__b[j+47:j+32] + __b[j+63:j+48])
896/// result[j+111:j+96] := SATURATE16(__b[j+79:j+64] + __b[j+95:j+80])
897/// result[j+127:j+112] := SATURATE16(__b[j+111:j+96] + __b[j+127:j+112])
898/// ENDFOR
899/// \endcode
900///
901/// \headerfile <immintrin.h>
902///
903/// This intrinsic corresponds to the \c VPHADDSW instruction.
904///
905/// \param __a
906/// A 256-bit vector of [16 x i16] containing one of the source operands.
907/// \param __b
908/// A 256-bit vector of [16 x i16] containing one of the source operands.
909/// \returns A 256-bit vector of [16 x i16] containing the sums.
217910static __inline__ __m256i __DEFAULT_FN_ATTRS256
218911_mm256_hadds_epi16(__m256i __a, __m256i __b)
219912{
220913 return (__m256i)__builtin_ia32_phaddsw256((__v16hi)__a, (__v16hi)__b);
221914}
222915
916/// Horizontally subtracts adjacent pairs of 16-bit integers from two 256-bit
917/// vectors of [16 x i16] and returns the lower 16 bits of each difference
918/// in an element of the [16 x i16] result (overflow is ignored).
919/// Differences from \a __a are returned in the lower 64 bits of each
920/// 128-bit half of the result; differences from \a __b are returned in the
921/// upper 64 bits of each 128-bit half of the result.
922///
923/// \code{.operation}
924/// FOR i := 0 TO 1
925/// j := i*128
926/// result[j+15:j] := __a[j+15:j] - __a[j+31:j+16]
927/// result[j+31:j+16] := __a[j+47:j+32] - __a[j+63:j+48]
928/// result[j+47:j+32] := __a[j+79:j+64] - __a[j+95:j+80]
929/// result[j+63:j+48] := __a[j+111:j+96] - __a[j+127:j+112]
930/// result[j+79:j+64] := __b[j+15:j] - __b[j+31:j+16]
931/// result[j+95:j+80] := __b[j+47:j+32] - __b[j+63:j+48]
932/// result[j+111:j+96] := __b[j+79:j+64] - __b[j+95:j+80]
933/// result[j+127:j+112] := __b[j+111:j+96] - __b[j+127:j+112]
934/// ENDFOR
935/// \endcode
936///
937/// \headerfile <immintrin.h>
938///
939/// This intrinsic corresponds to the \c VPHSUBW instruction.
940///
941/// \param __a
942/// A 256-bit vector of [16 x i16] containing one of the source operands.
943/// \param __b
944/// A 256-bit vector of [16 x i16] containing one of the source operands.
945/// \returns A 256-bit vector of [16 x i16] containing the differences.
223946static __inline__ __m256i __DEFAULT_FN_ATTRS256
224947_mm256_hsub_epi16(__m256i __a, __m256i __b)
225948{
226949 return (__m256i)__builtin_ia32_phsubw256((__v16hi)__a, (__v16hi)__b);
227950}
228951
952/// Horizontally subtracts adjacent pairs of 32-bit integers from two 256-bit
953/// vectors of [8 x i32] and returns the lower 32 bits of each difference in
954/// an element of the [8 x i32] result (overflow is ignored). Differences
955/// from \a __a are returned in the lower 64 bits of each 128-bit half of
956/// the result; differences from \a __b are returned in the upper 64 bits
957/// of each 128-bit half of the result.
958///
959/// \code{.operation}
960/// FOR i := 0 TO 1
961/// j := i*128
962/// result[j+31:j] := __a[j+31:j] - __a[j+63:j+32]
963/// result[j+63:j+32] := __a[j+95:j+64] - __a[j+127:j+96]
964/// result[j+95:j+64] := __b[j+31:j] - __b[j+63:j+32]
965/// result[j+127:j+96] := __b[j+95:j+64] - __b[j+127:j+96]
966/// ENDFOR
967/// \endcode
968///
969/// \headerfile <immintrin.h>
970///
971/// This intrinsic corresponds to the \c VPHSUBD instruction.
972///
973/// \param __a
974/// A 256-bit vector of [8 x i32] containing one of the source operands.
975/// \param __b
976/// A 256-bit vector of [8 x i32] containing one of the source operands.
977/// \returns A 256-bit vector of [8 x i32] containing the differences.
229978static __inline__ __m256i __DEFAULT_FN_ATTRS256
230979_mm256_hsub_epi32(__m256i __a, __m256i __b)
231980{
232981 return (__m256i)__builtin_ia32_phsubd256((__v8si)__a, (__v8si)__b);
233982}
234983
984/// Horizontally subtracts adjacent pairs of 16-bit integers from two 256-bit
985/// vectors of [16 x i16] using signed saturation and returns each sum in
986/// an element of the [16 x i16] result. Differences from \a __a are
987/// returned in the lower 64 bits of each 128-bit half of the result;
988/// differences from \a __b are returned in the upper 64 bits of each
989/// 128-bit half of the result.
990///
991/// \code{.operation}
992/// FOR i := 0 TO 1
993/// j := i*128
994/// result[j+15:j] := SATURATE16(__a[j+15:j] - __a[j+31:j+16])
995/// result[j+31:j+16] := SATURATE16(__a[j+47:j+32] - __a[j+63:j+48])
996/// result[j+47:j+32] := SATURATE16(__a[j+79:j+64] - __a[j+95:j+80])
997/// result[j+63:j+48] := SATURATE16(__a[j+111:j+96] - __a[j+127:j+112])
998/// result[j+79:j+64] := SATURATE16(__b[j+15:j] - __b[j+31:j+16])
999/// result[j+95:j+80] := SATURATE16(__b[j+47:j+32] - __b[j+63:j+48])
1000/// result[j+111:j+96] := SATURATE16(__b[j+79:j+64] - __b[j+95:j+80])
1001/// result[j+127:j+112] := SATURATE16(__b[j+111:j+96] - __b[j+127:j+112])
1002/// ENDFOR
1003/// \endcode
1004///
1005/// \headerfile <immintrin.h>
1006///
1007/// This intrinsic corresponds to the \c VPHSUBSW instruction.
1008///
1009/// \param __a
1010/// A 256-bit vector of [16 x i16] containing one of the source operands.
1011/// \param __b
1012/// A 256-bit vector of [16 x i16] containing one of the source operands.
1013/// \returns A 256-bit vector of [16 x i16] containing the differences.
2351014static __inline__ __m256i __DEFAULT_FN_ATTRS256
2361015_mm256_hsubs_epi16(__m256i __a, __m256i __b)
2371016{
2381017 return (__m256i)__builtin_ia32_phsubsw256((__v16hi)__a, (__v16hi)__b);
2391018}
2401019
1020/// Multiplies each unsigned byte from the 256-bit integer vector in \a __a
1021/// with the corresponding signed byte from the 256-bit integer vector in
1022/// \a __b, forming signed 16-bit intermediate products. Adds adjacent
1023/// pairs of those products using signed saturation to form 16-bit sums
1024/// returned as elements of the [16 x i16] result.
1025///
1026/// \code{.operation}
1027/// FOR i := 0 TO 15
1028/// j := i*16
1029/// temp1 := __a[j+7:j] * __b[j+7:j]
1030/// temp2 := __a[j+15:j+8] * __b[j+15:j+8]
1031/// result[j+15:j] := SATURATE16(temp1 + temp2)
1032/// ENDFOR
1033/// \endcode
1034///
1035/// \headerfile <immintrin.h>
1036///
1037/// This intrinsic corresponds to the \c VPMADDUBSW instruction.
1038///
1039/// \param __a
1040/// A 256-bit vector containing one of the source operands.
1041/// \param __b
1042/// A 256-bit vector containing one of the source operands.
1043/// \returns A 256-bit vector of [16 x i16] containing the result.
2411044static __inline__ __m256i __DEFAULT_FN_ATTRS256
2421045_mm256_maddubs_epi16(__m256i __a, __m256i __b)
2431046{
2441047 return (__m256i)__builtin_ia32_pmaddubsw256((__v32qi)__a, (__v32qi)__b);
2451048}
2461049
1050/// Multiplies corresponding 16-bit elements of two 256-bit vectors of
1051/// [16 x i16], forming 32-bit intermediate products, and adds pairs of
1052/// those products to form 32-bit sums returned as elements of the
1053/// [8 x i32] result.
1054///
1055/// There is only one wraparound case: when all four of the 16-bit sources
1056/// are \c 0x8000, the result will be \c 0x80000000.
1057///
1058/// \code{.operation}
1059/// FOR i := 0 TO 7
1060/// j := i*32
1061/// temp1 := __a[j+15:j] * __b[j+15:j]
1062/// temp2 := __a[j+31:j+16] * __b[j+31:j+16]
1063/// result[j+31:j] := temp1 + temp2
1064/// ENDFOR
1065/// \endcode
1066///
1067/// \headerfile <immintrin.h>
1068///
1069/// This intrinsic corresponds to the \c VPMADDWD instruction.
1070///
1071/// \param __a
1072/// A 256-bit vector of [16 x i16] containing one of the source operands.
1073/// \param __b
1074/// A 256-bit vector of [16 x i16] containing one of the source operands.
1075/// \returns A 256-bit vector of [8 x i32] containing the result.
2471076static __inline__ __m256i __DEFAULT_FN_ATTRS256
2481077_mm256_madd_epi16(__m256i __a, __m256i __b)
2491078{
2501079 return (__m256i)__builtin_ia32_pmaddwd256((__v16hi)__a, (__v16hi)__b);
2511080}
2521081
1082/// Compares the corresponding signed bytes in the two 256-bit integer vectors
1083/// in \a __a and \a __b and returns the larger of each pair in the
1084/// corresponding byte of the 256-bit result.
1085///
1086/// \headerfile <immintrin.h>
1087///
1088/// This intrinsic corresponds to the \c VPMAXSB instruction.
1089///
1090/// \param __a
1091/// A 256-bit integer vector.
1092/// \param __b
1093/// A 256-bit integer vector.
1094/// \returns A 256-bit integer vector containing the result.
2531095static __inline__ __m256i __DEFAULT_FN_ATTRS256
2541096_mm256_max_epi8(__m256i __a, __m256i __b)
2551097{
2561098 return (__m256i)__builtin_elementwise_max((__v32qs)__a, (__v32qs)__b);
2571099}
2581100
1101/// Compares the corresponding signed 16-bit integers in the two 256-bit
1102/// vectors of [16 x i16] in \a __a and \a __b and returns the larger of
1103/// each pair in the corresponding element of the 256-bit result.
1104///
1105/// \headerfile <immintrin.h>
1106///
1107/// This intrinsic corresponds to the \c VPMAXSW instruction.
1108///
1109/// \param __a
1110/// A 256-bit vector of [16 x i16].
1111/// \param __b
1112/// A 256-bit vector of [16 x i16].
1113/// \returns A 256-bit vector of [16 x i16] containing the result.
2591114static __inline__ __m256i __DEFAULT_FN_ATTRS256
2601115_mm256_max_epi16(__m256i __a, __m256i __b)
2611116{
2621117 return (__m256i)__builtin_elementwise_max((__v16hi)__a, (__v16hi)__b);
2631118}
2641119
1120/// Compares the corresponding signed 32-bit integers in the two 256-bit
1121/// vectors of [8 x i32] in \a __a and \a __b and returns the larger of
1122/// each pair in the corresponding element of the 256-bit result.
1123///
1124/// \headerfile <immintrin.h>
1125///
1126/// This intrinsic corresponds to the \c VPMAXSD instruction.
1127///
1128/// \param __a
1129/// A 256-bit vector of [8 x i32].
1130/// \param __b
1131/// A 256-bit vector of [8 x i32].
1132/// \returns A 256-bit vector of [8 x i32] containing the result.
2651133static __inline__ __m256i __DEFAULT_FN_ATTRS256
2661134_mm256_max_epi32(__m256i __a, __m256i __b)
2671135{
2681136 return (__m256i)__builtin_elementwise_max((__v8si)__a, (__v8si)__b);
2691137}
2701138
1139/// Compares the corresponding unsigned bytes in the two 256-bit integer
1140/// vectors in \a __a and \a __b and returns the larger of each pair in
1141/// the corresponding byte of the 256-bit result.
1142///
1143/// \headerfile <immintrin.h>
1144///
1145/// This intrinsic corresponds to the \c VPMAXUB instruction.
1146///
1147/// \param __a
1148/// A 256-bit integer vector.
1149/// \param __b
1150/// A 256-bit integer vector.
1151/// \returns A 256-bit integer vector containing the result.
2711152static __inline__ __m256i __DEFAULT_FN_ATTRS256
2721153_mm256_max_epu8(__m256i __a, __m256i __b)
2731154{
2741155 return (__m256i)__builtin_elementwise_max((__v32qu)__a, (__v32qu)__b);
2751156}
2761157
1158/// Compares the corresponding unsigned 16-bit integers in the two 256-bit
1159/// vectors of [16 x i16] in \a __a and \a __b and returns the larger of
1160/// each pair in the corresponding element of the 256-bit result.
1161///
1162/// \headerfile <immintrin.h>
1163///
1164/// This intrinsic corresponds to the \c VPMAXUW instruction.
1165///
1166/// \param __a
1167/// A 256-bit vector of [16 x i16].
1168/// \param __b
1169/// A 256-bit vector of [16 x i16].
1170/// \returns A 256-bit vector of [16 x i16] containing the result.
2771171static __inline__ __m256i __DEFAULT_FN_ATTRS256
2781172_mm256_max_epu16(__m256i __a, __m256i __b)
2791173{
2801174 return (__m256i)__builtin_elementwise_max((__v16hu)__a, (__v16hu)__b);
2811175}
2821176
1177/// Compares the corresponding unsigned 32-bit integers in the two 256-bit
1178/// vectors of [8 x i32] in \a __a and \a __b and returns the larger of
1179/// each pair in the corresponding element of the 256-bit result.
1180///
1181/// \headerfile <immintrin.h>
1182///
1183/// This intrinsic corresponds to the \c VPMAXUD instruction.
1184///
1185/// \param __a
1186/// A 256-bit vector of [8 x i32].
1187/// \param __b
1188/// A 256-bit vector of [8 x i32].
1189/// \returns A 256-bit vector of [8 x i32] containing the result.
2831190static __inline__ __m256i __DEFAULT_FN_ATTRS256
2841191_mm256_max_epu32(__m256i __a, __m256i __b)
2851192{
2861193 return (__m256i)__builtin_elementwise_max((__v8su)__a, (__v8su)__b);
2871194}
2881195
1196/// Compares the corresponding signed bytes in the two 256-bit integer vectors
1197/// in \a __a and \a __b and returns the smaller of each pair in the
1198/// corresponding byte of the 256-bit result.
1199///
1200/// \headerfile <immintrin.h>
1201///
1202/// This intrinsic corresponds to the \c VPMINSB instruction.
1203///
1204/// \param __a
1205/// A 256-bit integer vector.
1206/// \param __b
1207/// A 256-bit integer vector.
1208/// \returns A 256-bit integer vector containing the result.
2891209static __inline__ __m256i __DEFAULT_FN_ATTRS256
2901210_mm256_min_epi8(__m256i __a, __m256i __b)
2911211{
2921212 return (__m256i)__builtin_elementwise_min((__v32qs)__a, (__v32qs)__b);
2931213}
2941214
1215/// Compares the corresponding signed 16-bit integers in the two 256-bit
1216/// vectors of [16 x i16] in \a __a and \a __b and returns the smaller of
1217/// each pair in the corresponding element of the 256-bit result.
1218///
1219/// \headerfile <immintrin.h>
1220///
1221/// This intrinsic corresponds to the \c VPMINSW instruction.
1222///
1223/// \param __a
1224/// A 256-bit vector of [16 x i16].
1225/// \param __b
1226/// A 256-bit vector of [16 x i16].
1227/// \returns A 256-bit vector of [16 x i16] containing the result.
2951228static __inline__ __m256i __DEFAULT_FN_ATTRS256
2961229_mm256_min_epi16(__m256i __a, __m256i __b)
2971230{
2981231 return (__m256i)__builtin_elementwise_min((__v16hi)__a, (__v16hi)__b);
2991232}
3001233
1234/// Compares the corresponding signed 32-bit integers in the two 256-bit
1235/// vectors of [8 x i32] in \a __a and \a __b and returns the smaller of
1236/// each pair in the corresponding element of the 256-bit result.
1237///
1238/// \headerfile <immintrin.h>
1239///
1240/// This intrinsic corresponds to the \c VPMINSD instruction.
1241///
1242/// \param __a
1243/// A 256-bit vector of [8 x i32].
1244/// \param __b
1245/// A 256-bit vector of [8 x i32].
1246/// \returns A 256-bit vector of [8 x i32] containing the result.
3011247static __inline__ __m256i __DEFAULT_FN_ATTRS256
3021248_mm256_min_epi32(__m256i __a, __m256i __b)
3031249{
3041250 return (__m256i)__builtin_elementwise_min((__v8si)__a, (__v8si)__b);
3051251}
3061252
1253/// Compares the corresponding unsigned bytes in the two 256-bit integer
1254/// vectors in \a __a and \a __b and returns the smaller of each pair in
1255/// the corresponding byte of the 256-bit result.
1256///
1257/// \headerfile <immintrin.h>
1258///
1259/// This intrinsic corresponds to the \c VPMINUB instruction.
1260///
1261/// \param __a
1262/// A 256-bit integer vector.
1263/// \param __b
1264/// A 256-bit integer vector.
1265/// \returns A 256-bit integer vector containing the result.
3071266static __inline__ __m256i __DEFAULT_FN_ATTRS256
3081267_mm256_min_epu8(__m256i __a, __m256i __b)
3091268{
3101269 return (__m256i)__builtin_elementwise_min((__v32qu)__a, (__v32qu)__b);
3111270}
3121271
1272/// Compares the corresponding unsigned 16-bit integers in the two 256-bit
1273/// vectors of [16 x i16] in \a __a and \a __b and returns the smaller of
1274/// each pair in the corresponding element of the 256-bit result.
1275///
1276/// \headerfile <immintrin.h>
1277///
1278/// This intrinsic corresponds to the \c VPMINUW instruction.
1279///
1280/// \param __a
1281/// A 256-bit vector of [16 x i16].
1282/// \param __b
1283/// A 256-bit vector of [16 x i16].
1284/// \returns A 256-bit vector of [16 x i16] containing the result.
3131285static __inline__ __m256i __DEFAULT_FN_ATTRS256
3141286_mm256_min_epu16(__m256i __a, __m256i __b)
3151287{
3161288 return (__m256i)__builtin_elementwise_min((__v16hu)__a, (__v16hu)__b);
3171289}
3181290
1291/// Compares the corresponding unsigned 32-bit integers in the two 256-bit
1292/// vectors of [8 x i32] in \a __a and \a __b and returns the smaller of
1293/// each pair in the corresponding element of the 256-bit result.
1294///
1295/// \headerfile <immintrin.h>
1296///
1297/// This intrinsic corresponds to the \c VPMINUD instruction.
1298///
1299/// \param __a
1300/// A 256-bit vector of [8 x i32].
1301/// \param __b
1302/// A 256-bit vector of [8 x i32].
1303/// \returns A 256-bit vector of [8 x i32] containing the result.
3191304static __inline__ __m256i __DEFAULT_FN_ATTRS256
3201305_mm256_min_epu32(__m256i __a, __m256i __b)
3211306{
......@@ -328,6 +1313,26 @@ _mm256_movemask_epi8(__m256i __a)
3281313 return __builtin_ia32_pmovmskb256((__v32qi)__a);
3291314}
3301315
1316/// Sign-extends bytes from the 128-bit integer vector in \a __V and returns
1317/// the 16-bit values in the corresponding elements of a 256-bit vector
1318/// of [16 x i16].
1319///
1320/// \code{.operation}
1321/// FOR i := 0 TO 15
1322/// j := i*8
1323/// k := i*16
1324/// result[k+15:k] := SignExtend(__V[j+7:j])
1325/// ENDFOR
1326/// \endcode
1327///
1328/// \headerfile <immintrin.h>
1329///
1330/// This intrinsic corresponds to the \c VPMOVSXBW instruction.
1331///
1332/// \param __V
1333/// A 128-bit integer vector containing the source bytes.
1334/// \returns A 256-bit vector of [16 x i16] containing the sign-extended
1335/// values.
3311336static __inline__ __m256i __DEFAULT_FN_ATTRS256
3321337_mm256_cvtepi8_epi16(__m128i __V)
3331338{
......@@ -336,6 +1341,26 @@ _mm256_cvtepi8_epi16(__m128i __V)
3361341 return (__m256i)__builtin_convertvector((__v16qs)__V, __v16hi);
3371342}
3381343
1344/// Sign-extends bytes from the lower half of the 128-bit integer vector in
1345/// \a __V and returns the 32-bit values in the corresponding elements of a
1346/// 256-bit vector of [8 x i32].
1347///
1348/// \code{.operation}
1349/// FOR i := 0 TO 7
1350/// j := i*8
1351/// k := i*32
1352/// result[k+31:k] := SignExtend(__V[j+7:j])
1353/// ENDFOR
1354/// \endcode
1355///
1356/// \headerfile <immintrin.h>
1357///
1358/// This intrinsic corresponds to the \c VPMOVSXBD instruction.
1359///
1360/// \param __V
1361/// A 128-bit integer vector containing the source bytes.
1362/// \returns A 256-bit vector of [8 x i32] containing the sign-extended
1363/// values.
3391364static __inline__ __m256i __DEFAULT_FN_ATTRS256
3401365_mm256_cvtepi8_epi32(__m128i __V)
3411366{
......@@ -344,6 +1369,25 @@ _mm256_cvtepi8_epi32(__m128i __V)
3441369 return (__m256i)__builtin_convertvector(__builtin_shufflevector((__v16qs)__V, (__v16qs)__V, 0, 1, 2, 3, 4, 5, 6, 7), __v8si);
3451370}
3461371
1372/// Sign-extends the first four bytes from the 128-bit integer vector in
1373/// \a __V and returns the 64-bit values in the corresponding elements of a
1374/// 256-bit vector of [4 x i64].
1375///
1376/// \code{.operation}
1377/// result[63:0] := SignExtend(__V[7:0])
1378/// result[127:64] := SignExtend(__V[15:8])
1379/// result[191:128] := SignExtend(__V[23:16])
1380/// result[255:192] := SignExtend(__V[31:24])
1381/// \endcode
1382///
1383/// \headerfile <immintrin.h>
1384///
1385/// This intrinsic corresponds to the \c VPMOVSXBQ instruction.
1386///
1387/// \param __V
1388/// A 128-bit integer vector containing the source bytes.
1389/// \returns A 256-bit vector of [4 x i64] containing the sign-extended
1390/// values.
3471391static __inline__ __m256i __DEFAULT_FN_ATTRS256
3481392_mm256_cvtepi8_epi64(__m128i __V)
3491393{
......@@ -352,357 +1396,1571 @@ _mm256_cvtepi8_epi64(__m128i __V)
3521396 return (__m256i)__builtin_convertvector(__builtin_shufflevector((__v16qs)__V, (__v16qs)__V, 0, 1, 2, 3), __v4di);
3531397}
3541398
1399/// Sign-extends 16-bit elements from the 128-bit vector of [8 x i16] in
1400/// \a __V and returns the 32-bit values in the corresponding elements of a
1401/// 256-bit vector of [8 x i32].
1402///
1403/// \code{.operation}
1404/// FOR i := 0 TO 7
1405/// j := i*16
1406/// k := i*32
1407/// result[k+31:k] := SignExtend(__V[j+15:j])
1408/// ENDFOR
1409/// \endcode
1410///
1411/// \headerfile <immintrin.h>
1412///
1413/// This intrinsic corresponds to the \c VPMOVSXWD instruction.
1414///
1415/// \param __V
1416/// A 128-bit vector of [8 x i16] containing the source values.
1417/// \returns A 256-bit vector of [8 x i32] containing the sign-extended
1418/// values.
3551419static __inline__ __m256i __DEFAULT_FN_ATTRS256
3561420_mm256_cvtepi16_epi32(__m128i __V)
3571421{
3581422 return (__m256i)__builtin_convertvector((__v8hi)__V, __v8si);
3591423}
3601424
1425/// Sign-extends 16-bit elements from the lower half of the 128-bit vector of
1426/// [8 x i16] in \a __V and returns the 64-bit values in the corresponding
1427/// elements of a 256-bit vector of [4 x i64].
1428///
1429/// \code{.operation}
1430/// result[63:0] := SignExtend(__V[15:0])
1431/// result[127:64] := SignExtend(__V[31:16])
1432/// result[191:128] := SignExtend(__V[47:32])
1433/// result[255:192] := SignExtend(__V[64:48])
1434/// \endcode
1435///
1436/// \headerfile <immintrin.h>
1437///
1438/// This intrinsic corresponds to the \c VPMOVSXWQ instruction.
1439///
1440/// \param __V
1441/// A 128-bit vector of [8 x i16] containing the source values.
1442/// \returns A 256-bit vector of [4 x i64] containing the sign-extended
1443/// values.
3611444static __inline__ __m256i __DEFAULT_FN_ATTRS256
3621445_mm256_cvtepi16_epi64(__m128i __V)
3631446{
3641447 return (__m256i)__builtin_convertvector(__builtin_shufflevector((__v8hi)__V, (__v8hi)__V, 0, 1, 2, 3), __v4di);
3651448}
3661449
1450/// Sign-extends 32-bit elements from the 128-bit vector of [4 x i32] in
1451/// \a __V and returns the 64-bit values in the corresponding elements of a
1452/// 256-bit vector of [4 x i64].
1453///
1454/// \code{.operation}
1455/// result[63:0] := SignExtend(__V[31:0])
1456/// result[127:64] := SignExtend(__V[63:32])
1457/// result[191:128] := SignExtend(__V[95:64])
1458/// result[255:192] := SignExtend(__V[127:96])
1459/// \endcode
1460///
1461/// \headerfile <immintrin.h>
1462///
1463/// This intrinsic corresponds to the \c VPMOVSXDQ instruction.
1464///
1465/// \param __V
1466/// A 128-bit vector of [4 x i32] containing the source values.
1467/// \returns A 256-bit vector of [4 x i64] containing the sign-extended
1468/// values.
3671469static __inline__ __m256i __DEFAULT_FN_ATTRS256
3681470_mm256_cvtepi32_epi64(__m128i __V)
3691471{
3701472 return (__m256i)__builtin_convertvector((__v4si)__V, __v4di);
3711473}
3721474
1475/// Zero-extends bytes from the 128-bit integer vector in \a __V and returns
1476/// the 16-bit values in the corresponding elements of a 256-bit vector
1477/// of [16 x i16].
1478///
1479/// \code{.operation}
1480/// FOR i := 0 TO 15
1481/// j := i*8
1482/// k := i*16
1483/// result[k+15:k] := ZeroExtend(__V[j+7:j])
1484/// ENDFOR
1485/// \endcode
1486///
1487/// \headerfile <immintrin.h>
1488///
1489/// This intrinsic corresponds to the \c VPMOVZXBW instruction.
1490///
1491/// \param __V
1492/// A 128-bit integer vector containing the source bytes.
1493/// \returns A 256-bit vector of [16 x i16] containing the zero-extended
1494/// values.
3731495static __inline__ __m256i __DEFAULT_FN_ATTRS256
3741496_mm256_cvtepu8_epi16(__m128i __V)
3751497{
3761498 return (__m256i)__builtin_convertvector((__v16qu)__V, __v16hi);
3771499}
3781500
1501/// Zero-extends bytes from the lower half of the 128-bit integer vector in
1502/// \a __V and returns the 32-bit values in the corresponding elements of a
1503/// 256-bit vector of [8 x i32].
1504///
1505/// \code{.operation}
1506/// FOR i := 0 TO 7
1507/// j := i*8
1508/// k := i*32
1509/// result[k+31:k] := ZeroExtend(__V[j+7:j])
1510/// ENDFOR
1511/// \endcode
1512///
1513/// \headerfile <immintrin.h>
1514///
1515/// This intrinsic corresponds to the \c VPMOVZXBD instruction.
1516///
1517/// \param __V
1518/// A 128-bit integer vector containing the source bytes.
1519/// \returns A 256-bit vector of [8 x i32] containing the zero-extended
1520/// values.
3791521static __inline__ __m256i __DEFAULT_FN_ATTRS256
3801522_mm256_cvtepu8_epi32(__m128i __V)
3811523{
3821524 return (__m256i)__builtin_convertvector(__builtin_shufflevector((__v16qu)__V, (__v16qu)__V, 0, 1, 2, 3, 4, 5, 6, 7), __v8si);
3831525}
3841526
1527/// Zero-extends the first four bytes from the 128-bit integer vector in
1528/// \a __V and returns the 64-bit values in the corresponding elements of a
1529/// 256-bit vector of [4 x i64].
1530///
1531/// \code{.operation}
1532/// result[63:0] := ZeroExtend(__V[7:0])
1533/// result[127:64] := ZeroExtend(__V[15:8])
1534/// result[191:128] := ZeroExtend(__V[23:16])
1535/// result[255:192] := ZeroExtend(__V[31:24])
1536/// \endcode
1537///
1538/// \headerfile <immintrin.h>
1539///
1540/// This intrinsic corresponds to the \c VPMOVZXBQ instruction.
1541///
1542/// \param __V
1543/// A 128-bit integer vector containing the source bytes.
1544/// \returns A 256-bit vector of [4 x i64] containing the zero-extended
1545/// values.
3851546static __inline__ __m256i __DEFAULT_FN_ATTRS256
3861547_mm256_cvtepu8_epi64(__m128i __V)
3871548{
3881549 return (__m256i)__builtin_convertvector(__builtin_shufflevector((__v16qu)__V, (__v16qu)__V, 0, 1, 2, 3), __v4di);
3891550}
3901551
1552/// Zero-extends 16-bit elements from the 128-bit vector of [8 x i16] in
1553/// \a __V and returns the 32-bit values in the corresponding elements of a
1554/// 256-bit vector of [8 x i32].
1555///
1556/// \code{.operation}
1557/// FOR i := 0 TO 7
1558/// j := i*16
1559/// k := i*32
1560/// result[k+31:k] := ZeroExtend(__V[j+15:j])
1561/// ENDFOR
1562/// \endcode
1563///
1564/// \headerfile <immintrin.h>
1565///
1566/// This intrinsic corresponds to the \c VPMOVZXWD instruction.
1567///
1568/// \param __V
1569/// A 128-bit vector of [8 x i16] containing the source values.
1570/// \returns A 256-bit vector of [8 x i32] containing the zero-extended
1571/// values.
3911572static __inline__ __m256i __DEFAULT_FN_ATTRS256
3921573_mm256_cvtepu16_epi32(__m128i __V)
3931574{
3941575 return (__m256i)__builtin_convertvector((__v8hu)__V, __v8si);
3951576}
3961577
1578/// Zero-extends 16-bit elements from the lower half of the 128-bit vector of
1579/// [8 x i16] in \a __V and returns the 64-bit values in the corresponding
1580/// elements of a 256-bit vector of [4 x i64].
1581///
1582/// \code{.operation}
1583/// result[63:0] := ZeroExtend(__V[15:0])
1584/// result[127:64] := ZeroExtend(__V[31:16])
1585/// result[191:128] := ZeroExtend(__V[47:32])
1586/// result[255:192] := ZeroExtend(__V[64:48])
1587/// \endcode
1588///
1589/// \headerfile <immintrin.h>
1590///
1591/// This intrinsic corresponds to the \c VPMOVSXWQ instruction.
1592///
1593/// \param __V
1594/// A 128-bit vector of [8 x i16] containing the source values.
1595/// \returns A 256-bit vector of [4 x i64] containing the zero-extended
1596/// values.
3971597static __inline__ __m256i __DEFAULT_FN_ATTRS256
3981598_mm256_cvtepu16_epi64(__m128i __V)
3991599{
4001600 return (__m256i)__builtin_convertvector(__builtin_shufflevector((__v8hu)__V, (__v8hu)__V, 0, 1, 2, 3), __v4di);
4011601}
4021602
1603/// Zero-extends 32-bit elements from the 128-bit vector of [4 x i32] in
1604/// \a __V and returns the 64-bit values in the corresponding elements of a
1605/// 256-bit vector of [4 x i64].
1606///
1607/// \code{.operation}
1608/// result[63:0] := ZeroExtend(__V[31:0])
1609/// result[127:64] := ZeroExtend(__V[63:32])
1610/// result[191:128] := ZeroExtend(__V[95:64])
1611/// result[255:192] := ZeroExtend(__V[127:96])
1612/// \endcode
1613///
1614/// \headerfile <immintrin.h>
1615///
1616/// This intrinsic corresponds to the \c VPMOVZXDQ instruction.
1617///
1618/// \param __V
1619/// A 128-bit vector of [4 x i32] containing the source values.
1620/// \returns A 256-bit vector of [4 x i64] containing the zero-extended
1621/// values.
4031622static __inline__ __m256i __DEFAULT_FN_ATTRS256
4041623_mm256_cvtepu32_epi64(__m128i __V)
4051624{
4061625 return (__m256i)__builtin_convertvector((__v4su)__V, __v4di);
4071626}
4081627
1628/// Multiplies signed 32-bit integers from even-numbered elements of two
1629/// 256-bit vectors of [8 x i32] and returns the 64-bit products in the
1630/// [4 x i64] result.
1631///
1632/// \code{.operation}
1633/// result[63:0] := __a[31:0] * __b[31:0]
1634/// result[127:64] := __a[95:64] * __b[95:64]
1635/// result[191:128] := __a[159:128] * __b[159:128]
1636/// result[255:192] := __a[223:192] * __b[223:192]
1637/// \endcode
1638///
1639/// \headerfile <immintrin.h>
1640///
1641/// This intrinsic corresponds to the \c VPMULDQ instruction.
1642///
1643/// \param __a
1644/// A 256-bit vector of [8 x i32] containing one of the source operands.
1645/// \param __b
1646/// A 256-bit vector of [8 x i32] containing one of the source operands.
1647/// \returns A 256-bit vector of [4 x i64] containing the products.
4091648static __inline__ __m256i __DEFAULT_FN_ATTRS256
4101649_mm256_mul_epi32(__m256i __a, __m256i __b)
4111650{
4121651 return (__m256i)__builtin_ia32_pmuldq256((__v8si)__a, (__v8si)__b);
4131652}
4141653
1654/// Multiplies signed 16-bit integer elements of two 256-bit vectors of
1655/// [16 x i16], truncates the 32-bit results to the most significant 18
1656/// bits, rounds by adding 1, and returns bits [16:1] of each rounded
1657/// product in the [16 x i16] result.
1658///
1659/// \code{.operation}
1660/// FOR i := 0 TO 15
1661/// j := i*16
1662/// temp := ((__a[j+15:j] * __b[j+15:j]) >> 14) + 1
1663/// result[j+15:j] := temp[16:1]
1664/// \endcode
1665///
1666/// \headerfile <immintrin.h>
1667///
1668/// This intrinsic corresponds to the \c VPMULHRSW instruction.
1669///
1670/// \param __a
1671/// A 256-bit vector of [16 x i16] containing one of the source operands.
1672/// \param __b
1673/// A 256-bit vector of [16 x i16] containing one of the source operands.
1674/// \returns A 256-bit vector of [16 x i16] containing the rounded products.
4151675static __inline__ __m256i __DEFAULT_FN_ATTRS256
4161676_mm256_mulhrs_epi16(__m256i __a, __m256i __b)
4171677{
4181678 return (__m256i)__builtin_ia32_pmulhrsw256((__v16hi)__a, (__v16hi)__b);
4191679}
4201680
1681/// Multiplies unsigned 16-bit integer elements of two 256-bit vectors of
1682/// [16 x i16], and returns the upper 16 bits of each 32-bit product in the
1683/// [16 x i16] result.
1684///
1685/// \headerfile <immintrin.h>
1686///
1687/// This intrinsic corresponds to the \c VPMULHUW instruction.
1688///
1689/// \param __a
1690/// A 256-bit vector of [16 x i16] containing one of the source operands.
1691/// \param __b
1692/// A 256-bit vector of [16 x i16] containing one of the source operands.
1693/// \returns A 256-bit vector of [16 x i16] containing the products.
4211694static __inline__ __m256i __DEFAULT_FN_ATTRS256
4221695_mm256_mulhi_epu16(__m256i __a, __m256i __b)
4231696{
4241697 return (__m256i)__builtin_ia32_pmulhuw256((__v16hi)__a, (__v16hi)__b);
4251698}
4261699
1700/// Multiplies signed 16-bit integer elements of two 256-bit vectors of
1701/// [16 x i16], and returns the upper 16 bits of each 32-bit product in the
1702/// [16 x i16] result.
1703///
1704/// \headerfile <immintrin.h>
1705///
1706/// This intrinsic corresponds to the \c VPMULHW instruction.
1707///
1708/// \param __a
1709/// A 256-bit vector of [16 x i16] containing one of the source operands.
1710/// \param __b
1711/// A 256-bit vector of [16 x i16] containing one of the source operands.
1712/// \returns A 256-bit vector of [16 x i16] containing the products.
4271713static __inline__ __m256i __DEFAULT_FN_ATTRS256
4281714_mm256_mulhi_epi16(__m256i __a, __m256i __b)
4291715{
4301716 return (__m256i)__builtin_ia32_pmulhw256((__v16hi)__a, (__v16hi)__b);
4311717}
4321718
1719/// Multiplies signed 16-bit integer elements of two 256-bit vectors of
1720/// [16 x i16], and returns the lower 16 bits of each 32-bit product in the
1721/// [16 x i16] result.
1722///
1723/// \headerfile <immintrin.h>
1724///
1725/// This intrinsic corresponds to the \c VPMULLW instruction.
1726///
1727/// \param __a
1728/// A 256-bit vector of [16 x i16] containing one of the source operands.
1729/// \param __b
1730/// A 256-bit vector of [16 x i16] containing one of the source operands.
1731/// \returns A 256-bit vector of [16 x i16] containing the products.
4331732static __inline__ __m256i __DEFAULT_FN_ATTRS256
4341733_mm256_mullo_epi16(__m256i __a, __m256i __b)
4351734{
4361735 return (__m256i)((__v16hu)__a * (__v16hu)__b);
4371736}
4381737
1738/// Multiplies signed 32-bit integer elements of two 256-bit vectors of
1739/// [8 x i32], and returns the lower 32 bits of each 64-bit product in the
1740/// [8 x i32] result.
1741///
1742/// \headerfile <immintrin.h>
1743///
1744/// This intrinsic corresponds to the \c VPMULLD instruction.
1745///
1746/// \param __a
1747/// A 256-bit vector of [8 x i32] containing one of the source operands.
1748/// \param __b
1749/// A 256-bit vector of [8 x i32] containing one of the source operands.
1750/// \returns A 256-bit vector of [8 x i32] containing the products.
4391751static __inline__ __m256i __DEFAULT_FN_ATTRS256
4401752_mm256_mullo_epi32 (__m256i __a, __m256i __b)
4411753{
4421754 return (__m256i)((__v8su)__a * (__v8su)__b);
4431755}
4441756
1757/// Multiplies unsigned 32-bit integers from even-numered elements of two
1758/// 256-bit vectors of [8 x i32] and returns the 64-bit products in the
1759/// [4 x i64] result.
1760///
1761/// \code{.operation}
1762/// result[63:0] := __a[31:0] * __b[31:0]
1763/// result[127:64] := __a[95:64] * __b[95:64]
1764/// result[191:128] := __a[159:128] * __b[159:128]
1765/// result[255:192] := __a[223:192] * __b[223:192]
1766/// \endcode
1767///
1768/// \headerfile <immintrin.h>
1769///
1770/// This intrinsic corresponds to the \c VPMULUDQ instruction.
1771///
1772/// \param __a
1773/// A 256-bit vector of [8 x i32] containing one of the source operands.
1774/// \param __b
1775/// A 256-bit vector of [8 x i32] containing one of the source operands.
1776/// \returns A 256-bit vector of [4 x i64] containing the products.
4451777static __inline__ __m256i __DEFAULT_FN_ATTRS256
4461778_mm256_mul_epu32(__m256i __a, __m256i __b)
4471779{
4481780 return __builtin_ia32_pmuludq256((__v8si)__a, (__v8si)__b);
4491781}
4501782
1783/// Computes the bitwise OR of the 256-bit integer vectors in \a __a and
1784/// \a __b.
1785///
1786/// \headerfile <immintrin.h>
1787///
1788/// This intrinsic corresponds to the \c VPOR instruction.
1789///
1790/// \param __a
1791/// A 256-bit integer vector.
1792/// \param __b
1793/// A 256-bit integer vector.
1794/// \returns A 256-bit integer vector containing the result.
4511795static __inline__ __m256i __DEFAULT_FN_ATTRS256
4521796_mm256_or_si256(__m256i __a, __m256i __b)
4531797{
4541798 return (__m256i)((__v4du)__a | (__v4du)__b);
4551799}
4561800
1801/// Computes four sum of absolute difference (SAD) operations on sets of eight
1802/// unsigned 8-bit integers from the 256-bit integer vectors \a __a and
1803/// \a __b.
1804///
1805/// One SAD result is computed for each set of eight bytes from \a __a and
1806/// eight bytes from \a __b. The zero-extended SAD value is returned in the
1807/// corresponding 64-bit element of the result.
1808///
1809/// A single SAD operation takes the differences between the corresponding
1810/// bytes of \a __a and \a __b, takes the absolute value of each difference,
1811/// and sums these eight values to form one 16-bit result. This operation
1812/// is repeated four times with successive sets of eight bytes.
1813///
1814/// \code{.operation}
1815/// FOR i := 0 TO 3
1816/// j := i*64
1817/// temp0 := ABS(__a[j+7:j] - __b[j+7:j])
1818/// temp1 := ABS(__a[j+15:j+8] - __b[j+15:j+8])
1819/// temp2 := ABS(__a[j+23:j+16] - __b[j+23:j+16])
1820/// temp3 := ABS(__a[j+31:j+24] - __b[j+31:j+24])
1821/// temp4 := ABS(__a[j+39:j+32] - __b[j+39:j+32])
1822/// temp5 := ABS(__a[j+47:j+40] - __b[j+47:j+40])
1823/// temp6 := ABS(__a[j+55:j+48] - __b[j+55:j+48])
1824/// temp7 := ABS(__a[j+63:j+56] - __b[j+63:j+56])
1825/// result[j+15:j] := temp0 + temp1 + temp2 + temp3 +
1826/// temp4 + temp5 + temp6 + temp7
1827/// result[j+63:j+16] := 0
1828/// ENDFOR
1829/// \endcode
1830///
1831/// \headerfile <immintrin.h>
1832///
1833/// This intrinsic corresponds to the \c VPSADBW instruction.
1834///
1835/// \param __a
1836/// A 256-bit integer vector.
1837/// \param __b
1838/// A 256-bit integer vector.
1839/// \returns A 256-bit integer vector containing the result.
4571840static __inline__ __m256i __DEFAULT_FN_ATTRS256
4581841_mm256_sad_epu8(__m256i __a, __m256i __b)
4591842{
4601843 return __builtin_ia32_psadbw256((__v32qi)__a, (__v32qi)__b);
4611844}
4621845
1846/// Shuffles 8-bit integers in the 256-bit integer vector \a __a according
1847/// to control information in the 256-bit integer vector \a __b, and
1848/// returns the 256-bit result. In effect there are two separate 128-bit
1849/// shuffles in the lower and upper halves.
1850///
1851/// \code{.operation}
1852/// FOR i := 0 TO 31
1853/// j := i*8
1854/// IF __b[j+7] == 1
1855/// result[j+7:j] := 0
1856/// ELSE
1857/// k := __b[j+3:j] * 8
1858/// IF i > 15
1859/// k := k + 128
1860/// FI
1861/// result[j+7:j] := __a[k+7:k]
1862/// FI
1863/// ENDFOR
1864/// \endcode
1865///
1866/// \headerfile <immintrin.h>
1867///
1868/// This intrinsic corresponds to the \c VPSHUFB instruction.
1869///
1870/// \param __a
1871/// A 256-bit integer vector containing source values.
1872/// \param __b
1873/// A 256-bit integer vector containing control information to determine
1874/// what goes into the corresponding byte of the result. If bit 7 of the
1875/// control byte is 1, the result byte is 0; otherwise, bits 3:0 of the
1876/// control byte specify the index (within the same 128-bit half) of \a __a
1877/// to copy to the result byte.
1878/// \returns A 256-bit integer vector containing the result.
4631879static __inline__ __m256i __DEFAULT_FN_ATTRS256
4641880_mm256_shuffle_epi8(__m256i __a, __m256i __b)
4651881{
4661882 return (__m256i)__builtin_ia32_pshufb256((__v32qi)__a, (__v32qi)__b);
4671883}
4681884
1885/// Shuffles 32-bit integers from the 256-bit vector of [8 x i32] in \a a
1886/// according to control information in the integer literal \a imm, and
1887/// returns the 256-bit result. In effect there are two parallel 128-bit
1888/// shuffles in the lower and upper halves.
1889///
1890/// \code{.operation}
1891/// FOR i := 0 to 3
1892/// j := i*32
1893/// k := (imm >> i*2)[1:0] * 32
1894/// result[j+31:j] := a[k+31:k]
1895/// result[128+j+31:128+j] := a[128+k+31:128+k]
1896/// ENDFOR
1897/// \endcode
1898///
1899/// \headerfile <immintrin.h>
1900///
1901/// \code
1902/// __m256i _mm256_shuffle_epi32(__m256i a, const int imm);
1903/// \endcode
1904///
1905/// This intrinsic corresponds to the \c VPSHUFB instruction.
1906///
1907/// \param a
1908/// A 256-bit vector of [8 x i32] containing source values.
1909/// \param imm
1910/// An immediate 8-bit value specifying which elements to copy from \a a.
1911/// \a imm[1:0] specifies the index in \a a for elements 0 and 4 of the
1912/// result, \a imm[3:2] specifies the index for elements 1 and 5, and so
1913/// forth.
1914/// \returns A 256-bit vector of [8 x i32] containing the result.
4691915#define _mm256_shuffle_epi32(a, imm) \
4701916 ((__m256i)__builtin_ia32_pshufd256((__v8si)(__m256i)(a), (int)(imm)))
4711917
1918/// Shuffles 16-bit integers from the 256-bit vector of [16 x i16] in \a a
1919/// according to control information in the integer literal \a imm, and
1920/// returns the 256-bit result. The upper 64 bits of each 128-bit half
1921/// are shuffled in parallel; the lower 64 bits of each 128-bit half are
1922/// copied from \a a unchanged.
1923///
1924/// \code{.operation}
1925/// result[63:0] := a[63:0]
1926/// result[191:128] := a[191:128]
1927/// FOR i := 0 TO 3
1928/// j := i * 16 + 64
1929/// k := (imm >> i*2)[1:0] * 16 + 64
1930/// result[j+15:j] := a[k+15:k]
1931/// result[128+j+15:128+j] := a[128+k+15:128+k]
1932/// ENDFOR
1933/// \endcode
1934///
1935/// \headerfile <immintrin.h>
1936///
1937/// \code
1938/// __m256i _mm256_shufflehi_epi16(__m256i a, const int imm);
1939/// \endcode
1940///
1941/// This intrinsic corresponds to the \c VPSHUFHW instruction.
1942///
1943/// \param a
1944/// A 256-bit vector of [16 x i16] containing source values.
1945/// \param imm
1946/// An immediate 8-bit value specifying which elements to copy from \a a.
1947/// \a imm[1:0] specifies the index in \a a for elements 4 and 8 of the
1948/// result, \a imm[3:2] specifies the index for elements 5 and 9, and so
1949/// forth. Indexes are offset by 4 (so 0 means index 4, and so forth).
1950/// \returns A 256-bit vector of [16 x i16] containing the result.
4721951#define _mm256_shufflehi_epi16(a, imm) \
4731952 ((__m256i)__builtin_ia32_pshufhw256((__v16hi)(__m256i)(a), (int)(imm)))
4741953
1954/// Shuffles 16-bit integers from the 256-bit vector of [16 x i16] \a a
1955/// according to control information in the integer literal \a imm, and
1956/// returns the 256-bit [16 x i16] result. The lower 64 bits of each
1957/// 128-bit half are shuffled; the upper 64 bits of each 128-bit half are
1958/// copied from \a a unchanged.
1959///
1960/// \code{.operation}
1961/// result[127:64] := a[127:64]
1962/// result[255:192] := a[255:192]
1963/// FOR i := 0 TO 3
1964/// j := i * 16
1965/// k := (imm >> i*2)[1:0] * 16
1966/// result[j+15:j] := a[k+15:k]
1967/// result[128+j+15:128+j] := a[128+k+15:128+k]
1968/// ENDFOR
1969/// \endcode
1970///
1971/// \headerfile <immintrin.h>
1972///
1973/// \code
1974/// __m256i _mm256_shufflelo_epi16(__m256i a, const int imm);
1975/// \endcode
1976///
1977/// This intrinsic corresponds to the \c VPSHUFLW instruction.
1978///
1979/// \param a
1980/// A 256-bit vector of [16 x i16] to use as a source of data for the
1981/// result.
1982/// \param imm
1983/// An immediate 8-bit value specifying which elements to copy from \a a.
1984/// \a imm[1:0] specifies the index in \a a for elements 0 and 8 of the
1985/// result, \a imm[3:2] specifies the index for elements 1 and 9, and so
1986/// forth.
1987/// \returns A 256-bit vector of [16 x i16] containing the result.
4751988#define _mm256_shufflelo_epi16(a, imm) \
4761989 ((__m256i)__builtin_ia32_pshuflw256((__v16hi)(__m256i)(a), (int)(imm)))
4771990
1991/// Sets each byte of the result to the corresponding byte of the 256-bit
1992/// integer vector in \a __a, the negative of that byte, or zero, depending
1993/// on whether the corresponding byte of the 256-bit integer vector in
1994/// \a __b is greater than zero, less than zero, or equal to zero,
1995/// respectively.
1996///
1997/// \headerfile <immintrin.h>
1998///
1999/// This intrinsic corresponds to the \c VPSIGNB instruction.
2000///
2001/// \param __a
2002/// A 256-bit integer vector.
2003/// \param __b
2004/// A 256-bit integer vector].
2005/// \returns A 256-bit integer vector containing the result.
4782006static __inline__ __m256i __DEFAULT_FN_ATTRS256
4792007_mm256_sign_epi8(__m256i __a, __m256i __b)
4802008{
4812009 return (__m256i)__builtin_ia32_psignb256((__v32qi)__a, (__v32qi)__b);
4822010}
4832011
2012/// Sets each element of the result to the corresponding element of the
2013/// 256-bit vector of [16 x i16] in \a __a, the negative of that element,
2014/// or zero, depending on whether the corresponding element of the 256-bit
2015/// vector of [16 x i16] in \a __b is greater than zero, less than zero, or
2016/// equal to zero, respectively.
2017///
2018/// \headerfile <immintrin.h>
2019///
2020/// This intrinsic corresponds to the \c VPSIGNW instruction.
2021///
2022/// \param __a
2023/// A 256-bit vector of [16 x i16].
2024/// \param __b
2025/// A 256-bit vector of [16 x i16].
2026/// \returns A 256-bit vector of [16 x i16] containing the result.
4842027static __inline__ __m256i __DEFAULT_FN_ATTRS256
4852028_mm256_sign_epi16(__m256i __a, __m256i __b)
4862029{
4872030 return (__m256i)__builtin_ia32_psignw256((__v16hi)__a, (__v16hi)__b);
4882031}
4892032
2033/// Sets each element of the result to the corresponding element of the
2034/// 256-bit vector of [8 x i32] in \a __a, the negative of that element, or
2035/// zero, depending on whether the corresponding element of the 256-bit
2036/// vector of [8 x i32] in \a __b is greater than zero, less than zero, or
2037/// equal to zero, respectively.
2038///
2039/// \headerfile <immintrin.h>
2040///
2041/// This intrinsic corresponds to the \c VPSIGND instruction.
2042///
2043/// \param __a
2044/// A 256-bit vector of [8 x i32].
2045/// \param __b
2046/// A 256-bit vector of [8 x i32].
2047/// \returns A 256-bit vector of [8 x i32] containing the result.
4902048static __inline__ __m256i __DEFAULT_FN_ATTRS256
4912049_mm256_sign_epi32(__m256i __a, __m256i __b)
4922050{
4932051 return (__m256i)__builtin_ia32_psignd256((__v8si)__a, (__v8si)__b);
4942052}
4952053
2054/// Shifts each 128-bit half of the 256-bit integer vector \a a left by
2055/// \a imm bytes, shifting in zero bytes, and returns the result. If \a imm
2056/// is greater than 15, the returned result is all zeroes.
2057///
2058/// \headerfile <immintrin.h>
2059///
2060/// \code
2061/// __m256i _mm256_slli_si256(__m256i a, const int imm);
2062/// \endcode
2063///
2064/// This intrinsic corresponds to the \c VPSLLDQ instruction.
2065///
2066/// \param a
2067/// A 256-bit integer vector to be shifted.
2068/// \param imm
2069/// An unsigned immediate value specifying the shift count (in bytes).
2070/// \returns A 256-bit integer vector containing the result.
4962071#define _mm256_slli_si256(a, imm) \
4972072 ((__m256i)__builtin_ia32_pslldqi256_byteshift((__v4di)(__m256i)(a), (int)(imm)))
4982073
2074/// Shifts each 128-bit half of the 256-bit integer vector \a a left by
2075/// \a imm bytes, shifting in zero bytes, and returns the result. If \a imm
2076/// is greater than 15, the returned result is all zeroes.
2077///
2078/// \headerfile <immintrin.h>
2079///
2080/// \code
2081/// __m256i _mm256_bslli_epi128(__m256i a, const int imm);
2082/// \endcode
2083///
2084/// This intrinsic corresponds to the \c VPSLLDQ instruction.
2085///
2086/// \param a
2087/// A 256-bit integer vector to be shifted.
2088/// \param imm
2089/// An unsigned immediate value specifying the shift count (in bytes).
2090/// \returns A 256-bit integer vector containing the result.
4992091#define _mm256_bslli_epi128(a, imm) \
5002092 ((__m256i)__builtin_ia32_pslldqi256_byteshift((__v4di)(__m256i)(a), (int)(imm)))
5012093
2094/// Shifts each 16-bit element of the 256-bit vector of [16 x i16] in \a __a
2095/// left by \a __count bits, shifting in zero bits, and returns the result.
2096/// If \a __count is greater than 15, the returned result is all zeroes.
2097///
2098/// \headerfile <immintrin.h>
2099///
2100/// This intrinsic corresponds to the \c VPSLLW instruction.
2101///
2102/// \param __a
2103/// A 256-bit vector of [16 x i16] to be shifted.
2104/// \param __count
2105/// An unsigned integer value specifying the shift count (in bits).
2106/// \returns A 256-bit vector of [16 x i16] containing the result.
5022107static __inline__ __m256i __DEFAULT_FN_ATTRS256
5032108_mm256_slli_epi16(__m256i __a, int __count)
5042109{
5052110 return (__m256i)__builtin_ia32_psllwi256((__v16hi)__a, __count);
5062111}
5072112
2113/// Shifts each 16-bit element of the 256-bit vector of [16 x i16] in \a __a
2114/// left by the number of bits specified by the lower 64 bits of \a __count,
2115/// shifting in zero bits, and returns the result. If \a __count is greater
2116/// than 15, the returned result is all zeroes.
2117///
2118/// \headerfile <immintrin.h>
2119///
2120/// This intrinsic corresponds to the \c VPSLLW instruction.
2121///
2122/// \param __a
2123/// A 256-bit vector of [16 x i16] to be shifted.
2124/// \param __count
2125/// A 128-bit vector of [2 x i64] whose lower element gives the unsigned
2126/// shift count (in bits). The upper element is ignored.
2127/// \returns A 256-bit vector of [16 x i16] containing the result.
5082128static __inline__ __m256i __DEFAULT_FN_ATTRS256
5092129_mm256_sll_epi16(__m256i __a, __m128i __count)
5102130{
5112131 return (__m256i)__builtin_ia32_psllw256((__v16hi)__a, (__v8hi)__count);
5122132}
5132133
2134/// Shifts each 32-bit element of the 256-bit vector of [8 x i32] in \a __a
2135/// left by \a __count bits, shifting in zero bits, and returns the result.
2136/// If \a __count is greater than 31, the returned result is all zeroes.
2137///
2138/// \headerfile <immintrin.h>
2139///
2140/// This intrinsic corresponds to the \c VPSLLD instruction.
2141///
2142/// \param __a
2143/// A 256-bit vector of [8 x i32] to be shifted.
2144/// \param __count
2145/// An unsigned integer value specifying the shift count (in bits).
2146/// \returns A 256-bit vector of [8 x i32] containing the result.
5142147static __inline__ __m256i __DEFAULT_FN_ATTRS256
5152148_mm256_slli_epi32(__m256i __a, int __count)
5162149{
5172150 return (__m256i)__builtin_ia32_pslldi256((__v8si)__a, __count);
5182151}
5192152
2153/// Shifts each 32-bit element of the 256-bit vector of [8 x i32] in \a __a
2154/// left by the number of bits given in the lower 64 bits of \a __count,
2155/// shifting in zero bits, and returns the result. If \a __count is greater
2156/// than 31, the returned result is all zeroes.
2157///
2158/// \headerfile <immintrin.h>
2159///
2160/// This intrinsic corresponds to the \c VPSLLD instruction.
2161///
2162/// \param __a
2163/// A 256-bit vector of [8 x i32] to be shifted.
2164/// \param __count
2165/// A 128-bit vector of [2 x i64] whose lower element gives the unsigned
2166/// shift count (in bits). The upper element is ignored.
2167/// \returns A 256-bit vector of [8 x i32] containing the result.
5202168static __inline__ __m256i __DEFAULT_FN_ATTRS256
5212169_mm256_sll_epi32(__m256i __a, __m128i __count)
5222170{
5232171 return (__m256i)__builtin_ia32_pslld256((__v8si)__a, (__v4si)__count);
5242172}
5252173
2174/// Shifts each 64-bit element of the 256-bit vector of [4 x i64] in \a __a
2175/// left by \a __count bits, shifting in zero bits, and returns the result.
2176/// If \a __count is greater than 63, the returned result is all zeroes.
2177///
2178/// \headerfile <immintrin.h>
2179///
2180/// This intrinsic corresponds to the \c VPSLLQ instruction.
2181///
2182/// \param __a
2183/// A 256-bit vector of [4 x i64] to be shifted.
2184/// \param __count
2185/// An unsigned integer value specifying the shift count (in bits).
2186/// \returns A 256-bit vector of [4 x i64] containing the result.
5262187static __inline__ __m256i __DEFAULT_FN_ATTRS256
5272188_mm256_slli_epi64(__m256i __a, int __count)
5282189{
5292190 return __builtin_ia32_psllqi256((__v4di)__a, __count);
5302191}
5312192
2193/// Shifts each 64-bit element of the 256-bit vector of [4 x i64] in \a __a
2194/// left by the number of bits given in the lower 64 bits of \a __count,
2195/// shifting in zero bits, and returns the result. If \a __count is greater
2196/// than 63, the returned result is all zeroes.
2197///
2198/// \headerfile <immintrin.h>
2199///
2200/// This intrinsic corresponds to the \c VPSLLQ instruction.
2201///
2202/// \param __a
2203/// A 256-bit vector of [4 x i64] to be shifted.
2204/// \param __count
2205/// A 128-bit vector of [2 x i64] whose lower element gives the unsigned
2206/// shift count (in bits). The upper element is ignored.
2207/// \returns A 256-bit vector of [4 x i64] containing the result.
5322208static __inline__ __m256i __DEFAULT_FN_ATTRS256
5332209_mm256_sll_epi64(__m256i __a, __m128i __count)
5342210{
5352211 return __builtin_ia32_psllq256((__v4di)__a, __count);
5362212}
5372213
2214/// Shifts each 16-bit element of the 256-bit vector of [16 x i16] in \a __a
2215/// right by \a __count bits, shifting in sign bits, and returns the result.
2216/// If \a __count is greater than 15, each element of the result is either
2217/// 0 or -1 according to the corresponding input sign bit.
2218///
2219/// \headerfile <immintrin.h>
2220///
2221/// This intrinsic corresponds to the \c VPSRAW instruction.
2222///
2223/// \param __a
2224/// A 256-bit vector of [16 x i16] to be shifted.
2225/// \param __count
2226/// An unsigned integer value specifying the shift count (in bits).
2227/// \returns A 256-bit vector of [16 x i16] containing the result.
5382228static __inline__ __m256i __DEFAULT_FN_ATTRS256
5392229_mm256_srai_epi16(__m256i __a, int __count)
5402230{
5412231 return (__m256i)__builtin_ia32_psrawi256((__v16hi)__a, __count);
5422232}
5432233
2234/// Shifts each 16-bit element of the 256-bit vector of [16 x i16] in \a __a
2235/// right by the number of bits given in the lower 64 bits of \a __count,
2236/// shifting in sign bits, and returns the result. If \a __count is greater
2237/// than 15, each element of the result is either 0 or -1 according to the
2238/// corresponding input sign bit.
2239///
2240/// \headerfile <immintrin.h>
2241///
2242/// This intrinsic corresponds to the \c VPSRAW instruction.
2243///
2244/// \param __a
2245/// A 256-bit vector of [16 x i16] to be shifted.
2246/// \param __count
2247/// A 128-bit vector of [2 x i64] whose lower element gives the unsigned
2248/// shift count (in bits). The upper element is ignored.
2249/// \returns A 256-bit vector of [16 x i16] containing the result.
5442250static __inline__ __m256i __DEFAULT_FN_ATTRS256
5452251_mm256_sra_epi16(__m256i __a, __m128i __count)
5462252{
5472253 return (__m256i)__builtin_ia32_psraw256((__v16hi)__a, (__v8hi)__count);
5482254}
5492255
2256/// Shifts each 32-bit element of the 256-bit vector of [8 x i32] in \a __a
2257/// right by \a __count bits, shifting in sign bits, and returns the result.
2258/// If \a __count is greater than 31, each element of the result is either
2259/// 0 or -1 according to the corresponding input sign bit.
2260///
2261/// \headerfile <immintrin.h>
2262///
2263/// This intrinsic corresponds to the \c VPSRAD instruction.
2264///
2265/// \param __a
2266/// A 256-bit vector of [8 x i32] to be shifted.
2267/// \param __count
2268/// An unsigned integer value specifying the shift count (in bits).
2269/// \returns A 256-bit vector of [8 x i32] containing the result.
5502270static __inline__ __m256i __DEFAULT_FN_ATTRS256
5512271_mm256_srai_epi32(__m256i __a, int __count)
5522272{
5532273 return (__m256i)__builtin_ia32_psradi256((__v8si)__a, __count);
5542274}
5552275
2276/// Shifts each 32-bit element of the 256-bit vector of [8 x i32] in \a __a
2277/// right by the number of bits given in the lower 64 bits of \a __count,
2278/// shifting in sign bits, and returns the result. If \a __count is greater
2279/// than 31, each element of the result is either 0 or -1 according to the
2280/// corresponding input sign bit.
2281///
2282/// \headerfile <immintrin.h>
2283///
2284/// This intrinsic corresponds to the \c VPSRAD instruction.
2285///
2286/// \param __a
2287/// A 256-bit vector of [8 x i32] to be shifted.
2288/// \param __count
2289/// A 128-bit vector of [2 x i64] whose lower element gives the unsigned
2290/// shift count (in bits). The upper element is ignored.
2291/// \returns A 256-bit vector of [8 x i32] containing the result.
5562292static __inline__ __m256i __DEFAULT_FN_ATTRS256
5572293_mm256_sra_epi32(__m256i __a, __m128i __count)
5582294{
5592295 return (__m256i)__builtin_ia32_psrad256((__v8si)__a, (__v4si)__count);
5602296}
5612297
2298/// Shifts each 128-bit half of the 256-bit integer vector in \a a right by
2299/// \a imm bytes, shifting in zero bytes, and returns the result. If
2300/// \a imm is greater than 15, the returned result is all zeroes.
2301///
2302/// \headerfile <immintrin.h>
2303///
2304/// \code
2305/// __m256i _mm256_srli_si256(__m256i a, const int imm);
2306/// \endcode
2307///
2308/// This intrinsic corresponds to the \c VPSRLDQ instruction.
2309///
2310/// \param a
2311/// A 256-bit integer vector to be shifted.
2312/// \param imm
2313/// An unsigned immediate value specifying the shift count (in bytes).
2314/// \returns A 256-bit integer vector containing the result.
5622315#define _mm256_srli_si256(a, imm) \
5632316 ((__m256i)__builtin_ia32_psrldqi256_byteshift((__m256i)(a), (int)(imm)))
5642317
2318/// Shifts each 128-bit half of the 256-bit integer vector in \a a right by
2319/// \a imm bytes, shifting in zero bytes, and returns the result. If
2320/// \a imm is greater than 15, the returned result is all zeroes.
2321///
2322/// \headerfile <immintrin.h>
2323///
2324/// \code
2325/// __m256i _mm256_bsrli_epi128(__m256i a, const int imm);
2326/// \endcode
2327///
2328/// This intrinsic corresponds to the \c VPSRLDQ instruction.
2329///
2330/// \param a
2331/// A 256-bit integer vector to be shifted.
2332/// \param imm
2333/// An unsigned immediate value specifying the shift count (in bytes).
2334/// \returns A 256-bit integer vector containing the result.
5652335#define _mm256_bsrli_epi128(a, imm) \
5662336 ((__m256i)__builtin_ia32_psrldqi256_byteshift((__m256i)(a), (int)(imm)))
5672337
2338/// Shifts each 16-bit element of the 256-bit vector of [16 x i16] in \a __a
2339/// right by \a __count bits, shifting in zero bits, and returns the result.
2340/// If \a __count is greater than 15, the returned result is all zeroes.
2341///
2342/// \headerfile <immintrin.h>
2343///
2344/// This intrinsic corresponds to the \c VPSRLW instruction.
2345///
2346/// \param __a
2347/// A 256-bit vector of [16 x i16] to be shifted.
2348/// \param __count
2349/// An unsigned integer value specifying the shift count (in bits).
2350/// \returns A 256-bit vector of [16 x i16] containing the result.
5682351static __inline__ __m256i __DEFAULT_FN_ATTRS256
5692352_mm256_srli_epi16(__m256i __a, int __count)
5702353{
5712354 return (__m256i)__builtin_ia32_psrlwi256((__v16hi)__a, __count);
5722355}
5732356
2357/// Shifts each 16-bit element of the 256-bit vector of [16 x i16] in \a __a
2358/// right by the number of bits given in the lower 64 bits of \a __count,
2359/// shifting in zero bits, and returns the result. If \a __count is greater
2360/// than 15, the returned result is all zeroes.
2361///
2362/// \headerfile <immintrin.h>
2363///
2364/// This intrinsic corresponds to the \c VPSRLW instruction.
2365///
2366/// \param __a
2367/// A 256-bit vector of [16 x i16] to be shifted.
2368/// \param __count
2369/// A 128-bit vector of [2 x i64] whose lower element gives the unsigned
2370/// shift count (in bits). The upper element is ignored.
2371/// \returns A 256-bit vector of [16 x i16] containing the result.
5742372static __inline__ __m256i __DEFAULT_FN_ATTRS256
5752373_mm256_srl_epi16(__m256i __a, __m128i __count)
5762374{
5772375 return (__m256i)__builtin_ia32_psrlw256((__v16hi)__a, (__v8hi)__count);
5782376}
5792377
2378/// Shifts each 32-bit element of the 256-bit vector of [8 x i32] in \a __a
2379/// right by \a __count bits, shifting in zero bits, and returns the result.
2380/// If \a __count is greater than 31, the returned result is all zeroes.
2381///
2382/// \headerfile <immintrin.h>
2383///
2384/// This intrinsic corresponds to the \c VPSRLD instruction.
2385///
2386/// \param __a
2387/// A 256-bit vector of [8 x i32] to be shifted.
2388/// \param __count
2389/// An unsigned integer value specifying the shift count (in bits).
2390/// \returns A 256-bit vector of [8 x i32] containing the result.
5802391static __inline__ __m256i __DEFAULT_FN_ATTRS256
5812392_mm256_srli_epi32(__m256i __a, int __count)
5822393{
5832394 return (__m256i)__builtin_ia32_psrldi256((__v8si)__a, __count);
5842395}
5852396
2397/// Shifts each 32-bit element of the 256-bit vector of [8 x i32] in \a __a
2398/// right by the number of bits given in the lower 64 bits of \a __count,
2399/// shifting in zero bits, and returns the result. If \a __count is greater
2400/// than 31, the returned result is all zeroes.
2401///
2402/// \headerfile <immintrin.h>
2403///
2404/// This intrinsic corresponds to the \c VPSRLD instruction.
2405///
2406/// \param __a
2407/// A 256-bit vector of [8 x i32] to be shifted.
2408/// \param __count
2409/// A 128-bit vector of [2 x i64] whose lower element gives the unsigned
2410/// shift count (in bits). The upper element is ignored.
2411/// \returns A 256-bit vector of [8 x i32] containing the result.
5862412static __inline__ __m256i __DEFAULT_FN_ATTRS256
5872413_mm256_srl_epi32(__m256i __a, __m128i __count)
5882414{
5892415 return (__m256i)__builtin_ia32_psrld256((__v8si)__a, (__v4si)__count);
5902416}
5912417
2418/// Shifts each 64-bit element of the 256-bit vector of [4 x i64] in \a __a
2419/// right by \a __count bits, shifting in zero bits, and returns the result.
2420/// If \a __count is greater than 63, the returned result is all zeroes.
2421///
2422/// \headerfile <immintrin.h>
2423///
2424/// This intrinsic corresponds to the \c VPSRLQ instruction.
2425///
2426/// \param __a
2427/// A 256-bit vector of [4 x i64] to be shifted.
2428/// \param __count
2429/// An unsigned integer value specifying the shift count (in bits).
2430/// \returns A 256-bit vector of [4 x i64] containing the result.
5922431static __inline__ __m256i __DEFAULT_FN_ATTRS256
5932432_mm256_srli_epi64(__m256i __a, int __count)
5942433{
5952434 return __builtin_ia32_psrlqi256((__v4di)__a, __count);
5962435}
5972436
2437/// Shifts each 64-bit element of the 256-bit vector of [4 x i64] in \a __a
2438/// right by the number of bits given in the lower 64 bits of \a __count,
2439/// shifting in zero bits, and returns the result. If \a __count is greater
2440/// than 63, the returned result is all zeroes.
2441///
2442/// \headerfile <immintrin.h>
2443///
2444/// This intrinsic corresponds to the \c VPSRLQ instruction.
2445///
2446/// \param __a
2447/// A 256-bit vector of [4 x i64] to be shifted.
2448/// \param __count
2449/// A 128-bit vector of [2 x i64] whose lower element gives the unsigned
2450/// shift count (in bits). The upper element is ignored.
2451/// \returns A 256-bit vector of [4 x i64] containing the result.
5982452static __inline__ __m256i __DEFAULT_FN_ATTRS256
5992453_mm256_srl_epi64(__m256i __a, __m128i __count)
6002454{
6012455 return __builtin_ia32_psrlq256((__v4di)__a, __count);
6022456}
6032457
2458/// Subtracts 8-bit integers from corresponding bytes of two 256-bit integer
2459/// vectors. Returns the lower 8 bits of each difference in the
2460/// corresponding byte of the 256-bit integer vector result (overflow is
2461/// ignored).
2462///
2463/// \code{.operation}
2464/// FOR i := 0 TO 31
2465/// j := i*8
2466/// result[j+7:j] := __a[j+7:j] - __b[j+7:j]
2467/// ENDFOR
2468/// \endcode
2469///
2470/// \headerfile <immintrin.h>
2471///
2472/// This intrinsic corresponds to the \c VPSUBB instruction.
2473///
2474/// \param __a
2475/// A 256-bit integer vector containing the minuends.
2476/// \param __b
2477/// A 256-bit integer vector containing the subtrahends.
2478/// \returns A 256-bit integer vector containing the differences.
6042479static __inline__ __m256i __DEFAULT_FN_ATTRS256
6052480_mm256_sub_epi8(__m256i __a, __m256i __b)
6062481{
6072482 return (__m256i)((__v32qu)__a - (__v32qu)__b);
6082483}
6092484
2485/// Subtracts 16-bit integers from corresponding elements of two 256-bit
2486/// vectors of [16 x i16]. Returns the lower 16 bits of each difference in
2487/// the corresponding element of the [16 x i16] result (overflow is
2488/// ignored).
2489///
2490/// \code{.operation}
2491/// FOR i := 0 TO 15
2492/// j := i*16
2493/// result[j+15:j] := __a[j+15:j] - __b[j+15:j]
2494/// ENDFOR
2495/// \endcode
2496///
2497/// \headerfile <immintrin.h>
2498///
2499/// This intrinsic corresponds to the \c VPSUBW instruction.
2500///
2501/// \param __a
2502/// A 256-bit vector of [16 x i16] containing the minuends.
2503/// \param __b
2504/// A 256-bit vector of [16 x i16] containing the subtrahends.
2505/// \returns A 256-bit vector of [16 x i16] containing the differences.
6102506static __inline__ __m256i __DEFAULT_FN_ATTRS256
6112507_mm256_sub_epi16(__m256i __a, __m256i __b)
6122508{
6132509 return (__m256i)((__v16hu)__a - (__v16hu)__b);
6142510}
6152511
2512/// Subtracts 32-bit integers from corresponding elements of two 256-bit
2513/// vectors of [8 x i32]. Returns the lower 32 bits of each difference in
2514/// the corresponding element of the [8 x i32] result (overflow is ignored).
2515///
2516/// \code{.operation}
2517/// FOR i := 0 TO 7
2518/// j := i*32
2519/// result[j+31:j] := __a[j+31:j] - __b[j+31:j]
2520/// ENDFOR
2521/// \endcode
2522///
2523/// \headerfile <immintrin.h>
2524///
2525/// This intrinsic corresponds to the \c VPSUBD instruction.
2526///
2527/// \param __a
2528/// A 256-bit vector of [8 x i32] containing the minuends.
2529/// \param __b
2530/// A 256-bit vector of [8 x i32] containing the subtrahends.
2531/// \returns A 256-bit vector of [8 x i32] containing the differences.
6162532static __inline__ __m256i __DEFAULT_FN_ATTRS256
6172533_mm256_sub_epi32(__m256i __a, __m256i __b)
6182534{
6192535 return (__m256i)((__v8su)__a - (__v8su)__b);
6202536}
6212537
2538/// Subtracts 64-bit integers from corresponding elements of two 256-bit
2539/// vectors of [4 x i64]. Returns the lower 64 bits of each difference in
2540/// the corresponding element of the [4 x i64] result (overflow is ignored).
2541///
2542/// \code{.operation}
2543/// FOR i := 0 TO 3
2544/// j := i*64
2545/// result[j+63:j] := __a[j+63:j] - __b[j+63:j]
2546/// ENDFOR
2547/// \endcode
2548///
2549/// \headerfile <immintrin.h>
2550///
2551/// This intrinsic corresponds to the \c VPSUBQ instruction.
2552///
2553/// \param __a
2554/// A 256-bit vector of [4 x i64] containing the minuends.
2555/// \param __b
2556/// A 256-bit vector of [4 x i64] containing the subtrahends.
2557/// \returns A 256-bit vector of [4 x i64] containing the differences.
6222558static __inline__ __m256i __DEFAULT_FN_ATTRS256
6232559_mm256_sub_epi64(__m256i __a, __m256i __b)
6242560{
6252561 return (__m256i)((__v4du)__a - (__v4du)__b);
6262562}
6272563
2564/// Subtracts 8-bit integers from corresponding bytes of two 256-bit integer
2565/// vectors using signed saturation, and returns each differences in the
2566/// corresponding byte of the 256-bit integer vector result.
2567///
2568/// \code{.operation}
2569/// FOR i := 0 TO 31
2570/// j := i*8
2571/// result[j+7:j] := SATURATE8(__a[j+7:j] - __b[j+7:j])
2572/// ENDFOR
2573/// \endcode
2574///
2575/// \headerfile <immintrin.h>
2576///
2577/// This intrinsic corresponds to the \c VPSUBSB instruction.
2578///
2579/// \param __a
2580/// A 256-bit integer vector containing the minuends.
2581/// \param __b
2582/// A 256-bit integer vector containing the subtrahends.
2583/// \returns A 256-bit integer vector containing the differences.
6282584static __inline__ __m256i __DEFAULT_FN_ATTRS256
6292585_mm256_subs_epi8(__m256i __a, __m256i __b)
6302586{
6312587 return (__m256i)__builtin_elementwise_sub_sat((__v32qs)__a, (__v32qs)__b);
6322588}
6332589
2590/// Subtracts 16-bit integers from corresponding elements of two 256-bit
2591/// vectors of [16 x i16] using signed saturation, and returns each
2592/// difference in the corresponding element of the [16 x i16] result.
2593///
2594/// \code{.operation}
2595/// FOR i := 0 TO 15
2596/// j := i*16
2597/// result[j+7:j] := SATURATE16(__a[j+7:j] - __b[j+7:j])
2598/// ENDFOR
2599/// \endcode
2600///
2601/// \headerfile <immintrin.h>
2602///
2603/// This intrinsic corresponds to the \c VPSUBSW instruction.
2604///
2605/// \param __a
2606/// A 256-bit vector of [16 x i16] containing the minuends.
2607/// \param __b
2608/// A 256-bit vector of [16 x i16] containing the subtrahends.
2609/// \returns A 256-bit vector of [16 x i16] containing the differences.
6342610static __inline__ __m256i __DEFAULT_FN_ATTRS256
6352611_mm256_subs_epi16(__m256i __a, __m256i __b)
6362612{
6372613 return (__m256i)__builtin_elementwise_sub_sat((__v16hi)__a, (__v16hi)__b);
6382614}
6392615
2616/// Subtracts 8-bit integers from corresponding bytes of two 256-bit integer
2617/// vectors using unsigned saturation, and returns each difference in the
2618/// corresponding byte of the 256-bit integer vector result. For each byte,
2619/// computes <c> result = __a - __b </c>.
2620///
2621/// \code{.operation}
2622/// FOR i := 0 TO 31
2623/// j := i*8
2624/// result[j+7:j] := SATURATE8U(__a[j+7:j] - __b[j+7:j])
2625/// ENDFOR
2626/// \endcode
2627///
2628/// \headerfile <immintrin.h>
2629///
2630/// This intrinsic corresponds to the \c VPSUBUSB instruction.
2631///
2632/// \param __a
2633/// A 256-bit integer vector containing the minuends.
2634/// \param __b
2635/// A 256-bit integer vector containing the subtrahends.
2636/// \returns A 256-bit integer vector containing the differences.
6402637static __inline__ __m256i __DEFAULT_FN_ATTRS256
6412638_mm256_subs_epu8(__m256i __a, __m256i __b)
6422639{
6432640 return (__m256i)__builtin_elementwise_sub_sat((__v32qu)__a, (__v32qu)__b);
6442641}
6452642
2643/// Subtracts 16-bit integers from corresponding elements of two 256-bit
2644/// vectors of [16 x i16] using unsigned saturation, and returns each
2645/// difference in the corresponding element of the [16 x i16] result.
2646///
2647/// \code{.operation}
2648/// FOR i := 0 TO 15
2649/// j := i*16
2650/// result[j+15:j] := SATURATE16U(__a[j+15:j] - __b[j+15:j])
2651/// ENDFOR
2652/// \endcode
2653///
2654/// \headerfile <immintrin.h>
2655///
2656/// This intrinsic corresponds to the \c VPSUBUSW instruction.
2657///
2658/// \param __a
2659/// A 256-bit vector of [16 x i16] containing the minuends.
2660/// \param __b
2661/// A 256-bit vector of [16 x i16] containing the subtrahends.
2662/// \returns A 256-bit vector of [16 x i16] containing the differences.
6462663static __inline__ __m256i __DEFAULT_FN_ATTRS256
6472664_mm256_subs_epu16(__m256i __a, __m256i __b)
6482665{
6492666 return (__m256i)__builtin_elementwise_sub_sat((__v16hu)__a, (__v16hu)__b);
6502667}
6512668
2669/// Unpacks and interleaves 8-bit integers from parts of the 256-bit integer
2670/// vectors in \a __a and \a __b to form the 256-bit result. Specifically,
2671/// uses the upper 64 bits of each 128-bit half of \a __a and \a __b as
2672/// input; other bits in these parameters are ignored.
2673///
2674/// \code{.operation}
2675/// result[7:0] := __a[71:64]
2676/// result[15:8] := __b[71:64]
2677/// result[23:16] := __a[79:72]
2678/// result[31:24] := __b[79:72]
2679/// . . .
2680/// result[127:120] := __b[127:120]
2681/// result[135:128] := __a[199:192]
2682/// . . .
2683/// result[255:248] := __b[255:248]
2684/// \endcode
2685///
2686/// \headerfile <immintrin.h>
2687///
2688/// This intrinsic corresponds to the \c VPUNPCKHBW instruction.
2689///
2690/// \param __a
2691/// A 256-bit integer vector used as the source for the even-numbered bytes
2692/// of the result.
2693/// \param __b
2694/// A 256-bit integer vector used as the source for the odd-numbered bytes
2695/// of the result.
2696/// \returns A 256-bit integer vector containing the result.
6522697static __inline__ __m256i __DEFAULT_FN_ATTRS256
6532698_mm256_unpackhi_epi8(__m256i __a, __m256i __b)
6542699{
6552700 return (__m256i)__builtin_shufflevector((__v32qi)__a, (__v32qi)__b, 8, 32+8, 9, 32+9, 10, 32+10, 11, 32+11, 12, 32+12, 13, 32+13, 14, 32+14, 15, 32+15, 24, 32+24, 25, 32+25, 26, 32+26, 27, 32+27, 28, 32+28, 29, 32+29, 30, 32+30, 31, 32+31);
6562701}
6572702
2703/// Unpacks and interleaves 16-bit integers from parts of the 256-bit vectors
2704/// of [16 x i16] in \a __a and \a __b to return the resulting 256-bit
2705/// vector of [16 x i16]. Specifically, uses the upper 64 bits of each
2706/// 128-bit half of \a __a and \a __b as input; other bits in these
2707/// parameters are ignored.
2708///
2709/// \code{.operation}
2710/// result[15:0] := __a[79:64]
2711/// result[31:16] := __b[79:64]
2712/// result[47:32] := __a[95:80]
2713/// result[63:48] := __b[95:80]
2714/// . . .
2715/// result[127:112] := __b[127:112]
2716/// result[143:128] := __a[211:196]
2717/// . . .
2718/// result[255:240] := __b[255:240]
2719/// \endcode
2720///
2721/// \headerfile <immintrin.h>
2722///
2723/// This intrinsic corresponds to the \c VPUNPCKHWD instruction.
2724///
2725/// \param __a
2726/// A 256-bit vector of [16 x i16] used as the source for the even-numbered
2727/// elements of the result.
2728/// \param __b
2729/// A 256-bit vector of [16 x i16] used as the source for the odd-numbered
2730/// elements of the result.
2731/// \returns A 256-bit vector of [16 x i16] containing the result.
6582732static __inline__ __m256i __DEFAULT_FN_ATTRS256
6592733_mm256_unpackhi_epi16(__m256i __a, __m256i __b)
6602734{
6612735 return (__m256i)__builtin_shufflevector((__v16hi)__a, (__v16hi)__b, 4, 16+4, 5, 16+5, 6, 16+6, 7, 16+7, 12, 16+12, 13, 16+13, 14, 16+14, 15, 16+15);
6622736}
6632737
2738/// Unpacks and interleaves 32-bit integers from parts of the 256-bit vectors
2739/// of [8 x i32] in \a __a and \a __b to return the resulting 256-bit vector
2740/// of [8 x i32]. Specifically, uses the upper 64 bits of each 128-bit half
2741/// of \a __a and \a __b as input; other bits in these parameters are
2742/// ignored.
2743///
2744/// \code{.operation}
2745/// result[31:0] := __a[95:64]
2746/// result[63:32] := __b[95:64]
2747/// result[95:64] := __a[127:96]
2748/// result[127:96] := __b[127:96]
2749/// result[159:128] := __a[223:192]
2750/// result[191:160] := __b[223:192]
2751/// result[223:192] := __a[255:224]
2752/// result[255:224] := __b[255:224]
2753/// \endcode
2754///
2755/// \headerfile <immintrin.h>
2756///
2757/// This intrinsic corresponds to the \c VPUNPCKHDQ instruction.
2758///
2759/// \param __a
2760/// A 256-bit vector of [8 x i32] used as the source for the even-numbered
2761/// elements of the result.
2762/// \param __b
2763/// A 256-bit vector of [8 x i32] used as the source for the odd-numbered
2764/// elements of the result.
2765/// \returns A 256-bit vector of [8 x i32] containing the result.
6642766static __inline__ __m256i __DEFAULT_FN_ATTRS256
6652767_mm256_unpackhi_epi32(__m256i __a, __m256i __b)
6662768{
6672769 return (__m256i)__builtin_shufflevector((__v8si)__a, (__v8si)__b, 2, 8+2, 3, 8+3, 6, 8+6, 7, 8+7);
6682770}
6692771
2772/// Unpacks and interleaves 64-bit integers from parts of the 256-bit vectors
2773/// of [4 x i64] in \a __a and \a __b to return the resulting 256-bit vector
2774/// of [4 x i64]. Specifically, uses the upper 64 bits of each 128-bit half
2775/// of \a __a and \a __b as input; other bits in these parameters are
2776/// ignored.
2777///
2778/// \code{.operation}
2779/// result[63:0] := __a[127:64]
2780/// result[127:64] := __b[127:64]
2781/// result[191:128] := __a[255:192]
2782/// result[255:192] := __b[255:192]
2783/// \endcode
2784///
2785/// \headerfile <immintrin.h>
2786///
2787/// This intrinsic corresponds to the \c VPUNPCKHQDQ instruction.
2788///
2789/// \param __a
2790/// A 256-bit vector of [4 x i64] used as the source for the even-numbered
2791/// elements of the result.
2792/// \param __b
2793/// A 256-bit vector of [4 x i64] used as the source for the odd-numbered
2794/// elements of the result.
2795/// \returns A 256-bit vector of [4 x i64] containing the result.
6702796static __inline__ __m256i __DEFAULT_FN_ATTRS256
6712797_mm256_unpackhi_epi64(__m256i __a, __m256i __b)
6722798{
6732799 return (__m256i)__builtin_shufflevector((__v4di)__a, (__v4di)__b, 1, 4+1, 3, 4+3);
6742800}
6752801
2802/// Unpacks and interleaves 8-bit integers from parts of the 256-bit integer
2803/// vectors in \a __a and \a __b to form the 256-bit result. Specifically,
2804/// uses the lower 64 bits of each 128-bit half of \a __a and \a __b as
2805/// input; other bits in these parameters are ignored.
2806///
2807/// \code{.operation}
2808/// result[7:0] := __a[7:0]
2809/// result[15:8] := __b[7:0]
2810/// result[23:16] := __a[15:8]
2811/// result[31:24] := __b[15:8]
2812/// . . .
2813/// result[127:120] := __b[63:56]
2814/// result[135:128] := __a[135:128]
2815/// . . .
2816/// result[255:248] := __b[191:184]
2817/// \endcode
2818///
2819/// \headerfile <immintrin.h>
2820///
2821/// This intrinsic corresponds to the \c VPUNPCKLBW instruction.
2822///
2823/// \param __a
2824/// A 256-bit integer vector used as the source for the even-numbered bytes
2825/// of the result.
2826/// \param __b
2827/// A 256-bit integer vector used as the source for the odd-numbered bytes
2828/// of the result.
2829/// \returns A 256-bit integer vector containing the result.
6762830static __inline__ __m256i __DEFAULT_FN_ATTRS256
6772831_mm256_unpacklo_epi8(__m256i __a, __m256i __b)
6782832{
6792833 return (__m256i)__builtin_shufflevector((__v32qi)__a, (__v32qi)__b, 0, 32+0, 1, 32+1, 2, 32+2, 3, 32+3, 4, 32+4, 5, 32+5, 6, 32+6, 7, 32+7, 16, 32+16, 17, 32+17, 18, 32+18, 19, 32+19, 20, 32+20, 21, 32+21, 22, 32+22, 23, 32+23);
6802834}
6812835
2836/// Unpacks and interleaves 16-bit integers from parts of the 256-bit vectors
2837/// of [16 x i16] in \a __a and \a __b to return the resulting 256-bit
2838/// vector of [16 x i16]. Specifically, uses the lower 64 bits of each
2839/// 128-bit half of \a __a and \a __b as input; other bits in these
2840/// parameters are ignored.
2841///
2842/// \code{.operation}
2843/// result[15:0] := __a[15:0]
2844/// result[31:16] := __b[15:0]
2845/// result[47:32] := __a[31:16]
2846/// result[63:48] := __b[31:16]
2847/// . . .
2848/// result[127:112] := __b[63:48]
2849/// result[143:128] := __a[143:128]
2850/// . . .
2851/// result[255:239] := __b[191:176]
2852/// \endcode
2853///
2854/// \headerfile <immintrin.h>
2855///
2856/// This intrinsic corresponds to the \c VPUNPCKLWD instruction.
2857///
2858/// \param __a
2859/// A 256-bit vector of [16 x i16] used as the source for the even-numbered
2860/// elements of the result.
2861/// \param __b
2862/// A 256-bit vector of [16 x i16] used as the source for the odd-numbered
2863/// elements of the result.
2864/// \returns A 256-bit vector of [16 x i16] containing the result.
6822865static __inline__ __m256i __DEFAULT_FN_ATTRS256
6832866_mm256_unpacklo_epi16(__m256i __a, __m256i __b)
6842867{
6852868 return (__m256i)__builtin_shufflevector((__v16hi)__a, (__v16hi)__b, 0, 16+0, 1, 16+1, 2, 16+2, 3, 16+3, 8, 16+8, 9, 16+9, 10, 16+10, 11, 16+11);
6862869}
6872870
2871/// Unpacks and interleaves 32-bit integers from parts of the 256-bit vectors
2872/// of [8 x i32] in \a __a and \a __b to return the resulting 256-bit vector
2873/// of [8 x i32]. Specifically, uses the lower 64 bits of each 128-bit half
2874/// of \a __a and \a __b as input; other bits in these parameters are
2875/// ignored.
2876///
2877/// \code{.operation}
2878/// result[31:0] := __a[31:0]
2879/// result[63:32] := __b[31:0]
2880/// result[95:64] := __a[63:32]
2881/// result[127:96] := __b[63:32]
2882/// result[159:128] := __a[159:128]
2883/// result[191:160] := __b[159:128]
2884/// result[223:192] := __a[191:160]
2885/// result[255:224] := __b[191:190]
2886/// \endcode
2887///
2888/// \headerfile <immintrin.h>
2889///
2890/// This intrinsic corresponds to the \c VPUNPCKLDQ instruction.
2891///
2892/// \param __a
2893/// A 256-bit vector of [8 x i32] used as the source for the even-numbered
2894/// elements of the result.
2895/// \param __b
2896/// A 256-bit vector of [8 x i32] used as the source for the odd-numbered
2897/// elements of the result.
2898/// \returns A 256-bit vector of [8 x i32] containing the result.
6882899static __inline__ __m256i __DEFAULT_FN_ATTRS256
6892900_mm256_unpacklo_epi32(__m256i __a, __m256i __b)
6902901{
6912902 return (__m256i)__builtin_shufflevector((__v8si)__a, (__v8si)__b, 0, 8+0, 1, 8+1, 4, 8+4, 5, 8+5);
6922903}
6932904
2905/// Unpacks and interleaves 64-bit integers from parts of the 256-bit vectors
2906/// of [4 x i64] in \a __a and \a __b to return the resulting 256-bit vector
2907/// of [4 x i64]. Specifically, uses the lower 64 bits of each 128-bit half
2908/// of \a __a and \a __b as input; other bits in these parameters are
2909/// ignored.
2910///
2911/// \code{.operation}
2912/// result[63:0] := __a[63:0]
2913/// result[127:64] := __b[63:0]
2914/// result[191:128] := __a[191:128]
2915/// result[255:192] := __b[191:128]
2916/// \endcode
2917///
2918/// \headerfile <immintrin.h>
2919///
2920/// This intrinsic corresponds to the \c VPUNPCKLQDQ instruction.
2921///
2922/// \param __a
2923/// A 256-bit vector of [4 x i64] used as the source for the even-numbered
2924/// elements of the result.
2925/// \param __b
2926/// A 256-bit vector of [4 x i64] used as the source for the odd-numbered
2927/// elements of the result.
2928/// \returns A 256-bit vector of [4 x i64] containing the result.
6942929static __inline__ __m256i __DEFAULT_FN_ATTRS256
6952930_mm256_unpacklo_epi64(__m256i __a, __m256i __b)
6962931{
6972932 return (__m256i)__builtin_shufflevector((__v4di)__a, (__v4di)__b, 0, 4+0, 2, 4+2);
6982933}
6992934
2935/// Computes the bitwise XOR of the 256-bit integer vectors in \a __a and
2936/// \a __b.
2937///
2938/// \headerfile <immintrin.h>
2939///
2940/// This intrinsic corresponds to the \c VPXOR instruction.
2941///
2942/// \param __a
2943/// A 256-bit integer vector.
2944/// \param __b
2945/// A 256-bit integer vector.
2946/// \returns A 256-bit integer vector containing the result.
7002947static __inline__ __m256i __DEFAULT_FN_ATTRS256
7012948_mm256_xor_si256(__m256i __a, __m256i __b)
7022949{
7032950 return (__m256i)((__v4du)__a ^ (__v4du)__b);
7042951}
7052952
2953/// Loads the 256-bit integer vector from memory \a __V using a non-temporal
2954/// memory hint and returns the vector. \a __V must be aligned on a 32-byte
2955/// boundary.
2956///
2957/// \headerfile <immintrin.h>
2958///
2959/// This intrinsic corresponds to the \c VMOVNTDQA instruction.
2960///
2961/// \param __V
2962/// A pointer to the 32-byte aligned memory containing the vector to load.
2963/// \returns A 256-bit integer vector loaded from memory.
7062964static __inline__ __m256i __DEFAULT_FN_ATTRS256
7072965_mm256_stream_load_si256(__m256i const *__V)
7082966{
......@@ -710,30 +2968,84 @@ _mm256_stream_load_si256(__m256i const *__V)
7102968 return (__m256i)__builtin_nontemporal_load((const __v4di_aligned *)__V);
7112969}
7122970
2971/// Broadcasts the 32-bit floating-point value from the low element of the
2972/// 128-bit vector of [4 x float] in \a __X to all elements of the result's
2973/// 128-bit vector of [4 x float].
2974///
2975/// \headerfile <immintrin.h>
2976///
2977/// This intrinsic corresponds to the \c VBROADCASTSS instruction.
2978///
2979/// \param __X
2980/// A 128-bit vector of [4 x float] whose low element will be broadcast.
2981/// \returns A 128-bit vector of [4 x float] containing the result.
7132982static __inline__ __m128 __DEFAULT_FN_ATTRS128
7142983_mm_broadcastss_ps(__m128 __X)
7152984{
7162985 return (__m128)__builtin_shufflevector((__v4sf)__X, (__v4sf)__X, 0, 0, 0, 0);
7172986}
7182987
2988/// Broadcasts the 64-bit floating-point value from the low element of the
2989/// 128-bit vector of [2 x double] in \a __a to both elements of the
2990/// result's 128-bit vector of [2 x double].
2991///
2992/// \headerfile <immintrin.h>
2993///
2994/// This intrinsic corresponds to the \c MOVDDUP instruction.
2995///
2996/// \param __a
2997/// A 128-bit vector of [2 x double] whose low element will be broadcast.
2998/// \returns A 128-bit vector of [2 x double] containing the result.
7192999static __inline__ __m128d __DEFAULT_FN_ATTRS128
7203000_mm_broadcastsd_pd(__m128d __a)
7213001{
7223002 return __builtin_shufflevector((__v2df)__a, (__v2df)__a, 0, 0);
7233003}
7243004
3005/// Broadcasts the 32-bit floating-point value from the low element of the
3006/// 128-bit vector of [4 x float] in \a __X to all elements of the
3007/// result's 256-bit vector of [8 x float].
3008///
3009/// \headerfile <immintrin.h>
3010///
3011/// This intrinsic corresponds to the \c VBROADCASTSS instruction.
3012///
3013/// \param __X
3014/// A 128-bit vector of [4 x float] whose low element will be broadcast.
3015/// \returns A 256-bit vector of [8 x float] containing the result.
7253016static __inline__ __m256 __DEFAULT_FN_ATTRS256
7263017_mm256_broadcastss_ps(__m128 __X)
7273018{
7283019 return (__m256)__builtin_shufflevector((__v4sf)__X, (__v4sf)__X, 0, 0, 0, 0, 0, 0, 0, 0);
7293020}
7303021
3022/// Broadcasts the 64-bit floating-point value from the low element of the
3023/// 128-bit vector of [2 x double] in \a __X to all elements of the
3024/// result's 256-bit vector of [4 x double].
3025///
3026/// \headerfile <immintrin.h>
3027///
3028/// This intrinsic corresponds to the \c VBROADCASTSD instruction.
3029///
3030/// \param __X
3031/// A 128-bit vector of [2 x double] whose low element will be broadcast.
3032/// \returns A 256-bit vector of [4 x double] containing the result.
7313033static __inline__ __m256d __DEFAULT_FN_ATTRS256
7323034_mm256_broadcastsd_pd(__m128d __X)
7333035{
7343036 return (__m256d)__builtin_shufflevector((__v2df)__X, (__v2df)__X, 0, 0, 0, 0);
7353037}
7363038
3039/// Broadcasts the 128-bit integer data from \a __X to both the lower and
3040/// upper halves of the 256-bit result.
3041///
3042/// \headerfile <immintrin.h>
3043///
3044/// This intrinsic corresponds to the \c VBROADCASTI128 instruction.
3045///
3046/// \param __X
3047/// A 128-bit integer vector to be broadcast.
3048/// \returns A 256-bit integer vector containing the result.
7373049static __inline__ __m256i __DEFAULT_FN_ATTRS256
7383050_mm256_broadcastsi128_si256(__m128i __X)
7393051{
......@@ -742,295 +3054,1688 @@ _mm256_broadcastsi128_si256(__m128i __X)
7423054
7433055#define _mm_broadcastsi128_si256(X) _mm256_broadcastsi128_si256(X)
7443056
3057/// Merges 32-bit integer elements from either of the two 128-bit vectors of
3058/// [4 x i32] in \a V1 or \a V2 to the result's 128-bit vector of [4 x i32],
3059/// as specified by the immediate integer operand \a M.
3060///
3061/// \code{.operation}
3062/// FOR i := 0 TO 3
3063/// j := i*32
3064/// IF M[i] == 0
3065/// result[31+j:j] := V1[31+j:j]
3066/// ELSE
3067/// result[31+j:j] := V2[32+j:j]
3068/// FI
3069/// ENDFOR
3070/// \endcode
3071///
3072/// \headerfile <immintrin.h>
3073///
3074/// \code
3075/// __m128i _mm_blend_epi32(__m128i V1, __m128i V2, const int M);
3076/// \endcode
3077///
3078/// This intrinsic corresponds to the \c VPBLENDDD instruction.
3079///
3080/// \param V1
3081/// A 128-bit vector of [4 x i32] containing source values.
3082/// \param V2
3083/// A 128-bit vector of [4 x i32] containing source values.
3084/// \param M
3085/// An immediate 8-bit integer operand, with bits [3:0] specifying the
3086/// source for each element of the result. The position of the mask bit
3087/// corresponds to the index of a copied value. When a mask bit is 0, the
3088/// element is copied from \a V1; otherwise, it is copied from \a V2.
3089/// \returns A 128-bit vector of [4 x i32] containing the result.
7453090#define _mm_blend_epi32(V1, V2, M) \
7463091 ((__m128i)__builtin_ia32_pblendd128((__v4si)(__m128i)(V1), \
7473092 (__v4si)(__m128i)(V2), (int)(M)))
7483093
3094/// Merges 32-bit integer elements from either of the two 256-bit vectors of
3095/// [8 x i32] in \a V1 or \a V2 to return a 256-bit vector of [8 x i32],
3096/// as specified by the immediate integer operand \a M.
3097///
3098/// \code{.operation}
3099/// FOR i := 0 TO 7
3100/// j := i*32
3101/// IF M[i] == 0
3102/// result[31+j:j] := V1[31+j:j]
3103/// ELSE
3104/// result[31+j:j] := V2[32+j:j]
3105/// FI
3106/// ENDFOR
3107/// \endcode
3108///
3109/// \headerfile <immintrin.h>
3110///
3111/// \code
3112/// __m256i _mm256_blend_epi32(__m256i V1, __m256i V2, const int M);
3113/// \endcode
3114///
3115/// This intrinsic corresponds to the \c VPBLENDDD instruction.
3116///
3117/// \param V1
3118/// A 256-bit vector of [8 x i32] containing source values.
3119/// \param V2
3120/// A 256-bit vector of [8 x i32] containing source values.
3121/// \param M
3122/// An immediate 8-bit integer operand, with bits [7:0] specifying the
3123/// source for each element of the result. The position of the mask bit
3124/// corresponds to the index of a copied value. When a mask bit is 0, the
3125/// element is copied from \a V1; otherwise, it is is copied from \a V2.
3126/// \returns A 256-bit vector of [8 x i32] containing the result.
7493127#define _mm256_blend_epi32(V1, V2, M) \
7503128 ((__m256i)__builtin_ia32_pblendd256((__v8si)(__m256i)(V1), \
7513129 (__v8si)(__m256i)(V2), (int)(M)))
7523130
3131/// Broadcasts the low byte from the 128-bit integer vector in \a __X to all
3132/// bytes of the 256-bit result.
3133///
3134/// \headerfile <immintrin.h>
3135///
3136/// This intrinsic corresponds to the \c VPBROADCASTB instruction.
3137///
3138/// \param __X
3139/// A 128-bit integer vector whose low byte will be broadcast.
3140/// \returns A 256-bit integer vector containing the result.
7533141static __inline__ __m256i __DEFAULT_FN_ATTRS256
7543142_mm256_broadcastb_epi8(__m128i __X)
7553143{
7563144 return (__m256i)__builtin_shufflevector((__v16qi)__X, (__v16qi)__X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
7573145}
7583146
3147/// Broadcasts the low element from the 128-bit vector of [8 x i16] in \a __X
3148/// to all elements of the result's 256-bit vector of [16 x i16].
3149///
3150/// \headerfile <immintrin.h>
3151///
3152/// This intrinsic corresponds to the \c VPBROADCASTW instruction.
3153///
3154/// \param __X
3155/// A 128-bit vector of [8 x i16] whose low element will be broadcast.
3156/// \returns A 256-bit vector of [16 x i16] containing the result.
7593157static __inline__ __m256i __DEFAULT_FN_ATTRS256
7603158_mm256_broadcastw_epi16(__m128i __X)
7613159{
7623160 return (__m256i)__builtin_shufflevector((__v8hi)__X, (__v8hi)__X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
7633161}
7643162
3163/// Broadcasts the low element from the 128-bit vector of [4 x i32] in \a __X
3164/// to all elements of the result's 256-bit vector of [8 x i32].
3165///
3166/// \headerfile <immintrin.h>
3167///
3168/// This intrinsic corresponds to the \c VPBROADCASTD instruction.
3169///
3170/// \param __X
3171/// A 128-bit vector of [4 x i32] whose low element will be broadcast.
3172/// \returns A 256-bit vector of [8 x i32] containing the result.
7653173static __inline__ __m256i __DEFAULT_FN_ATTRS256
7663174_mm256_broadcastd_epi32(__m128i __X)
7673175{
7683176 return (__m256i)__builtin_shufflevector((__v4si)__X, (__v4si)__X, 0, 0, 0, 0, 0, 0, 0, 0);
7693177}
7703178
3179/// Broadcasts the low element from the 128-bit vector of [2 x i64] in \a __X
3180/// to all elements of the result's 256-bit vector of [4 x i64].
3181///
3182/// \headerfile <immintrin.h>
3183///
3184/// This intrinsic corresponds to the \c VPBROADCASTQ instruction.
3185///
3186/// \param __X
3187/// A 128-bit vector of [2 x i64] whose low element will be broadcast.
3188/// \returns A 256-bit vector of [4 x i64] containing the result.
7713189static __inline__ __m256i __DEFAULT_FN_ATTRS256
7723190_mm256_broadcastq_epi64(__m128i __X)
7733191{
7743192 return (__m256i)__builtin_shufflevector((__v2di)__X, (__v2di)__X, 0, 0, 0, 0);
7753193}
7763194
3195/// Broadcasts the low byte from the 128-bit integer vector in \a __X to all
3196/// bytes of the 128-bit result.
3197///
3198/// \headerfile <immintrin.h>
3199///
3200/// This intrinsic corresponds to the \c VPBROADCASTB instruction.
3201///
3202/// \param __X
3203/// A 128-bit integer vector whose low byte will be broadcast.
3204/// \returns A 128-bit integer vector containing the result.
7773205static __inline__ __m128i __DEFAULT_FN_ATTRS128
7783206_mm_broadcastb_epi8(__m128i __X)
7793207{
7803208 return (__m128i)__builtin_shufflevector((__v16qi)__X, (__v16qi)__X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
7813209}
7823210
3211/// Broadcasts the low element from the 128-bit vector of [8 x i16] in
3212/// \a __X to all elements of the result's 128-bit vector of [8 x i16].
3213///
3214/// \headerfile <immintrin.h>
3215///
3216/// This intrinsic corresponds to the \c VPBROADCASTW instruction.
3217///
3218/// \param __X
3219/// A 128-bit vector of [8 x i16] whose low element will be broadcast.
3220/// \returns A 128-bit vector of [8 x i16] containing the result.
7833221static __inline__ __m128i __DEFAULT_FN_ATTRS128
7843222_mm_broadcastw_epi16(__m128i __X)
7853223{
7863224 return (__m128i)__builtin_shufflevector((__v8hi)__X, (__v8hi)__X, 0, 0, 0, 0, 0, 0, 0, 0);
7873225}
7883226
789
3227/// Broadcasts the low element from the 128-bit vector of [4 x i32] in \a __X
3228/// to all elements of the result's vector of [4 x i32].
3229///
3230/// \headerfile <immintrin.h>
3231///
3232/// This intrinsic corresponds to the \c VPBROADCASTD instruction.
3233///
3234/// \param __X
3235/// A 128-bit vector of [4 x i32] whose low element will be broadcast.
3236/// \returns A 128-bit vector of [4 x i32] containing the result.
7903237static __inline__ __m128i __DEFAULT_FN_ATTRS128
7913238_mm_broadcastd_epi32(__m128i __X)
7923239{
7933240 return (__m128i)__builtin_shufflevector((__v4si)__X, (__v4si)__X, 0, 0, 0, 0);
7943241}
7953242
3243/// Broadcasts the low element from the 128-bit vector of [2 x i64] in \a __X
3244/// to both elements of the result's 128-bit vector of [2 x i64].
3245///
3246/// \headerfile <immintrin.h>
3247///
3248/// This intrinsic corresponds to the \c VPBROADCASTQ instruction.
3249///
3250/// \param __X
3251/// A 128-bit vector of [2 x i64] whose low element will be broadcast.
3252/// \returns A 128-bit vector of [2 x i64] containing the result.
7963253static __inline__ __m128i __DEFAULT_FN_ATTRS128
7973254_mm_broadcastq_epi64(__m128i __X)
7983255{
7993256 return (__m128i)__builtin_shufflevector((__v2di)__X, (__v2di)__X, 0, 0);
8003257}
8013258
3259/// Sets the result's 256-bit vector of [8 x i32] to copies of elements of the
3260/// 256-bit vector of [8 x i32] in \a __a as specified by indexes in the
3261/// elements of the 256-bit vector of [8 x i32] in \a __b.
3262///
3263/// \code{.operation}
3264/// FOR i := 0 TO 7
3265/// j := i*32
3266/// k := __b[j+2:j] * 32
3267/// result[j+31:j] := __a[k+31:k]
3268/// ENDFOR
3269/// \endcode
3270///
3271/// \headerfile <immintrin.h>
3272///
3273/// This intrinsic corresponds to the \c VPERMD instruction.
3274///
3275/// \param __a
3276/// A 256-bit vector of [8 x i32] containing the source values.
3277/// \param __b
3278/// A 256-bit vector of [8 x i32] containing indexes of values to use from
3279/// \a __a.
3280/// \returns A 256-bit vector of [8 x i32] containing the result.
8023281static __inline__ __m256i __DEFAULT_FN_ATTRS256
8033282_mm256_permutevar8x32_epi32(__m256i __a, __m256i __b)
8043283{
8053284 return (__m256i)__builtin_ia32_permvarsi256((__v8si)__a, (__v8si)__b);
8063285}
8073286
3287/// Sets the result's 256-bit vector of [4 x double] to copies of elements of
3288/// the 256-bit vector of [4 x double] in \a V as specified by the
3289/// immediate value \a M.
3290///
3291/// \code{.operation}
3292/// FOR i := 0 TO 3
3293/// j := i*64
3294/// k := (M >> i*2)[1:0] * 64
3295/// result[j+63:j] := V[k+63:k]
3296/// ENDFOR
3297/// \endcode
3298///
3299/// \headerfile <immintrin.h>
3300///
3301/// \code
3302/// __m256d _mm256_permute4x64_pd(__m256d V, const int M);
3303/// \endcode
3304///
3305/// This intrinsic corresponds to the \c VPERMPD instruction.
3306///
3307/// \param V
3308/// A 256-bit vector of [4 x double] containing the source values.
3309/// \param M
3310/// An immediate 8-bit value specifying which elements to copy from \a V.
3311/// \a M[1:0] specifies the index in \a a for element 0 of the result,
3312/// \a M[3:2] specifies the index for element 1, and so forth.
3313/// \returns A 256-bit vector of [4 x double] containing the result.
8083314#define _mm256_permute4x64_pd(V, M) \
8093315 ((__m256d)__builtin_ia32_permdf256((__v4df)(__m256d)(V), (int)(M)))
8103316
3317/// Sets the result's 256-bit vector of [8 x float] to copies of elements of
3318/// the 256-bit vector of [8 x float] in \a __a as specified by indexes in
3319/// the elements of the 256-bit vector of [8 x i32] in \a __b.
3320///
3321/// \code{.operation}
3322/// FOR i := 0 TO 7
3323/// j := i*32
3324/// k := __b[j+2:j] * 32
3325/// result[j+31:j] := __a[k+31:k]
3326/// ENDFOR
3327/// \endcode
3328///
3329/// \headerfile <immintrin.h>
3330///
3331/// This intrinsic corresponds to the \c VPERMPS instruction.
3332///
3333/// \param __a
3334/// A 256-bit vector of [8 x float] containing the source values.
3335/// \param __b
3336/// A 256-bit vector of [8 x i32] containing indexes of values to use from
3337/// \a __a.
3338/// \returns A 256-bit vector of [8 x float] containing the result.
8113339static __inline__ __m256 __DEFAULT_FN_ATTRS256
8123340_mm256_permutevar8x32_ps(__m256 __a, __m256i __b)
8133341{
8143342 return (__m256)__builtin_ia32_permvarsf256((__v8sf)__a, (__v8si)__b);
8153343}
8163344
3345/// Sets the result's 256-bit vector of [4 x i64] result to copies of elements
3346/// of the 256-bit vector of [4 x i64] in \a V as specified by the
3347/// immediate value \a M.
3348///
3349/// \code{.operation}
3350/// FOR i := 0 TO 3
3351/// j := i*64
3352/// k := (M >> i*2)[1:0] * 64
3353/// result[j+63:j] := V[k+63:k]
3354/// ENDFOR
3355/// \endcode
3356///
3357/// \headerfile <immintrin.h>
3358///
3359/// \code
3360/// __m256i _mm256_permute4x64_epi64(__m256i V, const int M);
3361/// \endcode
3362///
3363/// This intrinsic corresponds to the \c VPERMQ instruction.
3364///
3365/// \param V
3366/// A 256-bit vector of [4 x i64] containing the source values.
3367/// \param M
3368/// An immediate 8-bit value specifying which elements to copy from \a V.
3369/// \a M[1:0] specifies the index in \a a for element 0 of the result,
3370/// \a M[3:2] specifies the index for element 1, and so forth.
3371/// \returns A 256-bit vector of [4 x i64] containing the result.
8173372#define _mm256_permute4x64_epi64(V, M) \
8183373 ((__m256i)__builtin_ia32_permdi256((__v4di)(__m256i)(V), (int)(M)))
8193374
3375/// Sets each half of the 256-bit result either to zero or to one of the
3376/// four possible 128-bit halves of the 256-bit vectors \a V1 and \a V2,
3377/// as specified by the immediate value \a M.
3378///
3379/// \code{.operation}
3380/// FOR i := 0 TO 1
3381/// j := i*128
3382/// k := M >> (i*4)
3383/// IF k[3] == 0
3384/// CASE (k[1:0]) OF
3385/// 0: result[127+j:j] := V1[127:0]
3386/// 1: result[127+j:j] := V1[255:128]
3387/// 2: result[127+j:j] := V2[127:0]
3388/// 3: result[127+j:j] := V2[255:128]
3389/// ESAC
3390/// ELSE
3391/// result[127+j:j] := 0
3392/// FI
3393/// ENDFOR
3394/// \endcode
3395///
3396/// \headerfile <immintrin.h>
3397///
3398/// \code
3399/// __m256i _mm256_permute2x128_si256(__m256i V1, __m256i V2, const int M);
3400/// \endcode
3401///
3402/// This intrinsic corresponds to the \c VPERM2I128 instruction.
3403///
3404/// \param V1
3405/// A 256-bit integer vector containing source values.
3406/// \param V2
3407/// A 256-bit integer vector containing source values.
3408/// \param M
3409/// An immediate value specifying how to form the result. Bits [3:0]
3410/// control the lower half of the result, bits [7:4] control the upper half.
3411/// Within each 4-bit control value, if bit 3 is 1, the result is zero,
3412/// otherwise bits [1:0] determine the source as follows. \n
3413/// 0: the lower half of \a V1 \n
3414/// 1: the upper half of \a V1 \n
3415/// 2: the lower half of \a V2 \n
3416/// 3: the upper half of \a V2
3417/// \returns A 256-bit integer vector containing the result.
8203418#define _mm256_permute2x128_si256(V1, V2, M) \
8213419 ((__m256i)__builtin_ia32_permti256((__m256i)(V1), (__m256i)(V2), (int)(M)))
8223420
3421/// Extracts half of the 256-bit vector \a V to the 128-bit result. If bit 0
3422/// of the immediate \a M is zero, extracts the lower half of the result;
3423/// otherwise, extracts the upper half.
3424///
3425/// \headerfile <immintrin.h>
3426///
3427/// \code
3428/// __m128i _mm256_extracti128_si256(__m256i V, const int M);
3429/// \endcode
3430///
3431/// This intrinsic corresponds to the \c VEXTRACTI128 instruction.
3432///
3433/// \param V
3434/// A 256-bit integer vector containing the source values.
3435/// \param M
3436/// An immediate value specifying which half of \a V to extract.
3437/// \returns A 128-bit integer vector containing the result.
8233438#define _mm256_extracti128_si256(V, M) \
8243439 ((__m128i)__builtin_ia32_extract128i256((__v4di)(__m256i)(V), (int)(M)))
8253440
3441/// Copies the 256-bit vector \a V1 to the result, then overwrites half of the
3442/// result with the 128-bit vector \a V2. If bit 0 of the immediate \a M
3443/// is zero, overwrites the lower half of the result; otherwise,
3444/// overwrites the upper half.
3445///
3446/// \headerfile <immintrin.h>
3447///
3448/// \code
3449/// __m256i _mm256_inserti128_si256(__m256i V1, __m128i V2, const int M);
3450/// \endcode
3451///
3452/// This intrinsic corresponds to the \c VINSERTI128 instruction.
3453///
3454/// \param V1
3455/// A 256-bit integer vector containing a source value.
3456/// \param V2
3457/// A 128-bit integer vector containing a source value.
3458/// \param M
3459/// An immediate value specifying where to put \a V2 in the result.
3460/// \returns A 256-bit integer vector containing the result.
8263461#define _mm256_inserti128_si256(V1, V2, M) \
8273462 ((__m256i)__builtin_ia32_insert128i256((__v4di)(__m256i)(V1), \
8283463 (__v2di)(__m128i)(V2), (int)(M)))
8293464
3465/// Conditionally loads eight 32-bit integer elements from memory \a __X, if
3466/// the most significant bit of the corresponding element in the mask
3467/// \a __M is set; otherwise, sets that element of the result to zero.
3468/// Returns the 256-bit [8 x i32] result.
3469///
3470/// \code{.operation}
3471/// FOR i := 0 TO 7
3472/// j := i*32
3473/// IF __M[j+31] == 1
3474/// result[j+31:j] := Load32(__X+(i*4))
3475/// ELSE
3476/// result[j+31:j] := 0
3477/// FI
3478/// ENDFOR
3479/// \endcode
3480///
3481/// \headerfile <immintrin.h>
3482///
3483/// This intrinsic corresponds to the \c VPMASKMOVD instruction.
3484///
3485/// \param __X
3486/// A pointer to the memory used for loading values.
3487/// \param __M
3488/// A 256-bit vector of [8 x i32] containing the mask bits.
3489/// \returns A 256-bit vector of [8 x i32] containing the loaded or zeroed
3490/// elements.
8303491static __inline__ __m256i __DEFAULT_FN_ATTRS256
8313492_mm256_maskload_epi32(int const *__X, __m256i __M)
8323493{
8333494 return (__m256i)__builtin_ia32_maskloadd256((const __v8si *)__X, (__v8si)__M);
8343495}
8353496
3497/// Conditionally loads four 64-bit integer elements from memory \a __X, if
3498/// the most significant bit of the corresponding element in the mask
3499/// \a __M is set; otherwise, sets that element of the result to zero.
3500/// Returns the 256-bit [4 x i64] result.
3501///
3502/// \code{.operation}
3503/// FOR i := 0 TO 3
3504/// j := i*64
3505/// IF __M[j+63] == 1
3506/// result[j+63:j] := Load64(__X+(i*8))
3507/// ELSE
3508/// result[j+63:j] := 0
3509/// FI
3510/// ENDFOR
3511/// \endcode
3512///
3513/// \headerfile <immintrin.h>
3514///
3515/// This intrinsic corresponds to the \c VPMASKMOVQ instruction.
3516///
3517/// \param __X
3518/// A pointer to the memory used for loading values.
3519/// \param __M
3520/// A 256-bit vector of [4 x i64] containing the mask bits.
3521/// \returns A 256-bit vector of [4 x i64] containing the loaded or zeroed
3522/// elements.
8363523static __inline__ __m256i __DEFAULT_FN_ATTRS256
8373524_mm256_maskload_epi64(long long const *__X, __m256i __M)
8383525{
8393526 return (__m256i)__builtin_ia32_maskloadq256((const __v4di *)__X, (__v4di)__M);
8403527}
8413528
3529/// Conditionally loads four 32-bit integer elements from memory \a __X, if
3530/// the most significant bit of the corresponding element in the mask
3531/// \a __M is set; otherwise, sets that element of the result to zero.
3532/// Returns the 128-bit [4 x i32] result.
3533///
3534/// \code{.operation}
3535/// FOR i := 0 TO 3
3536/// j := i*32
3537/// IF __M[j+31] == 1
3538/// result[j+31:j] := Load32(__X+(i*4))
3539/// ELSE
3540/// result[j+31:j] := 0
3541/// FI
3542/// ENDFOR
3543/// \endcode
3544///
3545/// \headerfile <immintrin.h>
3546///
3547/// This intrinsic corresponds to the \c VPMASKMOVD instruction.
3548///
3549/// \param __X
3550/// A pointer to the memory used for loading values.
3551/// \param __M
3552/// A 128-bit vector of [4 x i32] containing the mask bits.
3553/// \returns A 128-bit vector of [4 x i32] containing the loaded or zeroed
3554/// elements.
8423555static __inline__ __m128i __DEFAULT_FN_ATTRS128
8433556_mm_maskload_epi32(int const *__X, __m128i __M)
8443557{
8453558 return (__m128i)__builtin_ia32_maskloadd((const __v4si *)__X, (__v4si)__M);
8463559}
8473560
3561/// Conditionally loads two 64-bit integer elements from memory \a __X, if
3562/// the most significant bit of the corresponding element in the mask
3563/// \a __M is set; otherwise, sets that element of the result to zero.
3564/// Returns the 128-bit [2 x i64] result.
3565///
3566/// \code{.operation}
3567/// FOR i := 0 TO 1
3568/// j := i*64
3569/// IF __M[j+63] == 1
3570/// result[j+63:j] := Load64(__X+(i*8))
3571/// ELSE
3572/// result[j+63:j] := 0
3573/// FI
3574/// ENDFOR
3575/// \endcode
3576///
3577/// \headerfile <immintrin.h>
3578///
3579/// This intrinsic corresponds to the \c VPMASKMOVQ instruction.
3580///
3581/// \param __X
3582/// A pointer to the memory used for loading values.
3583/// \param __M
3584/// A 128-bit vector of [2 x i64] containing the mask bits.
3585/// \returns A 128-bit vector of [2 x i64] containing the loaded or zeroed
3586/// elements.
8483587static __inline__ __m128i __DEFAULT_FN_ATTRS128
8493588_mm_maskload_epi64(long long const *__X, __m128i __M)
8503589{
8513590 return (__m128i)__builtin_ia32_maskloadq((const __v2di *)__X, (__v2di)__M);
8523591}
8533592
3593/// Conditionally stores eight 32-bit integer elements from the 256-bit vector
3594/// of [8 x i32] in \a __Y to memory \a __X, if the most significant bit of
3595/// the corresponding element in the mask \a __M is set; otherwise, the
3596/// memory element is unchanged.
3597///
3598/// \code{.operation}
3599/// FOR i := 0 TO 7
3600/// j := i*32
3601/// IF __M[j+31] == 1
3602/// Store32(__X+(i*4), __Y[j+31:j])
3603/// FI
3604/// ENDFOR
3605/// \endcode
3606///
3607/// \headerfile <immintrin.h>
3608///
3609/// This intrinsic corresponds to the \c VPMASKMOVD instruction.
3610///
3611/// \param __X
3612/// A pointer to the memory used for storing values.
3613/// \param __M
3614/// A 256-bit vector of [8 x i32] containing the mask bits.
3615/// \param __Y
3616/// A 256-bit vector of [8 x i32] containing the values to store.
8543617static __inline__ void __DEFAULT_FN_ATTRS256
8553618_mm256_maskstore_epi32(int *__X, __m256i __M, __m256i __Y)
8563619{
8573620 __builtin_ia32_maskstored256((__v8si *)__X, (__v8si)__M, (__v8si)__Y);
8583621}
8593622
3623/// Conditionally stores four 64-bit integer elements from the 256-bit vector
3624/// of [4 x i64] in \a __Y to memory \a __X, if the most significant bit of
3625/// the corresponding element in the mask \a __M is set; otherwise, the
3626/// memory element is unchanged.
3627///
3628/// \code{.operation}
3629/// FOR i := 0 TO 3
3630/// j := i*64
3631/// IF __M[j+63] == 1
3632/// Store64(__X+(i*8), __Y[j+63:j])
3633/// FI
3634/// ENDFOR
3635/// \endcode
3636///
3637/// \headerfile <immintrin.h>
3638///
3639/// This intrinsic corresponds to the \c VPMASKMOVQ instruction.
3640///
3641/// \param __X
3642/// A pointer to the memory used for storing values.
3643/// \param __M
3644/// A 256-bit vector of [4 x i64] containing the mask bits.
3645/// \param __Y
3646/// A 256-bit vector of [4 x i64] containing the values to store.
8603647static __inline__ void __DEFAULT_FN_ATTRS256
8613648_mm256_maskstore_epi64(long long *__X, __m256i __M, __m256i __Y)
8623649{
8633650 __builtin_ia32_maskstoreq256((__v4di *)__X, (__v4di)__M, (__v4di)__Y);
8643651}
8653652
3653/// Conditionally stores four 32-bit integer elements from the 128-bit vector
3654/// of [4 x i32] in \a __Y to memory \a __X, if the most significant bit of
3655/// the corresponding element in the mask \a __M is set; otherwise, the
3656/// memory element is unchanged.
3657///
3658/// \code{.operation}
3659/// FOR i := 0 TO 3
3660/// j := i*32
3661/// IF __M[j+31] == 1
3662/// Store32(__X+(i*4), __Y[j+31:j])
3663/// FI
3664/// ENDFOR
3665/// \endcode
3666///
3667/// \headerfile <immintrin.h>
3668///
3669/// This intrinsic corresponds to the \c VPMASKMOVD instruction.
3670///
3671/// \param __X
3672/// A pointer to the memory used for storing values.
3673/// \param __M
3674/// A 128-bit vector of [4 x i32] containing the mask bits.
3675/// \param __Y
3676/// A 128-bit vector of [4 x i32] containing the values to store.
8663677static __inline__ void __DEFAULT_FN_ATTRS128
8673678_mm_maskstore_epi32(int *__X, __m128i __M, __m128i __Y)
8683679{
8693680 __builtin_ia32_maskstored((__v4si *)__X, (__v4si)__M, (__v4si)__Y);
8703681}
8713682
3683/// Conditionally stores two 64-bit integer elements from the 128-bit vector
3684/// of [2 x i64] in \a __Y to memory \a __X, if the most significant bit of
3685/// the corresponding element in the mask \a __M is set; otherwise, the
3686/// memory element is unchanged.
3687///
3688/// \code{.operation}
3689/// FOR i := 0 TO 1
3690/// j := i*64
3691/// IF __M[j+63] == 1
3692/// Store64(__X+(i*8), __Y[j+63:j])
3693/// FI
3694/// ENDFOR
3695/// \endcode
3696///
3697/// \headerfile <immintrin.h>
3698///
3699/// This intrinsic corresponds to the \c VPMASKMOVQ instruction.
3700///
3701/// \param __X
3702/// A pointer to the memory used for storing values.
3703/// \param __M
3704/// A 128-bit vector of [2 x i64] containing the mask bits.
3705/// \param __Y
3706/// A 128-bit vector of [2 x i64] containing the values to store.
8723707static __inline__ void __DEFAULT_FN_ATTRS128
8733708_mm_maskstore_epi64(long long *__X, __m128i __M, __m128i __Y)
8743709{
8753710 __builtin_ia32_maskstoreq(( __v2di *)__X, (__v2di)__M, (__v2di)__Y);
8763711}
8773712
3713/// Shifts each 32-bit element of the 256-bit vector of [8 x i32] in \a __X
3714/// left by the number of bits given in the corresponding element of the
3715/// 256-bit vector of [8 x i32] in \a __Y, shifting in zero bits, and
3716/// returns the result. If the shift count for any element is greater than
3717/// 31, the result for that element is zero.
3718///
3719/// \headerfile <immintrin.h>
3720///
3721/// This intrinsic corresponds to the \c VPSLLVD instruction.
3722///
3723/// \param __X
3724/// A 256-bit vector of [8 x i32] to be shifted.
3725/// \param __Y
3726/// A 256-bit vector of [8 x i32] containing the unsigned shift counts (in
3727/// bits).
3728/// \returns A 256-bit vector of [8 x i32] containing the result.
8783729static __inline__ __m256i __DEFAULT_FN_ATTRS256
8793730_mm256_sllv_epi32(__m256i __X, __m256i __Y)
8803731{
8813732 return (__m256i)__builtin_ia32_psllv8si((__v8si)__X, (__v8si)__Y);
8823733}
8833734
3735/// Shifts each 32-bit element of the 128-bit vector of [4 x i32] in \a __X
3736/// left by the number of bits given in the corresponding element of the
3737/// 128-bit vector of [4 x i32] in \a __Y, shifting in zero bits, and
3738/// returns the result. If the shift count for any element is greater than
3739/// 31, the result for that element is zero.
3740///
3741/// \headerfile <immintrin.h>
3742///
3743/// This intrinsic corresponds to the \c VPSLLVD instruction.
3744///
3745/// \param __X
3746/// A 128-bit vector of [4 x i32] to be shifted.
3747/// \param __Y
3748/// A 128-bit vector of [4 x i32] containing the unsigned shift counts (in
3749/// bits).
3750/// \returns A 128-bit vector of [4 x i32] containing the result.
8843751static __inline__ __m128i __DEFAULT_FN_ATTRS128
8853752_mm_sllv_epi32(__m128i __X, __m128i __Y)
8863753{
8873754 return (__m128i)__builtin_ia32_psllv4si((__v4si)__X, (__v4si)__Y);
8883755}
8893756
3757/// Shifts each 64-bit element of the 256-bit vector of [4 x i64] in \a __X
3758/// left by the number of bits given in the corresponding element of the
3759/// 128-bit vector of [4 x i64] in \a __Y, shifting in zero bits, and
3760/// returns the result. If the shift count for any element is greater than
3761/// 63, the result for that element is zero.
3762///
3763/// \headerfile <immintrin.h>
3764///
3765/// This intrinsic corresponds to the \c VPSLLVQ instruction.
3766///
3767/// \param __X
3768/// A 256-bit vector of [4 x i64] to be shifted.
3769/// \param __Y
3770/// A 256-bit vector of [4 x i64] containing the unsigned shift counts (in
3771/// bits).
3772/// \returns A 256-bit vector of [4 x i64] containing the result.
8903773static __inline__ __m256i __DEFAULT_FN_ATTRS256
8913774_mm256_sllv_epi64(__m256i __X, __m256i __Y)
8923775{
8933776 return (__m256i)__builtin_ia32_psllv4di((__v4di)__X, (__v4di)__Y);
8943777}
8953778
3779/// Shifts each 64-bit element of the 128-bit vector of [2 x i64] in \a __X
3780/// left by the number of bits given in the corresponding element of the
3781/// 128-bit vector of [2 x i64] in \a __Y, shifting in zero bits, and
3782/// returns the result. If the shift count for any element is greater than
3783/// 63, the result for that element is zero.
3784///
3785/// \headerfile <immintrin.h>
3786///
3787/// This intrinsic corresponds to the \c VPSLLVQ instruction.
3788///
3789/// \param __X
3790/// A 128-bit vector of [2 x i64] to be shifted.
3791/// \param __Y
3792/// A 128-bit vector of [2 x i64] containing the unsigned shift counts (in
3793/// bits).
3794/// \returns A 128-bit vector of [2 x i64] containing the result.
8963795static __inline__ __m128i __DEFAULT_FN_ATTRS128
8973796_mm_sllv_epi64(__m128i __X, __m128i __Y)
8983797{
8993798 return (__m128i)__builtin_ia32_psllv2di((__v2di)__X, (__v2di)__Y);
9003799}
9013800
3801/// Shifts each 32-bit element of the 256-bit vector of [8 x i32] in \a __X
3802/// right by the number of bits given in the corresponding element of the
3803/// 256-bit vector of [8 x i32] in \a __Y, shifting in sign bits, and
3804/// returns the result. If the shift count for any element is greater than
3805/// 31, the result for that element is 0 or -1 according to the sign bit
3806/// for that element.
3807///
3808/// \headerfile <immintrin.h>
3809///
3810/// This intrinsic corresponds to the \c VPSRAVD instruction.
3811///
3812/// \param __X
3813/// A 256-bit vector of [8 x i32] to be shifted.
3814/// \param __Y
3815/// A 256-bit vector of [8 x i32] containing the unsigned shift counts (in
3816/// bits).
3817/// \returns A 256-bit vector of [8 x i32] containing the result.
9023818static __inline__ __m256i __DEFAULT_FN_ATTRS256
9033819_mm256_srav_epi32(__m256i __X, __m256i __Y)
9043820{
9053821 return (__m256i)__builtin_ia32_psrav8si((__v8si)__X, (__v8si)__Y);
9063822}
9073823
3824/// Shifts each 32-bit element of the 128-bit vector of [4 x i32] in \a __X
3825/// right by the number of bits given in the corresponding element of the
3826/// 128-bit vector of [4 x i32] in \a __Y, shifting in sign bits, and
3827/// returns the result. If the shift count for any element is greater than
3828/// 31, the result for that element is 0 or -1 according to the sign bit
3829/// for that element.
3830///
3831/// \headerfile <immintrin.h>
3832///
3833/// This intrinsic corresponds to the \c VPSRAVD instruction.
3834///
3835/// \param __X
3836/// A 128-bit vector of [4 x i32] to be shifted.
3837/// \param __Y
3838/// A 128-bit vector of [4 x i32] containing the unsigned shift counts (in
3839/// bits).
3840/// \returns A 128-bit vector of [4 x i32] containing the result.
9083841static __inline__ __m128i __DEFAULT_FN_ATTRS128
9093842_mm_srav_epi32(__m128i __X, __m128i __Y)
9103843{
9113844 return (__m128i)__builtin_ia32_psrav4si((__v4si)__X, (__v4si)__Y);
9123845}
9133846
3847/// Shifts each 32-bit element of the 256-bit vector of [8 x i32] in \a __X
3848/// right by the number of bits given in the corresponding element of the
3849/// 256-bit vector of [8 x i32] in \a __Y, shifting in zero bits, and
3850/// returns the result. If the shift count for any element is greater than
3851/// 31, the result for that element is zero.
3852///
3853/// \headerfile <immintrin.h>
3854///
3855/// This intrinsic corresponds to the \c VPSRLVD instruction.
3856///
3857/// \param __X
3858/// A 256-bit vector of [8 x i32] to be shifted.
3859/// \param __Y
3860/// A 256-bit vector of [8 x i32] containing the unsigned shift counts (in
3861/// bits).
3862/// \returns A 256-bit vector of [8 x i32] containing the result.
9143863static __inline__ __m256i __DEFAULT_FN_ATTRS256
9153864_mm256_srlv_epi32(__m256i __X, __m256i __Y)
9163865{
9173866 return (__m256i)__builtin_ia32_psrlv8si((__v8si)__X, (__v8si)__Y);
9183867}
9193868
3869/// Shifts each 32-bit element of the 128-bit vector of [4 x i32] in \a __X
3870/// right by the number of bits given in the corresponding element of the
3871/// 128-bit vector of [4 x i32] in \a __Y, shifting in zero bits, and
3872/// returns the result. If the shift count for any element is greater than
3873/// 31, the result for that element is zero.
3874///
3875/// \headerfile <immintrin.h>
3876///
3877/// This intrinsic corresponds to the \c VPSRLVD instruction.
3878///
3879/// \param __X
3880/// A 128-bit vector of [4 x i32] to be shifted.
3881/// \param __Y
3882/// A 128-bit vector of [4 x i32] containing the unsigned shift counts (in
3883/// bits).
3884/// \returns A 128-bit vector of [4 x i32] containing the result.
9203885static __inline__ __m128i __DEFAULT_FN_ATTRS128
9213886_mm_srlv_epi32(__m128i __X, __m128i __Y)
9223887{
9233888 return (__m128i)__builtin_ia32_psrlv4si((__v4si)__X, (__v4si)__Y);
9243889}
9253890
3891/// Shifts each 64-bit element of the 256-bit vector of [4 x i64] in \a __X
3892/// right by the number of bits given in the corresponding element of the
3893/// 128-bit vector of [4 x i64] in \a __Y, shifting in zero bits, and
3894/// returns the result. If the shift count for any element is greater than
3895/// 63, the result for that element is zero.
3896///
3897/// \headerfile <immintrin.h>
3898///
3899/// This intrinsic corresponds to the \c VPSRLVQ instruction.
3900///
3901/// \param __X
3902/// A 256-bit vector of [4 x i64] to be shifted.
3903/// \param __Y
3904/// A 256-bit vector of [4 x i64] containing the unsigned shift counts (in
3905/// bits).
3906/// \returns A 256-bit vector of [4 x i64] containing the result.
9263907static __inline__ __m256i __DEFAULT_FN_ATTRS256
9273908_mm256_srlv_epi64(__m256i __X, __m256i __Y)
9283909{
9293910 return (__m256i)__builtin_ia32_psrlv4di((__v4di)__X, (__v4di)__Y);
9303911}
9313912
3913/// Shifts each 64-bit element of the 128-bit vector of [2 x i64] in \a __X
3914/// right by the number of bits given in the corresponding element of the
3915/// 128-bit vector of [2 x i64] in \a __Y, shifting in zero bits, and
3916/// returns the result. If the shift count for any element is greater than
3917/// 63, the result for that element is zero.
3918///
3919/// \headerfile <immintrin.h>
3920///
3921/// This intrinsic corresponds to the \c VPSRLVQ instruction.
3922///
3923/// \param __X
3924/// A 128-bit vector of [2 x i64] to be shifted.
3925/// \param __Y
3926/// A 128-bit vector of [2 x i64] containing the unsigned shift counts (in
3927/// bits).
3928/// \returns A 128-bit vector of [2 x i64] containing the result.
9323929static __inline__ __m128i __DEFAULT_FN_ATTRS128
9333930_mm_srlv_epi64(__m128i __X, __m128i __Y)
9343931{
9353932 return (__m128i)__builtin_ia32_psrlv2di((__v2di)__X, (__v2di)__Y);
9363933}
9373934
3935/// Conditionally gathers two 64-bit floating-point values, either from the
3936/// 128-bit vector of [2 x double] in \a a, or from memory \a m using scaled
3937/// indexes from the 128-bit vector of [4 x i32] in \a i. The 128-bit vector
3938/// of [2 x double] in \a mask determines the source for each element.
3939///
3940/// \code{.operation}
3941/// FOR element := 0 to 1
3942/// j := element*64
3943/// k := element*32
3944/// IF mask[j+63] == 0
3945/// result[j+63:j] := a[j+63:j]
3946/// ELSE
3947/// result[j+63:j] := Load64(m + SignExtend(i[k+31:k])*s)
3948/// FI
3949/// ENDFOR
3950/// \endcode
3951///
3952/// \headerfile <immintrin.h>
3953///
3954/// \code
3955/// __m128d _mm_mask_i32gather_pd(__m128d a, const double *m, __m128i i,
3956/// __m128d mask, const int s);
3957/// \endcode
3958///
3959/// This intrinsic corresponds to the \c VGATHERDPD instruction.
3960///
3961/// \param a
3962/// A 128-bit vector of [2 x double] used as the source when a mask bit is
3963/// zero.
3964/// \param m
3965/// A pointer to the memory used for loading values.
3966/// \param i
3967/// A 128-bit vector of [4 x i32] containing signed indexes into \a m. Only
3968/// the first two elements are used.
3969/// \param mask
3970/// A 128-bit vector of [2 x double] containing the mask. The most
3971/// significant bit of each element in the mask vector represents the mask
3972/// bits. If a mask bit is zero, the corresponding value from vector \a a
3973/// is gathered; otherwise the value is loaded from memory.
3974/// \param s
3975/// A literal constant scale factor for the indexes in \a i. Must be
3976/// 1, 2, 4, or 8.
3977/// \returns A 128-bit vector of [2 x double] containing the gathered values.
9383978#define _mm_mask_i32gather_pd(a, m, i, mask, s) \
9393979 ((__m128d)__builtin_ia32_gatherd_pd((__v2df)(__m128i)(a), \
9403980 (double const *)(m), \
9413981 (__v4si)(__m128i)(i), \
9423982 (__v2df)(__m128d)(mask), (s)))
9433983
3984/// Conditionally gathers four 64-bit floating-point values, either from the
3985/// 256-bit vector of [4 x double] in \a a, or from memory \a m using scaled
3986/// indexes from the 128-bit vector of [4 x i32] in \a i. The 256-bit vector
3987/// of [4 x double] in \a mask determines the source for each element.
3988///
3989/// \code{.operation}
3990/// FOR element := 0 to 3
3991/// j := element*64
3992/// k := element*32
3993/// IF mask[j+63] == 0
3994/// result[j+63:j] := a[j+63:j]
3995/// ELSE
3996/// result[j+63:j] := Load64(m + SignExtend(i[k+31:k])*s)
3997/// FI
3998/// ENDFOR
3999/// \endcode
4000///
4001/// \headerfile <immintrin.h>
4002///
4003/// \code
4004/// __m256d _mm256_mask_i32gather_pd(__m256d a, const double *m, __m128i i,
4005/// __m256d mask, const int s);
4006/// \endcode
4007///
4008/// This intrinsic corresponds to the \c VGATHERDPD instruction.
4009///
4010/// \param a
4011/// A 256-bit vector of [4 x double] used as the source when a mask bit is
4012/// zero.
4013/// \param m
4014/// A pointer to the memory used for loading values.
4015/// \param i
4016/// A 128-bit vector of [4 x i32] containing signed indexes into \a m.
4017/// \param mask
4018/// A 256-bit vector of [4 x double] containing the mask. The most
4019/// significant bit of each element in the mask vector represents the mask
4020/// bits. If a mask bit is zero, the corresponding value from vector \a a
4021/// is gathered; otherwise the value is loaded from memory.
4022/// \param s
4023/// A literal constant scale factor for the indexes in \a i. Must be
4024/// 1, 2, 4, or 8.
4025/// \returns A 256-bit vector of [4 x double] containing the gathered values.
9444026#define _mm256_mask_i32gather_pd(a, m, i, mask, s) \
9454027 ((__m256d)__builtin_ia32_gatherd_pd256((__v4df)(__m256d)(a), \
9464028 (double const *)(m), \
9474029 (__v4si)(__m128i)(i), \
9484030 (__v4df)(__m256d)(mask), (s)))
9494031
4032/// Conditionally gathers two 64-bit floating-point values, either from the
4033/// 128-bit vector of [2 x double] in \a a, or from memory \a m using scaled
4034/// indexes from the 128-bit vector of [2 x i64] in \a i. The 128-bit vector
4035/// of [2 x double] in \a mask determines the source for each element.
4036///
4037/// \code{.operation}
4038/// FOR element := 0 to 1
4039/// j := element*64
4040/// k := element*64
4041/// IF mask[j+63] == 0
4042/// result[j+63:j] := a[j+63:j]
4043/// ELSE
4044/// result[j+63:j] := Load64(m + SignExtend(i[k+63:k])*s)
4045/// FI
4046/// ENDFOR
4047/// \endcode
4048///
4049/// \headerfile <immintrin.h>
4050///
4051/// \code
4052/// __m128d _mm_mask_i64gather_pd(__m128d a, const double *m, __m128i i,
4053/// __m128d mask, const int s);
4054/// \endcode
4055///
4056/// This intrinsic corresponds to the \c VGATHERQPD instruction.
4057///
4058/// \param a
4059/// A 128-bit vector of [2 x double] used as the source when a mask bit is
4060/// zero.
4061/// \param m
4062/// A pointer to the memory used for loading values.
4063/// \param i
4064/// A 128-bit vector of [2 x i64] containing signed indexes into \a m.
4065/// \param mask
4066/// A 128-bit vector of [2 x double] containing the mask. The most
4067/// significant bit of each element in the mask vector represents the mask
4068/// bits. If a mask bit is zero, the corresponding value from vector \a a
4069/// is gathered; otherwise the value is loaded from memory.
4070/// \param s
4071/// A literal constant scale factor for the indexes in \a i. Must be
4072/// 1, 2, 4, or 8.
4073/// \returns A 128-bit vector of [2 x double] containing the gathered values.
9504074#define _mm_mask_i64gather_pd(a, m, i, mask, s) \
9514075 ((__m128d)__builtin_ia32_gatherq_pd((__v2df)(__m128d)(a), \
9524076 (double const *)(m), \
9534077 (__v2di)(__m128i)(i), \
9544078 (__v2df)(__m128d)(mask), (s)))
9554079
4080/// Conditionally gathers four 64-bit floating-point values, either from the
4081/// 256-bit vector of [4 x double] in \a a, or from memory \a m using scaled
4082/// indexes from the 256-bit vector of [4 x i64] in \a i. The 256-bit vector
4083/// of [4 x double] in \a mask determines the source for each element.
4084///
4085/// \code{.operation}
4086/// FOR element := 0 to 3
4087/// j := element*64
4088/// k := element*64
4089/// IF mask[j+63] == 0
4090/// result[j+63:j] := a[j+63:j]
4091/// ELSE
4092/// result[j+63:j] := Load64(m + SignExtend(i[k+63:k])*s)
4093/// FI
4094/// ENDFOR
4095/// \endcode
4096///
4097/// \headerfile <immintrin.h>
4098///
4099/// \code
4100/// __m256d _mm256_mask_i64gather_pd(__m256d a, const double *m, __m256i i,
4101/// __m256d mask, const int s);
4102/// \endcode
4103///
4104/// This intrinsic corresponds to the \c VGATHERQPD instruction.
4105///
4106/// \param a
4107/// A 256-bit vector of [4 x double] used as the source when a mask bit is
4108/// zero.
4109/// \param m
4110/// A pointer to the memory used for loading values.
4111/// \param i
4112/// A 256-bit vector of [4 x i64] containing signed indexes into \a m.
4113/// \param mask
4114/// A 256-bit vector of [4 x double] containing the mask. The most
4115/// significant bit of each element in the mask vector represents the mask
4116/// bits. If a mask bit is zero, the corresponding value from vector \a a
4117/// is gathered; otherwise the value is loaded from memory.
4118/// \param s
4119/// A literal constant scale factor for the indexes in \a i. Must be
4120/// 1, 2, 4, or 8.
4121/// \returns A 256-bit vector of [4 x double] containing the gathered values.
9564122#define _mm256_mask_i64gather_pd(a, m, i, mask, s) \
9574123 ((__m256d)__builtin_ia32_gatherq_pd256((__v4df)(__m256d)(a), \
9584124 (double const *)(m), \
9594125 (__v4di)(__m256i)(i), \
9604126 (__v4df)(__m256d)(mask), (s)))
9614127
4128/// Conditionally gathers four 32-bit floating-point values, either from the
4129/// 128-bit vector of [4 x float] in \a a, or from memory \a m using scaled
4130/// indexes from the 128-bit vector of [4 x i32] in \a i. The 128-bit vector
4131/// of [4 x float] in \a mask determines the source for each element.
4132///
4133/// \code{.operation}
4134/// FOR element := 0 to 3
4135/// j := element*32
4136/// k := element*32
4137/// IF mask[j+31] == 0
4138/// result[j+31:j] := a[j+31:j]
4139/// ELSE
4140/// result[j+31:j] := Load32(m + SignExtend(i[k+31:k])*s)
4141/// FI
4142/// ENDFOR
4143/// \endcode
4144///
4145/// \headerfile <immintrin.h>
4146///
4147/// \code
4148/// __m128 _mm_mask_i32gather_ps(__m128 a, const float *m, __m128i i,
4149/// __m128 mask, const int s);
4150/// \endcode
4151///
4152/// This intrinsic corresponds to the \c VGATHERDPS instruction.
4153///
4154/// \param a
4155/// A 128-bit vector of [4 x float] used as the source when a mask bit is
4156/// zero.
4157/// \param m
4158/// A pointer to the memory used for loading values.
4159/// \param i
4160/// A 128-bit vector of [4 x i32] containing signed indexes into \a m.
4161/// \param mask
4162/// A 128-bit vector of [4 x float] containing the mask. The most
4163/// significant bit of each element in the mask vector represents the mask
4164/// bits. If a mask bit is zero, the corresponding value from vector \a a
4165/// is gathered; otherwise the value is loaded from memory.
4166/// \param s
4167/// A literal constant scale factor for the indexes in \a i. Must be
4168/// 1, 2, 4, or 8.
4169/// \returns A 128-bit vector of [4 x float] containing the gathered values.
9624170#define _mm_mask_i32gather_ps(a, m, i, mask, s) \
9634171 ((__m128)__builtin_ia32_gatherd_ps((__v4sf)(__m128)(a), \
9644172 (float const *)(m), \
9654173 (__v4si)(__m128i)(i), \
9664174 (__v4sf)(__m128)(mask), (s)))
9674175
4176/// Conditionally gathers eight 32-bit floating-point values, either from the
4177/// 256-bit vector of [8 x float] in \a a, or from memory \a m using scaled
4178/// indexes from the 256-bit vector of [8 x i32] in \a i. The 256-bit vector
4179/// of [8 x float] in \a mask determines the source for each element.
4180///
4181/// \code{.operation}
4182/// FOR element := 0 to 7
4183/// j := element*32
4184/// k := element*32
4185/// IF mask[j+31] == 0
4186/// result[j+31:j] := a[j+31:j]
4187/// ELSE
4188/// result[j+31:j] := Load32(m + SignExtend(i[k+31:k])*s)
4189/// FI
4190/// ENDFOR
4191/// \endcode
4192///
4193/// \headerfile <immintrin.h>
4194///
4195/// \code
4196/// __m256 _mm256_mask_i32gather_ps(__m256 a, const float *m, __m256i i,
4197/// __m256 mask, const int s);
4198/// \endcode
4199///
4200/// This intrinsic corresponds to the \c VGATHERDPS instruction.
4201///
4202/// \param a
4203/// A 256-bit vector of [8 x float] used as the source when a mask bit is
4204/// zero.
4205/// \param m
4206/// A pointer to the memory used for loading values.
4207/// \param i
4208/// A 256-bit vector of [8 x i32] containing signed indexes into \a m.
4209/// \param mask
4210/// A 256-bit vector of [8 x float] containing the mask. The most
4211/// significant bit of each element in the mask vector represents the mask
4212/// bits. If a mask bit is zero, the corresponding value from vector \a a
4213/// is gathered; otherwise the value is loaded from memory.
4214/// \param s
4215/// A literal constant scale factor for the indexes in \a i. Must be
4216/// 1, 2, 4, or 8.
4217/// \returns A 256-bit vector of [8 x float] containing the gathered values.
9684218#define _mm256_mask_i32gather_ps(a, m, i, mask, s) \
9694219 ((__m256)__builtin_ia32_gatherd_ps256((__v8sf)(__m256)(a), \
9704220 (float const *)(m), \
9714221 (__v8si)(__m256i)(i), \
9724222 (__v8sf)(__m256)(mask), (s)))
9734223
4224/// Conditionally gathers two 32-bit floating-point values, either from the
4225/// 128-bit vector of [4 x float] in \a a, or from memory \a m using scaled
4226/// indexes from the 128-bit vector of [2 x i64] in \a i. The 128-bit vector
4227/// of [4 x float] in \a mask determines the source for the lower two
4228/// elements. The upper two elements of the result are zeroed.
4229///
4230/// \code{.operation}
4231/// FOR element := 0 to 1
4232/// j := element*32
4233/// k := element*64
4234/// IF mask[j+31] == 0
4235/// result[j+31:j] := a[j+31:j]
4236/// ELSE
4237/// result[j+31:j] := Load32(m + SignExtend(i[k+63:k])*s)
4238/// FI
4239/// ENDFOR
4240/// result[127:64] := 0
4241/// \endcode
4242///
4243/// \headerfile <immintrin.h>
4244///
4245/// \code
4246/// __m128 _mm_mask_i64gather_ps(__m128 a, const float *m, __m128i i,
4247/// __m128 mask, const int s);
4248/// \endcode
4249///
4250/// This intrinsic corresponds to the \c VGATHERQPS instruction.
4251///
4252/// \param a
4253/// A 128-bit vector of [4 x float] used as the source when a mask bit is
4254/// zero. Only the first two elements are used.
4255/// \param m
4256/// A pointer to the memory used for loading values.
4257/// \param i
4258/// A 128-bit vector of [2 x i64] containing signed indexes into \a m.
4259/// \param mask
4260/// A 128-bit vector of [4 x float] containing the mask. The most
4261/// significant bit of each element in the mask vector represents the mask
4262/// bits. If a mask bit is zero, the corresponding value from vector \a a
4263/// is gathered; otherwise the value is loaded from memory. Only the first
4264/// two elements are used.
4265/// \param s
4266/// A literal constant scale factor for the indexes in \a i. Must be
4267/// 1, 2, 4, or 8.
4268/// \returns A 128-bit vector of [4 x float] containing the gathered values.
9744269#define _mm_mask_i64gather_ps(a, m, i, mask, s) \
9754270 ((__m128)__builtin_ia32_gatherq_ps((__v4sf)(__m128)(a), \
9764271 (float const *)(m), \
9774272 (__v2di)(__m128i)(i), \
9784273 (__v4sf)(__m128)(mask), (s)))
9794274
4275/// Conditionally gathers four 32-bit floating-point values, either from the
4276/// 128-bit vector of [4 x float] in \a a, or from memory \a m using scaled
4277/// indexes from the 256-bit vector of [4 x i64] in \a i. The 128-bit vector
4278/// of [4 x float] in \a mask determines the source for each element.
4279///
4280/// \code{.operation}
4281/// FOR element := 0 to 3
4282/// j := element*32
4283/// k := element*64
4284/// IF mask[j+31] == 0
4285/// result[j+31:j] := a[j+31:j]
4286/// ELSE
4287/// result[j+31:j] := Load32(m + SignExtend(i[k+63:k])*s)
4288/// FI
4289/// ENDFOR
4290/// \endcode
4291///
4292/// \headerfile <immintrin.h>
4293///
4294/// \code
4295/// __m128 _mm256_mask_i64gather_ps(__m128 a, const float *m, __m256i i,
4296/// __m128 mask, const int s);
4297/// \endcode
4298///
4299/// This intrinsic corresponds to the \c VGATHERQPS instruction.
4300///
4301/// \param a
4302/// A 128-bit vector of [4 x float] used as the source when a mask bit is
4303/// zero.
4304/// \param m
4305/// A pointer to the memory used for loading values.
4306/// \param i
4307/// A 256-bit vector of [4 x i64] containing signed indexes into \a m.
4308/// \param mask
4309/// A 128-bit vector of [4 x float] containing the mask. The most
4310/// significant bit of each element in the mask vector represents the mask
4311/// bits. If a mask bit is zero, the corresponding value from vector \a a
4312/// is gathered; otherwise the value is loaded from memory.
4313/// \param s
4314/// A literal constant scale factor for the indexes in \a i. Must be
4315/// 1, 2, 4, or 8.
4316/// \returns A 128-bit vector of [4 x float] containing the gathered values.
9804317#define _mm256_mask_i64gather_ps(a, m, i, mask, s) \
9814318 ((__m128)__builtin_ia32_gatherq_ps256((__v4sf)(__m128)(a), \
9824319 (float const *)(m), \
9834320 (__v4di)(__m256i)(i), \
9844321 (__v4sf)(__m128)(mask), (s)))
9854322
4323/// Conditionally gathers four 32-bit integer values, either from the
4324/// 128-bit vector of [4 x i32] in \a a, or from memory \a m using scaled
4325/// indexes from the 128-bit vector of [4 x i32] in \a i. The 128-bit vector
4326/// of [4 x i32] in \a mask determines the source for each element.
4327///
4328/// \code{.operation}
4329/// FOR element := 0 to 3
4330/// j := element*32
4331/// k := element*32
4332/// IF mask[j+31] == 0
4333/// result[j+31:j] := a[j+31:j]
4334/// ELSE
4335/// result[j+31:j] := Load32(m + SignExtend(i[k+31:k])*s)
4336/// FI
4337/// ENDFOR
4338/// \endcode
4339///
4340/// \headerfile <immintrin.h>
4341///
4342/// \code
4343/// __m128i _mm_mask_i32gather_epi32(__m128i a, const int *m, __m128i i,
4344/// __m128i mask, const int s);
4345/// \endcode
4346///
4347/// This intrinsic corresponds to the \c VPGATHERDD instruction.
4348///
4349/// \param a
4350/// A 128-bit vector of [4 x i32] used as the source when a mask bit is
4351/// zero.
4352/// \param m
4353/// A pointer to the memory used for loading values.
4354/// \param i
4355/// A 128-bit vector of [4 x i32] containing signed indexes into \a m.
4356/// \param mask
4357/// A 128-bit vector of [4 x i32] containing the mask. The most significant
4358/// bit of each element in the mask vector represents the mask bits. If a
4359/// mask bit is zero, the corresponding value from vector \a a is gathered;
4360/// otherwise the value is loaded from memory.
4361/// \param s
4362/// A literal constant scale factor for the indexes in \a i. Must be
4363/// 1, 2, 4, or 8.
4364/// \returns A 128-bit vector of [4 x i32] containing the gathered values.
9864365#define _mm_mask_i32gather_epi32(a, m, i, mask, s) \
9874366 ((__m128i)__builtin_ia32_gatherd_d((__v4si)(__m128i)(a), \
9884367 (int const *)(m), \
9894368 (__v4si)(__m128i)(i), \
9904369 (__v4si)(__m128i)(mask), (s)))
9914370
4371/// Conditionally gathers eight 32-bit integer values, either from the
4372/// 256-bit vector of [8 x i32] in \a a, or from memory \a m using scaled
4373/// indexes from the 256-bit vector of [8 x i32] in \a i. The 256-bit vector
4374/// of [8 x i32] in \a mask determines the source for each element.
4375///
4376/// \code{.operation}
4377/// FOR element := 0 to 7
4378/// j := element*32
4379/// k := element*32
4380/// IF mask[j+31] == 0
4381/// result[j+31:j] := a[j+31:j]
4382/// ELSE
4383/// result[j+31:j] := Load32(m + SignExtend(i[k+31:k])*s)
4384/// FI
4385/// ENDFOR
4386/// \endcode
4387///
4388/// \headerfile <immintrin.h>
4389///
4390/// \code
4391/// __m256i _mm256_mask_i32gather_epi32(__m256i a, const int *m, __m256i i,
4392/// __m256i mask, const int s);
4393/// \endcode
4394///
4395/// This intrinsic corresponds to the \c VPGATHERDD instruction.
4396///
4397/// \param a
4398/// A 256-bit vector of [8 x i32] used as the source when a mask bit is
4399/// zero.
4400/// \param m
4401/// A pointer to the memory used for loading values.
4402/// \param i
4403/// A 256-bit vector of [8 x i32] containing signed indexes into \a m.
4404/// \param mask
4405/// A 256-bit vector of [8 x i32] containing the mask. The most significant
4406/// bit of each element in the mask vector represents the mask bits. If a
4407/// mask bit is zero, the corresponding value from vector \a a is gathered;
4408/// otherwise the value is loaded from memory.
4409/// \param s
4410/// A literal constant scale factor for the indexes in \a i. Must be
4411/// 1, 2, 4, or 8.
4412/// \returns A 256-bit vector of [8 x i32] containing the gathered values.
9924413#define _mm256_mask_i32gather_epi32(a, m, i, mask, s) \
9934414 ((__m256i)__builtin_ia32_gatherd_d256((__v8si)(__m256i)(a), \
9944415 (int const *)(m), \
9954416 (__v8si)(__m256i)(i), \
9964417 (__v8si)(__m256i)(mask), (s)))
9974418
4419/// Conditionally gathers two 32-bit integer values, either from the
4420/// 128-bit vector of [4 x i32] in \a a, or from memory \a m using scaled
4421/// indexes from the 128-bit vector of [2 x i64] in \a i. The 128-bit vector
4422/// of [4 x i32] in \a mask determines the source for the lower two
4423/// elements. The upper two elements of the result are zeroed.
4424///
4425/// \code{.operation}
4426/// FOR element := 0 to 1
4427/// j := element*32
4428/// k := element*64
4429/// IF mask[j+31] == 0
4430/// result[j+31:j] := a[j+31:j]
4431/// ELSE
4432/// result[j+31:j] := Load32(m + SignExtend(i[k+63:k])*s)
4433/// FI
4434/// ENDFOR
4435/// result[127:64] := 0
4436/// \endcode
4437///
4438/// \headerfile <immintrin.h>
4439///
4440/// \code
4441/// __m128i _mm_mask_i64gather_epi32(__m128i a, const int *m, __m128i i,
4442/// __m128i mask, const int s);
4443/// \endcode
4444///
4445/// This intrinsic corresponds to the \c VPGATHERQD instruction.
4446///
4447/// \param a
4448/// A 128-bit vector of [4 x i32] used as the source when a mask bit is
4449/// zero. Only the first two elements are used.
4450/// \param m
4451/// A pointer to the memory used for loading values.
4452/// \param i
4453/// A 128-bit vector of [2 x i64] containing indexes into \a m.
4454/// \param mask
4455/// A 128-bit vector of [4 x i32] containing the mask. The most significant
4456/// bit of each element in the mask vector represents the mask bits. If a
4457/// mask bit is zero, the corresponding value from vector \a a is gathered;
4458/// otherwise the value is loaded from memory. Only the first two elements
4459/// are used.
4460/// \param s
4461/// A literal constant scale factor for the indexes in \a i. Must be
4462/// 1, 2, 4, or 8.
4463/// \returns A 128-bit vector of [4 x i32] containing the gathered values.
9984464#define _mm_mask_i64gather_epi32(a, m, i, mask, s) \
9994465 ((__m128i)__builtin_ia32_gatherq_d((__v4si)(__m128i)(a), \
10004466 (int const *)(m), \
10014467 (__v2di)(__m128i)(i), \
10024468 (__v4si)(__m128i)(mask), (s)))
10034469
4470/// Conditionally gathers four 32-bit integer values, either from the
4471/// 128-bit vector of [4 x i32] in \a a, or from memory \a m using scaled
4472/// indexes from the 256-bit vector of [4 x i64] in \a i. The 128-bit vector
4473/// of [4 x i32] in \a mask determines the source for each element.
4474///
4475/// \code{.operation}
4476/// FOR element := 0 to 3
4477/// j := element*32
4478/// k := element*64
4479/// IF mask[j+31] == 0
4480/// result[j+31:j] := a[j+31:j]
4481/// ELSE
4482/// result[j+31:j] := Load32(m + SignExtend(i[k+63:k])*s)
4483/// FI
4484/// ENDFOR
4485/// \endcode
4486///
4487/// \headerfile <immintrin.h>
4488///
4489/// \code
4490/// __m128i _mm256_mask_i64gather_epi32(__m128i a, const int *m, __m256i i,
4491/// __m128i mask, const int s);
4492/// \endcode
4493///
4494/// This intrinsic corresponds to the \c VPGATHERQD instruction.
4495///
4496/// \param a
4497/// A 128-bit vector of [4 x i32] used as the source when a mask bit is
4498/// zero.
4499/// \param m
4500/// A pointer to the memory used for loading values.
4501/// \param i
4502/// A 256-bit vector of [4 x i64] containing signed indexes into \a m.
4503/// \param mask
4504/// A 128-bit vector of [4 x i32] containing the mask. The most significant
4505/// bit of each element in the mask vector represents the mask bits. If a
4506/// mask bit is zero, the corresponding value from vector \a a is gathered;
4507/// otherwise the value is loaded from memory.
4508/// \param s
4509/// A literal constant scale factor for the indexes in \a i. Must be
4510/// 1, 2, 4, or 8.
4511/// \returns A 128-bit vector of [4 x i32] containing the gathered values.
10044512#define _mm256_mask_i64gather_epi32(a, m, i, mask, s) \
10054513 ((__m128i)__builtin_ia32_gatherq_d256((__v4si)(__m128i)(a), \
10064514 (int const *)(m), \
10074515 (__v4di)(__m256i)(i), \
10084516 (__v4si)(__m128i)(mask), (s)))
10094517
4518/// Conditionally gathers two 64-bit integer values, either from the
4519/// 128-bit vector of [2 x i64] in \a a, or from memory \a m using scaled
4520/// indexes from the 128-bit vector of [4 x i32] in \a i. The 128-bit vector
4521/// of [2 x i64] in \a mask determines the source for each element.
4522///
4523/// \code{.operation}
4524/// FOR element := 0 to 1
4525/// j := element*64
4526/// k := element*32
4527/// IF mask[j+63] == 0
4528/// result[j+63:j] := a[j+63:j]
4529/// ELSE
4530/// result[j+63:j] := Load64(m + SignExtend(i[k+31:k])*s)
4531/// FI
4532/// ENDFOR
4533/// \endcode
4534///
4535/// \headerfile <immintrin.h>
4536///
4537/// \code
4538/// __m128i _mm_mask_i32gather_epi64(__m128i a, const long long *m, __m128i i,
4539/// __m128i mask, const int s);
4540/// \endcode
4541///
4542/// This intrinsic corresponds to the \c VPGATHERDQ instruction.
4543///
4544/// \param a
4545/// A 128-bit vector of [2 x i64] used as the source when a mask bit is
4546/// zero.
4547/// \param m
4548/// A pointer to the memory used for loading values.
4549/// \param i
4550/// A 128-bit vector of [4 x i32] containing signed indexes into \a m. Only
4551/// the first two elements are used.
4552/// \param mask
4553/// A 128-bit vector of [2 x i64] containing the mask. The most significant
4554/// bit of each element in the mask vector represents the mask bits. If a
4555/// mask bit is zero, the corresponding value from vector \a a is gathered;
4556/// otherwise the value is loaded from memory.
4557/// \param s
4558/// A literal constant scale factor for the indexes in \a i. Must be
4559/// 1, 2, 4, or 8.
4560/// \returns A 128-bit vector of [2 x i64] containing the gathered values.
10104561#define _mm_mask_i32gather_epi64(a, m, i, mask, s) \
10114562 ((__m128i)__builtin_ia32_gatherd_q((__v2di)(__m128i)(a), \
10124563 (long long const *)(m), \
10134564 (__v4si)(__m128i)(i), \
10144565 (__v2di)(__m128i)(mask), (s)))
10154566
4567/// Conditionally gathers four 64-bit integer values, either from the
4568/// 256-bit vector of [4 x i64] in \a a, or from memory \a m using scaled
4569/// indexes from the 128-bit vector of [4 x i32] in \a i. The 256-bit vector
4570/// of [4 x i64] in \a mask determines the source for each element.
4571///
4572/// \code{.operation}
4573/// FOR element := 0 to 3
4574/// j := element*64
4575/// k := element*32
4576/// IF mask[j+63] == 0
4577/// result[j+63:j] := a[j+63:j]
4578/// ELSE
4579/// result[j+63:j] := Load64(m + SignExtend(i[k+31:k])*s)
4580/// FI
4581/// ENDFOR
4582/// \endcode
4583///
4584/// \headerfile <immintrin.h>
4585///
4586/// \code
4587/// __m256i _mm256_mask_i32gather_epi64(__m256i a, const long long *m,
4588/// __m128i i, __m256i mask, const int s);
4589/// \endcode
4590///
4591/// This intrinsic corresponds to the \c VPGATHERDQ instruction.
4592///
4593/// \param a
4594/// A 256-bit vector of [4 x i64] used as the source when a mask bit is
4595/// zero.
4596/// \param m
4597/// A pointer to the memory used for loading values.
4598/// \param i
4599/// A 128-bit vector of [4 x i32] containing signed indexes into \a m.
4600/// \param mask
4601/// A 256-bit vector of [4 x i64] containing the mask. The most significant
4602/// bit of each element in the mask vector represents the mask bits. If a
4603/// mask bit is zero, the corresponding value from vector \a a is gathered;
4604/// otherwise the value is loaded from memory.
4605/// \param s
4606/// A literal constant scale factor for the indexes in \a i. Must be
4607/// 1, 2, 4, or 8.
4608/// \returns A 256-bit vector of [4 x i64] containing the gathered values.
10164609#define _mm256_mask_i32gather_epi64(a, m, i, mask, s) \
10174610 ((__m256i)__builtin_ia32_gatherd_q256((__v4di)(__m256i)(a), \
10184611 (long long const *)(m), \
10194612 (__v4si)(__m128i)(i), \
10204613 (__v4di)(__m256i)(mask), (s)))
10214614
4615/// Conditionally gathers two 64-bit integer values, either from the
4616/// 128-bit vector of [2 x i64] in \a a, or from memory \a m using scaled
4617/// indexes from the 128-bit vector of [2 x i64] in \a i. The 128-bit vector
4618/// of [2 x i64] in \a mask determines the source for each element.
4619///
4620/// \code{.operation}
4621/// FOR element := 0 to 1
4622/// j := element*64
4623/// k := element*64
4624/// IF mask[j+63] == 0
4625/// result[j+63:j] := a[j+63:j]
4626/// ELSE
4627/// result[j+63:j] := Load64(m + SignExtend(i[k+63:k])*s)
4628/// FI
4629/// ENDFOR
4630/// \endcode
4631///
4632/// \headerfile <immintrin.h>
4633///
4634/// \code
4635/// __m128i _mm_mask_i64gather_epi64(__m128i a, const long long *m, __m128i i,
4636/// __m128i mask, const int s);
4637/// \endcode
4638///
4639/// This intrinsic corresponds to the \c VPGATHERQQ instruction.
4640///
4641/// \param a
4642/// A 128-bit vector of [2 x i64] used as the source when a mask bit is
4643/// zero.
4644/// \param m
4645/// A pointer to the memory used for loading values.
4646/// \param i
4647/// A 128-bit vector of [2 x i64] containing signed indexes into \a m.
4648/// \param mask
4649/// A 128-bit vector of [2 x i64] containing the mask. The most significant
4650/// bit of each element in the mask vector represents the mask bits. If a
4651/// mask bit is zero, the corresponding value from vector \a a is gathered;
4652/// otherwise the value is loaded from memory.
4653/// \param s
4654/// A literal constant scale factor for the indexes in \a i. Must be
4655/// 1, 2, 4, or 8.
4656/// \returns A 128-bit vector of [2 x i64] containing the gathered values.
10224657#define _mm_mask_i64gather_epi64(a, m, i, mask, s) \
10234658 ((__m128i)__builtin_ia32_gatherq_q((__v2di)(__m128i)(a), \
10244659 (long long const *)(m), \
10254660 (__v2di)(__m128i)(i), \
10264661 (__v2di)(__m128i)(mask), (s)))
10274662
4663/// Conditionally gathers four 64-bit integer values, either from the
4664/// 256-bit vector of [4 x i64] in \a a, or from memory \a m using scaled
4665/// indexes from the 256-bit vector of [4 x i64] in \a i. The 256-bit vector
4666/// of [4 x i64] in \a mask determines the source for each element.
4667///
4668/// \code{.operation}
4669/// FOR element := 0 to 3
4670/// j := element*64
4671/// k := element*64
4672/// IF mask[j+63] == 0
4673/// result[j+63:j] := a[j+63:j]
4674/// ELSE
4675/// result[j+63:j] := Load64(m + SignExtend(i[k+63:k])*s)
4676/// FI
4677/// ENDFOR
4678/// \endcode
4679///
4680/// \headerfile <immintrin.h>
4681///
4682/// \code
4683/// __m256i _mm256_mask_i64gather_epi64(__m256i a, const long long *m,
4684/// __m256i i, __m256i mask, const int s);
4685/// \endcode
4686///
4687/// This intrinsic corresponds to the \c VPGATHERQQ instruction.
4688///
4689/// \param a
4690/// A 256-bit vector of [4 x i64] used as the source when a mask bit is
4691/// zero.
4692/// \param m
4693/// A pointer to the memory used for loading values.
4694/// \param i
4695/// A 256-bit vector of [4 x i64] containing signed indexes into \a m.
4696/// \param mask
4697/// A 256-bit vector of [4 x i64] containing the mask. The most significant
4698/// bit of each element in the mask vector represents the mask bits. If a
4699/// mask bit is zero, the corresponding value from vector \a a is gathered;
4700/// otherwise the value is loaded from memory.
4701/// \param s
4702/// A literal constant scale factor for the indexes in \a i. Must be
4703/// 1, 2, 4, or 8.
4704/// \returns A 256-bit vector of [4 x i64] containing the gathered values.
10284705#define _mm256_mask_i64gather_epi64(a, m, i, mask, s) \
10294706 ((__m256i)__builtin_ia32_gatherq_q256((__v4di)(__m256i)(a), \
10304707 (long long const *)(m), \
10314708 (__v4di)(__m256i)(i), \
10324709 (__v4di)(__m256i)(mask), (s)))
10334710
4711/// Gathers two 64-bit floating-point values from memory \a m using scaled
4712/// indexes from the 128-bit vector of [4 x i32] in \a i.
4713///
4714/// \code{.operation}
4715/// FOR element := 0 to 1
4716/// j := element*64
4717/// k := element*32
4718/// result[j+63:j] := Load64(m + SignExtend(i[k+31:k])*s)
4719/// ENDFOR
4720/// \endcode
4721///
4722/// \headerfile <immintrin.h>
4723///
4724/// \code
4725/// __m128d _mm_i32gather_pd(const double *m, __m128i i, const int s);
4726/// \endcode
4727///
4728/// This intrinsic corresponds to the \c VGATHERDPD instruction.
4729///
4730/// \param m
4731/// A pointer to the memory used for loading values.
4732/// \param i
4733/// A 128-bit vector of [4 x i32] containing signed indexes into \a m. Only
4734/// the first two elements are used.
4735/// \param s
4736/// A literal constant scale factor for the indexes in \a i. Must be
4737/// 1, 2, 4, or 8.
4738/// \returns A 128-bit vector of [2 x double] containing the gathered values.
10344739#define _mm_i32gather_pd(m, i, s) \
10354740 ((__m128d)__builtin_ia32_gatherd_pd((__v2df)_mm_undefined_pd(), \
10364741 (double const *)(m), \
......@@ -1039,6 +4744,33 @@ _mm_srlv_epi64(__m128i __X, __m128i __Y)
10394744 _mm_setzero_pd()), \
10404745 (s)))
10414746
4747/// Gathers four 64-bit floating-point values from memory \a m using scaled
4748/// indexes from the 128-bit vector of [4 x i32] in \a i.
4749///
4750/// \code{.operation}
4751/// FOR element := 0 to 3
4752/// j := element*64
4753/// k := element*32
4754/// result[j+63:j] := Load64(m + SignExtend(i[k+31:k])*s)
4755/// ENDFOR
4756/// \endcode
4757///
4758/// \headerfile <immintrin.h>
4759///
4760/// \code
4761/// __m256d _mm256_i32gather_pd(const double *m, __m128i i, const int s);
4762/// \endcode
4763///
4764/// This intrinsic corresponds to the \c VGATHERDPD instruction.
4765///
4766/// \param m
4767/// A pointer to the memory used for loading values.
4768/// \param i
4769/// A 128-bit vector of [4 x i32] containing signed indexes into \a m.
4770/// \param s
4771/// A literal constant scale factor for the indexes in \a i. Must be
4772/// 1, 2, 4, or 8.
4773/// \returns A 256-bit vector of [4 x double] containing the gathered values.
10424774#define _mm256_i32gather_pd(m, i, s) \
10434775 ((__m256d)__builtin_ia32_gatherd_pd256((__v4df)_mm256_undefined_pd(), \
10444776 (double const *)(m), \
......@@ -1048,6 +4780,33 @@ _mm_srlv_epi64(__m128i __X, __m128i __Y)
10484780 _CMP_EQ_OQ), \
10494781 (s)))
10504782
4783/// Gathers two 64-bit floating-point values from memory \a m using scaled
4784/// indexes from the 128-bit vector of [2 x i64] in \a i.
4785///
4786/// \code{.operation}
4787/// FOR element := 0 to 1
4788/// j := element*64
4789/// k := element*64
4790/// result[j+63:j] := Load64(m + SignExtend(i[k+63:k])*s)
4791/// ENDFOR
4792/// \endcode
4793///
4794/// \headerfile <immintrin.h>
4795///
4796/// \code
4797/// __m128d _mm_i64gather_pd(const double *m, __m128i i, const int s);
4798/// \endcode
4799///
4800/// This intrinsic corresponds to the \c VGATHERQPD instruction.
4801///
4802/// \param m
4803/// A pointer to the memory used for loading values.
4804/// \param i
4805/// A 128-bit vector of [2 x i64] containing signed indexes into \a m.
4806/// \param s
4807/// A literal constant scale factor for the indexes in \a i. Must be
4808/// 1, 2, 4, or 8.
4809/// \returns A 128-bit vector of [2 x double] containing the gathered values.
10514810#define _mm_i64gather_pd(m, i, s) \
10524811 ((__m128d)__builtin_ia32_gatherq_pd((__v2df)_mm_undefined_pd(), \
10534812 (double const *)(m), \
......@@ -1056,6 +4815,33 @@ _mm_srlv_epi64(__m128i __X, __m128i __Y)
10564815 _mm_setzero_pd()), \
10574816 (s)))
10584817
4818/// Gathers four 64-bit floating-point values from memory \a m using scaled
4819/// indexes from the 256-bit vector of [4 x i64] in \a i.
4820///
4821/// \code{.operation}
4822/// FOR element := 0 to 3
4823/// j := element*64
4824/// k := element*64
4825/// result[j+63:j] := Load64(m + SignExtend(i[k+63:k])*s)
4826/// ENDFOR
4827/// \endcode
4828///
4829/// \headerfile <immintrin.h>
4830///
4831/// \code
4832/// __m256d _mm256_i64gather_pd(const double *m, __m256i i, const int s);
4833/// \endcode
4834///
4835/// This intrinsic corresponds to the \c VGATHERQPD instruction.
4836///
4837/// \param m
4838/// A pointer to the memory used for loading values.
4839/// \param i
4840/// A 256-bit vector of [4 x i64] containing signed indexes into \a m.
4841/// \param s
4842/// A literal constant scale factor for the indexes in \a i. Must be
4843/// 1, 2, 4, or 8.
4844/// \returns A 256-bit vector of [4 x double] containing the gathered values.
10594845#define _mm256_i64gather_pd(m, i, s) \
10604846 ((__m256d)__builtin_ia32_gatherq_pd256((__v4df)_mm256_undefined_pd(), \
10614847 (double const *)(m), \
......@@ -1065,6 +4851,33 @@ _mm_srlv_epi64(__m128i __X, __m128i __Y)
10654851 _CMP_EQ_OQ), \
10664852 (s)))
10674853
4854/// Gathers four 32-bit floating-point values from memory \a m using scaled
4855/// indexes from the 128-bit vector of [4 x i32] in \a i.
4856///
4857/// \code{.operation}
4858/// FOR element := 0 to 3
4859/// j := element*32
4860/// k := element*32
4861/// result[j+31:j] := Load32(m + SignExtend(i[k+31:k])*s)
4862/// ENDFOR
4863/// \endcode
4864///
4865/// \headerfile <immintrin.h>
4866///
4867/// \code
4868/// __m128 _mm_i32gather_ps(const float *m, __m128i i, const int s);
4869/// \endcode
4870///
4871/// This intrinsic corresponds to the \c VGATHERDPS instruction.
4872///
4873/// \param m
4874/// A pointer to the memory used for loading values.
4875/// \param i
4876/// A 128-bit vector of [4 x i32] containing signed indexes into \a m.
4877/// \param s
4878/// A literal constant scale factor for the indexes in \a i. Must be
4879/// 1, 2, 4, or 8.
4880/// \returns A 128-bit vector of [4 x float] containing the gathered values.
10684881#define _mm_i32gather_ps(m, i, s) \
10694882 ((__m128)__builtin_ia32_gatherd_ps((__v4sf)_mm_undefined_ps(), \
10704883 (float const *)(m), \
......@@ -1073,6 +4886,33 @@ _mm_srlv_epi64(__m128i __X, __m128i __Y)
10734886 _mm_setzero_ps()), \
10744887 (s)))
10754888
4889/// Gathers eight 32-bit floating-point values from memory \a m using scaled
4890/// indexes from the 256-bit vector of [8 x i32] in \a i.
4891///
4892/// \code{.operation}
4893/// FOR element := 0 to 7
4894/// j := element*32
4895/// k := element*32
4896/// result[j+31:j] := Load32(m + SignExtend(i[k+31:k])*s)
4897/// ENDFOR
4898/// \endcode
4899///
4900/// \headerfile <immintrin.h>
4901///
4902/// \code
4903/// __m256 _mm256_i32gather_ps(const float *m, __m256i i, const int s);
4904/// \endcode
4905///
4906/// This intrinsic corresponds to the \c VGATHERDPS instruction.
4907///
4908/// \param m
4909/// A pointer to the memory used for loading values.
4910/// \param i
4911/// A 256-bit vector of [8 x i32] containing signed indexes into \a m.
4912/// \param s
4913/// A literal constant scale factor for the indexes in \a i. Must be
4914/// 1, 2, 4, or 8.
4915/// \returns A 256-bit vector of [8 x float] containing the gathered values.
10764916#define _mm256_i32gather_ps(m, i, s) \
10774917 ((__m256)__builtin_ia32_gatherd_ps256((__v8sf)_mm256_undefined_ps(), \
10784918 (float const *)(m), \
......@@ -1082,6 +4922,35 @@ _mm_srlv_epi64(__m128i __X, __m128i __Y)
10824922 _CMP_EQ_OQ), \
10834923 (s)))
10844924
4925/// Gathers two 32-bit floating-point values from memory \a m using scaled
4926/// indexes from the 128-bit vector of [2 x i64] in \a i. The upper two
4927/// elements of the result are zeroed.
4928///
4929/// \code{.operation}
4930/// FOR element := 0 to 1
4931/// j := element*32
4932/// k := element*64
4933/// result[j+31:j] := Load32(m + SignExtend(i[k+63:k])*s)
4934/// ENDFOR
4935/// result[127:64] := 0
4936/// \endcode
4937///
4938/// \headerfile <immintrin.h>
4939///
4940/// \code
4941/// __m128 _mm_i64gather_ps(const float *m, __m128i i, const int s);
4942/// \endcode
4943///
4944/// This intrinsic corresponds to the \c VGATHERQPS instruction.
4945///
4946/// \param m
4947/// A pointer to the memory used for loading values.
4948/// \param i
4949/// A 128-bit vector of [2 x i64] containing signed indexes into \a m.
4950/// \param s
4951/// A literal constant scale factor for the indexes in \a i. Must be
4952/// 1, 2, 4, or 8.
4953/// \returns A 128-bit vector of [4 x float] containing the gathered values.
10854954#define _mm_i64gather_ps(m, i, s) \
10864955 ((__m128)__builtin_ia32_gatherq_ps((__v4sf)_mm_undefined_ps(), \
10874956 (float const *)(m), \
......@@ -1090,6 +4959,33 @@ _mm_srlv_epi64(__m128i __X, __m128i __Y)
10904959 _mm_setzero_ps()), \
10914960 (s)))
10924961
4962/// Gathers four 32-bit floating-point values from memory \a m using scaled
4963/// indexes from the 256-bit vector of [4 x i64] in \a i.
4964///
4965/// \code{.operation}
4966/// FOR element := 0 to 3
4967/// j := element*32
4968/// k := element*64
4969/// result[j+31:j] := Load32(m + SignExtend(i[k+64:k])*s)
4970/// ENDFOR
4971/// \endcode
4972///
4973/// \headerfile <immintrin.h>
4974///
4975/// \code
4976/// __m128 _mm256_i64gather_ps(const float *m, __m256i i, const int s);
4977/// \endcode
4978///
4979/// This intrinsic corresponds to the \c VGATHERQPS instruction.
4980///
4981/// \param m
4982/// A pointer to the memory used for loading values.
4983/// \param i
4984/// A 256-bit vector of [4 x i64] containing signed indexes into \a m.
4985/// \param s
4986/// A literal constant scale factor for the indexes in \a i. Must be
4987/// 1, 2, 4, or 8.
4988/// \returns A 128-bit vector of [4 x float] containing the gathered values.
10934989#define _mm256_i64gather_ps(m, i, s) \
10944990 ((__m128)__builtin_ia32_gatherq_ps256((__v4sf)_mm_undefined_ps(), \
10954991 (float const *)(m), \
......@@ -1098,44 +4994,263 @@ _mm_srlv_epi64(__m128i __X, __m128i __Y)
10984994 _mm_setzero_ps()), \
10994995 (s)))
11004996
4997/// Gathers four 32-bit floating-point values from memory \a m using scaled
4998/// indexes from the 128-bit vector of [4 x i32] in \a i.
4999///
5000/// \code{.operation}
5001/// FOR element := 0 to 3
5002/// j := element*32
5003/// k := element*32
5004/// result[j+31:j] := Load32(m + SignExtend(i[k+31:k])*s)
5005/// ENDFOR
5006/// \endcode
5007///
5008/// \headerfile <immintrin.h>
5009///
5010/// \code
5011/// __m128i _mm_i32gather_epi32(const int *m, __m128i i, const int s);
5012/// \endcode
5013///
5014/// This intrinsic corresponds to the \c VPGATHERDD instruction.
5015///
5016/// \param m
5017/// A pointer to the memory used for loading values.
5018/// \param i
5019/// A 128-bit vector of [4 x i32] containing signed indexes into \a m.
5020/// \param s
5021/// A literal constant scale factor for the indexes in \a i. Must be
5022/// 1, 2, 4, or 8.
5023/// \returns A 128-bit vector of [4 x i32] containing the gathered values.
11015024#define _mm_i32gather_epi32(m, i, s) \
11025025 ((__m128i)__builtin_ia32_gatherd_d((__v4si)_mm_undefined_si128(), \
11035026 (int const *)(m), (__v4si)(__m128i)(i), \
11045027 (__v4si)_mm_set1_epi32(-1), (s)))
11055028
5029/// Gathers eight 32-bit floating-point values from memory \a m using scaled
5030/// indexes from the 256-bit vector of [8 x i32] in \a i.
5031///
5032/// \code{.operation}
5033/// FOR element := 0 to 7
5034/// j := element*32
5035/// k := element*32
5036/// result[j+31:j] := Load32(m + SignExtend(i[k+31:k])*s)
5037/// ENDFOR
5038/// \endcode
5039///
5040/// \headerfile <immintrin.h>
5041///
5042/// \code
5043/// __m256i _mm256_i32gather_epi32(const int *m, __m256i i, const int s);
5044/// \endcode
5045///
5046/// This intrinsic corresponds to the \c VPGATHERDD instruction.
5047///
5048/// \param m
5049/// A pointer to the memory used for loading values.
5050/// \param i
5051/// A 256-bit vector of [8 x i32] containing signed indexes into \a m.
5052/// \param s
5053/// A literal constant scale factor for the indexes in \a i. Must be
5054/// 1, 2, 4, or 8.
5055/// \returns A 256-bit vector of [8 x i32] containing the gathered values.
11065056#define _mm256_i32gather_epi32(m, i, s) \
11075057 ((__m256i)__builtin_ia32_gatherd_d256((__v8si)_mm256_undefined_si256(), \
11085058 (int const *)(m), (__v8si)(__m256i)(i), \
11095059 (__v8si)_mm256_set1_epi32(-1), (s)))
11105060
5061/// Gathers two 32-bit integer values from memory \a m using scaled indexes
5062/// from the 128-bit vector of [2 x i64] in \a i. The upper two elements
5063/// of the result are zeroed.
5064///
5065/// \code{.operation}
5066/// FOR element := 0 to 1
5067/// j := element*32
5068/// k := element*64
5069/// result[j+31:j] := Load32(m + SignExtend(i[k+63:k])*s)
5070/// ENDFOR
5071/// result[127:64] := 0
5072/// \endcode
5073///
5074/// \headerfile <immintrin.h>
5075///
5076/// \code
5077/// __m128i _mm_i64gather_epi32(const int *m, __m128i i, const int s);
5078/// \endcode
5079///
5080/// This intrinsic corresponds to the \c VPGATHERQD instruction.
5081///
5082/// \param m
5083/// A pointer to the memory used for loading values.
5084/// \param i
5085/// A 128-bit vector of [2 x i64] containing signed indexes into \a m.
5086/// \param s
5087/// A literal constant scale factor for the indexes in \a i. Must be
5088/// 1, 2, 4, or 8.
5089/// \returns A 128-bit vector of [4 x i32] containing the gathered values.
11115090#define _mm_i64gather_epi32(m, i, s) \
11125091 ((__m128i)__builtin_ia32_gatherq_d((__v4si)_mm_undefined_si128(), \
11135092 (int const *)(m), (__v2di)(__m128i)(i), \
11145093 (__v4si)_mm_set1_epi32(-1), (s)))
11155094
5095/// Gathers four 32-bit integer values from memory \a m using scaled indexes
5096/// from the 256-bit vector of [4 x i64] in \a i.
5097///
5098/// \code{.operation}
5099/// FOR element := 0 to 3
5100/// j := element*32
5101/// k := element*64
5102/// result[j+31:j] := Load32(m + SignExtend(i[k+63:k])*s)
5103/// ENDFOR
5104/// \endcode
5105///
5106/// \headerfile <immintrin.h>
5107///
5108/// \code
5109/// __m128i _mm256_i64gather_epi32(const int *m, __m256i i, const int s);
5110/// \endcode
5111///
5112/// This intrinsic corresponds to the \c VPGATHERQD instruction.
5113///
5114/// \param m
5115/// A pointer to the memory used for loading values.
5116/// \param i
5117/// A 256-bit vector of [4 x i64] containing signed indexes into \a m.
5118/// \param s
5119/// A literal constant scale factor for the indexes in \a i. Must be
5120/// 1, 2, 4, or 8.
5121/// \returns A 128-bit vector of [4 x i32] containing the gathered values.
11165122#define _mm256_i64gather_epi32(m, i, s) \
11175123 ((__m128i)__builtin_ia32_gatherq_d256((__v4si)_mm_undefined_si128(), \
11185124 (int const *)(m), (__v4di)(__m256i)(i), \
11195125 (__v4si)_mm_set1_epi32(-1), (s)))
11205126
5127/// Gathers two 64-bit integer values from memory \a m using scaled indexes
5128/// from the 128-bit vector of [4 x i32] in \a i.
5129///
5130/// \code{.operation}
5131/// FOR element := 0 to 1
5132/// j := element*64
5133/// k := element*32
5134/// result[j+63:j] := Load64(m + SignExtend(i[k+31:k])*s)
5135/// ENDFOR
5136/// \endcode
5137///
5138/// \headerfile <immintrin.h>
5139///
5140/// \code
5141/// __m128i _mm_i32gather_epi64(const long long *m, __m128i i, const int s);
5142/// \endcode
5143///
5144/// This intrinsic corresponds to the \c VPGATHERDQ instruction.
5145///
5146/// \param m
5147/// A pointer to the memory used for loading values.
5148/// \param i
5149/// A 128-bit vector of [4 x i32] containing signed indexes into \a m. Only
5150/// the first two elements are used.
5151/// \param s
5152/// A literal constant scale factor for the indexes in \a i. Must be
5153/// 1, 2, 4, or 8.
5154/// \returns A 128-bit vector of [2 x i64] containing the gathered values.
11215155#define _mm_i32gather_epi64(m, i, s) \
11225156 ((__m128i)__builtin_ia32_gatherd_q((__v2di)_mm_undefined_si128(), \
11235157 (long long const *)(m), \
11245158 (__v4si)(__m128i)(i), \
11255159 (__v2di)_mm_set1_epi64x(-1), (s)))
11265160
5161/// Gathers four 64-bit integer values from memory \a m using scaled indexes
5162/// from the 128-bit vector of [4 x i32] in \a i.
5163///
5164/// \code{.operation}
5165/// FOR element := 0 to 3
5166/// j := element*64
5167/// k := element*32
5168/// result[j+63:j] := Load64(m + SignExtend(i[k+31:k])*s)
5169/// ENDFOR
5170/// \endcode
5171///
5172/// \headerfile <immintrin.h>
5173///
5174/// \code
5175/// __m256i _mm256_i32gather_epi64(const long long *m, __m128i i, const int s);
5176/// \endcode
5177///
5178/// This intrinsic corresponds to the \c VPGATHERDQ instruction.
5179///
5180/// \param m
5181/// A pointer to the memory used for loading values.
5182/// \param i
5183/// A 128-bit vector of [4 x i32] containing signed indexes into \a m.
5184/// \param s
5185/// A literal constant scale factor for the indexes in \a i. Must be
5186/// 1, 2, 4, or 8.
5187/// \returns A 256-bit vector of [4 x i64] containing the gathered values.
11275188#define _mm256_i32gather_epi64(m, i, s) \
11285189 ((__m256i)__builtin_ia32_gatherd_q256((__v4di)_mm256_undefined_si256(), \
11295190 (long long const *)(m), \
11305191 (__v4si)(__m128i)(i), \
11315192 (__v4di)_mm256_set1_epi64x(-1), (s)))
11325193
5194/// Gathers two 64-bit integer values from memory \a m using scaled indexes
5195/// from the 128-bit vector of [2 x i64] in \a i.
5196///
5197/// \code{.operation}
5198/// FOR element := 0 to 1
5199/// j := element*64
5200/// k := element*64
5201/// result[j+63:j] := Load64(m + SignExtend(i[k+63:k])*s)
5202/// ENDFOR
5203/// \endcode
5204///
5205/// \headerfile <immintrin.h>
5206///
5207/// \code
5208/// __m128i _mm_i64gather_epi64(const long long *m, __m128i i, const int s);
5209/// \endcode
5210///
5211/// This intrinsic corresponds to the \c VPGATHERQQ instruction.
5212///
5213/// \param m
5214/// A pointer to the memory used for loading values.
5215/// \param i
5216/// A 128-bit vector of [2 x i64] containing signed indexes into \a m.
5217/// \param s
5218/// A literal constant scale factor for the indexes in \a i. Must be
5219/// 1, 2, 4, or 8.
5220/// \returns A 128-bit vector of [2 x i64] containing the gathered values.
11335221#define _mm_i64gather_epi64(m, i, s) \
11345222 ((__m128i)__builtin_ia32_gatherq_q((__v2di)_mm_undefined_si128(), \
11355223 (long long const *)(m), \
11365224 (__v2di)(__m128i)(i), \
11375225 (__v2di)_mm_set1_epi64x(-1), (s)))
11385226
5227/// Gathers four 64-bit integer values from memory \a m using scaled indexes
5228/// from the 256-bit vector of [4 x i64] in \a i.
5229///
5230/// \code{.operation}
5231/// FOR element := 0 to 3
5232/// j := element*64
5233/// k := element*64
5234/// result[j+63:j] := Load64(m + SignExtend(i[k+63:k])*s)
5235/// ENDFOR
5236/// \endcode
5237///
5238/// \headerfile <immintrin.h>
5239///
5240/// \code
5241/// __m256i _mm256_i64gather_epi64(const long long *m, __m256i i, const int s);
5242/// \endcode
5243///
5244/// This intrinsic corresponds to the \c VPGATHERQQ instruction.
5245///
5246/// \param m
5247/// A pointer to the memory used for loading values.
5248/// \param i
5249/// A 256-bit vector of [4 x i64] containing signed indexes into \a m.
5250/// \param s
5251/// A literal constant scale factor for the indexes in \a i. Must be
5252/// 1, 2, 4, or 8.
5253/// \returns A 256-bit vector of [4 x i64] containing the gathered values.
11395254#define _mm256_i64gather_epi64(m, i, s) \
11405255 ((__m256i)__builtin_ia32_gatherq_q256((__v4di)_mm256_undefined_si256(), \
11415256 (long long const *)(m), \
lib/include/avx512fintrin.h+17-7
......@@ -397,14 +397,15 @@ _mm512_broadcastsd_pd(__m128d __A)
397397static __inline __m512d __DEFAULT_FN_ATTRS512
398398_mm512_castpd256_pd512(__m256d __a)
399399{
400 return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, -1, -1, -1, -1);
400 return __builtin_shufflevector(__a, __builtin_nondeterministic_value(__a), 0,
401 1, 2, 3, 4, 5, 6, 7);
401402}
402403
403404static __inline __m512 __DEFAULT_FN_ATTRS512
404405_mm512_castps256_ps512(__m256 __a)
405406{
406 return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, 4, 5, 6, 7,
407 -1, -1, -1, -1, -1, -1, -1, -1);
407 return __builtin_shufflevector(__a, __builtin_nondeterministic_value(__a), 0,
408 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
408409}
409410
410411static __inline __m128d __DEFAULT_FN_ATTRS512
......@@ -446,7 +447,10 @@ _mm512_castpd_si512 (__m512d __A)
446447static __inline__ __m512d __DEFAULT_FN_ATTRS512
447448_mm512_castpd128_pd512 (__m128d __A)
448449{
449 return __builtin_shufflevector( __A, __A, 0, 1, -1, -1, -1, -1, -1, -1);
450 __m256d __B = __builtin_nondeterministic_value(__B);
451 return __builtin_shufflevector(
452 __builtin_shufflevector(__A, __builtin_nondeterministic_value(__A), 0, 1, 2, 3),
453 __B, 0, 1, 2, 3, 4, 5, 6, 7);
450454}
451455
452456static __inline __m512d __DEFAULT_FN_ATTRS512
......@@ -464,19 +468,25 @@ _mm512_castps_si512 (__m512 __A)
464468static __inline__ __m512 __DEFAULT_FN_ATTRS512
465469_mm512_castps128_ps512 (__m128 __A)
466470{
467 return __builtin_shufflevector( __A, __A, 0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
471 __m256 __B = __builtin_nondeterministic_value(__B);
472 return __builtin_shufflevector(
473 __builtin_shufflevector(__A, __builtin_nondeterministic_value(__A), 0, 1, 2, 3, 4, 5, 6, 7),
474 __B, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
468475}
469476
470477static __inline__ __m512i __DEFAULT_FN_ATTRS512
471478_mm512_castsi128_si512 (__m128i __A)
472479{
473 return __builtin_shufflevector( __A, __A, 0, 1, -1, -1, -1, -1, -1, -1);
480 __m256i __B = __builtin_nondeterministic_value(__B);
481 return __builtin_shufflevector(
482 __builtin_shufflevector(__A, __builtin_nondeterministic_value(__A), 0, 1, 2, 3),
483 __B, 0, 1, 2, 3, 4, 5, 6, 7);
474484}
475485
476486static __inline__ __m512i __DEFAULT_FN_ATTRS512
477487_mm512_castsi256_si512 (__m256i __A)
478488{
479 return __builtin_shufflevector( __A, __A, 0, 1, 2, 3, -1, -1, -1, -1);
489 return __builtin_shufflevector( __A, __builtin_nondeterministic_value(__A), 0, 1, 2, 3, 4, 5, 6, 7);
480490}
481491
482492static __inline __m512 __DEFAULT_FN_ATTRS512
lib/include/avx512fp16intrin.h+12-8
......@@ -192,22 +192,26 @@ _mm512_castph512_ph256(__m512h __a) {
192192
193193static __inline__ __m256h __DEFAULT_FN_ATTRS256
194194_mm256_castph128_ph256(__m128h __a) {
195 return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1,
196 -1, -1, -1, -1, -1);
195 return __builtin_shufflevector(__a, __builtin_nondeterministic_value(__a),
196 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
197197}
198198
199199static __inline__ __m512h __DEFAULT_FN_ATTRS512
200200_mm512_castph128_ph512(__m128h __a) {
201 return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1,
202 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
203 -1, -1, -1, -1, -1, -1, -1, -1, -1);
201 __m256h __b = __builtin_nondeterministic_value(__b);
202 return __builtin_shufflevector(
203 __builtin_shufflevector(__a, __builtin_nondeterministic_value(__a),
204 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
205 __b, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
206 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31);
204207}
205208
206209static __inline__ __m512h __DEFAULT_FN_ATTRS512
207210_mm512_castph256_ph512(__m256h __a) {
208 return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
209 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1,
210 -1, -1, -1, -1, -1, -1, -1, -1);
211 return __builtin_shufflevector(__a, __builtin_nondeterministic_value(__a), 0,
212 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
213 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
214 27, 28, 29, 30, 31);
211215}
212216
213217/// Constructs a 256-bit floating-point vector of [16 x half] from a
lib/include/avxintrin.h+20-7
......@@ -3017,8 +3017,11 @@ _mm256_zeroupper(void)
30173017static __inline __m128 __DEFAULT_FN_ATTRS128
30183018_mm_broadcast_ss(float const *__a)
30193019{
3020 float __f = *__a;
3021 return __extension__ (__m128)(__v4sf){ __f, __f, __f, __f };
3020 struct __mm_broadcast_ss_struct {
3021 float __f;
3022 } __attribute__((__packed__, __may_alias__));
3023 float __f = ((const struct __mm_broadcast_ss_struct*)__a)->__f;
3024 return __extension__ (__m128){ __f, __f, __f, __f };
30223025}
30233026
30243027/// Loads a scalar double-precision floating point value from the
......@@ -3036,7 +3039,10 @@ _mm_broadcast_ss(float const *__a)
30363039static __inline __m256d __DEFAULT_FN_ATTRS
30373040_mm256_broadcast_sd(double const *__a)
30383041{
3039 double __d = *__a;
3042 struct __mm256_broadcast_sd_struct {
3043 double __d;
3044 } __attribute__((__packed__, __may_alias__));
3045 double __d = ((const struct __mm256_broadcast_sd_struct*)__a)->__d;
30403046 return __extension__ (__m256d)(__v4df){ __d, __d, __d, __d };
30413047}
30423048
......@@ -3055,7 +3061,10 @@ _mm256_broadcast_sd(double const *__a)
30553061static __inline __m256 __DEFAULT_FN_ATTRS
30563062_mm256_broadcast_ss(float const *__a)
30573063{
3058 float __f = *__a;
3064 struct __mm256_broadcast_ss_struct {
3065 float __f;
3066 } __attribute__((__packed__, __may_alias__));
3067 float __f = ((const struct __mm256_broadcast_ss_struct*)__a)->__f;
30593068 return __extension__ (__m256)(__v8sf){ __f, __f, __f, __f, __f, __f, __f, __f };
30603069}
30613070
......@@ -4499,7 +4508,8 @@ _mm256_castsi256_si128(__m256i __a)
44994508static __inline __m256d __DEFAULT_FN_ATTRS
45004509_mm256_castpd128_pd256(__m128d __a)
45014510{
4502 return __builtin_shufflevector((__v2df)__a, (__v2df)__a, 0, 1, -1, -1);
4511 return __builtin_shufflevector(
4512 (__v2df)__a, (__v2df)__builtin_nondeterministic_value(__a), 0, 1, 2, 3);
45034513}
45044514
45054515/// Constructs a 256-bit floating-point vector of [8 x float] from a
......@@ -4520,7 +4530,9 @@ _mm256_castpd128_pd256(__m128d __a)
45204530static __inline __m256 __DEFAULT_FN_ATTRS
45214531_mm256_castps128_ps256(__m128 __a)
45224532{
4523 return __builtin_shufflevector((__v4sf)__a, (__v4sf)__a, 0, 1, 2, 3, -1, -1, -1, -1);
4533 return __builtin_shufflevector((__v4sf)__a,
4534 (__v4sf)__builtin_nondeterministic_value(__a),
4535 0, 1, 2, 3, 4, 5, 6, 7);
45244536}
45254537
45264538/// Constructs a 256-bit integer vector from a 128-bit integer vector.
......@@ -4539,7 +4551,8 @@ _mm256_castps128_ps256(__m128 __a)
45394551static __inline __m256i __DEFAULT_FN_ATTRS
45404552_mm256_castsi128_si256(__m128i __a)
45414553{
4542 return __builtin_shufflevector((__v2di)__a, (__v2di)__a, 0, 1, -1, -1);
4554 return __builtin_shufflevector(
4555 (__v2di)__a, (__v2di)__builtin_nondeterministic_value(__a), 0, 1, 2, 3);
45434556}
45444557
45454558/// Constructs a 256-bit floating-point vector of [4 x double] from a
lib/include/avxvnniint16intrin.h created+473
......@@ -0,0 +1,473 @@
1/*===----------- avxvnniint16intrin.h - AVXVNNIINT16 intrinsics-------------===
2 *
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 * See https://llvm.org/LICENSE.txt for license information.
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 *
7 *===-----------------------------------------------------------------------===
8 */
9
10#ifndef __IMMINTRIN_H
11#error \
12 "Never use <avxvnniint16intrin.h> directly; include <immintrin.h> instead."
13#endif // __IMMINTRIN_H
14
15#ifndef __AVXVNNIINT16INTRIN_H
16#define __AVXVNNIINT16INTRIN_H
17
18/* Define the default attributes for the functions in this file. */
19#define __DEFAULT_FN_ATTRS128 \
20 __attribute__((__always_inline__, __nodebug__, __target__("avxvnniint16"), \
21 __min_vector_width__(128)))
22#define __DEFAULT_FN_ATTRS256 \
23 __attribute__((__always_inline__, __nodebug__, __target__("avxvnniint16"), \
24 __min_vector_width__(256)))
25
26/// Multiply groups of 2 adjacent pairs of signed 16-bit integers in \a __A with
27/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
28/// signed 16-bit results. Sum these 2 results with the corresponding
29/// 32-bit integer in \a __W, and store the packed 32-bit results in \a dst.
30///
31/// \headerfile <immintrin.h>
32///
33/// \code
34/// __m128i _mm_dpwsud_epi32(__m128i __W, __m128i __A, __m128i __B)
35/// \endcode
36///
37/// This intrinsic corresponds to the \c VPDPWSUD instruction.
38///
39/// \param __W
40/// A 128-bit vector of [4 x int].
41/// \param __A
42/// A 128-bit vector of [8 x short].
43/// \param __B
44/// A 128-bit vector of [8 x unsigned short].
45/// \returns
46/// A 128-bit vector of [4 x int].
47///
48/// \code{.operation}
49/// FOR j := 0 to 3
50/// tmp1.dword := SignExtend32(__A.word[2*j]) * ZeroExtend32(__B.word[2*j])
51/// tmp2.dword := SignExtend32(__A.word[2*j+1]) * ZeroExtend32(__B.word[2*j+1])
52/// dst.dword[j] := __W.dword[j] + tmp1 + tmp2
53/// ENDFOR
54/// dst[MAX:128] := 0
55/// \endcode
56static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwsud_epi32(__m128i __W,
57 __m128i __A,
58 __m128i __B) {
59 return (__m128i)__builtin_ia32_vpdpwsud128((__v4si)__W, (__v4si)__A,
60 (__v4si)__B);
61}
62
63/// Multiply groups of 2 adjacent pairs of signed 16-bit integers in \a __A with
64/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
65/// signed 16-bit results. Sum these 2 results with the corresponding
66/// 32-bit integer in \a __W, and store the packed 32-bit results in \a dst.
67///
68/// \headerfile <immintrin.h>
69///
70/// \code
71/// __m256i _mm256_dpwsud_epi32(__m256i __W, __m256i __A, __m256i __B)
72/// \endcode
73///
74/// This intrinsic corresponds to the \c VPDPWSUD instruction.
75///
76/// \param __W
77/// A 256-bit vector of [8 x int].
78/// \param __A
79/// A 256-bit vector of [16 x short].
80/// \param __B
81/// A 256-bit vector of [16 x unsigned short].
82/// \returns
83/// A 256-bit vector of [8 x int].
84///
85/// \code{.operation}
86/// FOR j := 0 to 7
87/// tmp1.dword := SignExtend32(__A.word[2*j]) * ZeroExtend32(__B.word[2*j])
88/// tmp2.dword := SignExtend32(__A.word[2*j+1]) * ZeroExtend32(__B.word[2*j+1])
89/// dst.dword[j] := __W.dword[j] + tmp1 + tmp2
90/// ENDFOR
91/// dst[MAX:256] := 0
92/// \endcode
93static __inline__ __m256i __DEFAULT_FN_ATTRS256
94_mm256_dpwsud_epi32(__m256i __W, __m256i __A, __m256i __B) {
95 return (__m256i)__builtin_ia32_vpdpwsud256((__v8si)__W, (__v8si)__A,
96 (__v8si)__B);
97}
98
99/// Multiply groups of 2 adjacent pairs of signed 16-bit integers in \a __A with
100/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
101/// signed 16-bit results. Sum these 2 results with the corresponding
102/// 32-bit integer in \a __W with signed saturation, and store the packed
103/// 32-bit results in \a dst.
104///
105/// \headerfile <immintrin.h>
106///
107/// \code
108/// __m128i _mm_dpwsuds_epi32(__m128i __W, __m128i __A, __m128i __B)
109/// \endcode
110///
111/// This intrinsic corresponds to the \c VPDPWSUDS instruction.
112///
113/// \param __W
114/// A 128-bit vector of [4 x int].
115/// \param __A
116/// A 128-bit vector of [8 x short].
117/// \param __B
118/// A 128-bit vector of [8 x unsigned short].
119/// \returns
120/// A 128-bit vector of [4 x int].
121///
122/// \code{.operation}
123/// FOR j := 0 to 3
124/// tmp1.dword := SignExtend32(__A.word[2*j]) * ZeroExtend32(__B.word[2*j])
125/// tmp2.dword := SignExtend32(__A.word[2*j+1]) * ZeroExtend32(__B.word[2*j+1])
126/// dst.dword[j] := SIGNED_DWORD_SATURATE(__W.dword[j] + tmp1 + tmp2)
127/// ENDFOR
128/// dst[MAX:128] := 0
129/// \endcode
130static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwsuds_epi32(__m128i __W,
131 __m128i __A,
132 __m128i __B) {
133 return (__m128i)__builtin_ia32_vpdpwsuds128((__v4si)__W, (__v4si)__A,
134 (__v4si)__B);
135}
136
137/// Multiply groups of 2 adjacent pairs of signed 16-bit integers in \a __A with
138/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
139/// signed 16-bit results. Sum these 2 results with the corresponding
140/// 32-bit integer in \a __W with signed saturation, and store the packed
141/// 32-bit results in \a dst.
142///
143/// \headerfile <immintrin.h>
144///
145/// \code
146/// __m256i _mm256_dpwsuds_epi32(__m256i __W, __m256i __A, __m256i __B)
147/// \endcode
148///
149/// This intrinsic corresponds to the \c VPDPWSUDS instruction.
150///
151/// \param __W
152/// A 256-bit vector of [8 x int].
153/// \param __A
154/// A 256-bit vector of [16 x short].
155/// \param __B
156/// A 256-bit vector of [16 x unsigned short].
157/// \returns
158/// A 256-bit vector of [8 x int].
159///
160/// \code{.operation}
161/// FOR j := 0 to 7
162/// tmp1.dword := SignExtend32(__A.word[2*j]) * ZeroExtend32(__B.word[2*j])
163/// tmp2.dword := SignExtend32(__A.word[2*j+1]) * ZeroExtend32(__B.word[2*j+1])
164/// dst.dword[j] := SIGNED_DWORD_SATURATE(__W.dword[j] + tmp1 + tmp2)
165/// ENDFOR
166/// dst[MAX:256] := 0
167/// \endcode
168static __inline__ __m256i __DEFAULT_FN_ATTRS256
169_mm256_dpwsuds_epi32(__m256i __W, __m256i __A, __m256i __B) {
170 return (__m256i)__builtin_ia32_vpdpwsuds256((__v8si)__W, (__v8si)__A,
171 (__v8si)__B);
172}
173
174/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
175/// corresponding signed 16-bit integers in \a __B, producing 2 intermediate
176/// signed 16-bit results. Sum these 2 results with the corresponding
177/// 32-bit integer in \a __W, and store the packed 32-bit results in \a dst.
178///
179/// \headerfile <immintrin.h>
180///
181/// \code
182/// __m128i _mm_dpbusd_epi32(__m128i __W, __m128i __A, __m128i __B)
183/// \endcode
184///
185/// This intrinsic corresponds to the \c VPDPWUSD instruction.
186///
187/// \param __W
188/// A 128-bit vector of [4 x int].
189/// \param __A
190/// A 128-bit vector of [8 x unsigned short].
191/// \param __B
192/// A 128-bit vector of [8 x short].
193/// \returns
194/// A 128-bit vector of [4 x int].
195///
196/// \code{.operation}
197/// FOR j := 0 to 3
198/// tmp1.dword := ZeroExtend32(__A.word[2*j]) * SignExtend32(__B.word[2*j])
199/// tmp2.dword := ZeroExtend32(__A.word[2*j+1]) * SignExtend32(__B.word[2*j+1])
200/// dst.dword[j] := __W.dword[j] + tmp1 + tmp2
201/// ENDFOR
202/// dst[MAX:128] := 0
203/// \endcode
204static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwusd_epi32(__m128i __W,
205 __m128i __A,
206 __m128i __B) {
207 return (__m128i)__builtin_ia32_vpdpwusd128((__v4si)__W, (__v4si)__A,
208 (__v4si)__B);
209}
210
211/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
212/// corresponding signed 16-bit integers in \a __B, producing 2 intermediate
213/// signed 16-bit results. Sum these 2 results with the corresponding
214/// 32-bit integer in \a __W, and store the packed 32-bit results in \a dst.
215///
216/// \headerfile <immintrin.h>
217///
218/// \code
219/// __m256i _mm256_dpwusd_epi32(__m256i __W, __m256i __A, __m256i __B)
220/// \endcode
221///
222/// This intrinsic corresponds to the \c VPDPWUSD instruction.
223///
224/// \param __W
225/// A 256-bit vector of [8 x int].
226/// \param __A
227/// A 256-bit vector of [16 x unsigned short].
228/// \param __B
229/// A 256-bit vector of [16 x short].
230/// \returns
231/// A 256-bit vector of [8 x int].
232///
233/// \code{.operation}
234/// FOR j := 0 to 7
235/// tmp1.dword := ZeroExtend32(__A.word[2*j]) * SignExtend32(__B.word[2*j])
236/// tmp2.dword := ZeroExtend32(__A.word[2*j+1]) * SignExtend32(__B.word[2*j+1])
237/// dst.dword[j] := __W.dword[j] + tmp1 + tmp2
238/// ENDFOR
239/// dst[MAX:256] := 0
240/// \endcode
241static __inline__ __m256i __DEFAULT_FN_ATTRS256
242_mm256_dpwusd_epi32(__m256i __W, __m256i __A, __m256i __B) {
243 return (__m256i)__builtin_ia32_vpdpwusd256((__v8si)__W, (__v8si)__A,
244 (__v8si)__B);
245}
246
247/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
248/// corresponding signed 16-bit integers in \a __B, producing 2 intermediate
249/// signed 16-bit results. Sum these 2 results with the corresponding
250/// 32-bit integer in \a __W with signed saturation, and store the packed
251/// 32-bit results in \a dst.
252///
253/// \headerfile <immintrin.h>
254///
255/// \code
256/// __m128i _mm_dpwusds_epi32(__m128i __W, __m128i __A, __m128i __B)
257/// \endcode
258///
259/// This intrinsic corresponds to the \c VPDPWSUDS instruction.
260///
261/// \param __W
262/// A 128-bit vector of [4 x int].
263/// \param __A
264/// A 128-bit vector of [8 x unsigned short].
265/// \param __B
266/// A 128-bit vector of [8 x short].
267/// \returns
268/// A 128-bit vector of [4 x int].
269///
270/// \code{.operation}
271/// FOR j := 0 to 3
272/// tmp1.dword := ZeroExtend32(__A.word[2*j]) * SignExtend32(__B.word[2*j])
273/// tmp2.dword := ZeroExtend32(__A.word[2*j+1]) * SignExtend32(__B.word[2*j+1])
274/// dst.dword[j] := SIGNED_DWORD_SATURATE(__W.dword[j] + tmp1 + tmp2)
275/// ENDFOR
276/// dst[MAX:128] := 0
277/// \endcode
278static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwusds_epi32(__m128i __W,
279 __m128i __A,
280 __m128i __B) {
281 return (__m128i)__builtin_ia32_vpdpwusds128((__v4si)__W, (__v4si)__A,
282 (__v4si)__B);
283}
284
285/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
286/// corresponding signed 16-bit integers in \a __B, producing 2 intermediate
287/// signed 16-bit results. Sum these 2 results with the corresponding
288/// 32-bit integer in \a __W with signed saturation, and store the packed
289/// 32-bit results in \a dst.
290///
291/// \headerfile <immintrin.h>
292///
293/// \code
294/// __m256i _mm256_dpwsuds_epi32(__m256i __W, __m256i __A, __m256i __B)
295/// \endcode
296///
297/// This intrinsic corresponds to the \c VPDPWSUDS instruction.
298///
299/// \param __W
300/// A 256-bit vector of [8 x int].
301/// \param __A
302/// A 256-bit vector of [16 x unsigned short].
303/// \param __B
304/// A 256-bit vector of [16 x short].
305/// \returns
306/// A 256-bit vector of [8 x int].
307///
308/// \code{.operation}
309/// FOR j := 0 to 7
310/// tmp1.dword := ZeroExtend32(__A.word[2*j]) * SignExtend32(__B.word[2*j])
311/// tmp2.dword := ZeroExtend32(__A.word[2*j+1]) * SignExtend32(__B.word[2*j+1])
312/// dst.dword[j] := SIGNED_DWORD_SATURATE(__W.dword[j] + tmp1 + tmp2)
313/// ENDFOR
314/// dst[MAX:256] := 0
315/// \endcode
316static __inline__ __m256i __DEFAULT_FN_ATTRS256
317_mm256_dpwusds_epi32(__m256i __W, __m256i __A, __m256i __B) {
318 return (__m256i)__builtin_ia32_vpdpwusds256((__v8si)__W, (__v8si)__A,
319 (__v8si)__B);
320}
321
322/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
323/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
324/// signed 16-bit results. Sum these 2 results with the corresponding
325/// 32-bit integer in \a __W, and store the packed 32-bit results in \a dst.
326///
327/// \headerfile <immintrin.h>
328///
329/// \code
330/// __m128i _mm_dpwuud_epi32(__m128i __W, __m128i __A, __m128i __B)
331/// \endcode
332///
333/// This intrinsic corresponds to the \c VPDPWUUD instruction.
334///
335/// \param __W
336/// A 128-bit vector of [4 x unsigned int].
337/// \param __A
338/// A 128-bit vector of [8 x unsigned short].
339/// \param __B
340/// A 128-bit vector of [8 x unsigned short].
341/// \returns
342/// A 128-bit vector of [4 x unsigned int].
343///
344/// \code{.operation}
345/// FOR j := 0 to 3
346/// tmp1.dword := ZeroExtend32(__A.word[2*j]) * ZeroExtend32(__B.word[2*j])
347/// tmp2.dword := ZeroExtend32(__A.word[2*j+1]) * ZeroExtend32(__B.word[2*j+1])
348/// dst.dword[j] := __W.dword[j] + tmp1 + tmp2
349/// ENDFOR
350/// dst[MAX:128] := 0
351/// \endcode
352static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwuud_epi32(__m128i __W,
353 __m128i __A,
354 __m128i __B) {
355 return (__m128i)__builtin_ia32_vpdpwuud128((__v4si)__W, (__v4si)__A,
356 (__v4si)__B);
357}
358
359/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
360/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
361/// signed 16-bit results. Sum these 2 results with the corresponding
362/// 32-bit integer in \a __W, and store the packed 32-bit results in \a dst.
363///
364/// \headerfile <immintrin.h>
365///
366/// \code
367/// __m256i _mm256_dpwuud_epi32(__m256i __W, __m256i __A, __m256i __B)
368/// \endcode
369///
370/// This intrinsic corresponds to the \c VPDPWUUD instruction.
371///
372/// \param __W
373/// A 256-bit vector of [8 x unsigned int].
374/// \param __A
375/// A 256-bit vector of [16 x unsigned short].
376/// \param __B
377/// A 256-bit vector of [16 x unsigned short].
378/// \returns
379/// A 256-bit vector of [8 x unsigned int].
380///
381/// \code{.operation}
382/// FOR j := 0 to 7
383/// tmp1.dword := ZeroExtend32(__A.word[2*j]) * ZeroExtend32(__B.word[2*j])
384/// tmp2.dword := ZeroExtend32(__A.word[2*j+1]) * ZeroExtend32(__B.word[2*j+1])
385/// dst.dword[j] := __W.dword[j] + tmp1 + tmp2
386/// ENDFOR
387/// dst[MAX:256] := 0
388/// \endcode
389static __inline__ __m256i __DEFAULT_FN_ATTRS256
390_mm256_dpwuud_epi32(__m256i __W, __m256i __A, __m256i __B) {
391 return (__m256i)__builtin_ia32_vpdpwuud256((__v8si)__W, (__v8si)__A,
392 (__v8si)__B);
393}
394
395/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
396/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
397/// signed 16-bit results. Sum these 2 results with the corresponding
398/// 32-bit integer in \a __W with signed saturation, and store the packed
399/// 32-bit results in \a dst.
400///
401/// \headerfile <immintrin.h>
402///
403/// \code
404/// __m128i _mm_dpwsuds_epi32(__m128i __W, __m128i __A, __m128i __B)
405/// \endcode
406///
407/// This intrinsic corresponds to the \c VPDPWSUDS instruction.
408///
409/// \param __W
410/// A 128-bit vector of [4 x unsigned int].
411/// \param __A
412/// A 128-bit vector of [8 x unsigned short].
413/// \param __B
414/// A 128-bit vector of [8 x unsigned short].
415/// \returns
416/// A 128-bit vector of [4 x unsigned int].
417///
418/// \code{.operation}
419/// FOR j := 0 to 3
420/// tmp1.dword := ZeroExtend32(__A.word[2*j]) * ZeroExtend32(__B.word[2*j])
421/// tmp2.dword := ZeroExtend32(__A.word[2*j+1]) * ZeroExtend32(__B.word[2*j+1])
422/// dst.dword[j] := UNSIGNED_DWORD_SATURATE(__W.dword[j] + tmp1 + tmp2)
423/// ENDFOR
424/// dst[MAX:128] := 0
425/// \endcode
426static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwuuds_epi32(__m128i __W,
427 __m128i __A,
428 __m128i __B) {
429 return (__m128i)__builtin_ia32_vpdpwuuds128((__v4si)__W, (__v4si)__A,
430 (__v4si)__B);
431}
432
433/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
434/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
435/// signed 16-bit results. Sum these 2 results with the corresponding
436/// 32-bit integer in \a __W with signed saturation, and store the packed
437/// 32-bit results in \a dst.
438///
439/// \headerfile <immintrin.h>
440///
441/// \code
442/// __m256i _mm256_dpwuuds_epi32(__m256i __W, __m256i __A, __m256i __B)
443/// \endcode
444///
445/// This intrinsic corresponds to the \c VPDPWSUDS instruction.
446///
447/// \param __W
448/// A 256-bit vector of [8 x unsigned int].
449/// \param __A
450/// A 256-bit vector of [16 x unsigned short].
451/// \param __B
452/// A 256-bit vector of [16 x unsigned short].
453/// \returns
454/// A 256-bit vector of [8 x unsigned int].
455///
456/// \code{.operation}
457/// FOR j := 0 to 7
458/// tmp1.dword := ZeroExtend32(__A.word[2*j]) * ZeroExtend32(__B.word[2*j])
459/// tmp2.dword := ZeroExtend32(__A.word[2*j+1]) * ZeroExtend32(__B.word[2*j+1])
460/// dst.dword[j] := UNSIGNED_DWORD_SATURATE(__W.dword[j] + tmp1 + tmp2)
461/// ENDFOR
462/// dst[MAX:256] := 0
463/// \endcode
464static __inline__ __m256i __DEFAULT_FN_ATTRS256
465_mm256_dpwuuds_epi32(__m256i __W, __m256i __A, __m256i __B) {
466 return (__m256i)__builtin_ia32_vpdpwuuds256((__v8si)__W, (__v8si)__A,
467 (__v8si)__B);
468}
469
470#undef __DEFAULT_FN_ATTRS128
471#undef __DEFAULT_FN_ATTRS256
472
473#endif // __AVXVNNIINT16INTRIN_H
lib/include/bmi2intrin.h+187-13
......@@ -7,8 +7,8 @@
77 *===-----------------------------------------------------------------------===
88 */
99
10#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H
11#error "Never use <bmi2intrin.h> directly; include <x86intrin.h> instead."
10#ifndef __IMMINTRIN_H
11#error "Never use <bmi2intrin.h> directly; include <immintrin.h> instead."
1212#endif
1313
1414#ifndef __BMI2INTRIN_H
......@@ -17,44 +17,228 @@
1717/* Define the default attributes for the functions in this file. */
1818#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("bmi2")))
1919
20/// Copies the unsigned 32-bit integer \a __X and zeroes the upper bits
21/// starting at bit number \a __Y.
22///
23/// \code{.operation}
24/// i := __Y[7:0]
25/// result := __X
26/// IF i < 32
27/// result[31:i] := 0
28/// FI
29/// \endcode
30///
31/// \headerfile <immintrin.h>
32///
33/// This intrinsic corresponds to the \c BZHI instruction.
34///
35/// \param __X
36/// The 32-bit source value to copy.
37/// \param __Y
38/// The lower 8 bits specify the bit number of the lowest bit to zero.
39/// \returns The partially zeroed 32-bit value.
2040static __inline__ unsigned int __DEFAULT_FN_ATTRS
2141_bzhi_u32(unsigned int __X, unsigned int __Y)
2242{
2343 return __builtin_ia32_bzhi_si(__X, __Y);
2444}
2545
46/// Deposit (scatter) low-order bits from the unsigned 32-bit integer \a __X
47/// into the 32-bit result, according to the mask in the unsigned 32-bit
48/// integer \a __Y. All other bits of the result are zero.
49///
50/// \code{.operation}
51/// i := 0
52/// result := 0
53/// FOR m := 0 TO 31
54/// IF __Y[m] == 1
55/// result[m] := __X[i]
56/// i := i + 1
57/// ENDIF
58/// ENDFOR
59/// \endcode
60///
61/// \headerfile <immintrin.h>
62///
63/// This intrinsic corresponds to the \c PDEP instruction.
64///
65/// \param __X
66/// The 32-bit source value to copy.
67/// \param __Y
68/// The 32-bit mask specifying where to deposit source bits.
69/// \returns The 32-bit result.
2670static __inline__ unsigned int __DEFAULT_FN_ATTRS
2771_pdep_u32(unsigned int __X, unsigned int __Y)
2872{
2973 return __builtin_ia32_pdep_si(__X, __Y);
3074}
3175
76/// Extract (gather) bits from the unsigned 32-bit integer \a __X into the
77/// low-order bits of the 32-bit result, according to the mask in the
78/// unsigned 32-bit integer \a __Y. All other bits of the result are zero.
79///
80/// \code{.operation}
81/// i := 0
82/// result := 0
83/// FOR m := 0 TO 31
84/// IF __Y[m] == 1
85/// result[i] := __X[m]
86/// i := i + 1
87/// ENDIF
88/// ENDFOR
89/// \endcode
90///
91/// \headerfile <immintrin.h>
92///
93/// This intrinsic corresponds to the \c PEXT instruction.
94///
95/// \param __X
96/// The 32-bit source value to copy.
97/// \param __Y
98/// The 32-bit mask specifying which source bits to extract.
99/// \returns The 32-bit result.
32100static __inline__ unsigned int __DEFAULT_FN_ATTRS
33101_pext_u32(unsigned int __X, unsigned int __Y)
34102{
35103 return __builtin_ia32_pext_si(__X, __Y);
36104}
37105
106/// Multiplies the unsigned 32-bit integers \a __X and \a __Y to form a
107/// 64-bit product. Stores the upper 32 bits of the product in the
108/// memory at \a __P and returns the lower 32 bits.
109///
110/// \code{.operation}
111/// Store32(__P, (__X * __Y)[63:32])
112/// result := (__X * __Y)[31:0]
113/// \endcode
114///
115/// \headerfile <immintrin.h>
116///
117/// This intrinsic corresponds to the \c MULX instruction.
118///
119/// \param __X
120/// An unsigned 32-bit multiplicand.
121/// \param __Y
122/// An unsigned 32-bit multiplicand.
123/// \param __P
124/// A pointer to memory for storing the upper half of the product.
125/// \returns The lower half of the product.
126static __inline__ unsigned int __DEFAULT_FN_ATTRS
127_mulx_u32(unsigned int __X, unsigned int __Y, unsigned int *__P)
128{
129 unsigned long long __res = (unsigned long long) __X * __Y;
130 *__P = (unsigned int)(__res >> 32);
131 return (unsigned int)__res;
132}
133
38134#ifdef __x86_64__
39135
136/// Copies the unsigned 64-bit integer \a __X and zeroes the upper bits
137/// starting at bit number \a __Y.
138///
139/// \code{.operation}
140/// i := __Y[7:0]
141/// result := __X
142/// IF i < 64
143/// result[63:i] := 0
144/// FI
145/// \endcode
146///
147/// \headerfile <immintrin.h>
148///
149/// This intrinsic corresponds to the \c BZHI instruction.
150///
151/// \param __X
152/// The 64-bit source value to copy.
153/// \param __Y
154/// The lower 8 bits specify the bit number of the lowest bit to zero.
155/// \returns The partially zeroed 64-bit value.
40156static __inline__ unsigned long long __DEFAULT_FN_ATTRS
41157_bzhi_u64(unsigned long long __X, unsigned long long __Y)
42158{
43159 return __builtin_ia32_bzhi_di(__X, __Y);
44160}
45161
162/// Deposit (scatter) low-order bits from the unsigned 64-bit integer \a __X
163/// into the 64-bit result, according to the mask in the unsigned 64-bit
164/// integer \a __Y. All other bits of the result are zero.
165///
166/// \code{.operation}
167/// i := 0
168/// result := 0
169/// FOR m := 0 TO 63
170/// IF __Y[m] == 1
171/// result[m] := __X[i]
172/// i := i + 1
173/// ENDIF
174/// ENDFOR
175/// \endcode
176///
177/// \headerfile <immintrin.h>
178///
179/// This intrinsic corresponds to the \c PDEP instruction.
180///
181/// \param __X
182/// The 64-bit source value to copy.
183/// \param __Y
184/// The 64-bit mask specifying where to deposit source bits.
185/// \returns The 64-bit result.
46186static __inline__ unsigned long long __DEFAULT_FN_ATTRS
47187_pdep_u64(unsigned long long __X, unsigned long long __Y)
48188{
49189 return __builtin_ia32_pdep_di(__X, __Y);
50190}
51191
192/// Extract (gather) bits from the unsigned 64-bit integer \a __X into the
193/// low-order bits of the 64-bit result, according to the mask in the
194/// unsigned 64-bit integer \a __Y. All other bits of the result are zero.
195///
196/// \code{.operation}
197/// i := 0
198/// result := 0
199/// FOR m := 0 TO 63
200/// IF __Y[m] == 1
201/// result[i] := __X[m]
202/// i := i + 1
203/// ENDIF
204/// ENDFOR
205/// \endcode
206///
207/// \headerfile <immintrin.h>
208///
209/// This intrinsic corresponds to the \c PEXT instruction.
210///
211/// \param __X
212/// The 64-bit source value to copy.
213/// \param __Y
214/// The 64-bit mask specifying which source bits to extract.
215/// \returns The 64-bit result.
52216static __inline__ unsigned long long __DEFAULT_FN_ATTRS
53217_pext_u64(unsigned long long __X, unsigned long long __Y)
54218{
55219 return __builtin_ia32_pext_di(__X, __Y);
56220}
57221
222/// Multiplies the unsigned 64-bit integers \a __X and \a __Y to form a
223/// 128-bit product. Stores the upper 64 bits of the product to the
224/// memory addressed by \a __P and returns the lower 64 bits.
225///
226/// \code{.operation}
227/// Store64(__P, (__X * __Y)[127:64])
228/// result := (__X * __Y)[63:0]
229/// \endcode
230///
231/// \headerfile <immintrin.h>
232///
233/// This intrinsic corresponds to the \c MULX instruction.
234///
235/// \param __X
236/// An unsigned 64-bit multiplicand.
237/// \param __Y
238/// An unsigned 64-bit multiplicand.
239/// \param __P
240/// A pointer to memory for storing the upper half of the product.
241/// \returns The lower half of the product.
58242static __inline__ unsigned long long __DEFAULT_FN_ATTRS
59243_mulx_u64 (unsigned long long __X, unsigned long long __Y,
60244 unsigned long long *__P)
......@@ -64,17 +248,7 @@ _mulx_u64 (unsigned long long __X, unsigned long long __Y,
64248 return (unsigned long long) __res;
65249}
66250
67#else /* !__x86_64__ */
68
69static __inline__ unsigned int __DEFAULT_FN_ATTRS
70_mulx_u32 (unsigned int __X, unsigned int __Y, unsigned int *__P)
71{
72 unsigned long long __res = (unsigned long long) __X * __Y;
73 *__P = (unsigned int) (__res >> 32);
74 return (unsigned int) __res;
75}
76
77#endif /* !__x86_64__ */
251#endif /* __x86_64__ */
78252
79253#undef __DEFAULT_FN_ATTRS
80254
lib/include/clflushoptintrin.h+9
......@@ -17,6 +17,15 @@
1717/* Define the default attributes for the functions in this file. */
1818#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("clflushopt")))
1919
20/// Invalidates all levels of the cache hierarchy and flushes modified data to
21/// memory for the cache line specified by the address \a __m.
22///
23/// \headerfile <immintrin.h>
24///
25/// This intrinsic corresponds to the \c CLFLUSHOPT instruction.
26///
27/// \param __m
28/// An address within the cache line to flush and invalidate.
2029static __inline__ void __DEFAULT_FN_ATTRS
2130_mm_clflushopt(void const * __m) {
2231 __builtin_ia32_clflushopt(__m);
lib/include/clzerointrin.h+7-5
......@@ -6,7 +6,7 @@
66 *
77 *===-----------------------------------------------------------------------===
88 */
9#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H
9#ifndef __X86INTRIN_H
1010#error "Never use <clzerointrin.h> directly; include <x86intrin.h> instead."
1111#endif
1212
......@@ -17,14 +17,16 @@
1717#define __DEFAULT_FN_ATTRS \
1818 __attribute__((__always_inline__, __nodebug__, __target__("clzero")))
1919
20/// Loads the cache line address and zero's out the cacheline
20/// Zeroes out the cache line for the address \a __line. This uses a
21/// non-temporal store. Calling \c _mm_sfence() afterward might be needed
22/// to enforce ordering.
2123///
22/// \headerfile <clzerointrin.h>
24/// \headerfile <x86intrin.h>
2325///
24/// This intrinsic corresponds to the <c> CLZERO </c> instruction.
26/// This intrinsic corresponds to the \c CLZERO instruction.
2527///
2628/// \param __line
27/// A pointer to a cacheline which needs to be zeroed out.
29/// An address within the cache line to zero out.
2830static __inline__ void __DEFAULT_FN_ATTRS
2931_mm_clzero (void * __line)
3032{
lib/include/cuda_wrappers/bits/shared_ptr_base.h created+9
......@@ -0,0 +1,9 @@
1// CUDA headers define __noinline__ which interferes with libstdc++'s use of
2// `__attribute((__noinline__))`. In order to avoid compilation error,
3// temporarily unset __noinline__ when we include affected libstdc++ header.
4
5#pragma push_macro("__noinline__")
6#undef __noinline__
7#include_next "bits/shared_ptr_base.h"
8
9#pragma pop_macro("__noinline__")
lib/include/fmaintrin.h+564
......@@ -18,192 +18,756 @@
1818#define __DEFAULT_FN_ATTRS128 __attribute__((__always_inline__, __nodebug__, __target__("fma"), __min_vector_width__(128)))
1919#define __DEFAULT_FN_ATTRS256 __attribute__((__always_inline__, __nodebug__, __target__("fma"), __min_vector_width__(256)))
2020
21/// Computes a multiply-add of 128-bit vectors of [4 x float].
22/// For each element, computes <c> (__A * __B) + __C </c>.
23///
24/// \headerfile <immintrin.h>
25///
26/// This intrinsic corresponds to the \c VFMADD213PS instruction.
27///
28/// \param __A
29/// A 128-bit vector of [4 x float] containing the multiplicand.
30/// \param __B
31/// A 128-bit vector of [4 x float] containing the multiplier.
32/// \param __C
33/// A 128-bit vector of [4 x float] containing the addend.
34/// \returns A 128-bit vector of [4 x float] containing the result.
2135static __inline__ __m128 __DEFAULT_FN_ATTRS128
2236_mm_fmadd_ps(__m128 __A, __m128 __B, __m128 __C)
2337{
2438 return (__m128)__builtin_ia32_vfmaddps((__v4sf)__A, (__v4sf)__B, (__v4sf)__C);
2539}
2640
41/// Computes a multiply-add of 128-bit vectors of [2 x double].
42/// For each element, computes <c> (__A * __B) + __C </c>.
43///
44/// \headerfile <immintrin.h>
45///
46/// This intrinsic corresponds to the \c VFMADD213PD instruction.
47///
48/// \param __A
49/// A 128-bit vector of [2 x double] containing the multiplicand.
50/// \param __B
51/// A 128-bit vector of [2 x double] containing the multiplier.
52/// \param __C
53/// A 128-bit vector of [2 x double] containing the addend.
54/// \returns A 128-bit [2 x double] vector containing the result.
2755static __inline__ __m128d __DEFAULT_FN_ATTRS128
2856_mm_fmadd_pd(__m128d __A, __m128d __B, __m128d __C)
2957{
3058 return (__m128d)__builtin_ia32_vfmaddpd((__v2df)__A, (__v2df)__B, (__v2df)__C);
3159}
3260
61/// Computes a scalar multiply-add of the single-precision values in the
62/// low 32 bits of 128-bit vectors of [4 x float].
63/// \code
64/// result[31:0] = (__A[31:0] * __B[31:0]) + __C[31:0]
65/// result[127:32] = __A[127:32]
66/// \endcode
67///
68/// \headerfile <immintrin.h>
69///
70/// This intrinsic corresponds to the \c VFMADD213SS instruction.
71///
72/// \param __A
73/// A 128-bit vector of [4 x float] containing the multiplicand in the low
74/// 32 bits.
75/// \param __B
76/// A 128-bit vector of [4 x float] containing the multiplier in the low
77/// 32 bits.
78/// \param __C
79/// A 128-bit vector of [4 x float] containing the addend in the low
80/// 32 bits.
81/// \returns A 128-bit vector of [4 x float] containing the result in the low
82/// 32 bits and a copy of \a __A[127:32] in the upper 96 bits.
3383static __inline__ __m128 __DEFAULT_FN_ATTRS128
3484_mm_fmadd_ss(__m128 __A, __m128 __B, __m128 __C)
3585{
3686 return (__m128)__builtin_ia32_vfmaddss3((__v4sf)__A, (__v4sf)__B, (__v4sf)__C);
3787}
3888
89/// Computes a scalar multiply-add of the double-precision values in the
90/// low 64 bits of 128-bit vectors of [2 x double].
91/// \code
92/// result[63:0] = (__A[63:0] * __B[63:0]) + __C[63:0]
93/// result[127:64] = __A[127:64]
94/// \endcode
95///
96/// \headerfile <immintrin.h>
97///
98/// This intrinsic corresponds to the \c VFMADD213SD instruction.
99///
100/// \param __A
101/// A 128-bit vector of [2 x double] containing the multiplicand in the low
102/// 64 bits.
103/// \param __B
104/// A 128-bit vector of [2 x double] containing the multiplier in the low
105/// 64 bits.
106/// \param __C
107/// A 128-bit vector of [2 x double] containing the addend in the low
108/// 64 bits.
109/// \returns A 128-bit vector of [2 x double] containing the result in the low
110/// 64 bits and a copy of \a __A[127:64] in the upper 64 bits.
39111static __inline__ __m128d __DEFAULT_FN_ATTRS128
40112_mm_fmadd_sd(__m128d __A, __m128d __B, __m128d __C)
41113{
42114 return (__m128d)__builtin_ia32_vfmaddsd3((__v2df)__A, (__v2df)__B, (__v2df)__C);
43115}
44116
117/// Computes a multiply-subtract of 128-bit vectors of [4 x float].
118/// For each element, computes <c> (__A * __B) - __C </c>.
119///
120/// \headerfile <immintrin.h>
121///
122/// This intrinsic corresponds to the \c VFMSUB213PS instruction.
123///
124/// \param __A
125/// A 128-bit vector of [4 x float] containing the multiplicand.
126/// \param __B
127/// A 128-bit vector of [4 x float] containing the multiplier.
128/// \param __C
129/// A 128-bit vector of [4 x float] containing the subtrahend.
130/// \returns A 128-bit vector of [4 x float] containing the result.
45131static __inline__ __m128 __DEFAULT_FN_ATTRS128
46132_mm_fmsub_ps(__m128 __A, __m128 __B, __m128 __C)
47133{
48134 return (__m128)__builtin_ia32_vfmaddps((__v4sf)__A, (__v4sf)__B, -(__v4sf)__C);
49135}
50136
137/// Computes a multiply-subtract of 128-bit vectors of [2 x double].
138/// For each element, computes <c> (__A * __B) - __C </c>.
139///
140/// \headerfile <immintrin.h>
141///
142/// This intrinsic corresponds to the \c VFMSUB213PD instruction.
143///
144/// \param __A
145/// A 128-bit vector of [2 x double] containing the multiplicand.
146/// \param __B
147/// A 128-bit vector of [2 x double] containing the multiplier.
148/// \param __C
149/// A 128-bit vector of [2 x double] containing the addend.
150/// \returns A 128-bit vector of [2 x double] containing the result.
51151static __inline__ __m128d __DEFAULT_FN_ATTRS128
52152_mm_fmsub_pd(__m128d __A, __m128d __B, __m128d __C)
53153{
54154 return (__m128d)__builtin_ia32_vfmaddpd((__v2df)__A, (__v2df)__B, -(__v2df)__C);
55155}
56156
157/// Computes a scalar multiply-subtract of the single-precision values in
158/// the low 32 bits of 128-bit vectors of [4 x float].
159/// \code
160/// result[31:0] = (__A[31:0] * __B[31:0]) - __C[31:0]
161/// result[127:32] = __A[127:32]
162/// \endcode
163///
164/// \headerfile <immintrin.h>
165///
166/// This intrinsic corresponds to the \c VFMSUB213SS instruction.
167///
168/// \param __A
169/// A 128-bit vector of [4 x float] containing the multiplicand in the low
170/// 32 bits.
171/// \param __B
172/// A 128-bit vector of [4 x float] containing the multiplier in the low
173/// 32 bits.
174/// \param __C
175/// A 128-bit vector of [4 x float] containing the subtrahend in the low
176/// 32 bits.
177/// \returns A 128-bit vector of [4 x float] containing the result in the low
178/// 32 bits, and a copy of \a __A[127:32] in the upper 96 bits.
57179static __inline__ __m128 __DEFAULT_FN_ATTRS128
58180_mm_fmsub_ss(__m128 __A, __m128 __B, __m128 __C)
59181{
60182 return (__m128)__builtin_ia32_vfmaddss3((__v4sf)__A, (__v4sf)__B, -(__v4sf)__C);
61183}
62184
185/// Computes a scalar multiply-subtract of the double-precision values in
186/// the low 64 bits of 128-bit vectors of [2 x double].
187/// \code
188/// result[63:0] = (__A[63:0] * __B[63:0]) - __C[63:0]
189/// result[127:64] = __A[127:64]
190/// \endcode
191///
192/// \headerfile <immintrin.h>
193///
194/// This intrinsic corresponds to the \c VFMSUB213SD instruction.
195///
196/// \param __A
197/// A 128-bit vector of [2 x double] containing the multiplicand in the low
198/// 64 bits.
199/// \param __B
200/// A 128-bit vector of [2 x double] containing the multiplier in the low
201/// 64 bits.
202/// \param __C
203/// A 128-bit vector of [2 x double] containing the subtrahend in the low
204/// 64 bits.
205/// \returns A 128-bit vector of [2 x double] containing the result in the low
206/// 64 bits, and a copy of \a __A[127:64] in the upper 64 bits.
63207static __inline__ __m128d __DEFAULT_FN_ATTRS128
64208_mm_fmsub_sd(__m128d __A, __m128d __B, __m128d __C)
65209{
66210 return (__m128d)__builtin_ia32_vfmaddsd3((__v2df)__A, (__v2df)__B, -(__v2df)__C);
67211}
68212
213/// Computes a negated multiply-add of 128-bit vectors of [4 x float].
214/// For each element, computes <c> -(__A * __B) + __C </c>.
215///
216/// \headerfile <immintrin.h>
217///
218/// This intrinsic corresponds to the \c VFNMADD213DPS instruction.
219///
220/// \param __A
221/// A 128-bit vector of [4 x float] containing the multiplicand.
222/// \param __B
223/// A 128-bit vector of [4 x float] containing the multiplier.
224/// \param __C
225/// A 128-bit vector of [4 x float] containing the addend.
226/// \returns A 128-bit [4 x float] vector containing the result.
69227static __inline__ __m128 __DEFAULT_FN_ATTRS128
70228_mm_fnmadd_ps(__m128 __A, __m128 __B, __m128 __C)
71229{
72230 return (__m128)__builtin_ia32_vfmaddps(-(__v4sf)__A, (__v4sf)__B, (__v4sf)__C);
73231}
74232
233/// Computes a negated multiply-add of 128-bit vectors of [2 x double].
234/// For each element, computes <c> -(__A * __B) + __C </c>.
235///
236/// \headerfile <immintrin.h>
237///
238/// This intrinsic corresponds to the \c VFNMADD213PD instruction.
239///
240/// \param __A
241/// A 128-bit vector of [2 x double] containing the multiplicand.
242/// \param __B
243/// A 128-bit vector of [2 x double] containing the multiplier.
244/// \param __C
245/// A 128-bit vector of [2 x double] containing the addend.
246/// \returns A 128-bit vector of [2 x double] containing the result.
75247static __inline__ __m128d __DEFAULT_FN_ATTRS128
76248_mm_fnmadd_pd(__m128d __A, __m128d __B, __m128d __C)
77249{
78250 return (__m128d)__builtin_ia32_vfmaddpd(-(__v2df)__A, (__v2df)__B, (__v2df)__C);
79251}
80252
253/// Computes a scalar negated multiply-add of the single-precision values in
254/// the low 32 bits of 128-bit vectors of [4 x float].
255/// \code
256/// result[31:0] = -(__A[31:0] * __B[31:0]) + __C[31:0]
257/// result[127:32] = __A[127:32]
258/// \endcode
259///
260/// \headerfile <immintrin.h>
261///
262/// This intrinsic corresponds to the \c VFNMADD213SS instruction.
263///
264/// \param __A
265/// A 128-bit vector of [4 x float] containing the multiplicand in the low
266/// 32 bits.
267/// \param __B
268/// A 128-bit vector of [4 x float] containing the multiplier in the low
269/// 32 bits.
270/// \param __C
271/// A 128-bit vector of [4 x float] containing the addend in the low
272/// 32 bits.
273/// \returns A 128-bit vector of [4 x float] containing the result in the low
274/// 32 bits, and a copy of \a __A[127:32] in the upper 96 bits.
81275static __inline__ __m128 __DEFAULT_FN_ATTRS128
82276_mm_fnmadd_ss(__m128 __A, __m128 __B, __m128 __C)
83277{
84278 return (__m128)__builtin_ia32_vfmaddss3((__v4sf)__A, -(__v4sf)__B, (__v4sf)__C);
85279}
86280
281/// Computes a scalar negated multiply-add of the double-precision values
282/// in the low 64 bits of 128-bit vectors of [2 x double].
283/// \code
284/// result[63:0] = -(__A[63:0] * __B[63:0]) + __C[63:0]
285/// result[127:64] = __A[127:64]
286/// \endcode
287///
288/// \headerfile <immintrin.h>
289///
290/// This intrinsic corresponds to the \c VFNMADD213SD instruction.
291///
292/// \param __A
293/// A 128-bit vector of [2 x double] containing the multiplicand in the low
294/// 64 bits.
295/// \param __B
296/// A 128-bit vector of [2 x double] containing the multiplier in the low
297/// 64 bits.
298/// \param __C
299/// A 128-bit vector of [2 x double] containing the addend in the low
300/// 64 bits.
301/// \returns A 128-bit vector of [2 x double] containing the result in the low
302/// 64 bits, and a copy of \a __A[127:64] in the upper 64 bits.
87303static __inline__ __m128d __DEFAULT_FN_ATTRS128
88304_mm_fnmadd_sd(__m128d __A, __m128d __B, __m128d __C)
89305{
90306 return (__m128d)__builtin_ia32_vfmaddsd3((__v2df)__A, -(__v2df)__B, (__v2df)__C);
91307}
92308
309/// Computes a negated multiply-subtract of 128-bit vectors of [4 x float].
310/// For each element, computes <c> -(__A * __B) - __C </c>.
311///
312/// \headerfile <immintrin.h>
313///
314/// This intrinsic corresponds to the \c VFNMSUB213PS instruction.
315///
316/// \param __A
317/// A 128-bit vector of [4 x float] containing the multiplicand.
318/// \param __B
319/// A 128-bit vector of [4 x float] containing the multiplier.
320/// \param __C
321/// A 128-bit vector of [4 x float] containing the subtrahend.
322/// \returns A 128-bit vector of [4 x float] containing the result.
93323static __inline__ __m128 __DEFAULT_FN_ATTRS128
94324_mm_fnmsub_ps(__m128 __A, __m128 __B, __m128 __C)
95325{
96326 return (__m128)__builtin_ia32_vfmaddps(-(__v4sf)__A, (__v4sf)__B, -(__v4sf)__C);
97327}
98328
329/// Computes a negated multiply-subtract of 128-bit vectors of [2 x double].
330/// For each element, computes <c> -(__A * __B) - __C </c>.
331///
332/// \headerfile <immintrin.h>
333///
334/// This intrinsic corresponds to the \c VFNMSUB213PD instruction.
335///
336/// \param __A
337/// A 128-bit vector of [2 x double] containing the multiplicand.
338/// \param __B
339/// A 128-bit vector of [2 x double] containing the multiplier.
340/// \param __C
341/// A 128-bit vector of [2 x double] containing the subtrahend.
342/// \returns A 128-bit vector of [2 x double] containing the result.
99343static __inline__ __m128d __DEFAULT_FN_ATTRS128
100344_mm_fnmsub_pd(__m128d __A, __m128d __B, __m128d __C)
101345{
102346 return (__m128d)__builtin_ia32_vfmaddpd(-(__v2df)__A, (__v2df)__B, -(__v2df)__C);
103347}
104348
349/// Computes a scalar negated multiply-subtract of the single-precision
350/// values in the low 32 bits of 128-bit vectors of [4 x float].
351/// \code
352/// result[31:0] = -(__A[31:0] * __B[31:0]) - __C[31:0]
353/// result[127:32] = __A[127:32]
354/// \endcode
355///
356/// \headerfile <immintrin.h>
357///
358/// This intrinsic corresponds to the \c VFNMSUB213SS instruction.
359///
360/// \param __A
361/// A 128-bit vector of [4 x float] containing the multiplicand in the low
362/// 32 bits.
363/// \param __B
364/// A 128-bit vector of [4 x float] containing the multiplier in the low
365/// 32 bits.
366/// \param __C
367/// A 128-bit vector of [4 x float] containing the subtrahend in the low
368/// 32 bits.
369/// \returns A 128-bit vector of [4 x float] containing the result in the low
370/// 32 bits, and a copy of \a __A[127:32] in the upper 96 bits.
105371static __inline__ __m128 __DEFAULT_FN_ATTRS128
106372_mm_fnmsub_ss(__m128 __A, __m128 __B, __m128 __C)
107373{
108374 return (__m128)__builtin_ia32_vfmaddss3((__v4sf)__A, -(__v4sf)__B, -(__v4sf)__C);
109375}
110376
377/// Computes a scalar negated multiply-subtract of the double-precision
378/// values in the low 64 bits of 128-bit vectors of [2 x double].
379/// \code
380/// result[63:0] = -(__A[63:0] * __B[63:0]) - __C[63:0]
381/// result[127:64] = __A[127:64]
382/// \endcode
383///
384/// \headerfile <immintrin.h>
385///
386/// This intrinsic corresponds to the \c VFNMSUB213SD instruction.
387///
388/// \param __A
389/// A 128-bit vector of [2 x double] containing the multiplicand in the low
390/// 64 bits.
391/// \param __B
392/// A 128-bit vector of [2 x double] containing the multiplier in the low
393/// 64 bits.
394/// \param __C
395/// A 128-bit vector of [2 x double] containing the subtrahend in the low
396/// 64 bits.
397/// \returns A 128-bit vector of [2 x double] containing the result in the low
398/// 64 bits, and a copy of \a __A[127:64] in the upper 64 bits.
111399static __inline__ __m128d __DEFAULT_FN_ATTRS128
112400_mm_fnmsub_sd(__m128d __A, __m128d __B, __m128d __C)
113401{
114402 return (__m128d)__builtin_ia32_vfmaddsd3((__v2df)__A, -(__v2df)__B, -(__v2df)__C);
115403}
116404
405/// Computes a multiply with alternating add/subtract of 128-bit vectors of
406/// [4 x float].
407/// \code
408/// result[31:0] = (__A[31:0] * __B[31:0]) - __C[31:0]
409/// result[63:32] = (__A[63:32] * __B[63:32]) + __C[63:32]
410/// result[95:64] = (__A[95:64] * __B[95:64]) - __C[95:64]
411/// result[127:96] = (__A[127:96] * __B[127:96]) + __C[127:96]
412/// \endcode
413///
414/// \headerfile <immintrin.h>
415///
416/// This intrinsic corresponds to the \c VFMADDSUB213PS instruction.
417///
418/// \param __A
419/// A 128-bit vector of [4 x float] containing the multiplicand.
420/// \param __B
421/// A 128-bit vector of [4 x float] containing the multiplier.
422/// \param __C
423/// A 128-bit vector of [4 x float] containing the addend/subtrahend.
424/// \returns A 128-bit vector of [4 x float] containing the result.
117425static __inline__ __m128 __DEFAULT_FN_ATTRS128
118426_mm_fmaddsub_ps(__m128 __A, __m128 __B, __m128 __C)
119427{
120428 return (__m128)__builtin_ia32_vfmaddsubps((__v4sf)__A, (__v4sf)__B, (__v4sf)__C);
121429}
122430
431/// Computes a multiply with alternating add/subtract of 128-bit vectors of
432/// [2 x double].
433/// \code
434/// result[63:0] = (__A[63:0] * __B[63:0]) - __C[63:0]
435/// result[127:64] = (__A[127:64] * __B[127:64]) + __C[127:64]
436/// \endcode
437///
438/// \headerfile <immintrin.h>
439///
440/// This intrinsic corresponds to the \c VFMADDSUB213PD instruction.
441///
442/// \param __A
443/// A 128-bit vector of [2 x double] containing the multiplicand.
444/// \param __B
445/// A 128-bit vector of [2 x double] containing the multiplier.
446/// \param __C
447/// A 128-bit vector of [2 x double] containing the addend/subtrahend.
448/// \returns A 128-bit vector of [2 x double] containing the result.
123449static __inline__ __m128d __DEFAULT_FN_ATTRS128
124450_mm_fmaddsub_pd(__m128d __A, __m128d __B, __m128d __C)
125451{
126452 return (__m128d)__builtin_ia32_vfmaddsubpd((__v2df)__A, (__v2df)__B, (__v2df)__C);
127453}
128454
455/// Computes a multiply with alternating add/subtract of 128-bit vectors of
456/// [4 x float].
457/// \code
458/// result[31:0] = (__A[31:0] * __B[31:0]) + __C[31:0]
459/// result[63:32] = (__A[63:32] * __B[63:32]) - __C[63:32]
460/// result[95:64] = (__A[95:64] * __B[95:64]) + __C[95:64]
461/// result[127:96 = (__A[127:96] * __B[127:96]) - __C[127:96]
462/// \endcode
463///
464/// \headerfile <immintrin.h>
465///
466/// This intrinsic corresponds to the \c VFMSUBADD213PS instruction.
467///
468/// \param __A
469/// A 128-bit vector of [4 x float] containing the multiplicand.
470/// \param __B
471/// A 128-bit vector of [4 x float] containing the multiplier.
472/// \param __C
473/// A 128-bit vector of [4 x float] containing the addend/subtrahend.
474/// \returns A 128-bit vector of [4 x float] containing the result.
129475static __inline__ __m128 __DEFAULT_FN_ATTRS128
130476_mm_fmsubadd_ps(__m128 __A, __m128 __B, __m128 __C)
131477{
132478 return (__m128)__builtin_ia32_vfmaddsubps((__v4sf)__A, (__v4sf)__B, -(__v4sf)__C);
133479}
134480
481/// Computes a multiply with alternating add/subtract of 128-bit vectors of
482/// [2 x double].
483/// \code
484/// result[63:0] = (__A[63:0] * __B[63:0]) + __C[63:0]
485/// result[127:64] = (__A[127:64] * __B[127:64]) - __C[127:64]
486/// \endcode
487///
488/// \headerfile <immintrin.h>
489///
490/// This intrinsic corresponds to the \c VFMADDSUB213PD instruction.
491///
492/// \param __A
493/// A 128-bit vector of [2 x double] containing the multiplicand.
494/// \param __B
495/// A 128-bit vector of [2 x double] containing the multiplier.
496/// \param __C
497/// A 128-bit vector of [2 x double] containing the addend/subtrahend.
498/// \returns A 128-bit vector of [2 x double] containing the result.
135499static __inline__ __m128d __DEFAULT_FN_ATTRS128
136500_mm_fmsubadd_pd(__m128d __A, __m128d __B, __m128d __C)
137501{
138502 return (__m128d)__builtin_ia32_vfmaddsubpd((__v2df)__A, (__v2df)__B, -(__v2df)__C);
139503}
140504
505/// Computes a multiply-add of 256-bit vectors of [8 x float].
506/// For each element, computes <c> (__A * __B) + __C </c>.
507///
508/// \headerfile <immintrin.h>
509///
510/// This intrinsic corresponds to the \c VFMADD213PS instruction.
511///
512/// \param __A
513/// A 256-bit vector of [8 x float] containing the multiplicand.
514/// \param __B
515/// A 256-bit vector of [8 x float] containing the multiplier.
516/// \param __C
517/// A 256-bit vector of [8 x float] containing the addend.
518/// \returns A 256-bit vector of [8 x float] containing the result.
141519static __inline__ __m256 __DEFAULT_FN_ATTRS256
142520_mm256_fmadd_ps(__m256 __A, __m256 __B, __m256 __C)
143521{
144522 return (__m256)__builtin_ia32_vfmaddps256((__v8sf)__A, (__v8sf)__B, (__v8sf)__C);
145523}
146524
525/// Computes a multiply-add of 256-bit vectors of [4 x double].
526/// For each element, computes <c> (__A * __B) + __C </c>.
527///
528/// \headerfile <immintrin.h>
529///
530/// This intrinsic corresponds to the \c VFMADD213PD instruction.
531///
532/// \param __A
533/// A 256-bit vector of [4 x double] containing the multiplicand.
534/// \param __B
535/// A 256-bit vector of [4 x double] containing the multiplier.
536/// \param __C
537/// A 256-bit vector of [4 x double] containing the addend.
538/// \returns A 256-bit vector of [4 x double] containing the result.
147539static __inline__ __m256d __DEFAULT_FN_ATTRS256
148540_mm256_fmadd_pd(__m256d __A, __m256d __B, __m256d __C)
149541{
150542 return (__m256d)__builtin_ia32_vfmaddpd256((__v4df)__A, (__v4df)__B, (__v4df)__C);
151543}
152544
545/// Computes a multiply-subtract of 256-bit vectors of [8 x float].
546/// For each element, computes <c> (__A * __B) - __C </c>.
547///
548/// \headerfile <immintrin.h>
549///
550/// This intrinsic corresponds to the \c VFMSUB213PS instruction.
551///
552/// \param __A
553/// A 256-bit vector of [8 x float] containing the multiplicand.
554/// \param __B
555/// A 256-bit vector of [8 x float] containing the multiplier.
556/// \param __C
557/// A 256-bit vector of [8 x float] containing the subtrahend.
558/// \returns A 256-bit vector of [8 x float] containing the result.
153559static __inline__ __m256 __DEFAULT_FN_ATTRS256
154560_mm256_fmsub_ps(__m256 __A, __m256 __B, __m256 __C)
155561{
156562 return (__m256)__builtin_ia32_vfmaddps256((__v8sf)__A, (__v8sf)__B, -(__v8sf)__C);
157563}
158564
565/// Computes a multiply-subtract of 256-bit vectors of [4 x double].
566/// For each element, computes <c> (__A * __B) - __C </c>.
567///
568/// \headerfile <immintrin.h>
569///
570/// This intrinsic corresponds to the \c VFMSUB213PD instruction.
571///
572/// \param __A
573/// A 256-bit vector of [4 x double] containing the multiplicand.
574/// \param __B
575/// A 256-bit vector of [4 x double] containing the multiplier.
576/// \param __C
577/// A 256-bit vector of [4 x double] containing the subtrahend.
578/// \returns A 256-bit vector of [4 x double] containing the result.
159579static __inline__ __m256d __DEFAULT_FN_ATTRS256
160580_mm256_fmsub_pd(__m256d __A, __m256d __B, __m256d __C)
161581{
162582 return (__m256d)__builtin_ia32_vfmaddpd256((__v4df)__A, (__v4df)__B, -(__v4df)__C);
163583}
164584
585/// Computes a negated multiply-add of 256-bit vectors of [8 x float].
586/// For each element, computes <c> -(__A * __B) + __C </c>.
587///
588/// \headerfile <immintrin.h>
589///
590/// This intrinsic corresponds to the \c VFNMADD213PS instruction.
591///
592/// \param __A
593/// A 256-bit vector of [8 x float] containing the multiplicand.
594/// \param __B
595/// A 256-bit vector of [8 x float] containing the multiplier.
596/// \param __C
597/// A 256-bit vector of [8 x float] containing the addend.
598/// \returns A 256-bit vector of [8 x float] containing the result.
165599static __inline__ __m256 __DEFAULT_FN_ATTRS256
166600_mm256_fnmadd_ps(__m256 __A, __m256 __B, __m256 __C)
167601{
168602 return (__m256)__builtin_ia32_vfmaddps256(-(__v8sf)__A, (__v8sf)__B, (__v8sf)__C);
169603}
170604
605/// Computes a negated multiply-add of 256-bit vectors of [4 x double].
606/// For each element, computes <c> -(__A * __B) + __C </c>.
607///
608/// \headerfile <immintrin.h>
609///
610/// This intrinsic corresponds to the \c VFNMADD213PD instruction.
611///
612/// \param __A
613/// A 256-bit vector of [4 x double] containing the multiplicand.
614/// \param __B
615/// A 256-bit vector of [4 x double] containing the multiplier.
616/// \param __C
617/// A 256-bit vector of [4 x double] containing the addend.
618/// \returns A 256-bit vector of [4 x double] containing the result.
171619static __inline__ __m256d __DEFAULT_FN_ATTRS256
172620_mm256_fnmadd_pd(__m256d __A, __m256d __B, __m256d __C)
173621{
174622 return (__m256d)__builtin_ia32_vfmaddpd256(-(__v4df)__A, (__v4df)__B, (__v4df)__C);
175623}
176624
625/// Computes a negated multiply-subtract of 256-bit vectors of [8 x float].
626/// For each element, computes <c> -(__A * __B) - __C </c>.
627///
628/// \headerfile <immintrin.h>
629///
630/// This intrinsic corresponds to the \c VFNMSUB213PS instruction.
631///
632/// \param __A
633/// A 256-bit vector of [8 x float] containing the multiplicand.
634/// \param __B
635/// A 256-bit vector of [8 x float] containing the multiplier.
636/// \param __C
637/// A 256-bit vector of [8 x float] containing the subtrahend.
638/// \returns A 256-bit vector of [8 x float] containing the result.
177639static __inline__ __m256 __DEFAULT_FN_ATTRS256
178640_mm256_fnmsub_ps(__m256 __A, __m256 __B, __m256 __C)
179641{
180642 return (__m256)__builtin_ia32_vfmaddps256(-(__v8sf)__A, (__v8sf)__B, -(__v8sf)__C);
181643}
182644
645/// Computes a negated multiply-subtract of 256-bit vectors of [4 x double].
646/// For each element, computes <c> -(__A * __B) - __C </c>.
647///
648/// \headerfile <immintrin.h>
649///
650/// This intrinsic corresponds to the \c VFNMSUB213PD instruction.
651///
652/// \param __A
653/// A 256-bit vector of [4 x double] containing the multiplicand.
654/// \param __B
655/// A 256-bit vector of [4 x double] containing the multiplier.
656/// \param __C
657/// A 256-bit vector of [4 x double] containing the subtrahend.
658/// \returns A 256-bit vector of [4 x double] containing the result.
183659static __inline__ __m256d __DEFAULT_FN_ATTRS256
184660_mm256_fnmsub_pd(__m256d __A, __m256d __B, __m256d __C)
185661{
186662 return (__m256d)__builtin_ia32_vfmaddpd256(-(__v4df)__A, (__v4df)__B, -(__v4df)__C);
187663}
188664
665/// Computes a multiply with alternating add/subtract of 256-bit vectors of
666/// [8 x float].
667/// \code
668/// result[31:0] = (__A[31:0] * __B[31:0]) - __C[31:0]
669/// result[63:32] = (__A[63:32] * __B[63:32]) + __C[63:32]
670/// result[95:64] = (__A[95:64] * __B[95:64]) - __C[95:64]
671/// result[127:96] = (__A[127:96] * __B[127:96]) + __C[127:96]
672/// result[159:128] = (__A[159:128] * __B[159:128]) - __C[159:128]
673/// result[191:160] = (__A[191:160] * __B[191:160]) + __C[191:160]
674/// result[223:192] = (__A[223:192] * __B[223:192]) - __C[223:192]
675/// result[255:224] = (__A[255:224] * __B[255:224]) + __C[255:224]
676/// \endcode
677///
678/// \headerfile <immintrin.h>
679///
680/// This intrinsic corresponds to the \c VFMADDSUB213PS instruction.
681///
682/// \param __A
683/// A 256-bit vector of [8 x float] containing the multiplicand.
684/// \param __B
685/// A 256-bit vector of [8 x float] containing the multiplier.
686/// \param __C
687/// A 256-bit vector of [8 x float] containing the addend/subtrahend.
688/// \returns A 256-bit vector of [8 x float] containing the result.
189689static __inline__ __m256 __DEFAULT_FN_ATTRS256
190690_mm256_fmaddsub_ps(__m256 __A, __m256 __B, __m256 __C)
191691{
192692 return (__m256)__builtin_ia32_vfmaddsubps256((__v8sf)__A, (__v8sf)__B, (__v8sf)__C);
193693}
194694
695/// Computes a multiply with alternating add/subtract of 256-bit vectors of
696/// [4 x double].
697/// \code
698/// result[63:0] = (__A[63:0] * __B[63:0]) - __C[63:0]
699/// result[127:64] = (__A[127:64] * __B[127:64]) + __C[127:64]
700/// result[191:128] = (__A[191:128] * __B[191:128]) - __C[191:128]
701/// result[255:192] = (__A[255:192] * __B[255:192]) + __C[255:192]
702/// \endcode
703///
704/// \headerfile <immintrin.h>
705///
706/// This intrinsic corresponds to the \c VFMADDSUB213PD instruction.
707///
708/// \param __A
709/// A 256-bit vector of [4 x double] containing the multiplicand.
710/// \param __B
711/// A 256-bit vector of [4 x double] containing the multiplier.
712/// \param __C
713/// A 256-bit vector of [4 x double] containing the addend/subtrahend.
714/// \returns A 256-bit vector of [4 x double] containing the result.
195715static __inline__ __m256d __DEFAULT_FN_ATTRS256
196716_mm256_fmaddsub_pd(__m256d __A, __m256d __B, __m256d __C)
197717{
198718 return (__m256d)__builtin_ia32_vfmaddsubpd256((__v4df)__A, (__v4df)__B, (__v4df)__C);
199719}
200720
721/// Computes a vector multiply with alternating add/subtract of 256-bit
722/// vectors of [8 x float].
723/// \code
724/// result[31:0] = (__A[31:0] * __B[31:0]) + __C[31:0]
725/// result[63:32] = (__A[63:32] * __B[63:32]) - __C[63:32]
726/// result[95:64] = (__A[95:64] * __B[95:64]) + __C[95:64]
727/// result[127:96] = (__A[127:96] * __B[127:96]) - __C[127:96]
728/// result[159:128] = (__A[159:128] * __B[159:128]) + __C[159:128]
729/// result[191:160] = (__A[191:160] * __B[191:160]) - __C[191:160]
730/// result[223:192] = (__A[223:192] * __B[223:192]) + __C[223:192]
731/// result[255:224] = (__A[255:224] * __B[255:224]) - __C[255:224]
732/// \endcode
733///
734/// \headerfile <immintrin.h>
735///
736/// This intrinsic corresponds to the \c VFMSUBADD213PS instruction.
737///
738/// \param __A
739/// A 256-bit vector of [8 x float] containing the multiplicand.
740/// \param __B
741/// A 256-bit vector of [8 x float] containing the multiplier.
742/// \param __C
743/// A 256-bit vector of [8 x float] containing the addend/subtrahend.
744/// \returns A 256-bit vector of [8 x float] containing the result.
201745static __inline__ __m256 __DEFAULT_FN_ATTRS256
202746_mm256_fmsubadd_ps(__m256 __A, __m256 __B, __m256 __C)
203747{
204748 return (__m256)__builtin_ia32_vfmaddsubps256((__v8sf)__A, (__v8sf)__B, -(__v8sf)__C);
205749}
206750
751/// Computes a vector multiply with alternating add/subtract of 256-bit
752/// vectors of [4 x double].
753/// \code
754/// result[63:0] = (__A[63:0] * __B[63:0]) + __C[63:0]
755/// result[127:64] = (__A[127:64] * __B[127:64]) - __C[127:64]
756/// result[191:128] = (__A[191:128] * __B[191:128]) + __C[191:128]
757/// result[255:192] = (__A[255:192] * __B[255:192]) - __C[255:192]
758/// \endcode
759///
760/// \headerfile <immintrin.h>
761///
762/// This intrinsic corresponds to the \c VFMSUBADD213PD instruction.
763///
764/// \param __A
765/// A 256-bit vector of [4 x double] containing the multiplicand.
766/// \param __B
767/// A 256-bit vector of [4 x double] containing the multiplier.
768/// \param __C
769/// A 256-bit vector of [4 x double] containing the addend/subtrahend.
770/// \returns A 256-bit vector of [4 x double] containing the result.
207771static __inline__ __m256d __DEFAULT_FN_ATTRS256
208772_mm256_fmsubadd_pd(__m256d __A, __m256d __B, __m256d __C)
209773{
lib/include/immintrin.h+116-8
......@@ -269,6 +269,26 @@
269269#include <avxneconvertintrin.h>
270270#endif
271271
272#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
273 defined(__SHA512__)
274#include <sha512intrin.h>
275#endif
276
277#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
278 defined(__SM3__)
279#include <sm3intrin.h>
280#endif
281
282#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
283 defined(__SM4__)
284#include <sm4intrin.h>
285#endif
286
287#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
288 defined(__AVXVNNIINT16__)
289#include <avxvnniint16intrin.h>
290#endif
291
272292#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
273293 defined(__RDPID__)
274294/// Returns the value of the IA32_TSC_AUX MSR (0xc0000103).
......@@ -284,30 +304,53 @@ _rdpid_u32(void) {
284304
285305#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
286306 defined(__RDRND__)
307/// Returns a 16-bit hardware-generated random value.
308///
309/// \headerfile <immintrin.h>
310///
311/// This intrinsic corresponds to the <c> RDRAND </c> instruction.
312///
313/// \param __p
314/// A pointer to a 16-bit memory location to place the random value.
315/// \returns 1 if the value was successfully generated, 0 otherwise.
287316static __inline__ int __attribute__((__always_inline__, __nodebug__, __target__("rdrnd")))
288317_rdrand16_step(unsigned short *__p)
289318{
290319 return (int)__builtin_ia32_rdrand16_step(__p);
291320}
292321
322/// Returns a 32-bit hardware-generated random value.
323///
324/// \headerfile <immintrin.h>
325///
326/// This intrinsic corresponds to the <c> RDRAND </c> instruction.
327///
328/// \param __p
329/// A pointer to a 32-bit memory location to place the random value.
330/// \returns 1 if the value was successfully generated, 0 otherwise.
293331static __inline__ int __attribute__((__always_inline__, __nodebug__, __target__("rdrnd")))
294332_rdrand32_step(unsigned int *__p)
295333{
296334 return (int)__builtin_ia32_rdrand32_step(__p);
297335}
298336
299#ifdef __x86_64__
337/// Returns a 64-bit hardware-generated random value.
338///
339/// \headerfile <immintrin.h>
340///
341/// This intrinsic corresponds to the <c> RDRAND </c> instruction.
342///
343/// \param __p
344/// A pointer to a 64-bit memory location to place the random value.
345/// \returns 1 if the value was successfully generated, 0 otherwise.
300346static __inline__ int __attribute__((__always_inline__, __nodebug__, __target__("rdrnd")))
301347_rdrand64_step(unsigned long long *__p)
302348{
349#ifdef __x86_64__
303350 return (int)__builtin_ia32_rdrand64_step(__p);
304}
305351#else
306// We need to emulate the functionality of 64-bit rdrand with 2 32-bit
307// rdrand instructions.
308static __inline__ int __attribute__((__always_inline__, __nodebug__, __target__("rdrnd")))
309_rdrand64_step(unsigned long long *__p)
310{
352 // We need to emulate the functionality of 64-bit rdrand with 2 32-bit
353 // rdrand instructions.
311354 unsigned int __lo, __hi;
312355 unsigned int __res_lo = __builtin_ia32_rdrand32_step(&__lo);
313356 unsigned int __res_hi = __builtin_ia32_rdrand32_step(&__hi);
......@@ -318,55 +361,115 @@ _rdrand64_step(unsigned long long *__p)
318361 *__p = 0;
319362 return 0;
320363 }
321}
322364#endif
365}
323366#endif /* __RDRND__ */
324367
325368#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
326369 defined(__FSGSBASE__)
327370#ifdef __x86_64__
371/// Reads the FS base register.
372///
373/// \headerfile <immintrin.h>
374///
375/// This intrinsic corresponds to the <c> RDFSBASE </c> instruction.
376///
377/// \returns The lower 32 bits of the FS base register.
328378static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
329379_readfsbase_u32(void)
330380{
331381 return __builtin_ia32_rdfsbase32();
332382}
333383
384/// Reads the FS base register.
385///
386/// \headerfile <immintrin.h>
387///
388/// This intrinsic corresponds to the <c> RDFSBASE </c> instruction.
389///
390/// \returns The contents of the FS base register.
334391static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
335392_readfsbase_u64(void)
336393{
337394 return __builtin_ia32_rdfsbase64();
338395}
339396
397/// Reads the GS base register.
398///
399/// \headerfile <immintrin.h>
400///
401/// This intrinsic corresponds to the <c> RDGSBASE </c> instruction.
402///
403/// \returns The lower 32 bits of the GS base register.
340404static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
341405_readgsbase_u32(void)
342406{
343407 return __builtin_ia32_rdgsbase32();
344408}
345409
410/// Reads the GS base register.
411///
412/// \headerfile <immintrin.h>
413///
414/// This intrinsic corresponds to the <c> RDGSBASE </c> instruction.
415///
416/// \returns The contents of the GS base register.
346417static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
347418_readgsbase_u64(void)
348419{
349420 return __builtin_ia32_rdgsbase64();
350421}
351422
423/// Modifies the FS base register.
424///
425/// \headerfile <immintrin.h>
426///
427/// This intrinsic corresponds to the <c> WRFSBASE </c> instruction.
428///
429/// \param __V
430/// Value to use for the lower 32 bits of the FS base register.
352431static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
353432_writefsbase_u32(unsigned int __V)
354433{
355434 __builtin_ia32_wrfsbase32(__V);
356435}
357436
437/// Modifies the FS base register.
438///
439/// \headerfile <immintrin.h>
440///
441/// This intrinsic corresponds to the <c> WRFSBASE </c> instruction.
442///
443/// \param __V
444/// Value to use for the FS base register.
358445static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
359446_writefsbase_u64(unsigned long long __V)
360447{
361448 __builtin_ia32_wrfsbase64(__V);
362449}
363450
451/// Modifies the GS base register.
452///
453/// \headerfile <immintrin.h>
454///
455/// This intrinsic corresponds to the <c> WRGSBASE </c> instruction.
456///
457/// \param __V
458/// Value to use for the lower 32 bits of the GS base register.
364459static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
365460_writegsbase_u32(unsigned int __V)
366461{
367462 __builtin_ia32_wrgsbase32(__V);
368463}
369464
465/// Modifies the GS base register.
466///
467/// \headerfile <immintrin.h>
468///
469/// This intrinsic corresponds to the <c> WRFSBASE </c> instruction.
470///
471/// \param __V
472/// Value to use for GS base register.
370473static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
371474_writegsbase_u64(unsigned long long __V)
372475{
......@@ -538,6 +641,11 @@ _storebe_i64(void * __P, long long __D) {
538641#include <amxintrin.h>
539642#endif
540643
644#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
645 defined(__AMX_COMPLEX__)
646#include <amxcomplexintrin.h>
647#endif
648
541649#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
542650 defined(__AVX512VP2INTERSECT__)
543651#include <avx512vp2intersectintrin.h>
lib/include/limits.h+5-1
......@@ -52,7 +52,11 @@
5252#define LONG_MIN (-__LONG_MAX__ -1L)
5353
5454#define UCHAR_MAX (__SCHAR_MAX__*2 +1)
55#define USHRT_MAX (__SHRT_MAX__ *2 +1)
55#if __SHRT_WIDTH__ < __INT_WIDTH__
56#define USHRT_MAX (__SHRT_MAX__ * 2 + 1)
57#else
58#define USHRT_MAX (__SHRT_MAX__ * 2U + 1U)
59#endif
5660#define UINT_MAX (__INT_MAX__ *2U +1U)
5761#define ULONG_MAX (__LONG_MAX__ *2UL+1UL)
5862
lib/include/llvm_libc_wrappers/ctype.h created+85
......@@ -0,0 +1,85 @@
1//===-- Wrapper for C standard ctype.h declarations on the GPU ------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef __CLANG_LLVM_LIBC_WRAPPERS_CTYPE_H__
10#define __CLANG_LLVM_LIBC_WRAPPERS_CTYPE_H__
11
12#if !defined(_OPENMP) && !defined(__HIP__) && !defined(__CUDA__)
13#error "This file is for GPU offloading compilation only"
14#endif
15
16#include_next <ctype.h>
17
18#if __has_include(<llvm-libc-decls/ctype.h>)
19
20#if defined(__HIP__) || defined(__CUDA__)
21#define __LIBC_ATTRS __attribute__((device))
22#endif
23
24// The GNU headers like to provide these as macros, we need to undefine them so
25// they do not conflict with the following definitions for the GPU.
26
27#pragma push_macro("isalnum")
28#pragma push_macro("isalpha")
29#pragma push_macro("isblank")
30#pragma push_macro("iscntrl")
31#pragma push_macro("isdigit")
32#pragma push_macro("isgraph")
33#pragma push_macro("islower")
34#pragma push_macro("isprint")
35#pragma push_macro("ispunct")
36#pragma push_macro("isspace")
37#pragma push_macro("isupper")
38#pragma push_macro("isxdigit")
39#pragma push_macro("tolower")
40#pragma push_macro("toupper")
41
42#undef isalnum
43#undef isalpha
44#undef iscntrl
45#undef isdigit
46#undef islower
47#undef isgraph
48#undef isprint
49#undef ispunct
50#undef isspace
51#undef isupper
52#undef isblank
53#undef isxdigit
54#undef tolower
55#undef toupper
56
57#pragma omp begin declare target
58
59#include <llvm-libc-decls/ctype.h>
60
61#pragma omp end declare target
62
63// Restore the original macros when compiling on the host.
64#if !defined(__NVPTX__) && !defined(__AMDGPU__)
65#pragma pop_macro("isalnum")
66#pragma pop_macro("isalpha")
67#pragma pop_macro("isblank")
68#pragma pop_macro("iscntrl")
69#pragma pop_macro("isdigit")
70#pragma pop_macro("isgraph")
71#pragma pop_macro("islower")
72#pragma pop_macro("isprint")
73#pragma pop_macro("ispunct")
74#pragma pop_macro("isspace")
75#pragma pop_macro("isupper")
76#pragma pop_macro("isxdigit")
77#pragma pop_macro("tolower")
78#pragma pop_macro("toupper")
79#endif
80
81#undef __LIBC_ATTRS
82
83#endif
84
85#endif // __CLANG_LLVM_LIBC_WRAPPERS_CTYPE_H__
lib/include/llvm_libc_wrappers/inttypes.h created+34
......@@ -0,0 +1,34 @@
1//===-- Wrapper for C standard inttypes.h declarations on the GPU ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef __CLANG_LLVM_LIBC_WRAPPERS_INTTYPES_H__
10#define __CLANG_LLVM_LIBC_WRAPPERS_INTTYPES_H__
11
12#if !defined(_OPENMP) && !defined(__HIP__) && !defined(__CUDA__)
13#error "This file is for GPU offloading compilation only"
14#endif
15
16#include_next <inttypes.h>
17
18#if __has_include(<llvm-libc-decls/inttypes.h>)
19
20#if defined(__HIP__) || defined(__CUDA__)
21#define __LIBC_ATTRS __attribute__((device))
22#endif
23
24#pragma omp begin declare target
25
26#include <llvm-libc-decls/inttypes.h>
27
28#pragma omp end declare target
29
30#undef __LIBC_ATTRS
31
32#endif
33
34#endif // __CLANG_LLVM_LIBC_WRAPPERS_INTTYPES_H__
lib/include/llvm_libc_wrappers/stdio.h created+34
......@@ -0,0 +1,34 @@
1//===-- Wrapper for C standard stdio.h declarations on the GPU ------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef __CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__
10#define __CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__
11
12#if !defined(_OPENMP) && !defined(__HIP__) && !defined(__CUDA__)
13#error "This file is for GPU offloading compilation only"
14#endif
15
16#include_next <stdio.h>
17
18#if __has_include(<llvm-libc-decls/stdio.h>)
19
20#if defined(__HIP__) || defined(__CUDA__)
21#define __LIBC_ATTRS __attribute__((device))
22#endif
23
24#pragma omp begin declare target
25
26#include <llvm-libc-decls/stdio.h>
27
28#pragma omp end declare target
29
30#undef __LIBC_ATTRS
31
32#endif
33
34#endif // __CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__
lib/include/llvm_libc_wrappers/stdlib.h created+42
......@@ -0,0 +1,42 @@
1//===-- Wrapper for C standard stdlib.h declarations on the GPU -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef __CLANG_LLVM_LIBC_WRAPPERS_STDLIB_H__
10#define __CLANG_LLVM_LIBC_WRAPPERS_STDLIB_H__
11
12#if !defined(_OPENMP) && !defined(__HIP__) && !defined(__CUDA__)
13#error "This file is for GPU offloading compilation only"
14#endif
15
16#include_next <stdlib.h>
17
18#if __has_include(<llvm-libc-decls/stdlib.h>)
19
20#if defined(__HIP__) || defined(__CUDA__)
21#define __LIBC_ATTRS __attribute__((device))
22#endif
23
24#pragma omp begin declare target
25
26// The LLVM C library uses this type so we forward declare it.
27typedef void (*__atexithandler_t)(void);
28
29// Enforce ABI compatibility with the structs used by the LLVM C library.
30_Static_assert(__builtin_offsetof(div_t, quot) == 0, "ABI mismatch!");
31_Static_assert(__builtin_offsetof(ldiv_t, quot) == 0, "ABI mismatch!");
32_Static_assert(__builtin_offsetof(lldiv_t, quot) == 0, "ABI mismatch!");
33
34#include <llvm-libc-decls/stdlib.h>
35
36#pragma omp end declare target
37
38#undef __LIBC_ATTRS
39
40#endif
41
42#endif // __CLANG_LLVM_LIBC_WRAPPERS_STDLIB_H__
lib/include/llvm_libc_wrappers/string.h created+37
......@@ -0,0 +1,37 @@
1//===-- Wrapper for C standard string.h declarations on the GPU -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef __CLANG_LLVM_LIBC_WRAPPERS_STRING_H__
10#define __CLANG_LLVM_LIBC_WRAPPERS_STRING_H__
11
12#if !defined(_OPENMP) && !defined(__HIP__) && !defined(__CUDA__)
13#error "This file is for GPU offloading compilation only"
14#endif
15
16// FIXME: The GNU headers provide C++ standard compliant headers when in C++
17// mode and the LLVM libc does not. We cannot enable memchr, strchr, strchrnul,
18// strpbrk, strrchr, strstr, or strcasestr until this is addressed.
19#include_next <string.h>
20
21#if __has_include(<llvm-libc-decls/string.h>)
22
23#if defined(__HIP__) || defined(__CUDA__)
24#define __LIBC_ATTRS __attribute__((device))
25#endif
26
27#pragma omp begin declare target
28
29#include <llvm-libc-decls/string.h>
30
31#pragma omp end declare target
32
33#undef __LIBC_ATTRS
34
35#endif
36
37#endif // __CLANG_LLVM_LIBC_WRAPPERS_STRING_H__
lib/include/mwaitxintrin.h+29
......@@ -16,12 +16,41 @@
1616
1717/* Define the default attributes for the functions in this file. */
1818#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("mwaitx")))
19
20/// Establishes a linear address memory range to be monitored and puts
21/// the processor in the monitor event pending state. Data stored in the
22/// monitored address range causes the processor to exit the pending state.
23///
24/// \headerfile <x86intrin.h>
25///
26/// This intrinsic corresponds to the \c MONITORX instruction.
27///
28/// \param __p
29/// The memory range to be monitored. The size of the range is determined by
30/// CPUID function 0000_0005h.
31/// \param __extensions
32/// Optional extensions for the monitoring state.
33/// \param __hints
34/// Optional hints for the monitoring state.
1935static __inline__ void __DEFAULT_FN_ATTRS
2036_mm_monitorx(void * __p, unsigned __extensions, unsigned __hints)
2137{
2238 __builtin_ia32_monitorx(__p, __extensions, __hints);
2339}
2440
41/// Used with the \c MONITORX instruction to wait while the processor is in
42/// the monitor event pending state. Data stored in the monitored address
43/// range, or an interrupt, causes the processor to exit the pending state.
44///
45/// \headerfile <x86intrin.h>
46///
47/// This intrinsic corresponds to the \c MWAITX instruction.
48///
49/// \param __extensions
50/// Optional extensions for the monitoring state, which can vary by
51/// processor.
52/// \param __hints
53/// Optional hints for the monitoring state, which can vary by processor.
2554static __inline__ void __DEFAULT_FN_ATTRS
2655_mm_mwaitx(unsigned __extensions, unsigned __hints, unsigned __clock)
2756{
lib/include/opencl-c-base.h+3
......@@ -474,6 +474,9 @@ typedef enum memory_order
474474#define CLK_HALF_FLOAT 0x10DD
475475#define CLK_FLOAT 0x10DE
476476#define CLK_UNORM_INT24 0x10DF
477#if __OPENCL_C_VERSION__ >= CL_VERSION_3_0
478#define CLK_UNORM_INT_101010_2 0x10E0
479#endif // __OPENCL_C_VERSION__ >= CL_VERSION_3_0
477480
478481// Channel order, numbering must be aligned with cl_channel_order in cl.h
479482//
lib/include/openmp_wrappers/__clang_openmp_device_functions.h-1
......@@ -40,7 +40,6 @@ extern "C" {
4040
4141// Import types which will be used by __clang_hip_libdevice_declares.h
4242#ifndef __cplusplus
43#include <stdbool.h>
4443#include <stdint.h>
4544#endif
4645
lib/include/openmp_wrappers/new+1-1
......@@ -13,7 +13,7 @@
1313// which do not use nothrow_t are provided without the <new> header.
1414#include_next <new>
1515
16#if defined(__NVPTX__) && defined(_OPENMP)
16#if (defined(__NVPTX__) || defined(__AMDGPU__)) && defined(_OPENMP)
1717
1818#include <cstdlib>
1919
lib/include/pmmintrin.h+12-6
......@@ -253,9 +253,12 @@ _mm_movedup_pd(__m128d __a)
253253/// the processor in the monitor event pending state. Data stored in the
254254/// monitored address range causes the processor to exit the pending state.
255255///
256/// The \c MONITOR instruction can be used in kernel mode, and in other modes
257/// if MSR <c> C001_0015h[MonMwaitUserEn] </c> is set.
258///
256259/// \headerfile <x86intrin.h>
257260///
258/// This intrinsic corresponds to the <c> MONITOR </c> instruction.
261/// This intrinsic corresponds to the \c MONITOR instruction.
259262///
260263/// \param __p
261264/// The memory range to be monitored. The size of the range is determined by
......@@ -270,19 +273,22 @@ _mm_monitor(void const *__p, unsigned __extensions, unsigned __hints)
270273 __builtin_ia32_monitor(__p, __extensions, __hints);
271274}
272275
273/// Used with the MONITOR instruction to wait while the processor is in
276/// Used with the \c MONITOR instruction to wait while the processor is in
274277/// the monitor event pending state. Data stored in the monitored address
275/// range causes the processor to exit the pending state.
278/// range, or an interrupt, causes the processor to exit the pending state.
279///
280/// The \c MWAIT instruction can be used in kernel mode, and in other modes if
281/// MSR <c> C001_0015h[MonMwaitUserEn] </c> is set.
276282///
277283/// \headerfile <x86intrin.h>
278284///
279/// This intrinsic corresponds to the <c> MWAIT </c> instruction.
285/// This intrinsic corresponds to the \c MWAIT instruction.
280286///
281287/// \param __extensions
282/// Optional extensions for the monitoring state, which may vary by
288/// Optional extensions for the monitoring state, which can vary by
283289/// processor.
284290/// \param __hints
285/// Optional hints for the monitoring state, which may vary by processor.
291/// Optional hints for the monitoring state, which can vary by processor.
286292static __inline__ void __DEFAULT_FN_ATTRS
287293_mm_mwait(unsigned __extensions, unsigned __hints)
288294{
lib/include/ppc_wrappers/emmintrin.h+2-1
......@@ -46,6 +46,7 @@
4646
4747/* SSE2 */
4848typedef __vector double __v2df;
49typedef __vector float __v4f;
4950typedef __vector long long __v2di;
5051typedef __vector unsigned long long __v2du;
5152typedef __vector int __v4si;
......@@ -951,7 +952,7 @@ extern __inline __m128d
951952 _mm_cvtpi32_pd(__m64 __A) {
952953 __v4si __temp;
953954 __v2di __tmp2;
954 __v2df __result;
955 __v4f __result;
955956
956957 __temp = (__v4si)vec_splats(__A);
957958 __tmp2 = (__v2di)vec_unpackl(__temp);
lib/include/ppc_wrappers/smmintrin.h+2-2
......@@ -305,9 +305,9 @@ extern __inline int
305305extern __inline __m128i
306306 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
307307 _mm_blend_epi16(__m128i __A, __m128i __B, const int __imm8) {
308 __v16qi __charmask = vec_splats((signed char)__imm8);
308 __v16qu __charmask = vec_splats((unsigned char)__imm8);
309309 __charmask = vec_gb(__charmask);
310 __v8hu __shortmask = (__v8hu)vec_unpackh(__charmask);
310 __v8hu __shortmask = (__v8hu)vec_unpackh((__v16qi)__charmask);
311311#ifdef __BIG_ENDIAN__
312312 __shortmask = vec_reve(__shortmask);
313313#endif
lib/include/rdseedintrin.h+65-2
......@@ -7,8 +7,8 @@
77 *===-----------------------------------------------------------------------===
88 */
99
10#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H
11#error "Never use <rdseedintrin.h> directly; include <x86intrin.h> instead."
10#ifndef __IMMINTRIN_H
11#error "Never use <rdseedintrin.h> directly; include <immintrin.h> instead."
1212#endif
1313
1414#ifndef __RDSEEDINTRIN_H
......@@ -17,12 +17,54 @@
1717/* Define the default attributes for the functions in this file. */
1818#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("rdseed")))
1919
20/// Stores a hardware-generated 16-bit random value in the memory at \a __p.
21///
22/// The random number generator complies with NIST SP800-90B and SP800-90C.
23///
24/// \code{.operation}
25/// IF HW_NRND_GEN.ready == 1
26/// Store16(__p, HW_NRND_GEN.data)
27/// result := 1
28/// ELSE
29/// Store16(__p, 0)
30/// result := 0
31/// END
32/// \endcode
33///
34/// \headerfile <immintrin.h>
35///
36/// This intrinsic corresponds to the \c RDSEED instruction.
37///
38/// \param __p
39/// Pointer to memory for storing the 16-bit random number.
40/// \returns 1 if a random number was generated, 0 if not.
2041static __inline__ int __DEFAULT_FN_ATTRS
2142_rdseed16_step(unsigned short *__p)
2243{
2344 return (int) __builtin_ia32_rdseed16_step(__p);
2445}
2546
47/// Stores a hardware-generated 32-bit random value in the memory at \a __p.
48///
49/// The random number generator complies with NIST SP800-90B and SP800-90C.
50///
51/// \code{.operation}
52/// IF HW_NRND_GEN.ready == 1
53/// Store32(__p, HW_NRND_GEN.data)
54/// result := 1
55/// ELSE
56/// Store32(__p, 0)
57/// result := 0
58/// END
59/// \endcode
60///
61/// \headerfile <immintrin.h>
62///
63/// This intrinsic corresponds to the \c RDSEED instruction.
64///
65/// \param __p
66/// Pointer to memory for storing the 32-bit random number.
67/// \returns 1 if a random number was generated, 0 if not.
2668static __inline__ int __DEFAULT_FN_ATTRS
2769_rdseed32_step(unsigned int *__p)
2870{
......@@ -30,6 +72,27 @@ _rdseed32_step(unsigned int *__p)
3072}
3173
3274#ifdef __x86_64__
75/// Stores a hardware-generated 64-bit random value in the memory at \a __p.
76///
77/// The random number generator complies with NIST SP800-90B and SP800-90C.
78///
79/// \code{.operation}
80/// IF HW_NRND_GEN.ready == 1
81/// Store64(__p, HW_NRND_GEN.data)
82/// result := 1
83/// ELSE
84/// Store64(__p, 0)
85/// result := 0
86/// END
87/// \endcode
88///
89/// \headerfile <immintrin.h>
90///
91/// This intrinsic corresponds to the \c RDSEED instruction.
92///
93/// \param __p
94/// Pointer to memory for storing the 64-bit random number.
95/// \returns 1 if a random number was generated, 0 if not.
3396static __inline__ int __DEFAULT_FN_ATTRS
3497_rdseed64_step(unsigned long long *__p)
3598{
lib/include/riscv_ntlh.h created+28
......@@ -0,0 +1,28 @@
1/*===---- riscv_ntlh.h - RISC-V NTLH intrinsics ----------------------------===
2 *
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 * See https://llvm.org/LICENSE.txt for license information.
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 *
7 *===-----------------------------------------------------------------------===
8 */
9
10#ifndef __RISCV_NTLH_H
11#define __RISCV_NTLH_H
12
13#ifndef __riscv_zihintntl
14#error "NTLH intrinsics require the NTLH extension."
15#endif
16
17enum {
18 __RISCV_NTLH_INNERMOST_PRIVATE = 2,
19 __RISCV_NTLH_ALL_PRIVATE,
20 __RISCV_NTLH_INNERMOST_SHARED,
21 __RISCV_NTLH_ALL
22};
23
24#define __riscv_ntl_load(PTR, DOMAIN) __builtin_riscv_ntl_load((PTR), (DOMAIN))
25#define __riscv_ntl_store(PTR, VAL, DOMAIN) \
26 __builtin_riscv_ntl_store((PTR), (VAL), (DOMAIN))
27
28#endif
\ No newline at end of file
lib/include/riscv_vector.h+240-51
......@@ -25,52 +25,15 @@ extern "C" {
2525#pragma clang riscv intrinsic vector
2626
2727
28#define __riscv_vlenb() __builtin_rvv_vlenb()
29
30enum RVV_CSR {
31 RVV_VSTART = 0,
32 RVV_VXSAT,
33 RVV_VXRM,
34 RVV_VCSR,
28enum __RISCV_FRM {
29 __RISCV_FRM_RNE = 0,
30 __RISCV_FRM_RTZ = 1,
31 __RISCV_FRM_RDN = 2,
32 __RISCV_FRM_RUP = 3,
33 __RISCV_FRM_RMM = 4,
3534};
3635
37static __inline__ __attribute__((__always_inline__, __nodebug__))
38unsigned long __riscv_vread_csr(enum RVV_CSR __csr) {
39 unsigned long __rv = 0;
40 switch (__csr) {
41 case RVV_VSTART:
42 __asm__ __volatile__ ("csrr\t%0, vstart" : "=r"(__rv) : : "memory");
43 break;
44 case RVV_VXSAT:
45 __asm__ __volatile__ ("csrr\t%0, vxsat" : "=r"(__rv) : : "memory");
46 break;
47 case RVV_VXRM:
48 __asm__ __volatile__ ("csrr\t%0, vxrm" : "=r"(__rv) : : "memory");
49 break;
50 case RVV_VCSR:
51 __asm__ __volatile__ ("csrr\t%0, vcsr" : "=r"(__rv) : : "memory");
52 break;
53 }
54 return __rv;
55}
56
57static __inline__ __attribute__((__always_inline__, __nodebug__))
58void __riscv_vwrite_csr(enum RVV_CSR __csr, unsigned long __value) {
59 switch (__csr) {
60 case RVV_VSTART:
61 __asm__ __volatile__ ("csrw\tvstart, %z0" : : "rJ"(__value) : "memory");
62 break;
63 case RVV_VXSAT:
64 __asm__ __volatile__ ("csrw\tvxsat, %z0" : : "rJ"(__value) : "memory");
65 break;
66 case RVV_VXRM:
67 __asm__ __volatile__ ("csrw\tvxrm, %z0" : : "rJ"(__value) : "memory");
68 break;
69 case RVV_VCSR:
70 __asm__ __volatile__ ("csrw\tvcsr, %z0" : : "rJ"(__value) : "memory");
71 break;
72 }
73}
36#define __riscv_vlenb() __builtin_rvv_vlenb()
7437
7538#define __riscv_vsetvl_e8mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 6)
7639#define __riscv_vsetvl_e8mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 7)
......@@ -130,6 +93,13 @@ void __riscv_vwrite_csr(enum RVV_CSR __csr, unsigned long __value) {
13093#define __riscv_vsetvlmax_e64m8() __builtin_rvv_vsetvlimax(3, 3)
13194#endif
13295
96
97enum __RISCV_VXRM {
98 __RISCV_VXRM_RNU = 0,
99 __RISCV_VXRM_RNE = 1,
100 __RISCV_VXRM_RDN = 2,
101 __RISCV_VXRM_ROD = 3,
102};
133103typedef __rvv_bool64_t vbool64_t;
134104typedef __rvv_bool32_t vbool32_t;
135105typedef __rvv_bool16_t vbool16_t;
......@@ -139,70 +109,289 @@ typedef __rvv_bool2_t vbool2_t;
139109typedef __rvv_bool1_t vbool1_t;
140110typedef __rvv_int8mf8_t vint8mf8_t;
141111typedef __rvv_uint8mf8_t vuint8mf8_t;
112typedef __rvv_int8mf8x2_t vint8mf8x2_t;
113typedef __rvv_uint8mf8x2_t vuint8mf8x2_t;
114typedef __rvv_int8mf8x3_t vint8mf8x3_t;
115typedef __rvv_uint8mf8x3_t vuint8mf8x3_t;
116typedef __rvv_int8mf8x4_t vint8mf8x4_t;
117typedef __rvv_uint8mf8x4_t vuint8mf8x4_t;
118typedef __rvv_int8mf8x5_t vint8mf8x5_t;
119typedef __rvv_uint8mf8x5_t vuint8mf8x5_t;
120typedef __rvv_int8mf8x6_t vint8mf8x6_t;
121typedef __rvv_uint8mf8x6_t vuint8mf8x6_t;
122typedef __rvv_int8mf8x7_t vint8mf8x7_t;
123typedef __rvv_uint8mf8x7_t vuint8mf8x7_t;
124typedef __rvv_int8mf8x8_t vint8mf8x8_t;
125typedef __rvv_uint8mf8x8_t vuint8mf8x8_t;
142126typedef __rvv_int8mf4_t vint8mf4_t;
143127typedef __rvv_uint8mf4_t vuint8mf4_t;
128typedef __rvv_int8mf4x2_t vint8mf4x2_t;
129typedef __rvv_uint8mf4x2_t vuint8mf4x2_t;
130typedef __rvv_int8mf4x3_t vint8mf4x3_t;
131typedef __rvv_uint8mf4x3_t vuint8mf4x3_t;
132typedef __rvv_int8mf4x4_t vint8mf4x4_t;
133typedef __rvv_uint8mf4x4_t vuint8mf4x4_t;
134typedef __rvv_int8mf4x5_t vint8mf4x5_t;
135typedef __rvv_uint8mf4x5_t vuint8mf4x5_t;
136typedef __rvv_int8mf4x6_t vint8mf4x6_t;
137typedef __rvv_uint8mf4x6_t vuint8mf4x6_t;
138typedef __rvv_int8mf4x7_t vint8mf4x7_t;
139typedef __rvv_uint8mf4x7_t vuint8mf4x7_t;
140typedef __rvv_int8mf4x8_t vint8mf4x8_t;
141typedef __rvv_uint8mf4x8_t vuint8mf4x8_t;
144142typedef __rvv_int8mf2_t vint8mf2_t;
145143typedef __rvv_uint8mf2_t vuint8mf2_t;
144typedef __rvv_int8mf2x2_t vint8mf2x2_t;
145typedef __rvv_uint8mf2x2_t vuint8mf2x2_t;
146typedef __rvv_int8mf2x3_t vint8mf2x3_t;
147typedef __rvv_uint8mf2x3_t vuint8mf2x3_t;
148typedef __rvv_int8mf2x4_t vint8mf2x4_t;
149typedef __rvv_uint8mf2x4_t vuint8mf2x4_t;
150typedef __rvv_int8mf2x5_t vint8mf2x5_t;
151typedef __rvv_uint8mf2x5_t vuint8mf2x5_t;
152typedef __rvv_int8mf2x6_t vint8mf2x6_t;
153typedef __rvv_uint8mf2x6_t vuint8mf2x6_t;
154typedef __rvv_int8mf2x7_t vint8mf2x7_t;
155typedef __rvv_uint8mf2x7_t vuint8mf2x7_t;
156typedef __rvv_int8mf2x8_t vint8mf2x8_t;
157typedef __rvv_uint8mf2x8_t vuint8mf2x8_t;
146158typedef __rvv_int8m1_t vint8m1_t;
147159typedef __rvv_uint8m1_t vuint8m1_t;
160typedef __rvv_int8m1x2_t vint8m1x2_t;
161typedef __rvv_uint8m1x2_t vuint8m1x2_t;
162typedef __rvv_int8m1x3_t vint8m1x3_t;
163typedef __rvv_uint8m1x3_t vuint8m1x3_t;
164typedef __rvv_int8m1x4_t vint8m1x4_t;
165typedef __rvv_uint8m1x4_t vuint8m1x4_t;
166typedef __rvv_int8m1x5_t vint8m1x5_t;
167typedef __rvv_uint8m1x5_t vuint8m1x5_t;
168typedef __rvv_int8m1x6_t vint8m1x6_t;
169typedef __rvv_uint8m1x6_t vuint8m1x6_t;
170typedef __rvv_int8m1x7_t vint8m1x7_t;
171typedef __rvv_uint8m1x7_t vuint8m1x7_t;
172typedef __rvv_int8m1x8_t vint8m1x8_t;
173typedef __rvv_uint8m1x8_t vuint8m1x8_t;
148174typedef __rvv_int8m2_t vint8m2_t;
149175typedef __rvv_uint8m2_t vuint8m2_t;
176typedef __rvv_int8m2x2_t vint8m2x2_t;
177typedef __rvv_uint8m2x2_t vuint8m2x2_t;
178typedef __rvv_int8m2x3_t vint8m2x3_t;
179typedef __rvv_uint8m2x3_t vuint8m2x3_t;
180typedef __rvv_int8m2x4_t vint8m2x4_t;
181typedef __rvv_uint8m2x4_t vuint8m2x4_t;
150182typedef __rvv_int8m4_t vint8m4_t;
151183typedef __rvv_uint8m4_t vuint8m4_t;
184typedef __rvv_int8m4x2_t vint8m4x2_t;
185typedef __rvv_uint8m4x2_t vuint8m4x2_t;
152186typedef __rvv_int8m8_t vint8m8_t;
153187typedef __rvv_uint8m8_t vuint8m8_t;
154188typedef __rvv_int16mf4_t vint16mf4_t;
155189typedef __rvv_uint16mf4_t vuint16mf4_t;
190typedef __rvv_int16mf4x2_t vint16mf4x2_t;
191typedef __rvv_uint16mf4x2_t vuint16mf4x2_t;
192typedef __rvv_int16mf4x3_t vint16mf4x3_t;
193typedef __rvv_uint16mf4x3_t vuint16mf4x3_t;
194typedef __rvv_int16mf4x4_t vint16mf4x4_t;
195typedef __rvv_uint16mf4x4_t vuint16mf4x4_t;
196typedef __rvv_int16mf4x5_t vint16mf4x5_t;
197typedef __rvv_uint16mf4x5_t vuint16mf4x5_t;
198typedef __rvv_int16mf4x6_t vint16mf4x6_t;
199typedef __rvv_uint16mf4x6_t vuint16mf4x6_t;
200typedef __rvv_int16mf4x7_t vint16mf4x7_t;
201typedef __rvv_uint16mf4x7_t vuint16mf4x7_t;
202typedef __rvv_int16mf4x8_t vint16mf4x8_t;
203typedef __rvv_uint16mf4x8_t vuint16mf4x8_t;
156204typedef __rvv_int16mf2_t vint16mf2_t;
157205typedef __rvv_uint16mf2_t vuint16mf2_t;
206typedef __rvv_int16mf2x2_t vint16mf2x2_t;
207typedef __rvv_uint16mf2x2_t vuint16mf2x2_t;
208typedef __rvv_int16mf2x3_t vint16mf2x3_t;
209typedef __rvv_uint16mf2x3_t vuint16mf2x3_t;
210typedef __rvv_int16mf2x4_t vint16mf2x4_t;
211typedef __rvv_uint16mf2x4_t vuint16mf2x4_t;
212typedef __rvv_int16mf2x5_t vint16mf2x5_t;
213typedef __rvv_uint16mf2x5_t vuint16mf2x5_t;
214typedef __rvv_int16mf2x6_t vint16mf2x6_t;
215typedef __rvv_uint16mf2x6_t vuint16mf2x6_t;
216typedef __rvv_int16mf2x7_t vint16mf2x7_t;
217typedef __rvv_uint16mf2x7_t vuint16mf2x7_t;
218typedef __rvv_int16mf2x8_t vint16mf2x8_t;
219typedef __rvv_uint16mf2x8_t vuint16mf2x8_t;
158220typedef __rvv_int16m1_t vint16m1_t;
159221typedef __rvv_uint16m1_t vuint16m1_t;
222typedef __rvv_int16m1x2_t vint16m1x2_t;
223typedef __rvv_uint16m1x2_t vuint16m1x2_t;
224typedef __rvv_int16m1x3_t vint16m1x3_t;
225typedef __rvv_uint16m1x3_t vuint16m1x3_t;
226typedef __rvv_int16m1x4_t vint16m1x4_t;
227typedef __rvv_uint16m1x4_t vuint16m1x4_t;
228typedef __rvv_int16m1x5_t vint16m1x5_t;
229typedef __rvv_uint16m1x5_t vuint16m1x5_t;
230typedef __rvv_int16m1x6_t vint16m1x6_t;
231typedef __rvv_uint16m1x6_t vuint16m1x6_t;
232typedef __rvv_int16m1x7_t vint16m1x7_t;
233typedef __rvv_uint16m1x7_t vuint16m1x7_t;
234typedef __rvv_int16m1x8_t vint16m1x8_t;
235typedef __rvv_uint16m1x8_t vuint16m1x8_t;
160236typedef __rvv_int16m2_t vint16m2_t;
161237typedef __rvv_uint16m2_t vuint16m2_t;
238typedef __rvv_int16m2x2_t vint16m2x2_t;
239typedef __rvv_uint16m2x2_t vuint16m2x2_t;
240typedef __rvv_int16m2x3_t vint16m2x3_t;
241typedef __rvv_uint16m2x3_t vuint16m2x3_t;
242typedef __rvv_int16m2x4_t vint16m2x4_t;
243typedef __rvv_uint16m2x4_t vuint16m2x4_t;
162244typedef __rvv_int16m4_t vint16m4_t;
163245typedef __rvv_uint16m4_t vuint16m4_t;
246typedef __rvv_int16m4x2_t vint16m4x2_t;
247typedef __rvv_uint16m4x2_t vuint16m4x2_t;
164248typedef __rvv_int16m8_t vint16m8_t;
165249typedef __rvv_uint16m8_t vuint16m8_t;
166250typedef __rvv_int32mf2_t vint32mf2_t;
167251typedef __rvv_uint32mf2_t vuint32mf2_t;
252typedef __rvv_int32mf2x2_t vint32mf2x2_t;
253typedef __rvv_uint32mf2x2_t vuint32mf2x2_t;
254typedef __rvv_int32mf2x3_t vint32mf2x3_t;
255typedef __rvv_uint32mf2x3_t vuint32mf2x3_t;
256typedef __rvv_int32mf2x4_t vint32mf2x4_t;
257typedef __rvv_uint32mf2x4_t vuint32mf2x4_t;
258typedef __rvv_int32mf2x5_t vint32mf2x5_t;
259typedef __rvv_uint32mf2x5_t vuint32mf2x5_t;
260typedef __rvv_int32mf2x6_t vint32mf2x6_t;
261typedef __rvv_uint32mf2x6_t vuint32mf2x6_t;
262typedef __rvv_int32mf2x7_t vint32mf2x7_t;
263typedef __rvv_uint32mf2x7_t vuint32mf2x7_t;
264typedef __rvv_int32mf2x8_t vint32mf2x8_t;
265typedef __rvv_uint32mf2x8_t vuint32mf2x8_t;
168266typedef __rvv_int32m1_t vint32m1_t;
169267typedef __rvv_uint32m1_t vuint32m1_t;
268typedef __rvv_int32m1x2_t vint32m1x2_t;
269typedef __rvv_uint32m1x2_t vuint32m1x2_t;
270typedef __rvv_int32m1x3_t vint32m1x3_t;
271typedef __rvv_uint32m1x3_t vuint32m1x3_t;
272typedef __rvv_int32m1x4_t vint32m1x4_t;
273typedef __rvv_uint32m1x4_t vuint32m1x4_t;
274typedef __rvv_int32m1x5_t vint32m1x5_t;
275typedef __rvv_uint32m1x5_t vuint32m1x5_t;
276typedef __rvv_int32m1x6_t vint32m1x6_t;
277typedef __rvv_uint32m1x6_t vuint32m1x6_t;
278typedef __rvv_int32m1x7_t vint32m1x7_t;
279typedef __rvv_uint32m1x7_t vuint32m1x7_t;
280typedef __rvv_int32m1x8_t vint32m1x8_t;
281typedef __rvv_uint32m1x8_t vuint32m1x8_t;
170282typedef __rvv_int32m2_t vint32m2_t;
171283typedef __rvv_uint32m2_t vuint32m2_t;
284typedef __rvv_int32m2x2_t vint32m2x2_t;
285typedef __rvv_uint32m2x2_t vuint32m2x2_t;
286typedef __rvv_int32m2x3_t vint32m2x3_t;
287typedef __rvv_uint32m2x3_t vuint32m2x3_t;
288typedef __rvv_int32m2x4_t vint32m2x4_t;
289typedef __rvv_uint32m2x4_t vuint32m2x4_t;
172290typedef __rvv_int32m4_t vint32m4_t;
173291typedef __rvv_uint32m4_t vuint32m4_t;
292typedef __rvv_int32m4x2_t vint32m4x2_t;
293typedef __rvv_uint32m4x2_t vuint32m4x2_t;
174294typedef __rvv_int32m8_t vint32m8_t;
175295typedef __rvv_uint32m8_t vuint32m8_t;
176296typedef __rvv_int64m1_t vint64m1_t;
177297typedef __rvv_uint64m1_t vuint64m1_t;
298typedef __rvv_int64m1x2_t vint64m1x2_t;
299typedef __rvv_uint64m1x2_t vuint64m1x2_t;
300typedef __rvv_int64m1x3_t vint64m1x3_t;
301typedef __rvv_uint64m1x3_t vuint64m1x3_t;
302typedef __rvv_int64m1x4_t vint64m1x4_t;
303typedef __rvv_uint64m1x4_t vuint64m1x4_t;
304typedef __rvv_int64m1x5_t vint64m1x5_t;
305typedef __rvv_uint64m1x5_t vuint64m1x5_t;
306typedef __rvv_int64m1x6_t vint64m1x6_t;
307typedef __rvv_uint64m1x6_t vuint64m1x6_t;
308typedef __rvv_int64m1x7_t vint64m1x7_t;
309typedef __rvv_uint64m1x7_t vuint64m1x7_t;
310typedef __rvv_int64m1x8_t vint64m1x8_t;
311typedef __rvv_uint64m1x8_t vuint64m1x8_t;
178312typedef __rvv_int64m2_t vint64m2_t;
179313typedef __rvv_uint64m2_t vuint64m2_t;
314typedef __rvv_int64m2x2_t vint64m2x2_t;
315typedef __rvv_uint64m2x2_t vuint64m2x2_t;
316typedef __rvv_int64m2x3_t vint64m2x3_t;
317typedef __rvv_uint64m2x3_t vuint64m2x3_t;
318typedef __rvv_int64m2x4_t vint64m2x4_t;
319typedef __rvv_uint64m2x4_t vuint64m2x4_t;
180320typedef __rvv_int64m4_t vint64m4_t;
181321typedef __rvv_uint64m4_t vuint64m4_t;
322typedef __rvv_int64m4x2_t vint64m4x2_t;
323typedef __rvv_uint64m4x2_t vuint64m4x2_t;
182324typedef __rvv_int64m8_t vint64m8_t;
183325typedef __rvv_uint64m8_t vuint64m8_t;
184#if defined(__riscv_zvfh)
185326typedef __rvv_float16mf4_t vfloat16mf4_t;
327typedef __rvv_float16mf4x2_t vfloat16mf4x2_t;
328typedef __rvv_float16mf4x3_t vfloat16mf4x3_t;
329typedef __rvv_float16mf4x4_t vfloat16mf4x4_t;
330typedef __rvv_float16mf4x5_t vfloat16mf4x5_t;
331typedef __rvv_float16mf4x6_t vfloat16mf4x6_t;
332typedef __rvv_float16mf4x7_t vfloat16mf4x7_t;
333typedef __rvv_float16mf4x8_t vfloat16mf4x8_t;
186334typedef __rvv_float16mf2_t vfloat16mf2_t;
335typedef __rvv_float16mf2x2_t vfloat16mf2x2_t;
336typedef __rvv_float16mf2x3_t vfloat16mf2x3_t;
337typedef __rvv_float16mf2x4_t vfloat16mf2x4_t;
338typedef __rvv_float16mf2x5_t vfloat16mf2x5_t;
339typedef __rvv_float16mf2x6_t vfloat16mf2x6_t;
340typedef __rvv_float16mf2x7_t vfloat16mf2x7_t;
341typedef __rvv_float16mf2x8_t vfloat16mf2x8_t;
187342typedef __rvv_float16m1_t vfloat16m1_t;
343typedef __rvv_float16m1x2_t vfloat16m1x2_t;
344typedef __rvv_float16m1x3_t vfloat16m1x3_t;
345typedef __rvv_float16m1x4_t vfloat16m1x4_t;
346typedef __rvv_float16m1x5_t vfloat16m1x5_t;
347typedef __rvv_float16m1x6_t vfloat16m1x6_t;
348typedef __rvv_float16m1x7_t vfloat16m1x7_t;
349typedef __rvv_float16m1x8_t vfloat16m1x8_t;
188350typedef __rvv_float16m2_t vfloat16m2_t;
351typedef __rvv_float16m2x2_t vfloat16m2x2_t;
352typedef __rvv_float16m2x3_t vfloat16m2x3_t;
353typedef __rvv_float16m2x4_t vfloat16m2x4_t;
189354typedef __rvv_float16m4_t vfloat16m4_t;
355typedef __rvv_float16m4x2_t vfloat16m4x2_t;
190356typedef __rvv_float16m8_t vfloat16m8_t;
191#endif
192#if (__riscv_v_elen_fp >= 32)
193357typedef __rvv_float32mf2_t vfloat32mf2_t;
358typedef __rvv_float32mf2x2_t vfloat32mf2x2_t;
359typedef __rvv_float32mf2x3_t vfloat32mf2x3_t;
360typedef __rvv_float32mf2x4_t vfloat32mf2x4_t;
361typedef __rvv_float32mf2x5_t vfloat32mf2x5_t;
362typedef __rvv_float32mf2x6_t vfloat32mf2x6_t;
363typedef __rvv_float32mf2x7_t vfloat32mf2x7_t;
364typedef __rvv_float32mf2x8_t vfloat32mf2x8_t;
194365typedef __rvv_float32m1_t vfloat32m1_t;
366typedef __rvv_float32m1x2_t vfloat32m1x2_t;
367typedef __rvv_float32m1x3_t vfloat32m1x3_t;
368typedef __rvv_float32m1x4_t vfloat32m1x4_t;
369typedef __rvv_float32m1x5_t vfloat32m1x5_t;
370typedef __rvv_float32m1x6_t vfloat32m1x6_t;
371typedef __rvv_float32m1x7_t vfloat32m1x7_t;
372typedef __rvv_float32m1x8_t vfloat32m1x8_t;
195373typedef __rvv_float32m2_t vfloat32m2_t;
374typedef __rvv_float32m2x2_t vfloat32m2x2_t;
375typedef __rvv_float32m2x3_t vfloat32m2x3_t;
376typedef __rvv_float32m2x4_t vfloat32m2x4_t;
196377typedef __rvv_float32m4_t vfloat32m4_t;
378typedef __rvv_float32m4x2_t vfloat32m4x2_t;
197379typedef __rvv_float32m8_t vfloat32m8_t;
198#endif
199#if (__riscv_v_elen_fp >= 64)
200380typedef __rvv_float64m1_t vfloat64m1_t;
381typedef __rvv_float64m1x2_t vfloat64m1x2_t;
382typedef __rvv_float64m1x3_t vfloat64m1x3_t;
383typedef __rvv_float64m1x4_t vfloat64m1x4_t;
384typedef __rvv_float64m1x5_t vfloat64m1x5_t;
385typedef __rvv_float64m1x6_t vfloat64m1x6_t;
386typedef __rvv_float64m1x7_t vfloat64m1x7_t;
387typedef __rvv_float64m1x8_t vfloat64m1x8_t;
201388typedef __rvv_float64m2_t vfloat64m2_t;
389typedef __rvv_float64m2x2_t vfloat64m2x2_t;
390typedef __rvv_float64m2x3_t vfloat64m2x3_t;
391typedef __rvv_float64m2x4_t vfloat64m2x4_t;
202392typedef __rvv_float64m4_t vfloat64m4_t;
393typedef __rvv_float64m4x2_t vfloat64m4x2_t;
203394typedef __rvv_float64m8_t vfloat64m8_t;
204#endif
205
206395#define __riscv_v_intrinsic_overloading 1
207396
208397#ifdef __cplusplus
lib/include/sha512intrin.h created+200
......@@ -0,0 +1,200 @@
1/*===--------------- sha512intrin.h - SHA512 intrinsics -----------------===
2 *
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 * See https://llvm.org/LICENSE.txt for license information.
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 *
7 *===-----------------------------------------------------------------------===
8 */
9
10#ifndef __IMMINTRIN_H
11#error "Never use <sha512intrin.h> directly; include <immintrin.h> instead."
12#endif // __IMMINTRIN_H
13
14#ifndef __SHA512INTRIN_H
15#define __SHA512INTRIN_H
16
17#define __DEFAULT_FN_ATTRS256 \
18 __attribute__((__always_inline__, __nodebug__, __target__("sha512"), \
19 __min_vector_width__(256)))
20
21/// This intrinisc is one of the two SHA512 message scheduling instructions.
22/// The intrinsic performs an intermediate calculation for the next four
23/// SHA512 message qwords. The calculated results are stored in \a dst.
24///
25/// \headerfile <immintrin.h>
26///
27/// \code
28/// __m256i _mm256_sha512msg1_epi64(__m256i __A, __m128i __B)
29/// \endcode
30///
31/// This intrinsic corresponds to the \c VSHA512MSG1 instruction.
32///
33/// \param __A
34/// A 256-bit vector of [4 x long long].
35/// \param __B
36/// A 128-bit vector of [2 x long long].
37/// \returns
38/// A 256-bit vector of [4 x long long].
39///
40/// \code{.operation}
41/// DEFINE ROR64(qword, n) {
42/// count := n % 64
43/// dest := (qword >> count) | (qword << (64 - count))
44/// RETURN dest
45/// }
46/// DEFINE SHR64(qword, n) {
47/// RETURN qword >> n
48/// }
49/// DEFINE s0(qword):
50/// RETURN ROR64(qword,1) ^ ROR64(qword, 8) ^ SHR64(qword, 7)
51/// }
52/// W[4] := __B.qword[0]
53/// W[3] := __A.qword[3]
54/// W[2] := __A.qword[2]
55/// W[1] := __A.qword[1]
56/// W[0] := __A.qword[0]
57/// dst.qword[3] := W[3] + s0(W[4])
58/// dst.qword[2] := W[2] + s0(W[3])
59/// dst.qword[1] := W[1] + s0(W[2])
60/// dst.qword[0] := W[0] + s0(W[1])
61/// dst[MAX:256] := 0
62/// \endcode
63static __inline__ __m256i __DEFAULT_FN_ATTRS256
64_mm256_sha512msg1_epi64(__m256i __A, __m128i __B) {
65 return (__m256i)__builtin_ia32_vsha512msg1((__v4du)__A, (__v2du)__B);
66}
67
68/// This intrinisc is one of the two SHA512 message scheduling instructions.
69/// The intrinsic performs the final calculation for the next four SHA512
70/// message qwords. The calculated results are stored in \a dst.
71///
72/// \headerfile <immintrin.h>
73///
74/// \code
75/// __m256i _mm256_sha512msg2_epi64(__m256i __A, __m256i __B)
76/// \endcode
77///
78/// This intrinsic corresponds to the \c VSHA512MSG2 instruction.
79///
80/// \param __A
81/// A 256-bit vector of [4 x long long].
82/// \param __B
83/// A 256-bit vector of [4 x long long].
84/// \returns
85/// A 256-bit vector of [4 x long long].
86///
87/// \code{.operation}
88/// DEFINE ROR64(qword, n) {
89/// count := n % 64
90/// dest := (qword >> count) | (qword << (64 - count))
91/// RETURN dest
92/// }
93/// DEFINE SHR64(qword, n) {
94/// RETURN qword >> n
95/// }
96/// DEFINE s1(qword) {
97/// RETURN ROR64(qword,19) ^ ROR64(qword, 61) ^ SHR64(qword, 6)
98/// }
99/// W[14] := __B.qword[2]
100/// W[15] := __B.qword[3]
101/// W[16] := __A.qword[0] + s1(W[14])
102/// W[17] := __A.qword[1] + s1(W[15])
103/// W[18] := __A.qword[2] + s1(W[16])
104/// W[19] := __A.qword[3] + s1(W[17])
105/// dst.qword[3] := W[19]
106/// dst.qword[2] := W[18]
107/// dst.qword[1] := W[17]
108/// dst.qword[0] := W[16]
109/// dst[MAX:256] := 0
110/// \endcode
111static __inline__ __m256i __DEFAULT_FN_ATTRS256
112_mm256_sha512msg2_epi64(__m256i __A, __m256i __B) {
113 return (__m256i)__builtin_ia32_vsha512msg2((__v4du)__A, (__v4du)__B);
114}
115
116/// This intrinisc performs two rounds of SHA512 operation using initial SHA512
117/// state (C,D,G,H) from \a __A, an initial SHA512 state (A,B,E,F) from
118/// \a __A, and a pre-computed sum of the next two round message qwords and
119/// the corresponding round constants from \a __C (only the two lower qwords
120/// of the third operand). The updated SHA512 state (A,B,E,F) is written to
121/// \a __A, and \a __A can be used as the updated state (C,D,G,H) in later
122/// rounds.
123///
124/// \headerfile <immintrin.h>
125///
126/// \code
127/// __m256i _mm256_sha512rnds2_epi64(__m256i __A, __m256i __B, __m128i __C)
128/// \endcode
129///
130/// This intrinsic corresponds to the \c VSHA512RNDS2 instruction.
131///
132/// \param __A
133/// A 256-bit vector of [4 x long long].
134/// \param __B
135/// A 256-bit vector of [4 x long long].
136/// \param __C
137/// A 128-bit vector of [2 x long long].
138/// \returns
139/// A 256-bit vector of [4 x long long].
140///
141/// \code{.operation}
142/// DEFINE ROR64(qword, n) {
143/// count := n % 64
144/// dest := (qword >> count) | (qword << (64 - count))
145/// RETURN dest
146/// }
147/// DEFINE SHR64(qword, n) {
148/// RETURN qword >> n
149/// }
150/// DEFINE cap_sigma0(qword) {
151/// RETURN ROR64(qword,28) ^ ROR64(qword, 34) ^ ROR64(qword, 39)
152/// }
153/// DEFINE cap_sigma1(qword) {
154/// RETURN ROR64(qword,14) ^ ROR64(qword, 18) ^ ROR64(qword, 41)
155/// }
156/// DEFINE MAJ(a,b,c) {
157/// RETURN (a & b) ^ (a & c) ^ (b & c)
158/// }
159/// DEFINE CH(e,f,g) {
160/// RETURN (e & f) ^ (g & ~e)
161/// }
162/// A[0] := __B.qword[3]
163/// B[0] := __B.qword[2]
164/// C[0] := __C.qword[3]
165/// D[0] := __C.qword[2]
166/// E[0] := __B.qword[1]
167/// F[0] := __B.qword[0]
168/// G[0] := __C.qword[1]
169/// H[0] := __C.qword[0]
170/// WK[0]:= __A.qword[0]
171/// WK[1]:= __A.qword[1]
172/// FOR i := 0 to 1:
173/// A[i+1] := CH(E[i], F[i], G[i]) +
174/// cap_sigma1(E[i]) + WK[i] + H[i] +
175/// MAJ(A[i], B[i], C[i]) +
176/// cap_sigma0(A[i])
177/// B[i+1] := A[i]
178/// C[i+1] := B[i]
179/// D[i+1] := C[i]
180/// E[i+1] := CH(E[i], F[i], G[i]) +
181/// cap_sigma1(E[i]) + WK[i] + H[i] + D[i]
182/// F[i+1] := E[i]
183/// G[i+1] := F[i]
184/// H[i+1] := G[i]
185/// ENDFOR
186/// dst.qword[3] := A[2]
187/// dst.qword[2] := B[2]
188/// dst.qword[1] := E[2]
189/// dst.qword[0] := F[2]
190/// dst[MAX:256] := 0
191/// \endcode
192static __inline__ __m256i __DEFAULT_FN_ATTRS256
193_mm256_sha512rnds2_epi64(__m256i __A, __m256i __B, __m128i __C) {
194 return (__m256i)__builtin_ia32_vsha512rnds2((__v4du)__A, (__v4du)__B,
195 (__v2du)__C);
196}
197
198#undef __DEFAULT_FN_ATTRS256
199
200#endif // __SHA512INTRIN_H
lib/include/shaintrin.h+128
......@@ -17,39 +17,167 @@
1717/* Define the default attributes for the functions in this file. */
1818#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("sha"), __min_vector_width__(128)))
1919
20/// Performs four iterations of the inner loop of the SHA-1 message digest
21/// algorithm using the starting SHA-1 state (A, B, C, D) from the 128-bit
22/// vector of [4 x i32] in \a V1 and the next four 32-bit elements of the
23/// message from the 128-bit vector of [4 x i32] in \a V2. Note that the
24/// SHA-1 state variable E must have already been added to \a V2
25/// (\c _mm_sha1nexte_epu32() can perform this step). Returns the updated
26/// SHA-1 state (A, B, C, D) as a 128-bit vector of [4 x i32].
27///
28/// The SHA-1 algorithm has an inner loop of 80 iterations, twenty each
29/// with a different combining function and rounding constant. This
30/// intrinsic performs four iterations using a combining function and
31/// rounding constant selected by \a M[1:0].
32///
33/// \headerfile <immintrin.h>
34///
35/// \code
36/// __m128i _mm_sha1rnds4_epu32(__m128i V1, __m128i V2, const int M);
37/// \endcode
38///
39/// This intrinsic corresponds to the \c SHA1RNDS4 instruction.
40///
41/// \param V1
42/// A 128-bit vector of [4 x i32] containing the initial SHA-1 state.
43/// \param V2
44/// A 128-bit vector of [4 x i32] containing the next four elements of
45/// the message, plus SHA-1 state variable E.
46/// \param M
47/// An immediate value where bits [1:0] select among four possible
48/// combining functions and rounding constants (not specified here).
49/// \returns A 128-bit vector of [4 x i32] containing the updated SHA-1 state.
2050#define _mm_sha1rnds4_epu32(V1, V2, M) \
2151 __builtin_ia32_sha1rnds4((__v4si)(__m128i)(V1), (__v4si)(__m128i)(V2), (M))
2252
53/// Calculates the SHA-1 state variable E from the SHA-1 state variables in
54/// the 128-bit vector of [4 x i32] in \a __X, adds that to the next set of
55/// four message elements in the 128-bit vector of [4 x i32] in \a __Y, and
56/// returns the result.
57///
58/// \headerfile <immintrin.h>
59///
60/// This intrinsic corresponds to the \c SHA1NEXTE instruction.
61///
62/// \param __X
63/// A 128-bit vector of [4 x i32] containing the current SHA-1 state.
64/// \param __Y
65/// A 128-bit vector of [4 x i32] containing the next four elements of the
66/// message.
67/// \returns A 128-bit vector of [4 x i32] containing the updated SHA-1
68/// values.
2369static __inline__ __m128i __DEFAULT_FN_ATTRS
2470_mm_sha1nexte_epu32(__m128i __X, __m128i __Y)
2571{
2672 return (__m128i)__builtin_ia32_sha1nexte((__v4si)__X, (__v4si)__Y);
2773}
2874
75/// Performs an intermediate calculation for deriving the next four SHA-1
76/// message elements using previous message elements from the 128-bit
77/// vectors of [4 x i32] in \a __X and \a __Y, and returns the result.
78///
79/// \headerfile <immintrin.h>
80///
81/// This intrinsic corresponds to the \c SHA1MSG1 instruction.
82///
83/// \param __X
84/// A 128-bit vector of [4 x i32] containing previous message elements.
85/// \param __Y
86/// A 128-bit vector of [4 x i32] containing previous message elements.
87/// \returns A 128-bit vector of [4 x i32] containing the derived SHA-1
88/// elements.
2989static __inline__ __m128i __DEFAULT_FN_ATTRS
3090_mm_sha1msg1_epu32(__m128i __X, __m128i __Y)
3191{
3292 return (__m128i)__builtin_ia32_sha1msg1((__v4si)__X, (__v4si)__Y);
3393}
3494
95/// Performs the final calculation for deriving the next four SHA-1 message
96/// elements using previous message elements from the 128-bit vectors of
97/// [4 x i32] in \a __X and \a __Y, and returns the result.
98///
99/// \headerfile <immintrin.h>
100///
101/// This intrinsic corresponds to the \c SHA1MSG2 instruction.
102///
103/// \param __X
104/// A 128-bit vector of [4 x i32] containing an intermediate result.
105/// \param __Y
106/// A 128-bit vector of [4 x i32] containing previous message values.
107/// \returns A 128-bit vector of [4 x i32] containing the updated SHA-1
108/// values.
35109static __inline__ __m128i __DEFAULT_FN_ATTRS
36110_mm_sha1msg2_epu32(__m128i __X, __m128i __Y)
37111{
38112 return (__m128i)__builtin_ia32_sha1msg2((__v4si)__X, (__v4si)__Y);
39113}
40114
115/// Performs two rounds of SHA-256 operation using the following inputs: a
116/// starting SHA-256 state (C, D, G, H) from the 128-bit vector of
117/// [4 x i32] in \a __X; a starting SHA-256 state (A, B, E, F) from the
118/// 128-bit vector of [4 x i32] in \a __Y; and a pre-computed sum of the
119/// next two message elements (unsigned 32-bit integers) and corresponding
120/// rounding constants from the 128-bit vector of [4 x i32] in \a __Z.
121/// Returns the updated SHA-256 state (A, B, E, F) as a 128-bit vector of
122/// [4 x i32].
123///
124/// The SHA-256 algorithm has a core loop of 64 iterations. This intrinsic
125/// performs two of those iterations.
126///
127/// \headerfile <immintrin.h>
128///
129/// This intrinsic corresponds to the \c SHA256RNDS2 instruction.
130///
131/// \param __X
132/// A 128-bit vector of [4 x i32] containing part of the initial SHA-256
133/// state.
134/// \param __Y
135/// A 128-bit vector of [4 x i32] containing part of the initial SHA-256
136/// state.
137/// \param __Z
138/// A 128-bit vector of [4 x i32] containing additional input to the
139/// SHA-256 operation.
140/// \returns A 128-bit vector of [4 x i32] containing the updated SHA-1 state.
41141static __inline__ __m128i __DEFAULT_FN_ATTRS
42142_mm_sha256rnds2_epu32(__m128i __X, __m128i __Y, __m128i __Z)
43143{
44144 return (__m128i)__builtin_ia32_sha256rnds2((__v4si)__X, (__v4si)__Y, (__v4si)__Z);
45145}
46146
147/// Performs an intermediate calculation for deriving the next four SHA-256
148/// message elements using previous message elements from the 128-bit
149/// vectors of [4 x i32] in \a __X and \a __Y, and returns the result.
150///
151/// \headerfile <immintrin.h>
152///
153/// This intrinsic corresponds to the \c SHA256MSG1 instruction.
154///
155/// \param __X
156/// A 128-bit vector of [4 x i32] containing previous message elements.
157/// \param __Y
158/// A 128-bit vector of [4 x i32] containing previous message elements.
159/// \returns A 128-bit vector of [4 x i32] containing the updated SHA-256
160/// values.
47161static __inline__ __m128i __DEFAULT_FN_ATTRS
48162_mm_sha256msg1_epu32(__m128i __X, __m128i __Y)
49163{
50164 return (__m128i)__builtin_ia32_sha256msg1((__v4si)__X, (__v4si)__Y);
51165}
52166
167/// Performs the final calculation for deriving the next four SHA-256 message
168/// elements using previous message elements from the 128-bit vectors of
169/// [4 x i32] in \a __X and \a __Y, and returns the result.
170///
171/// \headerfile <immintrin.h>
172///
173/// This intrinsic corresponds to the \c SHA256MSG2 instruction.
174///
175/// \param __X
176/// A 128-bit vector of [4 x i32] containing an intermediate result.
177/// \param __Y
178/// A 128-bit vector of [4 x i32] containing previous message values.
179/// \returns A 128-bit vector of [4 x i32] containing the updated SHA-256
180/// values.
53181static __inline__ __m128i __DEFAULT_FN_ATTRS
54182_mm_sha256msg2_epu32(__m128i __X, __m128i __Y)
55183{
lib/include/sifive_vector.h created+16
......@@ -0,0 +1,16 @@
1//===----- sifive_vector.h - SiFive Vector definitions --------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _SIFIVE_VECTOR_H_
10#define _SIFIVE_VECTOR_H_
11
12#include "riscv_vector.h"
13
14#pragma clang riscv intrinsic sifive_vector
15
16#endif //_SIFIVE_VECTOR_H_
lib/include/sm3intrin.h created+238
......@@ -0,0 +1,238 @@
1/*===-------------------- sm3intrin.h - SM3 intrinsics ---------------------===
2 *
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 * See https://llvm.org/LICENSE.txt for license information.
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 *
7 *===-----------------------------------------------------------------------===
8 */
9
10#ifndef __IMMINTRIN_H
11#error "Never use <sm3intrin.h> directly; include <immintrin.h> instead."
12#endif // __IMMINTRIN_H
13
14#ifndef __SM3INTRIN_H
15#define __SM3INTRIN_H
16
17#define __DEFAULT_FN_ATTRS128 \
18 __attribute__((__always_inline__, __nodebug__, __target__("sm3"), \
19 __min_vector_width__(128)))
20
21/// This intrinisc is one of the two SM3 message scheduling intrinsics. The
22/// intrinsic performs an initial calculation for the next four SM3 message
23/// words. The calculated results are stored in \a dst.
24///
25/// \headerfile <immintrin.h>
26///
27/// \code
28/// __m128i _mm_sm3msg1_epi32(__m128i __A, __m128i __B, __m128i __C)
29/// \endcode
30///
31/// This intrinsic corresponds to the \c VSM3MSG1 instruction.
32///
33/// \param __A
34/// A 128-bit vector of [4 x int].
35/// \param __B
36/// A 128-bit vector of [4 x int].
37/// \param __C
38/// A 128-bit vector of [4 x int].
39/// \returns
40/// A 128-bit vector of [4 x int].
41///
42/// \code{.operation}
43/// DEFINE ROL32(dword, n) {
44/// count := n % 32
45/// dest := (dword << count) | (dword >> (32 - count))
46/// RETURN dest
47/// }
48/// DEFINE P1(x) {
49/// RETURN x ^ ROL32(x, 15) ^ ROL32(x, 23)
50/// }
51/// W[0] := __C.dword[0]
52/// W[1] := __C.dword[1]
53/// W[2] := __C.dword[2]
54/// W[3] := __C.dword[3]
55/// W[7] := __A.dword[0]
56/// W[8] := __A.dword[1]
57/// W[9] := __A.dword[2]
58/// W[10] := __A.dword[3]
59/// W[13] := __B.dword[0]
60/// W[14] := __B.dword[1]
61/// W[15] := __B.dword[2]
62/// TMP0 := W[7] ^ W[0] ^ ROL32(W[13], 15)
63/// TMP1 := W[8] ^ W[1] ^ ROL32(W[14], 15)
64/// TMP2 := W[9] ^ W[2] ^ ROL32(W[15], 15)
65/// TMP3 := W[10] ^ W[3]
66/// dst.dword[0] := P1(TMP0)
67/// dst.dword[1] := P1(TMP1)
68/// dst.dword[2] := P1(TMP2)
69/// dst.dword[3] := P1(TMP3)
70/// dst[MAX:128] := 0
71/// \endcode
72static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_sm3msg1_epi32(__m128i __A,
73 __m128i __B,
74 __m128i __C) {
75 return (__m128i)__builtin_ia32_vsm3msg1((__v4su)__A, (__v4su)__B,
76 (__v4su)__C);
77}
78
79/// This intrinisc is one of the two SM3 message scheduling intrinsics. The
80/// intrinsic performs the final calculation for the next four SM3 message
81/// words. The calculated results are stored in \a dst.
82///
83/// \headerfile <immintrin.h>
84///
85/// \code
86/// __m128i _mm_sm3msg2_epi32(__m128i __A, __m128i __B, __m128i __C)
87/// \endcode
88///
89/// This intrinsic corresponds to the \c VSM3MSG2 instruction.
90///
91/// \param __A
92/// A 128-bit vector of [4 x int].
93/// \param __B
94/// A 128-bit vector of [4 x int].
95/// \param __C
96/// A 128-bit vector of [4 x int].
97/// \returns
98/// A 128-bit vector of [4 x int].
99///
100/// \code{.operation}
101/// DEFINE ROL32(dword, n) {
102/// count := n % 32
103/// dest := (dword << count) | (dword >> (32-count))
104/// RETURN dest
105/// }
106/// WTMP[0] := __A.dword[0]
107/// WTMP[1] := __A.dword[1]
108/// WTMP[2] := __A.dword[2]
109/// WTMP[3] := __A.dword[3]
110/// W[3] := __B.dword[0]
111/// W[4] := __B.dword[1]
112/// W[5] := __B.dword[2]
113/// W[6] := __B.dword[3]
114/// W[10] := __C.dword[0]
115/// W[11] := __C.dword[1]
116/// W[12] := __C.dword[2]
117/// W[13] := __C.dword[3]
118/// W[16] := ROL32(W[3], 7) ^ W[10] ^ WTMP[0]
119/// W[17] := ROL32(W[4], 7) ^ W[11] ^ WTMP[1]
120/// W[18] := ROL32(W[5], 7) ^ W[12] ^ WTMP[2]
121/// W[19] := ROL32(W[6], 7) ^ W[13] ^ WTMP[3]
122/// W[19] := W[19] ^ ROL32(W[16], 6) ^ ROL32(W[16], 15) ^ ROL32(W[16], 30)
123/// dst.dword[0] := W[16]
124/// dst.dword[1] := W[17]
125/// dst.dword[2] := W[18]
126/// dst.dword[3] := W[19]
127/// dst[MAX:128] := 0
128/// \endcode
129static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_sm3msg2_epi32(__m128i __A,
130 __m128i __B,
131 __m128i __C) {
132 return (__m128i)__builtin_ia32_vsm3msg2((__v4su)__A, (__v4su)__B,
133 (__v4su)__C);
134}
135
136/// This intrinsic performs two rounds of SM3 operation using initial SM3 state
137/// (C, D, G, H) from \a __A, an initial SM3 states (A, B, E, F)
138/// from \a __B and a pre-computed words from the \a __C. \a __A with
139/// initial SM3 state of (C, D, G, H) assumes input of non-rotated left
140/// variables from previous state. The updated SM3 state (A, B, E, F) is
141/// written to \a __A. The \a imm8 should contain the even round number
142/// for the first of the two rounds computed by this instruction. The
143/// computation masks the \a imm8 value by AND’ing it with 0x3E so that only
144/// even round numbers from 0 through 62 are used for this operation. The
145/// calculated results are stored in \a dst.
146///
147/// \headerfile <immintrin.h>
148///
149/// \code
150/// __m128i _mm_sm3rnds2_epi32(__m128i __A, __m128i __B, __m128i __C, const int
151/// imm8) \endcode
152///
153/// This intrinsic corresponds to the \c VSM3RNDS2 instruction.
154///
155/// \param __A
156/// A 128-bit vector of [4 x int].
157/// \param __B
158/// A 128-bit vector of [4 x int].
159/// \param __C
160/// A 128-bit vector of [4 x int].
161/// \param imm8
162/// A 8-bit constant integer.
163/// \returns
164/// A 128-bit vector of [4 x int].
165///
166/// \code{.operation}
167/// DEFINE ROL32(dword, n) {
168/// count := n % 32
169/// dest := (dword << count) | (dword >> (32-count))
170/// RETURN dest
171/// }
172/// DEFINE P0(dword) {
173/// RETURN dword ^ ROL32(dword, 9) ^ ROL32(dword, 17)
174/// }
175/// DEFINE FF(x,y,z, round){
176/// IF round < 16
177/// RETURN (x ^ y ^ z)
178/// ELSE
179/// RETURN (x & y) | (x & z) | (y & z)
180/// FI
181/// }
182/// DEFINE GG(x, y, z, round){
183/// IF round < 16
184/// RETURN (x ^ y ^ z)
185/// ELSE
186/// RETURN (x & y) | (~x & z)
187/// FI
188/// }
189/// A[0] := __B.dword[3]
190/// B[0] := __B.dword[2]
191/// C[0] := __A.dword[3]
192/// D[0] := __A.dword[2]
193/// E[0] := __B.dword[1]
194/// F[0] := __B.dword[0]
195/// G[0] := __A.dword[1]
196/// H[0] := __A.dword[0]
197/// W[0] := __C.dword[0]
198/// W[1] := __C.dword[1]
199/// W[4] := __C.dword[2]
200/// W[5] := __C.dword[3]
201/// C[0] := ROL32(C[0], 9)
202/// D[0] := ROL32(D[0], 9)
203/// G[0] := ROL32(G[0], 19)
204/// H[0] := ROL32(H[0], 19)
205/// ROUND := __D & 0x3E
206/// IF ROUND < 16
207/// CONST := 0x79CC4519
208/// ELSE
209/// CONST := 0x7A879D8A
210/// FI
211/// CONST := ROL32(CONST,ROUND)
212/// FOR i:= 0 to 1
213/// S1 := ROL32((ROL32(A[i], 12) + E[i] + CONST), 7)
214/// S2 := S1 ^ ROL32(A[i], 12)
215/// T1 := FF(A[i], B[i], C[i], ROUND) + D[i] + S2 + (W[i] ^ W[i+4])
216/// T2 := GG(E[i], F[i], G[i], ROUND) + H[i] + S1 + W[i]
217/// D[i+1] := C[i]
218/// C[i+1] := ROL32(B[i],9)
219/// B[i+1] := A[i]
220/// A[i+1] := T1
221/// H[i+1] := G[i]
222/// G[i+1] := ROL32(F[i], 19)
223/// F[i+1] := E[i]
224/// E[i+1] := P0(T2)
225/// CONST := ROL32(CONST, 1)
226/// ENDFOR
227/// dst.dword[3] := A[2]
228/// dst.dword[2] := B[2]
229/// dst.dword[1] := E[2]
230/// dst.dword[0] := F[2]
231/// dst[MAX:128] := 0
232/// \endcode
233#define _mm_sm3rnds2_epi32(A, B, C, D) \
234 (__m128i) __builtin_ia32_vsm3rnds2((__v4su)A, (__v4su)B, (__v4su)C, (int)D)
235
236#undef __DEFAULT_FN_ATTRS128
237
238#endif // __SM3INTRIN_H
lib/include/sm4intrin.h created+269
......@@ -0,0 +1,269 @@
1/*===--------------- sm4intrin.h - SM4 intrinsics -----------------===
2 *
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 * See https://llvm.org/LICENSE.txt for license information.
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 *
7 *===-----------------------------------------------------------------------===
8 */
9
10#ifndef __IMMINTRIN_H
11#error "Never use <sm4intrin.h> directly; include <immintrin.h> instead."
12#endif // __IMMINTRIN_H
13
14#ifndef __SM4INTRIN_H
15#define __SM4INTRIN_H
16
17/// This intrinsic performs four rounds of SM4 key expansion. The intrinsic
18/// operates on independent 128-bit lanes. The calculated results are
19/// stored in \a dst.
20/// \headerfile <immintrin.h>
21///
22/// \code
23/// __m128i _mm_sm4key4_epi32(__m128i __A, __m128i __B)
24/// \endcode
25///
26/// This intrinsic corresponds to the \c VSM4KEY4 instruction.
27///
28/// \param __A
29/// A 128-bit vector of [4 x int].
30/// \param __B
31/// A 128-bit vector of [4 x int].
32/// \returns
33/// A 128-bit vector of [4 x int].
34///
35/// \code{.operation}
36/// DEFINE ROL32(dword, n) {
37/// count := n % 32
38/// dest := (dword << count) | (dword >> (32-count))
39/// RETURN dest
40/// }
41/// DEFINE SBOX_BYTE(dword, i) {
42/// RETURN sbox[dword.byte[i]]
43/// }
44/// DEFINE lower_t(dword) {
45/// tmp.byte[0] := SBOX_BYTE(dword, 0)
46/// tmp.byte[1] := SBOX_BYTE(dword, 1)
47/// tmp.byte[2] := SBOX_BYTE(dword, 2)
48/// tmp.byte[3] := SBOX_BYTE(dword, 3)
49/// RETURN tmp
50/// }
51/// DEFINE L_KEY(dword) {
52/// RETURN dword ^ ROL32(dword, 13) ^ ROL32(dword, 23)
53/// }
54/// DEFINE T_KEY(dword) {
55/// RETURN L_KEY(lower_t(dword))
56/// }
57/// DEFINE F_KEY(X0, X1, X2, X3, round_key) {
58/// RETURN X0 ^ T_KEY(X1 ^ X2 ^ X3 ^ round_key)
59/// }
60/// FOR i:= 0 to 0
61/// P[0] := __B.xmm[i].dword[0]
62/// P[1] := __B.xmm[i].dword[1]
63/// P[2] := __B.xmm[i].dword[2]
64/// P[3] := __B.xmm[i].dword[3]
65/// C[0] := F_KEY(P[0], P[1], P[2], P[3], __A.xmm[i].dword[0])
66/// C[1] := F_KEY(P[1], P[2], P[3], C[0], __A.xmm[i].dword[1])
67/// C[2] := F_KEY(P[2], P[3], C[0], C[1], __A.xmm[i].dword[2])
68/// C[3] := F_KEY(P[3], C[0], C[1], C[2], __A.xmm[i].dword[3])
69/// DEST.xmm[i].dword[0] := C[0]
70/// DEST.xmm[i].dword[1] := C[1]
71/// DEST.xmm[i].dword[2] := C[2]
72/// DEST.xmm[i].dword[3] := C[3]
73/// ENDFOR
74/// DEST[MAX:128] := 0
75/// \endcode
76#define _mm_sm4key4_epi32(A, B) \
77 (__m128i) __builtin_ia32_vsm4key4128((__v4su)A, (__v4su)B)
78
79/// This intrinsic performs four rounds of SM4 key expansion. The intrinsic
80/// operates on independent 128-bit lanes. The calculated results are
81/// stored in \a dst.
82/// \headerfile <immintrin.h>
83///
84/// \code
85/// __m256i _mm256_sm4key4_epi32(__m256i __A, __m256i __B)
86/// \endcode
87///
88/// This intrinsic corresponds to the \c VSM4KEY4 instruction.
89///
90/// \param __A
91/// A 256-bit vector of [8 x int].
92/// \param __B
93/// A 256-bit vector of [8 x int].
94/// \returns
95/// A 256-bit vector of [8 x int].
96///
97/// \code{.operation}
98/// DEFINE ROL32(dword, n) {
99/// count := n % 32
100/// dest := (dword << count) | (dword >> (32-count))
101/// RETURN dest
102/// }
103/// DEFINE SBOX_BYTE(dword, i) {
104/// RETURN sbox[dword.byte[i]]
105/// }
106/// DEFINE lower_t(dword) {
107/// tmp.byte[0] := SBOX_BYTE(dword, 0)
108/// tmp.byte[1] := SBOX_BYTE(dword, 1)
109/// tmp.byte[2] := SBOX_BYTE(dword, 2)
110/// tmp.byte[3] := SBOX_BYTE(dword, 3)
111/// RETURN tmp
112/// }
113/// DEFINE L_KEY(dword) {
114/// RETURN dword ^ ROL32(dword, 13) ^ ROL32(dword, 23)
115/// }
116/// DEFINE T_KEY(dword) {
117/// RETURN L_KEY(lower_t(dword))
118/// }
119/// DEFINE F_KEY(X0, X1, X2, X3, round_key) {
120/// RETURN X0 ^ T_KEY(X1 ^ X2 ^ X3 ^ round_key)
121/// }
122/// FOR i:= 0 to 1
123/// P[0] := __B.xmm[i].dword[0]
124/// P[1] := __B.xmm[i].dword[1]
125/// P[2] := __B.xmm[i].dword[2]
126/// P[3] := __B.xmm[i].dword[3]
127/// C[0] := F_KEY(P[0], P[1], P[2], P[3], __A.xmm[i].dword[0])
128/// C[1] := F_KEY(P[1], P[2], P[3], C[0], __A.xmm[i].dword[1])
129/// C[2] := F_KEY(P[2], P[3], C[0], C[1], __A.xmm[i].dword[2])
130/// C[3] := F_KEY(P[3], C[0], C[1], C[2], __A.xmm[i].dword[3])
131/// DEST.xmm[i].dword[0] := C[0]
132/// DEST.xmm[i].dword[1] := C[1]
133/// DEST.xmm[i].dword[2] := C[2]
134/// DEST.xmm[i].dword[3] := C[3]
135/// ENDFOR
136/// DEST[MAX:256] := 0
137/// \endcode
138#define _mm256_sm4key4_epi32(A, B) \
139 (__m256i) __builtin_ia32_vsm4key4256((__v8su)A, (__v8su)B)
140
141/// This intrinisc performs four rounds of SM4 encryption. The intrinisc
142/// operates on independent 128-bit lanes. The calculated results are
143/// stored in \a dst.
144/// \headerfile <immintrin.h>
145///
146/// \code
147/// __m128i _mm_sm4rnds4_epi32(__m128i __A, __m128i __B)
148/// \endcode
149///
150/// This intrinsic corresponds to the \c VSM4RNDS4 instruction.
151///
152/// \param __A
153/// A 128-bit vector of [4 x int].
154/// \param __B
155/// A 128-bit vector of [4 x int].
156/// \returns
157/// A 128-bit vector of [4 x int].
158///
159/// \code{.operation}
160/// DEFINE ROL32(dword, n) {
161/// count := n % 32
162/// dest := (dword << count) | (dword >> (32-count))
163/// RETURN dest
164/// }
165/// DEFINE lower_t(dword) {
166/// tmp.byte[0] := SBOX_BYTE(dword, 0)
167/// tmp.byte[1] := SBOX_BYTE(dword, 1)
168/// tmp.byte[2] := SBOX_BYTE(dword, 2)
169/// tmp.byte[3] := SBOX_BYTE(dword, 3)
170/// RETURN tmp
171/// }
172/// DEFINE L_RND(dword) {
173/// tmp := dword
174/// tmp := tmp ^ ROL32(dword, 2)
175/// tmp := tmp ^ ROL32(dword, 10)
176/// tmp := tmp ^ ROL32(dword, 18)
177/// tmp := tmp ^ ROL32(dword, 24)
178/// RETURN tmp
179/// }
180/// DEFINE T_RND(dword) {
181/// RETURN L_RND(lower_t(dword))
182/// }
183/// DEFINE F_RND(X0, X1, X2, X3, round_key) {
184/// RETURN X0 ^ T_RND(X1 ^ X2 ^ X3 ^ round_key)
185/// }
186/// FOR i:= 0 to 0
187/// P[0] := __B.xmm[i].dword[0]
188/// P[1] := __B.xmm[i].dword[1]
189/// P[2] := __B.xmm[i].dword[2]
190/// P[3] := __B.xmm[i].dword[3]
191/// C[0] := F_RND(P[0], P[1], P[2], P[3], __A.xmm[i].dword[0])
192/// C[1] := F_RND(P[1], P[2], P[3], C[0], __A.xmm[i].dword[1])
193/// C[2] := F_RND(P[2], P[3], C[0], C[1], __A.xmm[i].dword[2])
194/// C[3] := F_RND(P[3], C[0], C[1], C[2], __A.xmm[i].dword[3])
195/// DEST.xmm[i].dword[0] := C[0]
196/// DEST.xmm[i].dword[1] := C[1]
197/// DEST.xmm[i].dword[2] := C[2]
198/// DEST.xmm[i].dword[3] := C[3]
199/// ENDFOR
200/// DEST[MAX:128] := 0
201/// \endcode
202#define _mm_sm4rnds4_epi32(A, B) \
203 (__m128i) __builtin_ia32_vsm4rnds4128((__v4su)A, (__v4su)B)
204
205/// This intrinisc performs four rounds of SM4 encryption. The intrinisc
206/// operates on independent 128-bit lanes. The calculated results are
207/// stored in \a dst.
208/// \headerfile <immintrin.h>
209///
210/// \code
211/// __m256i _mm256_sm4rnds4_epi32(__m256i __A, __m256i __B)
212/// \endcode
213///
214/// This intrinsic corresponds to the \c VSM4RNDS4 instruction.
215///
216/// \param __A
217/// A 256-bit vector of [8 x int].
218/// \param __B
219/// A 256-bit vector of [8 x int].
220/// \returns
221/// A 256-bit vector of [8 x int].
222///
223/// \code{.operation}
224/// DEFINE ROL32(dword, n) {
225/// count := n % 32
226/// dest := (dword << count) | (dword >> (32-count))
227/// RETURN dest
228/// }
229/// DEFINE lower_t(dword) {
230/// tmp.byte[0] := SBOX_BYTE(dword, 0)
231/// tmp.byte[1] := SBOX_BYTE(dword, 1)
232/// tmp.byte[2] := SBOX_BYTE(dword, 2)
233/// tmp.byte[3] := SBOX_BYTE(dword, 3)
234/// RETURN tmp
235/// }
236/// DEFINE L_RND(dword) {
237/// tmp := dword
238/// tmp := tmp ^ ROL32(dword, 2)
239/// tmp := tmp ^ ROL32(dword, 10)
240/// tmp := tmp ^ ROL32(dword, 18)
241/// tmp := tmp ^ ROL32(dword, 24)
242/// RETURN tmp
243/// }
244/// DEFINE T_RND(dword) {
245/// RETURN L_RND(lower_t(dword))
246/// }
247/// DEFINE F_RND(X0, X1, X2, X3, round_key) {
248/// RETURN X0 ^ T_RND(X1 ^ X2 ^ X3 ^ round_key)
249/// }
250/// FOR i:= 0 to 0
251/// P[0] := __B.xmm[i].dword[0]
252/// P[1] := __B.xmm[i].dword[1]
253/// P[2] := __B.xmm[i].dword[2]
254/// P[3] := __B.xmm[i].dword[3]
255/// C[0] := F_RND(P[0], P[1], P[2], P[3], __A.xmm[i].dword[0])
256/// C[1] := F_RND(P[1], P[2], P[3], C[0], __A.xmm[i].dword[1])
257/// C[2] := F_RND(P[2], P[3], C[0], C[1], __A.xmm[i].dword[2])
258/// C[3] := F_RND(P[3], C[0], C[1], C[2], __A.xmm[i].dword[3])
259/// DEST.xmm[i].dword[0] := C[0]
260/// DEST.xmm[i].dword[1] := C[1]
261/// DEST.xmm[i].dword[2] := C[2]
262/// DEST.xmm[i].dword[3] := C[3]
263/// ENDFOR
264/// DEST[MAX:256] := 0
265/// \endcode
266#define _mm256_sm4rnds4_epi32(A, B) \
267 (__m256i) __builtin_ia32_vsm4rnds4256((__v8su)A, (__v8su)B)
268
269#endif // __SM4INTRIN_H
lib/include/stdalign.h+5
......@@ -10,6 +10,10 @@
1010#ifndef __STDALIGN_H
1111#define __STDALIGN_H
1212
13/* FIXME: This is using the placeholder dates Clang produces for these macros
14 in C2x mode; switch to the correct values once they've been published. */
15#if defined(__cplusplus) || \
16 (defined(__STDC_VERSION__) && __STDC_VERSION__ < 202000L)
1317#ifndef __cplusplus
1418#define alignas _Alignas
1519#define alignof _Alignof
......@@ -17,5 +21,6 @@
1721
1822#define __alignas_is_defined 1
1923#define __alignof_is_defined 1
24#endif /* __STDC_VERSION__ */
2025
2126#endif /* __STDALIGN_H */
lib/include/stdatomic.h+9-2
......@@ -45,9 +45,16 @@ extern "C" {
4545#define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
4646
4747/* 7.17.2 Initialization */
48
48/* FIXME: This is using the placeholder dates Clang produces for these macros
49 in C2x mode; switch to the correct values once they've been published. */
50#if (defined(__STDC_VERSION__) && __STDC_VERSION__ < 202000L) || \
51 defined(__cplusplus)
52/* ATOMIC_VAR_INIT was removed in C2x, but still remains in C++23. */
4953#define ATOMIC_VAR_INIT(value) (value)
50#if ((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201710L) || \
54#endif
55
56#if ((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201710L && \
57 __STDC_VERSION__ < 202000L) || \
5158 (defined(__cplusplus) && __cplusplus >= 202002L)) && \
5259 !defined(_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS)
5360/* ATOMIC_VAR_INIT was deprecated in C17 and C++20. */
lib/include/stddef.h+5
......@@ -103,6 +103,11 @@ using ::std::nullptr_t;
103103typedef typeof(nullptr) nullptr_t;
104104#endif /* defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L */
105105
106#if defined(__need_STDDEF_H_misc) && defined(__STDC_VERSION__) && \
107 __STDC_VERSION__ >= 202000L
108#define unreachable() __builtin_unreachable()
109#endif /* defined(__need_STDDEF_H_misc) && >= C23 */
110
106111#if defined(__need_STDDEF_H_misc)
107112#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
108113 (defined(__cplusplus) && __cplusplus >= 201103L)
lib/include/wasm_simd128.h+132-12
......@@ -961,17 +961,17 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_popcnt(v128_t __a) {
961961
962962static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_shl(v128_t __a,
963963 uint32_t __b) {
964 return (v128_t)((__i8x16)__a << __b);
964 return (v128_t)((__i8x16)__a << (__b & 0x7));
965965}
966966
967967static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_shr(v128_t __a,
968968 uint32_t __b) {
969 return (v128_t)((__i8x16)__a >> __b);
969 return (v128_t)((__i8x16)__a >> (__b & 0x7));
970970}
971971
972972static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u8x16_shr(v128_t __a,
973973 uint32_t __b) {
974 return (v128_t)((__u8x16)__a >> __b);
974 return (v128_t)((__u8x16)__a >> (__b & 0x7));
975975}
976976
977977static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_add(v128_t __a,
......@@ -1047,17 +1047,17 @@ static __inline__ uint32_t __DEFAULT_FN_ATTRS wasm_i16x8_bitmask(v128_t __a) {
10471047
10481048static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_shl(v128_t __a,
10491049 uint32_t __b) {
1050 return (v128_t)((__i16x8)__a << __b);
1050 return (v128_t)((__i16x8)__a << (__b & 0xF));
10511051}
10521052
10531053static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_shr(v128_t __a,
10541054 uint32_t __b) {
1055 return (v128_t)((__i16x8)__a >> __b);
1055 return (v128_t)((__i16x8)__a >> (__b & 0xF));
10561056}
10571057
10581058static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u16x8_shr(v128_t __a,
10591059 uint32_t __b) {
1060 return (v128_t)((__u16x8)__a >> __b);
1060 return (v128_t)((__u16x8)__a >> (__b & 0xF));
10611061}
10621062
10631063static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_add(v128_t __a,
......@@ -1138,17 +1138,17 @@ static __inline__ uint32_t __DEFAULT_FN_ATTRS wasm_i32x4_bitmask(v128_t __a) {
11381138
11391139static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_shl(v128_t __a,
11401140 uint32_t __b) {
1141 return (v128_t)((__i32x4)__a << __b);
1141 return (v128_t)((__i32x4)__a << (__b & 0x1F));
11421142}
11431143
11441144static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_shr(v128_t __a,
11451145 uint32_t __b) {
1146 return (v128_t)((__i32x4)__a >> __b);
1146 return (v128_t)((__i32x4)__a >> (__b & 0x1F));
11471147}
11481148
11491149static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u32x4_shr(v128_t __a,
11501150 uint32_t __b) {
1151 return (v128_t)((__u32x4)__a >> __b);
1151 return (v128_t)((__u32x4)__a >> (__b & 0x1F));
11521152}
11531153
11541154static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_add(v128_t __a,
......@@ -1209,17 +1209,17 @@ static __inline__ uint32_t __DEFAULT_FN_ATTRS wasm_i64x2_bitmask(v128_t __a) {
12091209
12101210static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_shl(v128_t __a,
12111211 uint32_t __b) {
1212 return (v128_t)((__i64x2)__a << (int64_t)__b);
1212 return (v128_t)((__i64x2)__a << ((int64_t)__b & 0x3F));
12131213}
12141214
12151215static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_shr(v128_t __a,
12161216 uint32_t __b) {
1217 return (v128_t)((__i64x2)__a >> (int64_t)__b);
1217 return (v128_t)((__i64x2)__a >> ((int64_t)__b & 0x3F));
12181218}
12191219
12201220static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u64x2_shr(v128_t __a,
12211221 uint32_t __b) {
1222 return (v128_t)((__u64x2)__a >> (int64_t)__b);
1222 return (v128_t)((__u64x2)__a >> ((int64_t)__b & 0x3F));
12231223}
12241224
12251225static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_add(v128_t __a,
......@@ -1760,6 +1760,126 @@ wasm_u64x2_load_32x2(const void *__mem) {
17601760 __DEPRECATED_WASM_MACRO("wasm_v64x2_shuffle", "wasm_i64x2_shuffle") \
17611761 wasm_i64x2_shuffle(__a, __b, __c0, __c1)
17621762
1763// Relaxed SIMD intrinsics
1764
1765#define __RELAXED_FN_ATTRS \
1766 __attribute__((__always_inline__, __nodebug__, __target__("relaxed-simd"), \
1767 __min_vector_width__(128)))
1768
1769static __inline__ v128_t __RELAXED_FN_ATTRS
1770wasm_f32x4_relaxed_madd(v128_t __a, v128_t __b, v128_t __c) {
1771 return (v128_t)__builtin_wasm_relaxed_madd_f32x4((__f32x4)__a, (__f32x4)__b,
1772 (__f32x4)__c);
1773}
1774
1775static __inline__ v128_t __RELAXED_FN_ATTRS
1776wasm_f32x4_relaxed_nmadd(v128_t __a, v128_t __b, v128_t __c) {
1777 return (v128_t)__builtin_wasm_relaxed_nmadd_f32x4((__f32x4)__a, (__f32x4)__b,
1778 (__f32x4)__c);
1779}
1780
1781static __inline__ v128_t __RELAXED_FN_ATTRS
1782wasm_f64x2_relaxed_madd(v128_t __a, v128_t __b, v128_t __c) {
1783 return (v128_t)__builtin_wasm_relaxed_madd_f64x2((__f64x2)__a, (__f64x2)__b,
1784 (__f64x2)__c);
1785}
1786
1787static __inline__ v128_t __RELAXED_FN_ATTRS
1788wasm_f64x2_relaxed_nmadd(v128_t __a, v128_t __b, v128_t __c) {
1789 return (v128_t)__builtin_wasm_relaxed_nmadd_f64x2((__f64x2)__a, (__f64x2)__b,
1790 (__f64x2)__c);
1791}
1792
1793static __inline__ v128_t __RELAXED_FN_ATTRS
1794wasm_i8x16_relaxed_laneselect(v128_t __a, v128_t __b, v128_t __m) {
1795 return (v128_t)__builtin_wasm_relaxed_laneselect_i8x16(
1796 (__i8x16)__a, (__i8x16)__b, (__i8x16)__m);
1797}
1798
1799static __inline__ v128_t __RELAXED_FN_ATTRS
1800wasm_i16x8_relaxed_laneselect(v128_t __a, v128_t __b, v128_t __m) {
1801 return (v128_t)__builtin_wasm_relaxed_laneselect_i16x8(
1802 (__i16x8)__a, (__i16x8)__b, (__i16x8)__m);
1803}
1804
1805static __inline__ v128_t __RELAXED_FN_ATTRS
1806wasm_i32x4_relaxed_laneselect(v128_t __a, v128_t __b, v128_t __m) {
1807 return (v128_t)__builtin_wasm_relaxed_laneselect_i32x4(
1808 (__i32x4)__a, (__i32x4)__b, (__i32x4)__m);
1809}
1810
1811static __inline__ v128_t __RELAXED_FN_ATTRS
1812wasm_i64x2_relaxed_laneselect(v128_t __a, v128_t __b, v128_t __m) {
1813 return (v128_t)__builtin_wasm_relaxed_laneselect_i64x2(
1814 (__i64x2)__a, (__i64x2)__b, (__i64x2)__m);
1815}
1816
1817static __inline__ v128_t __RELAXED_FN_ATTRS
1818wasm_i8x16_relaxed_swizzle(v128_t __a, v128_t __s) {
1819 return (v128_t)__builtin_wasm_relaxed_swizzle_i8x16((__i8x16)__a,
1820 (__i8x16)__s);
1821}
1822
1823static __inline__ v128_t __RELAXED_FN_ATTRS wasm_f32x4_relaxed_min(v128_t __a,
1824 v128_t __b) {
1825 return (v128_t)__builtin_wasm_relaxed_min_f32x4((__f32x4)__a, (__f32x4)__b);
1826}
1827
1828static __inline__ v128_t __RELAXED_FN_ATTRS wasm_f32x4_relaxed_max(v128_t __a,
1829 v128_t __b) {
1830 return (v128_t)__builtin_wasm_relaxed_max_f32x4((__f32x4)__a, (__f32x4)__b);
1831}
1832
1833static __inline__ v128_t __RELAXED_FN_ATTRS wasm_f64x2_relaxed_min(v128_t __a,
1834 v128_t __b) {
1835 return (v128_t)__builtin_wasm_relaxed_min_f64x2((__f64x2)__a, (__f64x2)__b);
1836}
1837
1838static __inline__ v128_t __RELAXED_FN_ATTRS wasm_f64x2_relaxed_max(v128_t __a,
1839 v128_t __b) {
1840 return (v128_t)__builtin_wasm_relaxed_max_f64x2((__f64x2)__a, (__f64x2)__b);
1841}
1842
1843static __inline__ v128_t __RELAXED_FN_ATTRS
1844wasm_i32x4_relaxed_trunc_f32x4(v128_t __a) {
1845 return (v128_t)__builtin_wasm_relaxed_trunc_s_i32x4_f32x4((__f32x4)__a);
1846}
1847
1848static __inline__ v128_t __RELAXED_FN_ATTRS
1849wasm_u32x4_relaxed_trunc_f32x4(v128_t __a) {
1850 return (v128_t)__builtin_wasm_relaxed_trunc_u_i32x4_f32x4((__f32x4)__a);
1851}
1852
1853static __inline__ v128_t __RELAXED_FN_ATTRS
1854wasm_i32x4_relaxed_trunc_f64x2_zero(v128_t __a) {
1855 return (v128_t)__builtin_wasm_relaxed_trunc_s_zero_i32x4_f64x2((__f64x2)__a);
1856}
1857
1858static __inline__ v128_t __RELAXED_FN_ATTRS
1859wasm_u32x4_relaxed_trunc_f64x2_zero(v128_t __a) {
1860 return (v128_t)__builtin_wasm_relaxed_trunc_u_zero_i32x4_f64x2((__f64x2)__a);
1861}
1862
1863static __inline__ v128_t __RELAXED_FN_ATTRS
1864wasm_i16x8_relaxed_q15mulr(v128_t __a, v128_t __b) {
1865 return (v128_t)__builtin_wasm_relaxed_q15mulr_s_i16x8((__i16x8)__a,
1866 (__i16x8)__b);
1867}
1868
1869static __inline__ v128_t __RELAXED_FN_ATTRS
1870wasm_i16x8_relaxed_dot_i8x16_i7x16(v128_t __a, v128_t __b) {
1871 return (v128_t)__builtin_wasm_relaxed_dot_i8x16_i7x16_s_i16x8((__i8x16)__a,
1872 (__i8x16)__b);
1873}
1874
1875static __inline__ v128_t __RELAXED_FN_ATTRS
1876wasm_i32x4_relaxed_dot_i8x16_i7x16_add(v128_t __a, v128_t __b, v128_t __c) {
1877 return (v128_t)__builtin_wasm_relaxed_dot_i8x16_i7x16_add_s_i32x4(
1878 (__i8x16)__a, (__i8x16)__b, (__i32x4)__c);
1879}
1880
1881// Deprecated intrinsics
1882
17631883static __inline__ v128_t __DEPRECATED_FN_ATTRS("wasm_i8x16_swizzle")
17641884wasm_v8x16_swizzle(v128_t __a, v128_t __b) {
17651885 return wasm_i8x16_swizzle(__a, __b);
lib/include/xsavecintrin.h+50
......@@ -17,12 +17,62 @@
1717/* Define the default attributes for the functions in this file. */
1818#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("xsavec")))
1919
20/// Performs a full or partial save of processor state to the memory at
21/// \a __p. The exact state saved depends on the 64-bit mask \a __m and
22/// processor control register \c XCR0.
23///
24/// \code{.operation}
25/// mask[62:0] := __m[62:0] AND XCR0[62:0]
26/// FOR i := 0 TO 62
27/// IF mask[i] == 1
28/// CASE (i) OF
29/// 0: save X87 FPU state
30/// 1: save SSE state
31/// DEFAULT: __p.Ext_Save_Area[i] := ProcessorState[i]
32/// FI
33/// ENDFOR
34/// __p.Header.XSTATE_BV[62:0] := INIT_FUNCTION(mask[62:0])
35/// \endcode
36///
37/// \headerfile <immintrin.h>
38///
39/// This intrinsic corresponds to the \c XSAVEC instruction.
40///
41/// \param __p
42/// Pointer to the save area; must be 64-byte aligned.
43/// \param __m
44/// A 64-bit mask indicating what state should be saved.
2045static __inline__ void __DEFAULT_FN_ATTRS
2146_xsavec(void *__p, unsigned long long __m) {
2247 __builtin_ia32_xsavec(__p, __m);
2348}
2449
2550#ifdef __x86_64__
51/// Performs a full or partial save of processor state to the memory at
52/// \a __p. The exact state saved depends on the 64-bit mask \a __m and
53/// processor control register \c XCR0.
54///
55/// \code{.operation}
56/// mask[62:0] := __m[62:0] AND XCR0[62:0]
57/// FOR i := 0 TO 62
58/// IF mask[i] == 1
59/// CASE (i) OF
60/// 0: save X87 FPU state
61/// 1: save SSE state
62/// DEFAULT: __p.Ext_Save_Area[i] := ProcessorState[i]
63/// FI
64/// ENDFOR
65/// __p.Header.XSTATE_BV[62:0] := INIT_FUNCTION(mask[62:0])
66/// \endcode
67///
68/// \headerfile <immintrin.h>
69///
70/// This intrinsic corresponds to the \c XSAVEC64 instruction.
71///
72/// \param __p
73/// Pointer to the save area; must be 64-byte aligned.
74/// \param __m
75/// A 64-bit mask indicating what state should be saved.
2676static __inline__ void __DEFAULT_FN_ATTRS
2777_xsavec64(void *__p, unsigned long long __m) {
2878 __builtin_ia32_xsavec64(__p, __m);
lib/libcxx/include/__algorithm/adjacent_find.h+5
......@@ -20,6 +20,9 @@
2020# pragma GCC system_header
2121#endif
2222
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
2326_LIBCPP_BEGIN_NAMESPACE_STD
2427
2528template <class _Iter, class _Sent, class _BinaryPredicate>
......@@ -50,4 +53,6 @@ adjacent_find(_ForwardIterator __first, _ForwardIterator __last) {
5053
5154_LIBCPP_END_NAMESPACE_STD
5255
56_LIBCPP_POP_MACROS
57
5358#endif // _LIBCPP___ALGORITHM_ADJACENT_FIND_H
lib/libcxx/include/__algorithm/all_of.h+1-1
......@@ -19,7 +19,7 @@
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
2121template <class _InputIterator, class _Predicate>
22_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
22_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
2323all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
2424 for (; __first != __last; ++__first)
2525 if (!__pred(*__first))
lib/libcxx/include/__algorithm/binary_search.h+1-2
......@@ -37,8 +37,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
3737bool
3838binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
3939{
40 return std::binary_search(__first, __last, __value,
41 __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
40 return std::binary_search(__first, __last, __value, __less<>());
4241}
4342
4443_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/clamp.h+3-3
......@@ -19,14 +19,14 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 14
22#if _LIBCPP_STD_VER >= 17
2323template<class _Tp, class _Compare>
2424_LIBCPP_NODISCARD_EXT inline
2525_LIBCPP_INLINE_VISIBILITY constexpr
2626const _Tp&
2727clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp)
2828{
29 _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp");
29 _LIBCPP_ASSERT_UNCATEGORIZED(!__comp(__hi, __lo), "Bad bounds passed to std::clamp");
3030 return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v;
3131
3232}
......@@ -37,7 +37,7 @@ _LIBCPP_INLINE_VISIBILITY constexpr
3737const _Tp&
3838clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi)
3939{
40 return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>());
40 return _VSTD::clamp(__v, __lo, __hi, __less<>());
4141}
4242#endif
4343
lib/libcxx/include/__algorithm/comp.h+14-33
......@@ -10,6 +10,8 @@
1010#define _LIBCPP___ALGORITHM_COMP_H
1111
1212#include <__config>
13#include <__type_traits/integral_constant.h>
14#include <__type_traits/predicate_traits.h>
1315
1416#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1517# pragma GCC system_header
......@@ -24,41 +26,20 @@ struct __equal_to {
2426 }
2527};
2628
27template <class _T1, class _T2 = _T1>
28struct __less
29{
30 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
31 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
29template <class _Lhs, class _Rhs>
30struct __is_trivial_equality_predicate<__equal_to, _Lhs, _Rhs> : true_type {};
3231
33 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
34 bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;}
32// The definition is required because __less is part of the ABI, but it's empty
33// because all comparisons should be transparent.
34template <class _T1 = void, class _T2 = _T1>
35struct __less {};
3536
36 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
37 bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;}
38
39 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
40 bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;}
41};
42
43template <class _T1>
44struct __less<_T1, _T1>
45{
46 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
47 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
48};
49
50template <class _T1>
51struct __less<const _T1, _T1>
52{
53 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
54 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
55};
56
57template <class _T1>
58struct __less<_T1, const _T1>
59{
60 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
61 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
37template <>
38struct __less<void, void> {
39 template <class _Tp, class _Up>
40 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __lhs, const _Up& __rhs) const {
41 return __lhs < __rhs;
42 }
6243};
6344
6445_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/comp_ref_type.h+6-7
......@@ -9,8 +9,8 @@
99#ifndef _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
1010#define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
1111
12#include <__assert>
1213#include <__config>
13#include <__debug>
1414#include <__utility/declval.h>
1515
1616#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -23,11 +23,10 @@ template <class _Compare>
2323struct __debug_less
2424{
2525 _Compare &__comp_;
26 _LIBCPP_CONSTEXPR_SINCE_CXX14
27 __debug_less(_Compare& __c) : __comp_(__c) {}
26 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI __debug_less(_Compare& __c) : __comp_(__c) {}
2827
2928 template <class _Tp, class _Up>
30 _LIBCPP_CONSTEXPR_SINCE_CXX14
29 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
3130 bool operator()(const _Tp& __x, const _Up& __y)
3231 {
3332 bool __r = __comp_(__x, __y);
......@@ -37,7 +36,7 @@ struct __debug_less
3736 }
3837
3938 template <class _Tp, class _Up>
40 _LIBCPP_CONSTEXPR_SINCE_CXX14
39 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
4140 bool operator()(_Tp& __x, _Up& __y)
4241 {
4342 bool __r = __comp_(__x, __y);
......@@ -52,7 +51,7 @@ struct __debug_less
5251 decltype((void)std::declval<_Compare&>()(
5352 std::declval<_LHS &>(), std::declval<_RHS &>()))
5453 __do_compare_assert(int, _LHS & __l, _RHS & __r) {
55 _LIBCPP_DEBUG_ASSERT(!__comp_(__l, __r),
54 _LIBCPP_ASSERT_UNCATEGORIZED(!__comp_(__l, __r),
5655 "Comparator does not induce a strict weak ordering");
5756 (void)__l;
5857 (void)__r;
......@@ -66,7 +65,7 @@ struct __debug_less
6665
6766// Pass the comparator by lvalue reference. Or in debug mode, using a
6867// debugging wrapper that stores a reference.
69#ifdef _LIBCPP_ENABLE_DEBUG_MODE
68#if _LIBCPP_ENABLE_DEBUG_MODE
7069template <class _Comp>
7170using __comp_ref_type = __debug_less<_Comp>;
7271#else
lib/libcxx/include/__algorithm/copy.h+19-21
......@@ -10,6 +10,7 @@
1010#define _LIBCPP___ALGORITHM_COPY_H
1111
1212#include <__algorithm/copy_move_common.h>
13#include <__algorithm/for_each_segment.h>
1314#include <__algorithm/iterator_operations.h>
1415#include <__algorithm/min.h>
1516#include <__config>
......@@ -44,36 +45,34 @@ struct __copy_loop {
4445 return std::make_pair(std::move(__first), std::move(__result));
4546 }
4647
47 template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
48 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
49 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
48 template <class _InIter, class _OutIter>
49 struct _CopySegment {
5050 using _Traits = __segmented_iterator_traits<_InIter>;
51 auto __sfirst = _Traits::__segment(__first);
52 auto __slast = _Traits::__segment(__last);
53 if (__sfirst == __slast) {
54 auto __iters = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
55 return std::make_pair(__last, std::move(__iters.second));
56 }
5751
58 __result = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second;
59 ++__sfirst;
60 while (__sfirst != __slast) {
61 __result =
62 std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second;
63 ++__sfirst;
52 _OutIter& __result_;
53
54 _LIBCPP_HIDE_FROM_ABI _CopySegment(_OutIter& __result) : __result_(__result) {}
55
56 _LIBCPP_HIDE_FROM_ABI void
57 operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
58 __result_ = std::__copy<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second;
6459 }
65 __result =
66 std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second;
60 };
61
62 template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
63 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
64 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
65 std::__for_each_segment(__first, __last, _CopySegment<_InIter, _OutIter>(__result));
6766 return std::make_pair(__last, std::move(__result));
6867 }
6968
7069 template <class _InIter,
7170 class _OutIter,
72 __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
71 __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
7372 !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
7473 int> = 0>
7574 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
76 operator()(_InIter __first, _InIter __last, _OutIter __result) {
75 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
7776 using _Traits = __segmented_iterator_traits<_OutIter>;
7877 using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
7978
......@@ -98,8 +97,7 @@ struct __copy_loop {
9897
9998struct __copy_trivial {
10099 // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
101 template <class _In, class _Out,
102 __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
100 template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
103101 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
104102 operator()(_In* __first, _In* __last, _Out* __result) const {
105103 return std::__copy_trivial_impl(__first, __last, __result);
lib/libcxx/include/__algorithm/copy_backward.h+2-2
......@@ -76,11 +76,11 @@ struct __copy_backward_loop {
7676
7777 template <class _InIter,
7878 class _OutIter,
79 __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
79 __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
8080 !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
8181 int> = 0>
8282 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
83 operator()(_InIter __first, _InIter __last, _OutIter __result) {
83 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
8484 using _Traits = __segmented_iterator_traits<_OutIter>;
8585 auto __orig_last = __last;
8686 auto __segment_iterator = _Traits::__segment(__result);
lib/libcxx/include/__algorithm/copy_move_common.h+4-29
......@@ -15,6 +15,7 @@
1515#include <__config>
1616#include <__iterator/iterator_traits.h>
1717#include <__memory/pointer_traits.h>
18#include <__string/constexpr_c_functions.h>
1819#include <__type_traits/enable_if.h>
1920#include <__type_traits/is_always_bitcastable.h>
2021#include <__type_traits/is_constant_evaluated.h>
......@@ -61,7 +62,8 @@ template <class _In, class _Out>
6162_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
6263__copy_trivial_impl(_In* __first, _In* __last, _Out* __result) {
6364 const size_t __n = static_cast<size_t>(__last - __first);
64 ::__builtin_memmove(__result, __first, __n * sizeof(_Out));
65
66 std::__constexpr_memmove(__result, __first, __element_count(__n));
6567
6668 return std::make_pair(__last, __result + __n);
6769}
......@@ -72,7 +74,7 @@ __copy_backward_trivial_impl(_In* __first, _In* __last, _Out* __result) {
7274 const size_t __n = static_cast<size_t>(__last - __first);
7375 __result -= __n;
7476
75 ::__builtin_memmove(__result, __first, __n * sizeof(_Out));
77 std::__constexpr_memmove(__result, __first, __element_count(__n));
7678
7779 return std::make_pair(__last, __result);
7880}
......@@ -119,16 +121,6 @@ __unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) {
119121 return _Algorithm()(std::move(__first), std::move(__last), std::move(__out_first));
120122}
121123
122template <class _IterOps, class _InValue, class _OutIter, class = void>
123struct __can_copy_without_conversion : false_type {};
124
125template <class _IterOps, class _InValue, class _OutIter>
126struct __can_copy_without_conversion<
127 _IterOps,
128 _InValue,
129 _OutIter,
130 __enable_if_t<is_same<_InValue, typename _IterOps::template __value_type<_OutIter> >::value> > : true_type {};
131
132124template <class _AlgPolicy,
133125 class _NaiveAlgorithm,
134126 class _OptimizedAlgorithm,
......@@ -137,23 +129,6 @@ template <class _AlgPolicy,
137129 class _OutIter>
138130_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
139131__dispatch_copy_or_move(_InIter __first, _Sent __last, _OutIter __out_first) {
140#ifdef _LIBCPP_COMPILER_GCC
141 // GCC doesn't support `__builtin_memmove` during constant evaluation.
142 if (__libcpp_is_constant_evaluated()) {
143 return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first));
144 }
145#else
146 // In Clang, `__builtin_memmove` only supports fully trivially copyable types (just having trivial copy assignment is
147 // insufficient). Also, conversions are not supported.
148 if (__libcpp_is_constant_evaluated()) {
149 using _InValue = typename _IterOps<_AlgPolicy>::template __value_type<_InIter>;
150 if (!is_trivially_copyable<_InValue>::value ||
151 !__can_copy_without_conversion<_IterOps<_AlgPolicy>, _InValue, _OutIter>::value) {
152 return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first));
153 }
154 }
155#endif // _LIBCPP_COMPILER_GCC
156
157132 using _Algorithm = __overload<_NaiveAlgorithm, _OptimizedAlgorithm>;
158133 return std::__unwrap_and_dispatch<_Algorithm>(std::move(__first), std::move(__last), std::move(__out_first));
159134}
lib/libcxx/include/__algorithm/copy_n.h+4-4
......@@ -12,8 +12,8 @@
1212#include <__algorithm/copy.h>
1313#include <__config>
1414#include <__iterator/iterator_traits.h>
15#include <__type_traits/enable_if.h>
1516#include <__utility/convert_to_integral.h>
16#include <type_traits>
1717
1818#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1919# pragma GCC system_header
......@@ -25,8 +25,8 @@ template<class _InputIterator, class _Size, class _OutputIterator>
2525inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
2626typename enable_if
2727<
28 __is_cpp17_input_iterator<_InputIterator>::value &&
29 !__is_cpp17_random_access_iterator<_InputIterator>::value,
28 __has_input_iterator_category<_InputIterator>::value &&
29 !__has_random_access_iterator_category<_InputIterator>::value,
3030 _OutputIterator
3131>::type
3232copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
......@@ -51,7 +51,7 @@ template<class _InputIterator, class _Size, class _OutputIterator>
5151inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
5252typename enable_if
5353<
54 __is_cpp17_random_access_iterator<_InputIterator>::value,
54 __has_random_access_iterator_category<_InputIterator>::value,
5555 _OutputIterator
5656>::type
5757copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
lib/libcxx/include/__algorithm/equal.h+73-10
......@@ -11,9 +11,20 @@
1111#define _LIBCPP___ALGORITHM_EQUAL_H
1212
1313#include <__algorithm/comp.h>
14#include <__algorithm/unwrap_iter.h>
1415#include <__config>
16#include <__functional/identity.h>
17#include <__functional/invoke.h>
1518#include <__iterator/distance.h>
1619#include <__iterator/iterator_traits.h>
20#include <__string/constexpr_c_functions.h>
21#include <__type_traits/enable_if.h>
22#include <__type_traits/integral_constant.h>
23#include <__type_traits/is_constant_evaluated.h>
24#include <__type_traits/is_equality_comparable.h>
25#include <__type_traits/is_volatile.h>
26#include <__type_traits/predicate_traits.h>
27#include <__utility/move.h>
1728
1829#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1930# pragma GCC system_header
......@@ -22,23 +33,42 @@
2233_LIBCPP_BEGIN_NAMESPACE_STD
2334
2435template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
25_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
26equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
36_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(
37 _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate& __pred) {
2738 for (; __first1 != __last1; ++__first1, (void)++__first2)
2839 if (!__pred(*__first1, *__first2))
2940 return false;
3041 return true;
3142}
3243
44template <
45 class _Tp,
46 class _Up,
47 class _BinaryPredicate,
48 __enable_if_t<__is_trivial_equality_predicate<_BinaryPredicate, _Tp, _Up>::value && !is_volatile<_Tp>::value &&
49 !is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
50 int> = 0>
51_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
52__equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) {
53 return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
54}
55
56template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
57_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
58equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
59 return std::__equal_iter_impl(
60 std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred);
61}
62
3363template <class _InputIterator1, class _InputIterator2>
34_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
64_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
3565equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
3666 return std::equal(__first1, __last1, __first2, __equal_to());
3767}
3868
39#if _LIBCPP_STD_VER > 11
69#if _LIBCPP_STD_VER >= 14
4070template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2>
41inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
71inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
4272__equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
4373 _BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) {
4474 for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
......@@ -47,19 +77,52 @@ __equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __fir
4777 return __first1 == __last1 && __first2 == __last2;
4878}
4979
80template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
81_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
82 _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __comp, _Proj1& __proj1, _Proj2& __proj2) {
83 while (__first1 != __last1 && __first2 != __last2) {
84 if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
85 return false;
86 ++__first1;
87 ++__first2;
88 }
89 return __first1 == __last1 && __first2 == __last2;
90}
91
92template <class _Tp,
93 class _Up,
94 class _Pred,
95 class _Proj1,
96 class _Proj2,
97 __enable_if_t<__is_trivial_equality_predicate<_Pred, _Tp, _Up>::value && __is_identity<_Proj1>::value &&
98 __is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value &&
99 __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
100 int> = 0>
101_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
102 _Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) {
103 return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
104}
105
50106template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
51inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
107inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
52108__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
53109 _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag,
54110 random_access_iterator_tag) {
55111 if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
56112 return false;
57 return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2,
58 _BinaryPredicate&>(__first1, __last1, __first2, __pred);
113 __identity __proj;
114 return std::__equal_impl(
115 std::__unwrap_iter(__first1),
116 std::__unwrap_iter(__last1),
117 std::__unwrap_iter(__first2),
118 std::__unwrap_iter(__last2),
119 __pred,
120 __proj,
121 __proj);
59122}
60123
61124template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
62_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
125_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
63126equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
64127 _BinaryPredicate __pred) {
65128 return _VSTD::__equal<_BinaryPredicate&>(
......@@ -68,7 +131,7 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first
68131}
69132
70133template <class _InputIterator1, class _InputIterator2>
71_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
134_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
72135equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
73136 return std::__equal(
74137 __first1,
lib/libcxx/include/__algorithm/equal_range.h+2-6
......@@ -50,7 +50,7 @@ __equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp
5050 } else {
5151 _Iter __mp1 = __mid;
5252 return pair<_Iter, _Iter>(
53 std::__lower_bound_impl<_AlgPolicy>(__first, __mid, __value, __comp, __proj),
53 std::__lower_bound<_AlgPolicy>(__first, __mid, __value, __comp, __proj),
5454 std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj));
5555 }
5656 }
......@@ -75,11 +75,7 @@ equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu
7575template <class _ForwardIterator, class _Tp>
7676_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
7777equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
78 return std::equal_range(
79 std::move(__first),
80 std::move(__last),
81 __value,
82 __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
78 return std::equal_range(std::move(__first), std::move(__last), __value, __less<>());
8379}
8480
8581_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/fill.h-1
......@@ -12,7 +12,6 @@
1212#include <__algorithm/fill_n.h>
1313#include <__config>
1414#include <__iterator/iterator_traits.h>
15#include <type_traits>
1615
1716#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1817# pragma GCC system_header
lib/libcxx/include/__algorithm/fill_n.h-1
......@@ -12,7 +12,6 @@
1212#include <__config>
1313#include <__iterator/iterator_traits.h>
1414#include <__utility/convert_to_integral.h>
15#include <type_traits>
1615
1716#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1817# pragma GCC system_header
lib/libcxx/include/__algorithm/find.h+49-4
......@@ -10,7 +10,16 @@
1010#ifndef _LIBCPP___ALGORITHM_FIND_H
1111#define _LIBCPP___ALGORITHM_FIND_H
1212
13#include <__algorithm/unwrap_iter.h>
1314#include <__config>
15#include <__functional/identity.h>
16#include <__functional/invoke.h>
17#include <__string/constexpr_c_functions.h>
18#include <__type_traits/is_same.h>
19
20#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
21# include <cwchar>
22#endif
1423
1524#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1625# pragma GCC system_header
......@@ -18,15 +27,51 @@
1827
1928_LIBCPP_BEGIN_NAMESPACE_STD
2029
21template <class _InputIterator, class _Tp>
22_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
23find(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
30template <class _Iter, class _Sent, class _Tp, class _Proj>
31_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
32__find_impl(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
2433 for (; __first != __last; ++__first)
25 if (*__first == __value)
34 if (std::__invoke(__proj, *__first) == __value)
2635 break;
2736 return __first;
2837}
2938
39template <class _Tp,
40 class _Up,
41 class _Proj,
42 __enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
43 sizeof(_Tp) == 1,
44 int> = 0>
45_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
46__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
47 if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first))
48 return __ret;
49 return __last;
50}
51
52#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
53template <class _Tp,
54 class _Up,
55 class _Proj,
56 __enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
57 sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t),
58 int> = 0>
59_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
60__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
61 if (auto __ret = std::__constexpr_wmemchr(__first, __value, __last - __first))
62 return __ret;
63 return __last;
64}
65#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
66
67template <class _InputIterator, class _Tp>
68_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
69find(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
70 __identity __proj;
71 return std::__rewrap_iter(
72 __first, std::__find_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value, __proj));
73}
74
3075_LIBCPP_END_NAMESPACE_STD
3176
3277#endif // _LIBCPP___ALGORITHM_FIND_H
lib/libcxx/include/__algorithm/find_end.h+1-1
......@@ -15,12 +15,12 @@
1515#include <__algorithm/search.h>
1616#include <__config>
1717#include <__functional/identity.h>
18#include <__functional/invoke.h>
1819#include <__iterator/advance.h>
1920#include <__iterator/iterator_traits.h>
2021#include <__iterator/next.h>
2122#include <__iterator/reverse_iterator.h>
2223#include <__utility/pair.h>
23#include <type_traits>
2424
2525#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2626# pragma GCC system_header
lib/libcxx/include/__algorithm/for_each_n.h+1-2
......@@ -12,7 +12,6 @@
1212
1313#include <__config>
1414#include <__utility/convert_to_integral.h>
15#include <type_traits>
1615
1716#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1817# pragma GCC system_header
......@@ -20,7 +19,7 @@
2019
2120_LIBCPP_BEGIN_NAMESPACE_STD
2221
23#if _LIBCPP_STD_VER > 14
22#if _LIBCPP_STD_VER >= 17
2423
2524template <class _InputIterator, class _Size, class _Function>
2625inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator for_each_n(_InputIterator __first,
lib/libcxx/include/__algorithm/for_each_segment.h created+53
......@@ -0,0 +1,53 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
10#define _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
11
12#include <__config>
13#include <__iterator/segmented_iterator.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21// __for_each_segment is a utility function for optimizing iterating over segmented iterators linearly.
22// __first and __last are expected to be a segmented range. __func is expected to take a range of local iterators.
23// Anything that is returned from __func is ignored.
24
25template <class _SegmentedIterator, class _Functor>
26_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
27__for_each_segment(_SegmentedIterator __first, _SegmentedIterator __last, _Functor __func) {
28 using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
29
30 auto __sfirst = _Traits::__segment(__first);
31 auto __slast = _Traits::__segment(__last);
32
33 // We are in a single segment, so we might not be at the beginning or end
34 if (__sfirst == __slast) {
35 __func(_Traits::__local(__first), _Traits::__local(__last));
36 return;
37 }
38
39 // We have more than one segment. Iterate over the first segment, since we might not start at the beginning
40 __func(_Traits::__local(__first), _Traits::__end(__sfirst));
41 ++__sfirst;
42 // iterate over the segments which are guaranteed to be completely in the range
43 while (__sfirst != __slast) {
44 __func(_Traits::__begin(__sfirst), _Traits::__end(__sfirst));
45 ++__sfirst;
46 }
47 // iterate over the last segment
48 __func(_Traits::__begin(__sfirst), _Traits::__local(__last));
49}
50
51_LIBCPP_END_NAMESPACE_STD
52
53#endif // _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
lib/libcxx/include/__algorithm/generate_n.h-1
......@@ -11,7 +11,6 @@
1111
1212#include <__config>
1313#include <__utility/convert_to_integral.h>
14#include <type_traits>
1514
1615#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1716# pragma GCC system_header
lib/libcxx/include/__algorithm/half_positive.h+3-1
......@@ -10,7 +10,9 @@
1010#define _LIBCPP___ALGORITHM_HALF_POSITIVE_H
1111
1212#include <__config>
13#include <type_traits>
13#include <__type_traits/enable_if.h>
14#include <__type_traits/is_integral.h>
15#include <__type_traits/make_unsigned.h>
1416
1517#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1618# pragma GCC system_header
lib/libcxx/include/__algorithm/in_found_result.h+2-2
......@@ -18,7 +18,7 @@
1818# pragma GCC system_header
1919#endif
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
......@@ -44,6 +44,6 @@ struct in_found_result {
4444
4545_LIBCPP_END_NAMESPACE_STD
4646
47#endif // _LIBCPP_STD_VER > 17
47#endif // _LIBCPP_STD_VER >= 20
4848
4949#endif // _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H
lib/libcxx/include/__algorithm/in_fun_result.h+2-2
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525namespace ranges {
2626template <class _InIter1, class _Func1>
......@@ -42,7 +42,7 @@ struct in_fun_result {
4242};
4343} // namespace ranges
4444
45#endif // _LIBCPP_STD_VER > 17
45#endif // _LIBCPP_STD_VER >= 20
4646
4747_LIBCPP_END_NAMESPACE_STD
4848
lib/libcxx/include/__algorithm/in_in_out_result.h+2-2
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525namespace ranges {
2626
......@@ -49,7 +49,7 @@ struct in_in_out_result {
4949
5050} // namespace ranges
5151
52#endif // _LIBCPP_STD_VER > 17
52#endif // _LIBCPP_STD_VER >= 20
5353
5454_LIBCPP_END_NAMESPACE_STD
5555
lib/libcxx/include/__algorithm/in_in_result.h+2-2
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525namespace ranges {
2626
......@@ -46,7 +46,7 @@ struct in_in_result {
4646
4747} // namespace ranges
4848
49#endif // _LIBCPP_STD_VER > 17
49#endif // _LIBCPP_STD_VER >= 20
5050
5151_LIBCPP_END_NAMESPACE_STD
5252
lib/libcxx/include/__algorithm/in_out_out_result.h+2-2
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525namespace ranges {
2626template <class _InIter1, class _OutIter1, class _OutIter2>
......@@ -47,7 +47,7 @@ struct in_out_out_result {
4747};
4848} // namespace ranges
4949
50#endif // _LIBCPP_STD_VER > 17
50#endif // _LIBCPP_STD_VER >= 20
5151
5252_LIBCPP_END_NAMESPACE_STD
5353
lib/libcxx/include/__algorithm/in_out_result.h+7-2
......@@ -18,9 +18,12 @@
1818# pragma GCC system_header
1919#endif
2020
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
2124_LIBCPP_BEGIN_NAMESPACE_STD
2225
23#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2427
2528namespace ranges {
2629
......@@ -46,8 +49,10 @@ struct in_out_result {
4649
4750} // namespace ranges
4851
49#endif // _LIBCPP_STD_VER > 17
52#endif // _LIBCPP_STD_VER >= 20
5053
5154_LIBCPP_END_NAMESPACE_STD
5255
56_LIBCPP_POP_MACROS
57
5358#endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H
lib/libcxx/include/__algorithm/includes.h+1-7
......@@ -61,13 +61,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
6161template <class _InputIterator1, class _InputIterator2>
6262_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
6363includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
64 return std::includes(
65 std::move(__first1),
66 std::move(__last1),
67 std::move(__first2),
68 std::move(__last2),
69 __less<typename iterator_traits<_InputIterator1>::value_type,
70 typename iterator_traits<_InputIterator2>::value_type>());
64 return std::includes(std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __less<>());
7165}
7266
7367_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/inplace_merge.h+1-2
......@@ -246,8 +246,7 @@ inline _LIBCPP_HIDE_FROM_ABI
246246void
247247inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last)
248248{
249 std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last),
250 __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
249 std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less<>());
251250}
252251
253252_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/is_heap.h+1-1
......@@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
3636bool
3737is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
3838{
39 return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
39 return _VSTD::is_heap(__first, __last, __less<>());
4040}
4141
4242_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/is_heap_until.h+1-1
......@@ -58,7 +58,7 @@ template<class _RandomAccessIterator>
5858_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
5959is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
6060{
61 return _VSTD::__is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
61 return _VSTD::__is_heap_until(__first, __last, __less<>());
6262}
6363
6464_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/is_permutation.h+10-5
......@@ -19,19 +19,22 @@
1919#include <__iterator/distance.h>
2020#include <__iterator/iterator_traits.h>
2121#include <__iterator/next.h>
22#include <__type_traits/is_callable.h>
2223#include <__utility/move.h>
23#include <type_traits>
2424
2525#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2626# pragma GCC system_header
2727#endif
2828
29_LIBCPP_PUSH_MACROS
30#include <__undef_macros>
31
2932_LIBCPP_BEGIN_NAMESPACE_STD
3033
3134template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class = void>
3235struct _ConstTimeDistance : false_type {};
3336
34#if _LIBCPP_STD_VER > 17
37#if _LIBCPP_STD_VER >= 20
3538
3639template <class _Iter1, class _Sent1, class _Iter2, class _Sent2>
3740struct _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2, __enable_if_t<
......@@ -47,7 +50,7 @@ struct _ConstTimeDistance<_Iter1, _Iter1, _Iter2, _Iter2, __enable_if_t<
4750 is_same<typename iterator_traits<_Iter2>::iterator_category, random_access_iterator_tag>::value
4851> > : true_type {};
4952
50#endif // _LIBCPP_STD_VER > 17
53#endif // _LIBCPP_STD_VER >= 20
5154
5255// Internal functions
5356
......@@ -202,7 +205,7 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIt
202205 return std::is_permutation(__first1, __last1, __first2, __equal_to());
203206}
204207
205#if _LIBCPP_STD_VER > 11
208#if _LIBCPP_STD_VER >= 14
206209
207210// 2+2 iterators
208211template <class _ForwardIterator1, class _ForwardIterator2>
......@@ -231,8 +234,10 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIt
231234 __pred, __identity(), __identity());
232235}
233236
234#endif // _LIBCPP_STD_VER > 11
237#endif // _LIBCPP_STD_VER >= 14
235238
236239_LIBCPP_END_NAMESPACE_STD
237240
241_LIBCPP_POP_MACROS
242
238243#endif // _LIBCPP___ALGORITHM_IS_PERMUTATION_H
lib/libcxx/include/__algorithm/is_sorted.h+1-1
......@@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
3636bool
3737is_sorted(_ForwardIterator __first, _ForwardIterator __last)
3838{
39 return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
39 return _VSTD::is_sorted(__first, __last, __less<>());
4040}
4141
4242_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/is_sorted_until.h+1-1
......@@ -48,7 +48,7 @@ template<class _ForwardIterator>
4848_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
4949is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
5050{
51 return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
51 return _VSTD::is_sorted_until(__first, __last, __less<>());
5252}
5353
5454_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/iterator_operations.h+6-1
......@@ -33,11 +33,14 @@
3333# pragma GCC system_header
3434#endif
3535
36_LIBCPP_PUSH_MACROS
37#include <__undef_macros>
38
3639_LIBCPP_BEGIN_NAMESPACE_STD
3740
3841template <class _AlgPolicy> struct _IterOps;
3942
40#if _LIBCPP_STD_VER > 17
43#if _LIBCPP_STD_VER >= 20
4144struct _RangeAlgPolicy {};
4245
4346template <>
......@@ -172,4 +175,6 @@ struct _IterOps<_ClassicAlgPolicy> {
172175
173176_LIBCPP_END_NAMESPACE_STD
174177
178_LIBCPP_POP_MACROS
179
175180#endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H
lib/libcxx/include/__algorithm/lexicographical_compare.h+1-3
......@@ -52,9 +52,7 @@ bool
5252lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
5353 _InputIterator2 __first2, _InputIterator2 __last2)
5454{
55 return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2,
56 __less<typename iterator_traits<_InputIterator1>::value_type,
57 typename iterator_traits<_InputIterator2>::value_type>());
55 return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>());
5856}
5957
6058_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/lexicographical_compare_three_way.h created+125
......@@ -0,0 +1,125 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
10#define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
11
12#include <__algorithm/min.h>
13#include <__algorithm/three_way_comp_ref_type.h>
14#include <__compare/compare_three_way.h>
15#include <__compare/ordering.h>
16#include <__concepts/arithmetic.h>
17#include <__config>
18#include <__iterator/iterator_traits.h>
19#include <__type_traits/common_type.h>
20#include <__type_traits/is_copy_constructible.h>
21#include <__utility/move.h>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24# pragma GCC system_header
25#endif
26
27_LIBCPP_PUSH_MACROS
28#include <__undef_macros>
29
30_LIBCPP_BEGIN_NAMESPACE_STD
31
32#if _LIBCPP_STD_VER >= 20
33
34// Fast path for random access iterators which computes the number of loop iterations up-front and
35// then skips the iterator comparisons inside the loop.
36template <class _InputIterator1, class _InputIterator2, class _Cmp>
37_LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_fast_path(
38 _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp)
39 -> decltype(__comp(*__first1, *__first2)) {
40 static_assert(
41 signed_integral<__iter_diff_t<_InputIterator1>>, "Using a non-integral difference_type is undefined behavior.");
42 static_assert(
43 signed_integral<__iter_diff_t<_InputIterator2>>, "Using a non-integral difference_type is undefined behavior.");
44
45 using _Len1 = __iter_diff_t<_InputIterator1>;
46 using _Len2 = __iter_diff_t<_InputIterator2>;
47 using _Common = common_type_t<_Len1, _Len2>;
48
49 _Len1 __len1 = __last1 - __first1;
50 _Len2 __len2 = __last2 - __first2;
51 _Common __min_len = std::min<_Common>(__len1, __len2);
52
53 for (_Common __i = 0; __i < __min_len; ++__i) {
54 auto __c = __comp(*__first1, *__first2);
55 if (__c != 0) {
56 return __c;
57 }
58 ++__first1;
59 ++__first2;
60 }
61
62 return __len1 <=> __len2;
63}
64
65// Unoptimized implementation which compares the iterators against the end in every loop iteration
66template <class _InputIterator1, class _InputIterator2, class _Cmp>
67_LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_slow_path(
68 _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp)
69 -> decltype(__comp(*__first1, *__first2)) {
70 while (true) {
71 bool __exhausted1 = __first1 == __last1;
72 bool __exhausted2 = __first2 == __last2;
73
74 if (__exhausted1 || __exhausted2) {
75 if (!__exhausted1)
76 return strong_ordering::greater;
77 if (!__exhausted2)
78 return strong_ordering::less;
79 return strong_ordering::equal;
80 }
81
82 auto __c = __comp(*__first1, *__first2);
83 if (__c != 0) {
84 return __c;
85 }
86
87 ++__first1;
88 ++__first2;
89 }
90}
91
92template <class _InputIterator1, class _InputIterator2, class _Cmp>
93_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way(
94 _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp __comp)
95 -> decltype(__comp(*__first1, *__first2)) {
96 static_assert(__comparison_category<decltype(__comp(*__first1, *__first2))>,
97 "The comparator passed to lexicographical_compare_three_way must return a comparison category type.");
98 static_assert(std::is_copy_constructible_v<_InputIterator1>, "Iterators must be copy constructible.");
99 static_assert(std::is_copy_constructible_v<_InputIterator2>, "Iterators must be copy constructible.");
100 __three_way_comp_ref_type<_Cmp> __wrapped_comp_ref(__comp);
101 if constexpr (__has_random_access_iterator_category<_InputIterator1>::value &&
102 __has_random_access_iterator_category<_InputIterator2>::value) {
103 return std::__lexicographical_compare_three_way_fast_path(
104 std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __wrapped_comp_ref);
105 } else {
106 // Unoptimized implementation which compares the iterators against the end in every loop iteration
107 return std::__lexicographical_compare_three_way_slow_path(
108 std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __wrapped_comp_ref);
109 }
110}
111
112template <class _InputIterator1, class _InputIterator2>
113_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way(
114 _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
115 return std::lexicographical_compare_three_way(
116 std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::compare_three_way());
117}
118
119#endif // _LIBCPP_STD_VER >= 20
120
121_LIBCPP_END_NAMESPACE_STD
122
123_LIBCPP_POP_MACROS
124
125#endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
lib/libcxx/include/__algorithm/lower_bound.h+3-5
......@@ -20,7 +20,6 @@
2020#include <__iterator/iterator_traits.h>
2121#include <__type_traits/is_callable.h>
2222#include <__type_traits/remove_reference.h>
23#include <type_traits>
2423
2524#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2625# pragma GCC system_header
......@@ -30,7 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3029
3130template <class _AlgPolicy, class _Iter, class _Sent, class _Type, class _Proj, class _Comp>
3231_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
33_Iter __lower_bound_impl(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
32_Iter __lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
3433 auto __len = _IterOps<_AlgPolicy>::distance(__first, __last);
3534
3635 while (__len != 0) {
......@@ -53,14 +52,13 @@ _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last,
5352 static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value,
5453 "The comparator has to be callable");
5554 auto __proj = std::__identity();
56 return std::__lower_bound_impl<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj);
55 return std::__lower_bound<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj);
5756}
5857
5958template <class _ForwardIterator, class _Tp>
6059_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
6160_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
62 return std::lower_bound(__first, __last, __value,
63 __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
61 return std::lower_bound(__first, __last, __value, __less<>());
6462}
6563
6664_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/make_heap.h+6-2
......@@ -21,6 +21,9 @@
2121# pragma GCC system_header
2222#endif
2323
24_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
2427_LIBCPP_BEGIN_NAMESPACE_STD
2528
2629template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
......@@ -47,10 +50,11 @@ void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
4750template <class _RandomAccessIterator>
4851inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4952void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
50 std::make_heap(std::move(__first), std::move(__last),
51 __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
53 std::make_heap(std::move(__first), std::move(__last), __less<>());
5254}
5355
5456_LIBCPP_END_NAMESPACE_STD
5557
58_LIBCPP_POP_MACROS
59
5660#endif // _LIBCPP___ALGORITHM_MAKE_HEAP_H
lib/libcxx/include/__algorithm/make_projected.h+20-33
......@@ -32,13 +32,14 @@ struct _ProjectedPred {
3232 _Pred& __pred; // Can be a unary or a binary predicate.
3333 _Proj& __proj;
3434
35 _LIBCPP_CONSTEXPR _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg) : __pred(__pred_arg), __proj(__proj_arg) {}
35 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg)
36 : __pred(__pred_arg), __proj(__proj_arg) {}
3637
3738 template <class _Tp>
3839 typename __invoke_of<_Pred&,
3940 decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>()))
4041 >::type
41 _LIBCPP_CONSTEXPR operator()(_Tp&& __v) const {
42 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_Tp&& __v) const {
4243 return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v)));
4344 }
4445
......@@ -47,7 +48,7 @@ struct _ProjectedPred {
4748 decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())),
4849 decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>()))
4950 >::type
50 _LIBCPP_CONSTEXPR operator()(_T1&& __lhs, _T2&& __rhs) const {
51 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_T1&& __lhs, _T2&& __rhs) const {
5152 return std::__invoke(__pred,
5253 std::__invoke(__proj, std::forward<_T1>(__lhs)),
5354 std::__invoke(__proj, std::forward<_T2>(__rhs)));
......@@ -55,25 +56,12 @@ struct _ProjectedPred {
5556
5657};
5758
58template <class _Pred, class _Proj, class = void>
59struct __can_use_pristine_comp : false_type {};
60
61template <class _Pred, class _Proj>
62struct __can_use_pristine_comp<_Pred, _Proj, __enable_if_t<
63 !is_member_pointer<typename decay<_Pred>::type>::value && (
64#if _LIBCPP_STD_VER > 17
65 is_same<typename decay<_Proj>::type, identity>::value ||
66#endif
67 is_same<typename decay<_Proj>::type, __identity>::value
68 )
69> > : true_type {};
70
71template <class _Pred, class _Proj>
72_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static
73__enable_if_t<
74 !__can_use_pristine_comp<_Pred, _Proj>::value,
75 _ProjectedPred<_Pred, _Proj>
76>
59template <class _Pred,
60 class _Proj,
61 __enable_if_t<!(!is_member_pointer<__decay_t<_Pred> >::value &&
62 __is_identity<__decay_t<_Proj> >::value),
63 int> = 0>
64_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj>
7765__make_projected(_Pred& __pred, _Proj& __proj) {
7866 return _ProjectedPred<_Pred, _Proj>(__pred, __proj);
7967}
......@@ -81,28 +69,27 @@ __make_projected(_Pred& __pred, _Proj& __proj) {
8169// Avoid creating the functor and just use the pristine comparator -- for certain algorithms, this would enable
8270// optimizations that rely on the type of the comparator. Additionally, this results in less layers of indirection in
8371// the call stack when the comparator is invoked, even in an unoptimized build.
84template <class _Pred, class _Proj>
85_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static
86__enable_if_t<
87 __can_use_pristine_comp<_Pred, _Proj>::value,
88 _Pred&
89>
90__make_projected(_Pred& __pred, _Proj&) {
72template <class _Pred,
73 class _Proj,
74 __enable_if_t<!is_member_pointer<__decay_t<_Pred> >::value &&
75 __is_identity<__decay_t<_Proj> >::value,
76 int> = 0>
77_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Pred& __make_projected(_Pred& __pred, _Proj&) {
9178 return __pred;
9279}
9380
9481_LIBCPP_END_NAMESPACE_STD
9582
96#if _LIBCPP_STD_VER > 17
83#if _LIBCPP_STD_VER >= 20
9784
9885_LIBCPP_BEGIN_NAMESPACE_STD
9986
10087namespace ranges {
10188
10289template <class _Comp, class _Proj1, class _Proj2>
103_LIBCPP_HIDE_FROM_ABI constexpr static
90_LIBCPP_HIDE_FROM_ABI constexpr
10491decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
105 if constexpr (same_as<decay_t<_Proj1>, identity> && same_as<decay_t<_Proj2>, identity> &&
92 if constexpr (__is_identity<decay_t<_Proj1>>::value && __is_identity<decay_t<_Proj2>>::value &&
10693 !is_member_pointer_v<decay_t<_Comp>>) {
10794 // Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable
10895 // optimizations that rely on the type of the comparator.
......@@ -121,6 +108,6 @@ decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __p
121108
122109_LIBCPP_END_NAMESPACE_STD
123110
124#endif // _LIBCPP_STD_VER > 17
111#endif // _LIBCPP_STD_VER >= 20
125112
126113#endif // _LIBCPP___ALGORITHM_MAKE_PROJECTED_H
lib/libcxx/include/__algorithm/max.h+4-4
......@@ -28,7 +28,7 @@ template <class _Tp, class _Compare>
2828_LIBCPP_NODISCARD_EXT inline
2929_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3030const _Tp&
31max(const _Tp& __a, const _Tp& __b, _Compare __comp)
31max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
3232{
3333 return __comp(__a, __b) ? __b : __a;
3434}
......@@ -37,9 +37,9 @@ template <class _Tp>
3737_LIBCPP_NODISCARD_EXT inline
3838_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3939const _Tp&
40max(const _Tp& __a, const _Tp& __b)
40max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
4141{
42 return _VSTD::max(__a, __b, __less<_Tp>());
42 return _VSTD::max(__a, __b, __less<>());
4343}
4444
4545#ifndef _LIBCPP_CXX03_LANG
......@@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
5959_Tp
6060max(initializer_list<_Tp> __t)
6161{
62 return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>());
62 return *_VSTD::max_element(__t.begin(), __t.end(), __less<>());
6363}
6464
6565#endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__algorithm/max_element.h+2-3
......@@ -24,7 +24,7 @@ template <class _Compare, class _ForwardIterator>
2424inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
2525__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
2626{
27 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
27 static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
2828 "std::max_element requires a ForwardIterator");
2929 if (__first != __last)
3030 {
......@@ -48,8 +48,7 @@ template <class _ForwardIterator>
4848_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
4949max_element(_ForwardIterator __first, _ForwardIterator __last)
5050{
51 return _VSTD::max_element(__first, __last,
52 __less<typename iterator_traits<_ForwardIterator>::value_type>());
51 return _VSTD::max_element(__first, __last, __less<>());
5352}
5453
5554_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/merge.h+1-3
......@@ -60,9 +60,7 @@ _OutputIterator
6060merge(_InputIterator1 __first1, _InputIterator1 __last1,
6161 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
6262{
63 typedef typename iterator_traits<_InputIterator1>::value_type __v1;
64 typedef typename iterator_traits<_InputIterator2>::value_type __v2;
65 return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>());
63 return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<>());
6664}
6765
6866_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/min.h+4-4
......@@ -28,7 +28,7 @@ template <class _Tp, class _Compare>
2828_LIBCPP_NODISCARD_EXT inline
2929_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3030const _Tp&
31min(const _Tp& __a, const _Tp& __b, _Compare __comp)
31min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
3232{
3333 return __comp(__b, __a) ? __b : __a;
3434}
......@@ -37,9 +37,9 @@ template <class _Tp>
3737_LIBCPP_NODISCARD_EXT inline
3838_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3939const _Tp&
40min(const _Tp& __a, const _Tp& __b)
40min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
4141{
42 return _VSTD::min(__a, __b, __less<_Tp>());
42 return _VSTD::min(__a, __b, __less<>());
4343}
4444
4545#ifndef _LIBCPP_CXX03_LANG
......@@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
5959_Tp
6060min(initializer_list<_Tp> __t)
6161{
62 return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>());
62 return *_VSTD::min_element(__t.begin(), __t.end(), __less<>());
6363}
6464
6565#endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__algorithm/min_element.h+7-3
......@@ -22,6 +22,9 @@
2222# pragma GCC system_header
2323#endif
2424
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
2528_LIBCPP_BEGIN_NAMESPACE_STD
2629
2730template <class _Comp, class _Iter, class _Sent, class _Proj>
......@@ -49,7 +52,7 @@ template <class _ForwardIterator, class _Compare>
4952_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
5053min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
5154{
52 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
55 static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
5356 "std::min_element requires a ForwardIterator");
5457 static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value,
5558 "The comparator has to be callable");
......@@ -61,10 +64,11 @@ template <class _ForwardIterator>
6164_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
6265min_element(_ForwardIterator __first, _ForwardIterator __last)
6366{
64 return _VSTD::min_element(__first, __last,
65 __less<typename iterator_traits<_ForwardIterator>::value_type>());
67 return _VSTD::min_element(__first, __last, __less<>());
6668}
6769
6870_LIBCPP_END_NAMESPACE_STD
6971
72_LIBCPP_POP_MACROS
73
7074#endif // _LIBCPP___ALGORITHM_MIN_ELEMENT_H
lib/libcxx/include/__algorithm/min_max_result.h+2-2
......@@ -23,7 +23,7 @@ _LIBCPP_PUSH_MACROS
2323
2424_LIBCPP_BEGIN_NAMESPACE_STD
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828namespace ranges {
2929
......@@ -47,7 +47,7 @@ struct min_max_result {
4747
4848} // namespace ranges
4949
50#endif // _LIBCPP_STD_VER > 17
50#endif // _LIBCPP_STD_VER >= 20
5151
5252_LIBCPP_END_NAMESPACE_STD
5353
lib/libcxx/include/__algorithm/minmax.h+4-4
......@@ -27,7 +27,7 @@ template<class _Tp, class _Compare>
2727_LIBCPP_NODISCARD_EXT inline
2828_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
2929pair<const _Tp&, const _Tp&>
30minmax(const _Tp& __a, const _Tp& __b, _Compare __comp)
30minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
3131{
3232 return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) :
3333 pair<const _Tp&, const _Tp&>(__a, __b);
......@@ -37,9 +37,9 @@ template<class _Tp>
3737_LIBCPP_NODISCARD_EXT inline
3838_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
3939pair<const _Tp&, const _Tp&>
40minmax(const _Tp& __a, const _Tp& __b)
40minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
4141{
42 return std::minmax(__a, __b, __less<_Tp>());
42 return std::minmax(__a, __b, __less<>());
4343}
4444
4545#ifndef _LIBCPP_CXX03_LANG
......@@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
5959pair<_Tp, _Tp>
6060minmax(initializer_list<_Tp> __t)
6161{
62 return std::minmax(__t, __less<_Tp>());
62 return std::minmax(__t, __less<>());
6363}
6464
6565#endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__algorithm/minmax_element.h+4-3
......@@ -12,9 +12,10 @@
1212#include <__algorithm/comp.h>
1313#include <__config>
1414#include <__functional/identity.h>
15#include <__functional/invoke.h>
1516#include <__iterator/iterator_traits.h>
17#include <__type_traits/is_callable.h>
1618#include <__utility/pair.h>
17#include <type_traits>
1819
1920#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2021# pragma GCC system_header
......@@ -82,7 +83,7 @@ template <class _ForwardIterator, class _Compare>
8283_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
8384pair<_ForwardIterator, _ForwardIterator>
8485minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
85 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
86 static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
8687 "std::minmax_element requires a ForwardIterator");
8788 static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value,
8889 "The comparator has to be callable");
......@@ -93,7 +94,7 @@ minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __com
9394template <class _ForwardIterator>
9495_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
9596pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) {
96 return std::minmax_element(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
97 return std::minmax_element(__first, __last, __less<>());
9798}
9899
99100_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/mismatch.h+1-1
......@@ -38,7 +38,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
3838 return std::mismatch(__first1, __last1, __first2, __equal_to());
3939}
4040
41#if _LIBCPP_STD_VER > 11
41#if _LIBCPP_STD_VER >= 14
4242template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
4343_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
4444 _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
lib/libcxx/include/__algorithm/move.h+18-19
......@@ -10,6 +10,7 @@
1010#define _LIBCPP___ALGORITHM_MOVE_H
1111
1212#include <__algorithm/copy_move_common.h>
13#include <__algorithm/for_each_segment.h>
1314#include <__algorithm/iterator_operations.h>
1415#include <__algorithm/min.h>
1516#include <__config>
......@@ -45,36 +46,34 @@ struct __move_loop {
4546 return std::make_pair(std::move(__first), std::move(__result));
4647 }
4748
48 template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
49 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
50 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
49 template <class _InIter, class _OutIter>
50 struct _MoveSegment {
5151 using _Traits = __segmented_iterator_traits<_InIter>;
52 auto __sfirst = _Traits::__segment(__first);
53 auto __slast = _Traits::__segment(__last);
54 if (__sfirst == __slast) {
55 auto __iters = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
56 return std::make_pair(__last, std::move(__iters.second));
57 }
5852
59 __result = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second;
60 ++__sfirst;
61 while (__sfirst != __slast) {
62 __result =
63 std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second;
64 ++__sfirst;
53 _OutIter& __result_;
54
55 _LIBCPP_HIDE_FROM_ABI _MoveSegment(_OutIter& __result) : __result_(__result) {}
56
57 _LIBCPP_HIDE_FROM_ABI void
58 operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
59 __result_ = std::__move<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second;
6560 }
66 __result =
67 std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second;
61 };
62
63 template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
64 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
65 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
66 std::__for_each_segment(__first, __last, _MoveSegment<_InIter, _OutIter>(__result));
6867 return std::make_pair(__last, std::move(__result));
6968 }
7069
7170 template <class _InIter,
7271 class _OutIter,
73 __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
72 __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
7473 !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
7574 int> = 0>
7675 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
77 operator()(_InIter __first, _InIter __last, _OutIter __result) {
76 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
7877 using _Traits = __segmented_iterator_traits<_OutIter>;
7978 using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
8079
lib/libcxx/include/__algorithm/move_backward.h+2-2
......@@ -76,11 +76,11 @@ struct __move_backward_loop {
7676
7777 template <class _InIter,
7878 class _OutIter,
79 __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
79 __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
8080 !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
8181 int> = 0>
8282 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
83 operator()(_InIter __first, _InIter __last, _OutIter __result) {
83 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
8484 using _Traits = __segmented_iterator_traits<_OutIter>;
8585 using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
8686
lib/libcxx/include/__algorithm/next_permutation.h+1-2
......@@ -69,8 +69,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
6969bool
7070next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
7171{
72 return _VSTD::next_permutation(__first, __last,
73 __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
72 return _VSTD::next_permutation(__first, __last, __less<>());
7473}
7574
7675_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/nth_element.h+1-3
......@@ -14,7 +14,6 @@
1414#include <__algorithm/iterator_operations.h>
1515#include <__algorithm/sort.h>
1616#include <__config>
17#include <__debug>
1817#include <__debug_utils/randomize_range.h>
1918#include <__iterator/iterator_traits.h>
2019#include <__utility/move.h>
......@@ -249,8 +248,7 @@ void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Ra
249248template <class _RandomAccessIterator>
250249inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
251250void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) {
252 std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<typename
253 iterator_traits<_RandomAccessIterator>::value_type>());
251 std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<>());
254252}
255253
256254_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/partial_sort.h+3-4
......@@ -16,11 +16,11 @@
1616#include <__algorithm/sift_down.h>
1717#include <__algorithm/sort_heap.h>
1818#include <__config>
19#include <__debug>
2019#include <__debug_utils/randomize_range.h>
2120#include <__iterator/iterator_traits.h>
21#include <__type_traits/is_copy_assignable.h>
22#include <__type_traits/is_copy_constructible.h>
2223#include <__utility/move.h>
23#include <type_traits>
2424
2525#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2626# pragma GCC system_header
......@@ -87,8 +87,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
8787void
8888partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
8989{
90 _VSTD::partial_sort(__first, __middle, __last,
91 __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
90 _VSTD::partial_sort(__first, __middle, __last, __less<>());
9291}
9392
9493_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/partial_sort_copy.h+1-2
......@@ -79,8 +79,7 @@ _RandomAccessIterator
7979partial_sort_copy(_InputIterator __first, _InputIterator __last,
8080 _RandomAccessIterator __result_first, _RandomAccessIterator __result_last)
8181{
82 return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last,
83 __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
82 return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>());
8483}
8584
8685_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/partition.h-1
......@@ -14,7 +14,6 @@
1414#include <__iterator/iterator_traits.h>
1515#include <__utility/move.h>
1616#include <__utility/pair.h>
17#include <type_traits>
1817
1918#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2019# pragma GCC system_header
lib/libcxx/include/__algorithm/pop_heap.h+9-4
......@@ -17,20 +17,24 @@
1717#include <__assert>
1818#include <__config>
1919#include <__iterator/iterator_traits.h>
20#include <__type_traits/is_copy_assignable.h>
21#include <__type_traits/is_copy_constructible.h>
2022#include <__utility/move.h>
21#include <type_traits>
2223
2324#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2425# pragma GCC system_header
2526#endif
2627
28_LIBCPP_PUSH_MACROS
29#include <__undef_macros>
30
2731_LIBCPP_BEGIN_NAMESPACE_STD
2832
2933template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
3034inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
3135void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp,
3236 typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
33 _LIBCPP_ASSERT(__len > 0, "The heap given to pop_heap must be non-empty");
37 _LIBCPP_ASSERT_UNCATEGORIZED(__len > 0, "The heap given to pop_heap must be non-empty");
3438
3539 __comp_ref_type<_Compare> __comp_ref = __comp;
3640
......@@ -64,10 +68,11 @@ void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp
6468template <class _RandomAccessIterator>
6569inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
6670void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
67 std::pop_heap(std::move(__first), std::move(__last),
68 __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
71 std::pop_heap(std::move(__first), std::move(__last), __less<>());
6972}
7073
7174_LIBCPP_END_NAMESPACE_STD
7275
76_LIBCPP_POP_MACROS
77
7378#endif // _LIBCPP___ALGORITHM_POP_HEAP_H
lib/libcxx/include/__algorithm/prev_permutation.h+1-2
......@@ -70,8 +70,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
7070bool
7171prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
7272{
73 return _VSTD::prev_permutation(__first, __last,
74 __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
73 return _VSTD::prev_permutation(__first, __last, __less<>());
7574}
7675
7776_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/pstl_any_all_none_of.h created+100
......@@ -0,0 +1,100 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
10#define _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
11
12#include <__algorithm/pstl_find.h>
13#include <__algorithm/pstl_frontend_dispatch.h>
14#include <__config>
15#include <__iterator/cpp17_iterator_concepts.h>
16#include <__iterator/iterator_traits.h>
17#include <__type_traits/enable_if.h>
18#include <__type_traits/is_execution_policy.h>
19#include <__type_traits/remove_cvref.h>
20#include <__utility/move.h>
21#include <__utility/terminate_on_exception.h>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24# pragma GCC system_header
25#endif
26
27#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31template <class>
32void __pstl_any_of(); // declaration needed for the frontend dispatch below
33
34template <class _ExecutionPolicy,
35 class _ForwardIterator,
36 class _Predicate,
37 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
38 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
39_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
40any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
41 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
42 return std::__pstl_frontend_dispatch(
43 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_any_of),
44 [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
45 return std::find_if(__policy, __g_first, __g_last, __g_pred) != __g_last;
46 },
47 std::move(__first),
48 std::move(__last),
49 std::move(__pred));
50}
51
52template <class>
53void __pstl_all_of(); // declaration needed for the frontend dispatch below
54
55template <class _ExecutionPolicy,
56 class _ForwardIterator,
57 class _Pred,
58 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
59 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
60_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
61all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
62 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
63 return std::__pstl_frontend_dispatch(
64 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_all_of),
65 [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) {
66 return !std::any_of(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) {
67 return !__g_pred(__value);
68 });
69 },
70 std::move(__first),
71 std::move(__last),
72 std::move(__pred));
73}
74
75template <class>
76void __pstl_none_of(); // declaration needed for the frontend dispatch below
77
78template <class _ExecutionPolicy,
79 class _ForwardIterator,
80 class _Pred,
81 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
82 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
83_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
84none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
85 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
86 return std::__pstl_frontend_dispatch(
87 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_none_of),
88 [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) {
89 return !std::any_of(__policy, __g_first, __g_last, __g_pred);
90 },
91 std::move(__first),
92 std::move(__last),
93 std::move(__pred));
94}
95
96_LIBCPP_END_NAMESPACE_STD
97
98#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
99
100#endif // _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
lib/libcxx/include/__algorithm/pstl_backend.h created+198
......@@ -0,0 +1,198 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_BACKEND_H
10#define _LIBCPP___ALGORITHM_PSTL_BACKEND_H
11
12#include <__algorithm/pstl_backends/cpu_backend.h>
13#include <__config>
14#include <execution>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24/*
25TODO: Documentation of how backends work
26
27A PSTL parallel backend is a tag type to which the following functions are associated, at minimum:
28
29 template <class _ExecutionPolicy, class _Iterator, class _Func>
30 void __pstl_for_each(_Backend, _ExecutionPolicy&&, _Iterator __first, _Iterator __last, _Func __f);
31
32 template <class _ExecutionPolicy, class _Iterator, class _Predicate>
33 _Iterator __pstl_find_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
34
35 template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp>
36 void __pstl_stable_sort(_Backend, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp);
37
38 template <class _ExecutionPolicy, class _InIterator, class _OutIterator, class _UnaryOperation>
39 _OutIterator __pstl_transform(_InIterator __first, _InIterator __last, _OutIterator __result, _UnaryOperation __op);
40
41 template <class _ExecutionPolicy, class _InIterator1, class _InIterator2, class _OutIterator, class _BinaryOperation>
42 _OutIterator __pstl_transform(_InIterator1 __first1,
43 _InIterator1 __last1,
44 _InIterator2 __first2,
45 _OutIterator __result,
46 _BinaryOperation __op);
47
48 template <class _ExecutionPolicy,
49 class _Iterator1,
50 class _Iterator2,
51 class _Tp,
52 class _BinaryOperation1,
53 class _BinaryOperation2>
54 _Tp __pstl_transform_reduce(_Backend,
55 _Iterator1 __first1,
56 _Iterator1 __last1,
57 _Iterator2 __first2,
58 _Iterator2 __last2,
59 _Tp __init,
60 _BinaryOperation1 __reduce,
61 _BinaryOperation2 __transform);
62
63 template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
64 _Tp __pstl_transform_reduce(_Backend,
65 _Iterator __first,
66 _Iterator __last,
67 _Tp __init,
68 _BinaryOperation __reduce,
69 _UnaryOperation __transform);
70
71// TODO: Complete this list
72
73The following functions are optional but can be provided. If provided, they are used by the corresponding
74algorithms, otherwise they are implemented in terms of other algorithms. If none of the optional algorithms are
75implemented, all the algorithms will eventually forward to the basis algorithms listed above:
76
77 template <class _ExecutionPolicy, class _Iterator, class _Size, class _Func>
78 void __pstl_for_each_n(_Backend, _Iterator __first, _Size __n, _Func __f);
79
80 template <class _ExecutionPolicy, class _Iterator, class _Predicate>
81 bool __pstl_any_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
82
83 template <class _ExecutionPolicy, class _Iterator, class _Predicate>
84 bool __pstl_all_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
85
86 template <class _ExecutionPolicy, class _Iterator, class _Predicate>
87 bool __pstl_none_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
88
89 template <class _ExecutionPolicy, class _Iterator, class _Tp>
90 _Iterator __pstl_find(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
91
92 template <class _ExecutionPolicy, class _Iterator, class _Predicate>
93 _Iterator __pstl_find_if_not(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
94
95 template <class _ExecutionPolicy, class _Iterator, class _Tp>
96 void __pstl_fill(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
97
98 template <class _ExecutionPolicy, class _Iterator, class _SizeT, class _Tp>
99 void __pstl_fill_n(_Backend, _Iterator __first, _SizeT __n, const _Tp& __value);
100
101 template <class _ExecutionPolicy, class _Iterator, class _Generator>
102 void __pstl_generate(_Backend, _Iterator __first, _Iterator __last, _Generator __gen);
103
104 template <class _ExecutionPolicy, class _Iterator, class _Predicate>
105 void __pstl_is_partitioned(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
106
107 template <class _ExecutionPolicy, class _Iterator, class _Size, class _Generator>
108 void __pstl_generator_n(_Backend, _Iterator __first, _Size __n, _Generator __gen);
109
110 template <class _ExecutionPolicy, class _terator1, class _Iterator2, class _OutIterator, class _Comp>
111 _OutIterator __pstl_merge(_Backend,
112 _Iterator1 __first1,
113 _Iterator1 __last1,
114 _Iterator2 __first2,
115 _Iterator2 __last2,
116 _OutIterator __result,
117 _Comp __comp);
118
119 template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation>
120 _Tp __pstl_reduce(_Backend, _Iterator __first, _Iterator __last, _Tp __init, _BinaryOperation __op);
121
122 temlate <class _ExecutionPolicy, class _Iterator>
123 __iter_value_type<_Iterator> __pstl_reduce(_Backend, _Iterator __first, _Iterator __last);
124
125 template <class _ExecuitonPolicy, class _Iterator, class _Tp>
126 __iter_diff_t<_Iterator> __pstl_count(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
127
128 template <class _ExecutionPolicy, class _Iterator, class _Predicate>
129 __iter_diff_t<_Iterator> __pstl_count_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
130
131 template <class _ExecutionPolicy, class _Iterator, class _Tp>
132 void __pstl_replace(_Backend, _Iterator __first, _Iterator __last, const _Tp& __old_value, const _Tp& __new_value);
133
134 template <class _ExecutionPolicy, class _Iterator, class _Pred, class _Tp>
135 void __pstl_replace_if(_Backend, _Iterator __first, _Iterator __last, _Pred __pred, const _Tp& __new_value);
136
137 template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Tp>
138 void __pstl_replace_copy(_Backend,
139 _Iterator __first,
140 _Iterator __last,
141 _OutIterator __result,
142 const _Tp& __old_value,
143 const _Tp& __new_value);
144
145 template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Pred, class _Tp>
146 void __pstl_replace_copy_if(_Backend,
147 _Iterator __first,
148 _Iterator __last,
149 _OutIterator __result,
150 _Pred __pred,
151 const _Tp& __new_value);
152
153 template <class _ExecutionPolicy, class _Iterator, class _Comp>
154 void __pstl_sort(_Backend, _Iterator __first, _Iterator __last, _Comp __comp);
155
156// TODO: Complete this list
157
158*/
159
160template <class _ExecutionPolicy>
161struct __select_backend;
162
163template <>
164struct __select_backend<std::execution::sequenced_policy> {
165 using type = __cpu_backend_tag;
166};
167
168# if _LIBCPP_STD_VER >= 20
169template <>
170struct __select_backend<std::execution::unsequenced_policy> {
171 using type = __cpu_backend_tag;
172};
173# endif
174
175# if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL) || defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD) || \
176 defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH)
177template <>
178struct __select_backend<std::execution::parallel_policy> {
179 using type = __cpu_backend_tag;
180};
181
182template <>
183struct __select_backend<std::execution::parallel_unsequenced_policy> {
184 using type = __cpu_backend_tag;
185};
186
187# else
188
189// ...New vendors can add parallel backends here...
190
191# error "Invalid choice of a PSTL parallel backend"
192# endif
193
194_LIBCPP_END_NAMESPACE_STD
195
196#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
197
198#endif // _LIBCPP___ALGORITHM_PSTL_BACKEND_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backend.h created+59
......@@ -0,0 +1,59 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
10#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
11
12#include <__config>
13
14/*
15
16 // _Functor takes a subrange for [__first, __last) that should be executed in serial
17 template <class _RandomAccessIterator, class _Functor>
18 void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func);
19
20 template <class _Iterator, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduction>
21 _Tp __parallel_transform_reduce(_Iterator __first, _Iterator __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduction);
22
23 // Cancel the execution of other jobs - they aren't needed anymore
24 void __cancel_execution();
25
26 template <class _RandomAccessIterator1,
27 class _RandomAccessIterator2,
28 class _RandomAccessIterator3,
29 class _Compare,
30 class _LeafMerge>
31 void __parallel_merge(
32 _RandomAccessIterator1 __first1,
33 _RandomAccessIterator1 __last1,
34 _RandomAccessIterator2 __first2,
35 _RandomAccessIterator2 __last2,
36 _RandomAccessIterator3 __outit,
37 _Compare __comp,
38 _LeafMerge __leaf_merge);
39
40 template <class _RandomAccessIterator, class _Comp, class _LeafSort>
41 void __parallel_stable_sort(_RandomAccessIterator __first,
42 _RandomAccessIterator __last,
43 _Comp __comp,
44 _LeafSort __leaf_sort);
45
46 TODO: Document the parallel backend
47*/
48
49#include <__algorithm/pstl_backends/cpu_backends/any_of.h>
50#include <__algorithm/pstl_backends/cpu_backends/backend.h>
51#include <__algorithm/pstl_backends/cpu_backends/fill.h>
52#include <__algorithm/pstl_backends/cpu_backends/find_if.h>
53#include <__algorithm/pstl_backends/cpu_backends/for_each.h>
54#include <__algorithm/pstl_backends/cpu_backends/merge.h>
55#include <__algorithm/pstl_backends/cpu_backends/stable_sort.h>
56#include <__algorithm/pstl_backends/cpu_backends/transform.h>
57#include <__algorithm/pstl_backends/cpu_backends/transform_reduce.h>
58
59#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/any_of.h created+90
......@@ -0,0 +1,90 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
10#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
11
12#include <__algorithm/any_of.h>
13#include <__algorithm/find_if.h>
14#include <__algorithm/pstl_backends/cpu_backends/backend.h>
15#include <__atomic/atomic.h>
16#include <__atomic/memory_order.h>
17#include <__config>
18#include <__functional/operations.h>
19#include <__iterator/iterator_traits.h>
20#include <__type_traits/is_execution_policy.h>
21#include <__utility/pair.h>
22#include <__utility/terminate_on_exception.h>
23#include <cstdint>
24
25#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29template <class _Index, class _Brick>
30_LIBCPP_HIDE_FROM_ABI bool __parallel_or(_Index __first, _Index __last, _Brick __f) {
31 std::atomic<bool> __found(false);
32 __par_backend::__parallel_for(__first, __last, [__f, &__found](_Index __i, _Index __j) {
33 if (!__found.load(std::memory_order_relaxed) && __f(__i, __j)) {
34 __found.store(true, std::memory_order_relaxed);
35 __par_backend::__cancel_execution();
36 }
37 });
38 return __found;
39}
40
41// TODO: check whether __simd_first() can be used here
42template <class _Index, class _DifferenceType, class _Pred>
43_LIBCPP_HIDE_FROM_ABI bool __simd_or(_Index __first, _DifferenceType __n, _Pred __pred) noexcept {
44 _DifferenceType __block_size = 4 < __n ? 4 : __n;
45 const _Index __last = __first + __n;
46 while (__last != __first) {
47 int32_t __flag = 1;
48 _PSTL_PRAGMA_SIMD_REDUCTION(& : __flag)
49 for (_DifferenceType __i = 0; __i < __block_size; ++__i)
50 if (__pred(*(__first + __i)))
51 __flag = 0;
52 if (!__flag)
53 return true;
54
55 __first += __block_size;
56 if (__last - __first >= __block_size << 1) {
57 // Double the block _Size. Any unnecessary iterations can be amortized against work done so far.
58 __block_size <<= 1;
59 } else {
60 __block_size = __last - __first;
61 }
62 }
63 return false;
64}
65
66template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
67_LIBCPP_HIDE_FROM_ABI bool
68__pstl_any_of(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
69 if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
70 __has_random_access_iterator_category<_ForwardIterator>::value) {
71 return std::__terminate_on_exception([&] {
72 return std::__parallel_or(
73 __first, __last, [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
74 return std::__pstl_any_of<__remove_parallel_policy_t<_ExecutionPolicy>>(
75 __cpu_backend_tag{}, __brick_first, __brick_last, __pred);
76 });
77 });
78 } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
79 __has_random_access_iterator_category<_ForwardIterator>::value) {
80 return std::__simd_or(__first, __last - __first, __pred);
81 } else {
82 return std::any_of(__first, __last, __pred);
83 }
84}
85
86_LIBCPP_END_NAMESPACE_STD
87
88#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
89
90#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h created+41
......@@ -0,0 +1,41 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
10#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
11
12#include <__config>
13#include <cstddef>
14
15#if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL)
16# include <__algorithm/pstl_backends/cpu_backends/serial.h>
17#elif defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD)
18# include <__algorithm/pstl_backends/cpu_backends/thread.h>
19#elif defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH)
20# include <__algorithm/pstl_backends/cpu_backends/libdispatch.h>
21#else
22# error "Invalid CPU backend choice"
23#endif
24
25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26# pragma GCC system_header
27#endif
28
29#if _LIBCPP_STD_VER >= 17
30
31_LIBCPP_BEGIN_NAMESPACE_STD
32
33struct __cpu_backend_tag {};
34
35inline constexpr size_t __lane_size = 64;
36
37_LIBCPP_END_NAMESPACE_STD
38
39#endif // _LIBCPP_STD_VER >= 17
40
41#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/fill.h created+60
......@@ -0,0 +1,60 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
10#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
11
12#include <__algorithm/fill.h>
13#include <__algorithm/pstl_backends/cpu_backends/backend.h>
14#include <__config>
15#include <__iterator/iterator_traits.h>
16#include <__type_traits/is_execution_policy.h>
17#include <__utility/terminate_on_exception.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Index, class _DifferenceType, class _Tp>
28_LIBCPP_HIDE_FROM_ABI _Index __simd_fill_n(_Index __first, _DifferenceType __n, const _Tp& __value) noexcept {
29 _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
30 _PSTL_PRAGMA_SIMD
31 for (_DifferenceType __i = 0; __i < __n; ++__i)
32 __first[__i] = __value;
33 return __first + __n;
34}
35
36template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
37_LIBCPP_HIDE_FROM_ABI void
38__pstl_fill(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
39 if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
40 __has_random_access_iterator_category<_ForwardIterator>::value) {
41 std::__terminate_on_exception([&] {
42 __par_backend::__parallel_for(
43 __first, __last, [&__value](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
44 std::__pstl_fill<__remove_parallel_policy_t<_ExecutionPolicy>>(
45 __cpu_backend_tag{}, __brick_first, __brick_last, __value);
46 });
47 });
48 } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
49 __has_random_access_iterator_category<_ForwardIterator>::value) {
50 std::__simd_fill_n(__first, __last - __first, __value);
51 } else {
52 std::fill(__first, __last, __value);
53 }
54}
55
56_LIBCPP_END_NAMESPACE_STD
57
58#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
59
60#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/find_if.h created+123
......@@ -0,0 +1,123 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
10#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
11
12#include <__algorithm/find_if.h>
13#include <__algorithm/pstl_backends/cpu_backends/backend.h>
14#include <__atomic/atomic.h>
15#include <__config>
16#include <__functional/operations.h>
17#include <__iterator/iterator_traits.h>
18#include <__type_traits/is_execution_policy.h>
19#include <__utility/pair.h>
20#include <__utility/terminate_on_exception.h>
21#include <cstddef>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24# pragma GCC system_header
25#endif
26
27#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31template <class _Index, class _Brick, class _Compare>
32_LIBCPP_HIDE_FROM_ABI _Index
33__parallel_find(_Index __first, _Index __last, _Brick __f, _Compare __comp, bool __b_first) {
34 typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType;
35 const _DifferenceType __n = __last - __first;
36 _DifferenceType __initial_dist = __b_first ? __n : -1;
37 std::atomic<_DifferenceType> __extremum(__initial_dist);
38 // TODO: find out what is better here: parallel_for or parallel_reduce
39 __par_backend::__parallel_for(__first, __last, [__comp, __f, __first, &__extremum](_Index __i, _Index __j) {
40 // See "Reducing Contention Through Priority Updates", PPoPP '13, for discussion of
41 // why using a shared variable scales fairly well in this situation.
42 if (__comp(__i - __first, __extremum)) {
43 _Index __res = __f(__i, __j);
44 // If not '__last' returned then we found what we want so put this to extremum
45 if (__res != __j) {
46 const _DifferenceType __k = __res - __first;
47 for (_DifferenceType __old = __extremum; __comp(__k, __old); __old = __extremum) {
48 __extremum.compare_exchange_weak(__old, __k);
49 }
50 }
51 }
52 });
53 return __extremum != __initial_dist ? __first + __extremum : __last;
54}
55
56template <class _Index, class _DifferenceType, class _Compare>
57_LIBCPP_HIDE_FROM_ABI _Index
58__simd_first(_Index __first, _DifferenceType __begin, _DifferenceType __end, _Compare __comp) noexcept {
59 // Experiments show good block sizes like this
60 const _DifferenceType __block_size = 8;
61 alignas(__lane_size) _DifferenceType __lane[__block_size] = {0};
62 while (__end - __begin >= __block_size) {
63 _DifferenceType __found = 0;
64 _PSTL_PRAGMA_SIMD_REDUCTION(| : __found) for (_DifferenceType __i = __begin; __i < __begin + __block_size; ++__i) {
65 const _DifferenceType __t = __comp(__first, __i);
66 __lane[__i - __begin] = __t;
67 __found |= __t;
68 }
69 if (__found) {
70 _DifferenceType __i;
71 // This will vectorize
72 for (__i = 0; __i < __block_size; ++__i) {
73 if (__lane[__i]) {
74 break;
75 }
76 }
77 return __first + __begin + __i;
78 }
79 __begin += __block_size;
80 }
81
82 // Keep remainder scalar
83 while (__begin != __end) {
84 if (__comp(__first, __begin)) {
85 return __first + __begin;
86 }
87 ++__begin;
88 }
89 return __first + __end;
90}
91
92template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
93_LIBCPP_HIDE_FROM_ABI _ForwardIterator
94__pstl_find_if(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
95 if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
96 __has_random_access_iterator_category<_ForwardIterator>::value) {
97 return std::__terminate_on_exception([&] {
98 return std::__parallel_find(
99 __first,
100 __last,
101 [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
102 return std::__pstl_find_if<__remove_parallel_policy_t<_ExecutionPolicy>>(
103 __cpu_backend_tag{}, __brick_first, __brick_last, __pred);
104 },
105 less<>{},
106 true);
107 });
108 } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
109 __has_random_access_iterator_category<_ForwardIterator>::value) {
110 using __diff_t = __iter_diff_t<_ForwardIterator>;
111 return std::__simd_first(__first, __diff_t(0), __last - __first, [&__pred](_ForwardIterator __iter, __diff_t __i) {
112 return __pred(__iter[__i]);
113 });
114 } else {
115 return std::find_if(__first, __last, __pred);
116 }
117}
118
119_LIBCPP_END_NAMESPACE_STD
120
121#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
122
123#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/for_each.h created+60
......@@ -0,0 +1,60 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
10#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
11
12#include <__algorithm/for_each.h>
13#include <__algorithm/pstl_backends/cpu_backends/backend.h>
14#include <__config>
15#include <__iterator/iterator_traits.h>
16#include <__type_traits/is_execution_policy.h>
17#include <__utility/terminate_on_exception.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Iterator, class _DifferenceType, class _Function>
28_LIBCPP_HIDE_FROM_ABI _Iterator __simd_walk_1(_Iterator __first, _DifferenceType __n, _Function __f) noexcept {
29 _PSTL_PRAGMA_SIMD
30 for (_DifferenceType __i = 0; __i < __n; ++__i)
31 __f(__first[__i]);
32
33 return __first + __n;
34}
35
36template <class _ExecutionPolicy, class _ForwardIterator, class _Functor>
37_LIBCPP_HIDE_FROM_ABI void
38__pstl_for_each(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Functor __func) {
39 if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
40 __has_random_access_iterator_category<_ForwardIterator>::value) {
41 std::__terminate_on_exception([&] {
42 std::__par_backend::__parallel_for(
43 __first, __last, [__func](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
44 std::__pstl_for_each<__remove_parallel_policy_t<_ExecutionPolicy>>(
45 __cpu_backend_tag{}, __brick_first, __brick_last, __func);
46 });
47 });
48 } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
49 __has_random_access_iterator_category<_ForwardIterator>::value) {
50 std::__simd_walk_1(__first, __last - __first, __func);
51 } else {
52 std::for_each(__first, __last, __func);
53 }
54}
55
56_LIBCPP_END_NAMESPACE_STD
57
58#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
59
60#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h created+241
......@@ -0,0 +1,241 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
10#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
11
12#include <__algorithm/lower_bound.h>
13#include <__algorithm/max.h>
14#include <__algorithm/upper_bound.h>
15#include <__atomic/atomic.h>
16#include <__config>
17#include <__exception/terminate.h>
18#include <__iterator/iterator_traits.h>
19#include <__iterator/move_iterator.h>
20#include <__memory/allocator.h>
21#include <__memory/construct_at.h>
22#include <__memory/unique_ptr.h>
23#include <__numeric/reduce.h>
24#include <__utility/exception_guard.h>
25#include <__utility/move.h>
26#include <__utility/pair.h>
27#include <__utility/terminate_on_exception.h>
28#include <cstddef>
29#include <new>
30
31_LIBCPP_PUSH_MACROS
32#include <__undef_macros>
33
34#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
35
36_LIBCPP_BEGIN_NAMESPACE_STD
37
38namespace __par_backend {
39inline namespace __libdispatch {
40
41// ::dispatch_apply is marked as __attribute__((nothrow)) because it doesn't let exceptions propagate, and neither do
42// we.
43// TODO: Do we want to add [[_Clang::__callback__(__func, __context, __)]]?
44_LIBCPP_EXPORTED_FROM_ABI void
45__dispatch_apply(size_t __chunk_count, void* __context, void (*__func)(void* __context, size_t __chunk)) noexcept;
46
47template <class _Func>
48_LIBCPP_HIDE_FROM_ABI void __dispatch_apply(size_t __chunk_count, _Func __func) noexcept {
49 __libdispatch::__dispatch_apply(__chunk_count, &__func, [](void* __context, size_t __chunk) {
50 (*static_cast<_Func*>(__context))(__chunk);
51 });
52}
53
54struct __chunk_partitions {
55 ptrdiff_t __chunk_count_; // includes the first chunk
56 ptrdiff_t __chunk_size_;
57 ptrdiff_t __first_chunk_size_;
58};
59
60[[__gnu__::__const__]] _LIBCPP_EXPORTED_FROM_ABI __chunk_partitions __partition_chunks(ptrdiff_t __size);
61
62template <class _RandomAccessIterator, class _Functor>
63_LIBCPP_HIDE_FROM_ABI void
64__parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func) {
65 auto __partitions = __libdispatch::__partition_chunks(__last - __first);
66
67 // Perform the chunked execution.
68 __libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) {
69 auto __this_chunk_size = __chunk == 0 ? __partitions.__first_chunk_size_ : __partitions.__chunk_size_;
70 auto __index =
71 __chunk == 0
72 ? 0
73 : (__chunk * __partitions.__chunk_size_) + (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
74 __func(__first + __index, __first + __index + __this_chunk_size);
75 });
76}
77
78template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIteratorOut>
79struct __merge_range {
80 __merge_range(_RandomAccessIterator1 __mid1, _RandomAccessIterator2 __mid2, _RandomAccessIteratorOut __result)
81 : __mid1_(__mid1), __mid2_(__mid2), __result_(__result) {}
82
83 _RandomAccessIterator1 __mid1_;
84 _RandomAccessIterator2 __mid2_;
85 _RandomAccessIteratorOut __result_;
86};
87
88template <typename _RandomAccessIterator1,
89 typename _RandomAccessIterator2,
90 typename _RandomAccessIterator3,
91 typename _Compare,
92 typename _LeafMerge>
93_LIBCPP_HIDE_FROM_ABI void __parallel_merge(
94 _RandomAccessIterator1 __first1,
95 _RandomAccessIterator1 __last1,
96 _RandomAccessIterator2 __first2,
97 _RandomAccessIterator2 __last2,
98 _RandomAccessIterator3 __result,
99 _Compare __comp,
100 _LeafMerge __leaf_merge) {
101 __chunk_partitions __partitions =
102 __libdispatch::__partition_chunks(std::max<ptrdiff_t>(__last1 - __first1, __last2 - __first2));
103
104 if (__partitions.__chunk_count_ == 0)
105 return;
106
107 if (__partitions.__chunk_count_ == 1) {
108 __leaf_merge(__first1, __last1, __first2, __last2, __result, __comp);
109 return;
110 }
111
112 using __merge_range_t = __merge_range<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3>;
113 auto const __n_ranges = __partitions.__chunk_count_ + 1;
114
115 // TODO: use __uninitialized_buffer
116 auto __destroy = [=](__merge_range_t* __ptr) {
117 std::destroy_n(__ptr, __n_ranges);
118 std::allocator<__merge_range_t>().deallocate(__ptr, __n_ranges);
119 };
120 unique_ptr<__merge_range_t[], decltype(__destroy)> __ranges(
121 std::allocator<__merge_range_t>().allocate(__n_ranges), __destroy);
122
123 // TODO: Improve the case where the smaller range is merged into just a few (or even one) chunks of the larger case
124 std::__terminate_on_exception([&] {
125 __merge_range_t* __r = __ranges.get();
126 std::__construct_at(__r++, __first1, __first2, __result);
127
128 bool __iterate_first_range = __last1 - __first1 > __last2 - __first2;
129
130 auto __compute_chunk = [&](size_t __chunk_size) -> __merge_range_t {
131 auto [__mid1, __mid2] = [&] {
132 if (__iterate_first_range) {
133 auto __m1 = __first1 + __chunk_size;
134 auto __m2 = std::lower_bound(__first2, __last2, __m1[-1], __comp);
135 return std::make_pair(__m1, __m2);
136 } else {
137 auto __m2 = __first2 + __chunk_size;
138 auto __m1 = std::lower_bound(__first1, __last1, __m2[-1], __comp);
139 return std::make_pair(__m1, __m2);
140 }
141 }();
142
143 __result += (__mid1 - __first1) + (__mid2 - __first2);
144 __first1 = __mid1;
145 __first2 = __mid2;
146 return {std::move(__mid1), std::move(__mid2), __result};
147 };
148
149 // handle first chunk
150 std::__construct_at(__r++, __compute_chunk(__partitions.__first_chunk_size_));
151
152 // handle 2 -> N - 1 chunks
153 for (ptrdiff_t __i = 0; __i != __partitions.__chunk_count_ - 2; ++__i)
154 std::__construct_at(__r++, __compute_chunk(__partitions.__chunk_size_));
155
156 // handle last chunk
157 std::__construct_at(__r, __last1, __last2, __result);
158
159 __libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __index) {
160 auto __first_iters = __ranges[__index];
161 auto __last_iters = __ranges[__index + 1];
162 __leaf_merge(
163 __first_iters.__mid1_,
164 __last_iters.__mid1_,
165 __first_iters.__mid2_,
166 __last_iters.__mid2_,
167 __first_iters.__result_,
168 __comp);
169 });
170 });
171}
172
173template <class _RandomAccessIterator, class _Transform, class _Value, class _Combiner, class _Reduction>
174_LIBCPP_HIDE_FROM_ABI _Value __parallel_transform_reduce(
175 _RandomAccessIterator __first,
176 _RandomAccessIterator __last,
177 _Transform __transform,
178 _Value __init,
179 _Combiner __combiner,
180 _Reduction __reduction) {
181 if (__first == __last)
182 return __init;
183
184 auto __partitions = __libdispatch::__partition_chunks(__last - __first);
185
186 auto __destroy = [__count = __partitions.__chunk_count_](_Value* __ptr) {
187 std::destroy_n(__ptr, __count);
188 std::allocator<_Value>().deallocate(__ptr, __count);
189 };
190
191 // TODO: use __uninitialized_buffer
192 // TODO: allocate one element per worker instead of one element per chunk
193 unique_ptr<_Value[], decltype(__destroy)> __values(
194 std::allocator<_Value>().allocate(__partitions.__chunk_count_), __destroy);
195
196 // __dispatch_apply is noexcept
197 __libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) {
198 auto __this_chunk_size = __chunk == 0 ? __partitions.__first_chunk_size_ : __partitions.__chunk_size_;
199 auto __index =
200 __chunk == 0
201 ? 0
202 : (__chunk * __partitions.__chunk_size_) + (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
203 if (__this_chunk_size != 1) {
204 std::__construct_at(
205 __values.get() + __chunk,
206 __reduction(__first + __index + 2,
207 __first + __index + __this_chunk_size,
208 __combiner(__transform(__first + __index), __transform(__first + __index + 1))));
209 } else {
210 std::__construct_at(__values.get() + __chunk, __transform(__first + __index));
211 }
212 });
213
214 return std::__terminate_on_exception([&] {
215 return std::reduce(
216 std::make_move_iterator(__values.get()),
217 std::make_move_iterator(__values.get() + __partitions.__chunk_count_),
218 std::move(__init),
219 __combiner);
220 });
221}
222
223// TODO: parallelize this
224template <class _RandomAccessIterator, class _Comp, class _LeafSort>
225_LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort(
226 _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp, _LeafSort __leaf_sort) {
227 __leaf_sort(__first, __last, __comp);
228}
229
230_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
231
232} // namespace __libdispatch
233} // namespace __par_backend
234
235_LIBCPP_END_NAMESPACE_STD
236
237#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
238
239_LIBCPP_POP_MACROS
240
241#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/merge.h created+79
......@@ -0,0 +1,79 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
10#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
11
12#include <__algorithm/merge.h>
13#include <__algorithm/pstl_backends/cpu_backends/backend.h>
14#include <__config>
15#include <__iterator/iterator_traits.h>
16#include <__type_traits/is_execution_policy.h>
17#include <__utility/move.h>
18#include <__utility/terminate_on_exception.h>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21# pragma GCC system_header
22#endif
23
24#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _ExecutionPolicy,
29 class _ForwardIterator1,
30 class _ForwardIterator2,
31 class _ForwardOutIterator,
32 class _Comp>
33_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_merge(
34 __cpu_backend_tag,
35 _ForwardIterator1 __first1,
36 _ForwardIterator1 __last1,
37 _ForwardIterator2 __first2,
38 _ForwardIterator2 __last2,
39 _ForwardOutIterator __result,
40 _Comp __comp) {
41 if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
42 __has_random_access_iterator_category<_ForwardIterator1>::value &&
43 __has_random_access_iterator_category<_ForwardIterator2>::value &&
44 __has_random_access_iterator_category<_ForwardOutIterator>::value) {
45 return std::__terminate_on_exception([&] {
46 __par_backend::__parallel_merge(
47 __first1,
48 __last1,
49 __first2,
50 __last2,
51 __result,
52 __comp,
53 [](_ForwardIterator1 __g_first1,
54 _ForwardIterator1 __g_last1,
55 _ForwardIterator2 __g_first2,
56 _ForwardIterator2 __g_last2,
57 _ForwardOutIterator __g_result,
58 _Comp __g_comp) {
59 return std::__pstl_merge<__remove_parallel_policy_t<_ExecutionPolicy>>(
60 __cpu_backend_tag{},
61 std::move(__g_first1),
62 std::move(__g_last1),
63 std::move(__g_first2),
64 std::move(__g_last2),
65 std::move(__g_result),
66 std::move(__g_comp));
67 });
68 return __result + (__last1 - __first1) + (__last2 - __first2);
69 });
70 } else {
71 return std::merge(__first1, __last1, __first2, __last2, __result, __comp);
72 }
73}
74
75_LIBCPP_END_NAMESPACE_STD
76
77#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
78
79#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/serial.h created+72
......@@ -0,0 +1,72 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
11#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
12
13#include <__config>
14#include <__utility/move.h>
15#include <cstddef>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18# pragma GCC system_header
19#endif
20
21#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25namespace __par_backend {
26inline namespace __serial_cpu_backend {
27
28template <class _RandomAccessIterator, class _Fp>
29_LIBCPP_HIDE_FROM_ABI void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) {
30 __f(__first, __last);
31}
32
33template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
34_LIBCPP_HIDE_FROM_ABI _Tp
35__parallel_transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) {
36 return __reduce(std::move(__first), std::move(__last), std::move(__init));
37}
38
39template <class _RandomAccessIterator, class _Compare, class _LeafSort>
40_LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort(
41 _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) {
42 __leaf_sort(__first, __last, __comp);
43}
44
45_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
46
47template <class _RandomAccessIterator1,
48 class _RandomAccessIterator2,
49 class _RandomAccessIterator3,
50 class _Compare,
51 class _LeafMerge>
52_LIBCPP_HIDE_FROM_ABI void __parallel_merge(
53 _RandomAccessIterator1 __first1,
54 _RandomAccessIterator1 __last1,
55 _RandomAccessIterator2 __first2,
56 _RandomAccessIterator2 __last2,
57 _RandomAccessIterator3 __outit,
58 _Compare __comp,
59 _LeafMerge __leaf_merge) {
60 __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
61}
62
63// TODO: Complete this list
64
65} // namespace __serial_cpu_backend
66} // namespace __par_backend
67
68_LIBCPP_END_NAMESPACE_STD
69
70#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17
71
72#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/stable_sort.h created+45
......@@ -0,0 +1,45 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
10#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
11
12#include <__algorithm/pstl_backends/cpu_backends/backend.h>
13#include <__algorithm/stable_sort.h>
14#include <__config>
15#include <__type_traits/is_execution_policy.h>
16#include <__utility/terminate_on_exception.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19# pragma GCC system_header
20#endif
21
22#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp>
27_LIBCPP_HIDE_FROM_ABI void
28__pstl_stable_sort(__cpu_backend_tag, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
29 if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy>) {
30 std::__terminate_on_exception([&] {
31 __par_backend::__parallel_stable_sort(
32 __first, __last, __comp, [](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) {
33 std::stable_sort(__g_first, __g_last, __g_comp);
34 });
35 });
36 } else {
37 std::stable_sort(__first, __last, __comp);
38 }
39}
40
41_LIBCPP_END_NAMESPACE_STD
42
43#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
44
45#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/thread.h created+78
......@@ -0,0 +1,78 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
10#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
11
12#include <__assert>
13#include <__config>
14#include <__utility/move.h>
15#include <cstddef>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18# pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
25
26// This backend implementation is for testing purposes only and not meant for production use. This will be replaced
27// by a proper implementation once the PSTL implementation is somewhat stable.
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31namespace __par_backend {
32inline namespace __thread_cpu_backend {
33
34template <class _RandomAccessIterator, class _Fp>
35_LIBCPP_HIDE_FROM_ABI void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) {
36 __f(__first, __last);
37}
38
39template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
40_LIBCPP_HIDE_FROM_ABI _Tp
41__parallel_transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) {
42 return __reduce(std::move(__first), std::move(__last), std::move(__init));
43}
44
45template <class _RandomAccessIterator, class _Compare, class _LeafSort>
46_LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort(
47 _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) {
48 __leaf_sort(__first, __last, __comp);
49}
50
51_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
52
53template <class _RandomAccessIterator1,
54 class _RandomAccessIterator2,
55 class _RandomAccessIterator3,
56 class _Compare,
57 class _LeafMerge>
58_LIBCPP_HIDE_FROM_ABI void __parallel_merge(
59 _RandomAccessIterator1 __first1,
60 _RandomAccessIterator1 __last1,
61 _RandomAccessIterator2 __first2,
62 _RandomAccessIterator2 __last2,
63 _RandomAccessIterator3 __outit,
64 _Compare __comp,
65 _LeafMerge __leaf_merge) {
66 __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
67}
68
69} // namespace __thread_cpu_backend
70} // namespace __par_backend
71
72_LIBCPP_END_NAMESPACE_STD
73
74#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17
75
76_LIBCPP_POP_MACROS
77
78#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform.h created+132
......@@ -0,0 +1,132 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
10#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
11
12#include <__algorithm/pstl_backends/cpu_backends/backend.h>
13#include <__algorithm/transform.h>
14#include <__config>
15#include <__iterator/iterator_traits.h>
16#include <__type_traits/enable_if.h>
17#include <__type_traits/is_execution_policy.h>
18#include <__type_traits/remove_cvref.h>
19#include <__utility/terminate_on_exception.h>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22# pragma GCC system_header
23#endif
24
25#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Function>
30_LIBCPP_HIDE_FROM_ABI _Iterator2
31__simd_walk_2(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Function __f) noexcept {
32 _PSTL_PRAGMA_SIMD
33 for (_DifferenceType __i = 0; __i < __n; ++__i)
34 __f(__first1[__i], __first2[__i]);
35 return __first2 + __n;
36}
37
38template <class _ExecutionPolicy, class _ForwardIterator, class _ForwardOutIterator, class _UnaryOperation>
39_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform(
40 __cpu_backend_tag,
41 _ForwardIterator __first,
42 _ForwardIterator __last,
43 _ForwardOutIterator __result,
44 _UnaryOperation __op) {
45 if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
46 __has_random_access_iterator_category<_ForwardIterator>::value &&
47 __has_random_access_iterator_category<_ForwardOutIterator>::value) {
48 std::__terminate_on_exception([&] {
49 std::__par_backend::__parallel_for(
50 __first, __last, [__op, __first, __result](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
51 return std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>(
52 __cpu_backend_tag{}, __brick_first, __brick_last, __result + (__brick_first - __first), __op);
53 });
54 });
55 return __result + (__last - __first);
56 } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
57 __has_random_access_iterator_category<_ForwardIterator>::value &&
58 __has_random_access_iterator_category<_ForwardOutIterator>::value) {
59 return std::__simd_walk_2(
60 __first,
61 __last - __first,
62 __result,
63 [&](__iter_reference<_ForwardIterator> __in_value, __iter_reference<_ForwardOutIterator> __out_value) {
64 __out_value = __op(__in_value);
65 });
66 } else {
67 return std::transform(__first, __last, __result, __op);
68 }
69}
70
71template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Iterator3, class _Function>
72_LIBCPP_HIDE_FROM_ABI _Iterator3 __simd_walk_3(
73 _Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Iterator3 __first3, _Function __f) noexcept {
74 _PSTL_PRAGMA_SIMD
75 for (_DifferenceType __i = 0; __i < __n; ++__i)
76 __f(__first1[__i], __first2[__i], __first3[__i]);
77 return __first3 + __n;
78}
79template <class _ExecutionPolicy,
80 class _ForwardIterator1,
81 class _ForwardIterator2,
82 class _ForwardOutIterator,
83 class _BinaryOperation,
84 enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
85_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform(
86 __cpu_backend_tag,
87 _ForwardIterator1 __first1,
88 _ForwardIterator1 __last1,
89 _ForwardIterator2 __first2,
90 _ForwardOutIterator __result,
91 _BinaryOperation __op) {
92 if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
93 __has_random_access_iterator_category<_ForwardIterator1>::value &&
94 __has_random_access_iterator_category<_ForwardIterator2>::value &&
95 __has_random_access_iterator_category<_ForwardOutIterator>::value) {
96 std::__terminate_on_exception([&] {
97 std::__par_backend::__parallel_for(
98 __first1,
99 __last1,
100 [__op, __first1, __first2, __result](_ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last) {
101 return std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>(
102 __cpu_backend_tag{},
103 __brick_first,
104 __brick_last,
105 __first2 + (__brick_first - __first1),
106 __result + (__brick_first - __first1),
107 __op);
108 });
109 });
110 return __result + (__last1 - __first1);
111 } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
112 __has_random_access_iterator_category<_ForwardIterator1>::value &&
113 __has_random_access_iterator_category<_ForwardIterator2>::value &&
114 __has_random_access_iterator_category<_ForwardOutIterator>::value) {
115 return std::__simd_walk_3(
116 __first1,
117 __last1 - __first1,
118 __first2,
119 __result,
120 [&](__iter_reference<_ForwardIterator1> __in1,
121 __iter_reference<_ForwardIterator2> __in2,
122 __iter_reference<_ForwardOutIterator> __out_value) { __out_value = __op(__in1, __in2); });
123 } else {
124 return std::transform(__first1, __last1, __first2, __result, __op);
125 }
126}
127
128_LIBCPP_END_NAMESPACE_STD
129
130#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
131
132#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h created+194
......@@ -0,0 +1,194 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
10#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
11
12#include <__algorithm/pstl_backends/cpu_backends/backend.h>
13#include <__config>
14#include <__iterator/iterator_traits.h>
15#include <__numeric/transform_reduce.h>
16#include <__type_traits/is_arithmetic.h>
17#include <__type_traits/is_execution_policy.h>
18#include <__type_traits/operation_traits.h>
19#include <__utility/move.h>
20#include <__utility/terminate_on_exception.h>
21#include <new>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24# pragma GCC system_header
25#endif
26
27#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31template <
32 typename _DifferenceType,
33 typename _Tp,
34 typename _BinaryOperation,
35 typename _UnaryOperation,
36 __enable_if_t<__is_trivial_plus_operation<_BinaryOperation, _Tp, _Tp>::value && is_arithmetic_v<_Tp>, int> = 0>
37_LIBCPP_HIDE_FROM_ABI _Tp
38__simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _UnaryOperation __f) noexcept {
39 _PSTL_PRAGMA_SIMD_REDUCTION(+ : __init)
40 for (_DifferenceType __i = 0; __i < __n; ++__i)
41 __init += __f(__i);
42 return __init;
43}
44
45template <
46 typename _Size,
47 typename _Tp,
48 typename _BinaryOperation,
49 typename _UnaryOperation,
50 __enable_if_t<!(__is_trivial_plus_operation<_BinaryOperation, _Tp, _Tp>::value && is_arithmetic_v<_Tp>), int> = 0>
51_LIBCPP_HIDE_FROM_ABI _Tp
52__simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __f) noexcept {
53 const _Size __block_size = __lane_size / sizeof(_Tp);
54 if (__n > 2 * __block_size && __block_size > 1) {
55 alignas(__lane_size) char __lane_buffer[__lane_size];
56 _Tp* __lane = reinterpret_cast<_Tp*>(__lane_buffer);
57
58 // initializer
59 _PSTL_PRAGMA_SIMD
60 for (_Size __i = 0; __i < __block_size; ++__i) {
61 ::new (__lane + __i) _Tp(__binary_op(__f(__i), __f(__block_size + __i)));
62 }
63 // main loop
64 _Size __i = 2 * __block_size;
65 const _Size __last_iteration = __block_size * (__n / __block_size);
66 for (; __i < __last_iteration; __i += __block_size) {
67 _PSTL_PRAGMA_SIMD
68 for (_Size __j = 0; __j < __block_size; ++__j) {
69 __lane[__j] = __binary_op(std::move(__lane[__j]), __f(__i + __j));
70 }
71 }
72 // remainder
73 _PSTL_PRAGMA_SIMD
74 for (_Size __j = 0; __j < __n - __last_iteration; ++__j) {
75 __lane[__j] = __binary_op(std::move(__lane[__j]), __f(__last_iteration + __j));
76 }
77 // combiner
78 for (_Size __j = 0; __j < __block_size; ++__j) {
79 __init = __binary_op(std::move(__init), std::move(__lane[__j]));
80 }
81 // destroyer
82 _PSTL_PRAGMA_SIMD
83 for (_Size __j = 0; __j < __block_size; ++__j) {
84 __lane[__j].~_Tp();
85 }
86 } else {
87 for (_Size __i = 0; __i < __n; ++__i) {
88 __init = __binary_op(std::move(__init), __f(__i));
89 }
90 }
91 return __init;
92}
93
94template <class _ExecutionPolicy,
95 class _ForwardIterator1,
96 class _ForwardIterator2,
97 class _Tp,
98 class _BinaryOperation1,
99 class _BinaryOperation2>
100_LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce(
101 __cpu_backend_tag,
102 _ForwardIterator1 __first1,
103 _ForwardIterator1 __last1,
104 _ForwardIterator2 __first2,
105 _Tp __init,
106 _BinaryOperation1 __reduce,
107 _BinaryOperation2 __transform) {
108 if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
109 __has_random_access_iterator_category<_ForwardIterator1>::value &&
110 __has_random_access_iterator_category<_ForwardIterator2>::value) {
111 return std::__terminate_on_exception([&] {
112 return __par_backend::__parallel_transform_reduce(
113 __first1,
114 std::move(__last1),
115 [__first1, __first2, __transform](_ForwardIterator1 __iter) {
116 return __transform(*__iter, *(__first2 + (__iter - __first1)));
117 },
118 std::move(__init),
119 std::move(__reduce),
120 [__first1, __first2, __reduce, __transform](
121 _ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last, _Tp __brick_init) {
122 return std::__pstl_transform_reduce<__remove_parallel_policy_t<_ExecutionPolicy>>(
123 __cpu_backend_tag{},
124 __brick_first,
125 std::move(__brick_last),
126 __first2 + (__brick_first - __first1),
127 std::move(__brick_init),
128 std::move(__reduce),
129 std::move(__transform));
130 });
131 });
132 } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
133 __has_random_access_iterator_category<_ForwardIterator1>::value &&
134 __has_random_access_iterator_category<_ForwardIterator2>::value) {
135 return std::__simd_transform_reduce(
136 __last1 - __first1, std::move(__init), std::move(__reduce), [&](__iter_diff_t<_ForwardIterator1> __i) {
137 return __transform(__first1[__i], __first2[__i]);
138 });
139 } else {
140 return std::transform_reduce(
141 std::move(__first1),
142 std::move(__last1),
143 std::move(__first2),
144 std::move(__init),
145 std::move(__reduce),
146 std::move(__transform));
147 }
148}
149
150template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
151_LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce(
152 __cpu_backend_tag,
153 _ForwardIterator __first,
154 _ForwardIterator __last,
155 _Tp __init,
156 _BinaryOperation __reduce,
157 _UnaryOperation __transform) {
158 if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
159 __has_random_access_iterator_category<_ForwardIterator>::value) {
160 return std::__terminate_on_exception([&] {
161 return __par_backend::__parallel_transform_reduce(
162 std::move(__first),
163 std::move(__last),
164 [__transform](_ForwardIterator __iter) { return __transform(*__iter); },
165 std::move(__init),
166 __reduce,
167 [__transform, __reduce](auto __brick_first, auto __brick_last, _Tp __brick_init) {
168 return std::__pstl_transform_reduce<__remove_parallel_policy_t<_ExecutionPolicy>>(
169 __cpu_backend_tag{},
170 std::move(__brick_first),
171 std::move(__brick_last),
172 std::move(__brick_init),
173 std::move(__reduce),
174 std::move(__transform));
175 });
176 });
177 } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
178 __has_random_access_iterator_category<_ForwardIterator>::value) {
179 return std::__simd_transform_reduce(
180 __last - __first,
181 std::move(__init),
182 std::move(__reduce),
183 [=, &__transform](__iter_diff_t<_ForwardIterator> __i) { return __transform(__first[__i]); });
184 } else {
185 return std::transform_reduce(
186 std::move(__first), std::move(__last), std::move(__init), std::move(__reduce), std::move(__transform));
187 }
188}
189
190_LIBCPP_END_NAMESPACE_STD
191
192#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
193
194#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
lib/libcxx/include/__algorithm/pstl_copy.h created+59
......@@ -0,0 +1,59 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_COPY_H
10#define _LIBCPP___ALGORITHM_PSTL_COPY_H
11
12#include <__algorithm/copy_n.h>
13#include <__algorithm/pstl_transform.h>
14#include <__config>
15#include <__functional/identity.h>
16#include <__iterator/iterator_traits.h>
17#include <__type_traits/enable_if.h>
18#include <__type_traits/is_constant_evaluated.h>
19#include <__type_traits/is_execution_policy.h>
20#include <__type_traits/is_trivially_copyable.h>
21#include <__type_traits/remove_cvref.h>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24# pragma GCC system_header
25#endif
26
27#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31// TODO: Use the std::copy/move shenanigans to forward to std::memmove
32
33template <class _ExecutionPolicy,
34 class _ForwardIterator,
35 class _ForwardOutIterator,
36 enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
37_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
38copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) {
39 return std::transform(__policy, __first, __last, __result, __identity());
40}
41
42template <class _ExecutionPolicy,
43 class _ForwardIterator,
44 class _ForwardOutIterator,
45 class _Size,
46 enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
47_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
48copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __result) {
49 if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value)
50 return std::copy(__policy, __first, __first + __n, __result);
51 else
52 return std::copy_n(__first, __n, __result);
53}
54
55_LIBCPP_END_NAMESPACE_STD
56
57#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
58
59#endif // _LIBCPP___ALGORITHM_PSTL_COPY_H
lib/libcxx/include/__algorithm/pstl_count.h created+89
......@@ -0,0 +1,89 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_COUNT_H
10#define _LIBCPP___ALGORITHM_PSTL_COUNT_H
11
12#include <__algorithm/count.h>
13#include <__algorithm/for_each.h>
14#include <__algorithm/pstl_backend.h>
15#include <__algorithm/pstl_for_each.h>
16#include <__algorithm/pstl_frontend_dispatch.h>
17#include <__atomic/atomic.h>
18#include <__config>
19#include <__functional/operations.h>
20#include <__iterator/iterator_traits.h>
21#include <__numeric/pstl_transform_reduce.h>
22#include <__type_traits/enable_if.h>
23#include <__type_traits/is_execution_policy.h>
24#include <__type_traits/remove_cvref.h>
25#include <__utility/move.h>
26#include <__utility/terminate_on_exception.h>
27
28#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
29# pragma GCC system_header
30#endif
31
32#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
33
34_LIBCPP_BEGIN_NAMESPACE_STD
35
36template <class>
37void __pstl_count_if(); // declaration needed for the frontend dispatch below
38
39template <class _ExecutionPolicy,
40 class _ForwardIterator,
41 class _Predicate,
42 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
43 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
44_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
45count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
46 using __diff_t = __iter_diff_t<_ForwardIterator>;
47 return std::__pstl_frontend_dispatch(
48 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count_if),
49 [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
50 return std::transform_reduce(
51 __policy,
52 std::move(__g_first),
53 std::move(__g_last),
54 __diff_t(),
55 std::plus{},
56 [&](__iter_reference<_ForwardIterator> __element) -> bool { return __g_pred(__element); });
57 },
58 std::move(__first),
59 std::move(__last),
60 std::move(__pred));
61}
62
63template <class>
64void __pstl_count(); // declaration needed for the frontend dispatch below
65
66template <class _ExecutionPolicy,
67 class _ForwardIterator,
68 class _Tp,
69 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
70 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
71_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
72count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
73 return std::__pstl_frontend_dispatch(
74 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count),
75 [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
76 return std::count_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __v) {
77 return __v == __g_value;
78 });
79 },
80 std::move(__first),
81 std::move(__last),
82 __value);
83}
84
85_LIBCPP_END_NAMESPACE_STD
86
87#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
88
89#endif // _LIBCPP___ALGORITHM_PSTL_COUNT_H
lib/libcxx/include/__algorithm/pstl_fill.h created+84
......@@ -0,0 +1,84 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_FILL_H
10#define _LIBCPP___ALGORITHM_PSTL_FILL_H
11
12#include <__algorithm/fill_n.h>
13#include <__algorithm/pstl_for_each.h>
14#include <__algorithm/pstl_frontend_dispatch.h>
15#include <__config>
16#include <__iterator/cpp17_iterator_concepts.h>
17#include <__iterator/iterator_traits.h>
18#include <__type_traits/enable_if.h>
19#include <__type_traits/is_execution_policy.h>
20#include <__type_traits/remove_cvref.h>
21#include <__utility/move.h>
22#include <__utility/terminate_on_exception.h>
23
24#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25# pragma GCC system_header
26#endif
27
28#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
29
30_LIBCPP_BEGIN_NAMESPACE_STD
31
32template <class>
33void __pstl_fill(); // declaration needed for the frontend dispatch below
34
35template <class _ExecutionPolicy,
36 class _ForwardIterator,
37 class _Tp,
38 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
39 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
40_LIBCPP_HIDE_FROM_ABI void
41fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
42 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
43 std::__pstl_frontend_dispatch(
44 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill),
45 [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
46 std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
47 __element = __g_value;
48 });
49 },
50 std::move(__first),
51 std::move(__last),
52 __value);
53}
54
55template <class>
56void __pstl_fill_n(); // declaration needed for the frontend dispatch below
57
58template <class _ExecutionPolicy,
59 class _ForwardIterator,
60 class _SizeT,
61 class _Tp,
62 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
63 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
64_LIBCPP_HIDE_FROM_ABI void
65fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _SizeT __n, const _Tp& __value) {
66 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
67 std::__pstl_frontend_dispatch(
68 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill_n),
69 [&](_ForwardIterator __g_first, _SizeT __g_n, const _Tp& __g_value) {
70 if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value)
71 std::fill(__policy, __g_first, __g_first + __g_n, __g_value);
72 else
73 std::fill_n(__g_first, __g_n, __g_value);
74 },
75 std::move(__first),
76 __n,
77 __value);
78}
79
80_LIBCPP_END_NAMESPACE_STD
81
82#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
83
84#endif // _LIBCPP___ALGORITHM_PSTL_FILL_H
lib/libcxx/include/__algorithm/pstl_find.h created+95
......@@ -0,0 +1,95 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_FIND_H
10#define _LIBCPP___ALGORITHM_PSTL_FIND_H
11
12#include <__algorithm/comp.h>
13#include <__algorithm/find.h>
14#include <__algorithm/pstl_backend.h>
15#include <__algorithm/pstl_frontend_dispatch.h>
16#include <__config>
17#include <__iterator/cpp17_iterator_concepts.h>
18#include <__iterator/iterator_traits.h>
19#include <__type_traits/enable_if.h>
20#include <__type_traits/is_execution_policy.h>
21#include <__type_traits/remove_cvref.h>
22#include <__utility/move.h>
23#include <__utility/terminate_on_exception.h>
24
25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26# pragma GCC system_header
27#endif
28
29#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
30
31_LIBCPP_BEGIN_NAMESPACE_STD
32
33template <class _ExecutionPolicy,
34 class _ForwardIterator,
35 class _Predicate,
36 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
37 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
38_LIBCPP_HIDE_FROM_ABI _ForwardIterator
39find_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
40 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
41 using _Backend = typename __select_backend<_RawPolicy>::type;
42 return std::__pstl_find_if<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__pred));
43}
44
45template <class>
46void __pstl_find_if_not();
47
48template <class _ExecutionPolicy,
49 class _ForwardIterator,
50 class _Predicate,
51 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
52 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
53_LIBCPP_HIDE_FROM_ABI _ForwardIterator
54find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
55 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
56 return std::__pstl_frontend_dispatch(
57 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find_if_not),
58 [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
59 return std::find_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) {
60 return !__g_pred(__value);
61 });
62 },
63 std::move(__first),
64 std::move(__last),
65 std::move(__pred));
66}
67
68template <class>
69void __pstl_find();
70
71template <class _ExecutionPolicy,
72 class _ForwardIterator,
73 class _Tp,
74 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
75 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
76_LIBCPP_HIDE_FROM_ABI _ForwardIterator
77find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
78 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
79 return std::__pstl_frontend_dispatch(
80 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find),
81 [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
82 return std::find_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
83 return __element == __g_value;
84 });
85 },
86 std::move(__first),
87 std::move(__last),
88 __value);
89}
90
91_LIBCPP_END_NAMESPACE_STD
92
93#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
94
95#endif // _LIBCPP___ALGORITHM_PSTL_FIND_H
lib/libcxx/include/__algorithm/pstl_for_each.h created+76
......@@ -0,0 +1,76 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
10#define _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
11
12#include <__algorithm/for_each.h>
13#include <__algorithm/for_each_n.h>
14#include <__algorithm/pstl_backend.h>
15#include <__algorithm/pstl_frontend_dispatch.h>
16#include <__config>
17#include <__iterator/cpp17_iterator_concepts.h>
18#include <__iterator/iterator_traits.h>
19#include <__type_traits/enable_if.h>
20#include <__type_traits/is_execution_policy.h>
21#include <__type_traits/remove_cvref.h>
22#include <__type_traits/void_t.h>
23#include <__utility/move.h>
24#include <__utility/terminate_on_exception.h>
25
26#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27# pragma GCC system_header
28#endif
29
30#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
31
32_LIBCPP_BEGIN_NAMESPACE_STD
33
34template <class _ExecutionPolicy,
35 class _ForwardIterator,
36 class _Function,
37 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
38 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
39_LIBCPP_HIDE_FROM_ABI void
40for_each(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __func) {
41 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
42 using _Backend = typename __select_backend<_RawPolicy>::type;
43 std::__pstl_for_each<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__func));
44}
45
46template <class>
47void __pstl_for_each_n(); // declaration needed for the frontend dispatch below
48
49template <class _ExecutionPolicy,
50 class _ForwardIterator,
51 class _Size,
52 class _Function,
53 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
54 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
55_LIBCPP_HIDE_FROM_ABI void
56for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) {
57 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
58 return std::__pstl_frontend_dispatch(
59 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_for_each_n),
60 [&](_ForwardIterator __g_first, _Size __g_size, _Function __g_func) {
61 if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
62 std::for_each(__policy, std::move(__g_first), __g_first + __g_size, std::move(__g_func));
63 } else {
64 std::for_each_n(std::move(__g_first), __g_size, std::move(__g_func));
65 }
66 },
67 __first,
68 __size,
69 std::move(__func));
70}
71
72_LIBCPP_END_NAMESPACE_STD
73
74#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
75
76#endif // _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
lib/libcxx/include/__algorithm/pstl_frontend_dispatch.h created+45
......@@ -0,0 +1,45 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH
10#define _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH
11
12#include <__config>
13#include <__type_traits/is_callable.h>
14#include <__utility/forward.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20#if _LIBCPP_STD_VER >= 17
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24# define _LIBCPP_PSTL_CUSTOMIZATION_POINT(name) \
25 [](auto&&... __args) -> decltype(std::name<_RawPolicy>(typename __select_backend<_RawPolicy>::type{}, \
26 std::forward<decltype(__args)>(__args)...)) { \
27 return std::name<_RawPolicy>( \
28 typename __select_backend<_RawPolicy>::type{}, std::forward<decltype(__args)>(__args)...); \
29 }
30
31template <class _SpecializedImpl, class _GenericImpl, class... _Args>
32_LIBCPP_HIDE_FROM_ABI decltype(auto)
33__pstl_frontend_dispatch(_SpecializedImpl __specialized_impl, _GenericImpl __generic_impl, _Args&&... __args) {
34 if constexpr (__is_callable<_SpecializedImpl, _Args...>::value) {
35 return __specialized_impl(std::forward<_Args>(__args)...);
36 } else {
37 return __generic_impl(std::forward<_Args>(__args)...);
38 }
39}
40
41_LIBCPP_END_NAMESPACE_STD
42
43#endif // _LIBCPP_STD_VER >= 17
44
45#endif // _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH
lib/libcxx/include/__algorithm/pstl_generate.h created+82
......@@ -0,0 +1,82 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_GENERATE_H
10#define _LIBCPP___ALGORITHM_PSTL_GENERATE_H
11
12#include <__algorithm/pstl_backend.h>
13#include <__algorithm/pstl_for_each.h>
14#include <__algorithm/pstl_frontend_dispatch.h>
15#include <__config>
16#include <__iterator/cpp17_iterator_concepts.h>
17#include <__type_traits/enable_if.h>
18#include <__type_traits/is_execution_policy.h>
19#include <__type_traits/remove_cvref.h>
20#include <__utility/move.h>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23# pragma GCC system_header
24#endif
25
26#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30template <class>
31void __pstl_generate();
32
33template <class _ExecutionPolicy,
34 class _ForwardIterator,
35 class _Generator,
36 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
37 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
38_LIBCPP_HIDE_FROM_ABI void
39generate(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
40 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
41 std::__pstl_frontend_dispatch(
42 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate),
43 [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Generator __g_gen) {
44 std::for_each(
45 __policy, std::move(__g_first), std::move(__g_last), [&](__iter_reference<_ForwardIterator> __element) {
46 __element = __g_gen();
47 });
48 },
49 std::move(__first),
50 std::move(__last),
51 std::move(__gen));
52}
53
54template <class>
55void __pstl_generate_n();
56
57template <class _ExecutionPolicy,
58 class _ForwardIterator,
59 class _Size,
60 class _Generator,
61 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
62 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
63_LIBCPP_HIDE_FROM_ABI void
64generate_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Generator __gen) {
65 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
66 std::__pstl_frontend_dispatch(
67 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate_n),
68 [&__policy](_ForwardIterator __g_first, _Size __g_n, _Generator __g_gen) {
69 std::for_each_n(__policy, std::move(__g_first), __g_n, [&](__iter_reference<_ForwardIterator> __element) {
70 __element = __g_gen();
71 });
72 },
73 std::move(__first),
74 __n,
75 std::move(__gen));
76}
77
78_LIBCPP_END_NAMESPACE_STD
79
80#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
81
82#endif // _LIBCPP___ALGORITHM_PSTL_GENERATE_H
lib/libcxx/include/__algorithm/pstl_is_partitioned.h created+58
......@@ -0,0 +1,58 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
10#define _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
11
12#include <__algorithm/pstl_any_all_none_of.h>
13#include <__algorithm/pstl_backend.h>
14#include <__algorithm/pstl_find.h>
15#include <__algorithm/pstl_frontend_dispatch.h>
16#include <__config>
17#include <__type_traits/enable_if.h>
18#include <__type_traits/is_execution_policy.h>
19#include <__type_traits/remove_cvref.h>
20#include <__utility/move.h>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23# pragma GCC system_header
24#endif
25
26#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30template <class>
31void __pstl_is_partitioned();
32
33template <class _ExecutionPolicy,
34 class _ForwardIterator,
35 class _Predicate,
36 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
37 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
38_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
39is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
40 return std::__pstl_frontend_dispatch(
41 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_is_partitioned),
42 [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
43 __g_first = std::find_if_not(__policy, __g_first, __g_last, __g_pred);
44 if (__g_first == __g_last)
45 return true;
46 ++__g_first;
47 return std::none_of(__policy, __g_first, __g_last, __g_pred);
48 },
49 std::move(__first),
50 std::move(__last),
51 std::move(__pred));
52}
53
54_LIBCPP_END_NAMESPACE_STD
55
56#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
57
58#endif // _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
lib/libcxx/include/__algorithm/pstl_merge.h created+58
......@@ -0,0 +1,58 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_MERGE_H
10#define _LIBCPP___ALGORITHM_PSTL_MERGE_H
11
12#include <__algorithm/pstl_backend.h>
13#include <__config>
14#include <__functional/operations.h>
15#include <__type_traits/enable_if.h>
16#include <__type_traits/is_execution_policy.h>
17#include <__type_traits/remove_cvref.h>
18#include <__utility/move.h>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21# pragma GCC system_header
22#endif
23
24#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _ExecutionPolicy,
29 class _ForwardIterator1,
30 class _ForwardIterator2,
31 class _ForwardOutIterator,
32 class _Comp = std::less<>,
33 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
34 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
35_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
36merge(_ExecutionPolicy&&,
37 _ForwardIterator1 __first1,
38 _ForwardIterator1 __last1,
39 _ForwardIterator2 __first2,
40 _ForwardIterator2 __last2,
41 _ForwardOutIterator __result,
42 _Comp __comp = {}) {
43 using _Backend = typename __select_backend<_RawPolicy>::type;
44 return std::__pstl_merge<_RawPolicy>(
45 _Backend{},
46 std::move(__first1),
47 std::move(__last1),
48 std::move(__first2),
49 std::move(__last2),
50 std::move(__result),
51 std::move(__comp));
52}
53
54_LIBCPP_END_NAMESPACE_STD
55
56#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
57
58#endif // _LIBCPP___ALGORITHM_PSTL_MERGE_H
lib/libcxx/include/__algorithm/pstl_replace.h created+167
......@@ -0,0 +1,167 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_REPLACE_H
10#define _LIBCPP___ALGORITHM_PSTL_REPLACE_H
11
12#include <__algorithm/pstl_backend.h>
13#include <__algorithm/pstl_for_each.h>
14#include <__algorithm/pstl_frontend_dispatch.h>
15#include <__algorithm/pstl_transform.h>
16#include <__config>
17#include <__iterator/iterator_traits.h>
18#include <__type_traits/enable_if.h>
19#include <__type_traits/remove_cvref.h>
20#include <__utility/move.h>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23# pragma GCC system_header
24#endif
25
26#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30template <class>
31void __pstl_replace_if();
32
33template <class _ExecutionPolicy,
34 class _ForwardIterator,
35 class _Pred,
36 class _Tp,
37 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
38 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
39_LIBCPP_HIDE_FROM_ABI void
40replace_if(_ExecutionPolicy&& __policy,
41 _ForwardIterator __first,
42 _ForwardIterator __last,
43 _Pred __pred,
44 const _Tp& __new_value) {
45 std::__pstl_frontend_dispatch(
46 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_if),
47 [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred, const _Tp& __g_new_value) {
48 std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
49 if (__g_pred(__element))
50 __element = __g_new_value;
51 });
52 },
53 std::move(__first),
54 std::move(__last),
55 std::move(__pred),
56 __new_value);
57}
58
59template <class>
60void __pstl_replace();
61
62template <class _ExecutionPolicy,
63 class _ForwardIterator,
64 class _Tp,
65 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
66 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
67_LIBCPP_HIDE_FROM_ABI void
68replace(_ExecutionPolicy&& __policy,
69 _ForwardIterator __first,
70 _ForwardIterator __last,
71 const _Tp& __old_value,
72 const _Tp& __new_value) {
73 std::__pstl_frontend_dispatch(
74 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace),
75 [&__policy](
76 _ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_old_value, const _Tp& __g_new_value) {
77 std::replace_if(
78 __policy,
79 std::move(__g_first),
80 std::move(__g_last),
81 [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; },
82 __g_new_value);
83 },
84 std::move(__first),
85 std::move(__last),
86 __old_value,
87 __new_value);
88}
89
90template <class>
91void __pstl_replace_copy_if();
92
93template <class _ExecutionPolicy,
94 class _ForwardIterator,
95 class _ForwardOutIterator,
96 class _Pred,
97 class _Tp,
98 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
99 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
100_LIBCPP_HIDE_FROM_ABI void replace_copy_if(
101 _ExecutionPolicy&& __policy,
102 _ForwardIterator __first,
103 _ForwardIterator __last,
104 _ForwardOutIterator __result,
105 _Pred __pred,
106 const _Tp& __new_value) {
107 std::__pstl_frontend_dispatch(
108 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy_if),
109 [&__policy](_ForwardIterator __g_first,
110 _ForwardIterator __g_last,
111 _ForwardOutIterator __g_result,
112 _Pred __g_pred,
113 const _Tp& __g_new_value) {
114 std::transform(__policy, __g_first, __g_last, __g_result, [&](__iter_reference<_ForwardIterator> __element) {
115 return __g_pred(__element) ? __g_new_value : __element;
116 });
117 },
118 std::move(__first),
119 std::move(__last),
120 std::move(__result),
121 std::move(__pred),
122 __new_value);
123}
124
125template <class>
126void __pstl_replace_copy();
127
128template <class _ExecutionPolicy,
129 class _ForwardIterator,
130 class _ForwardOutIterator,
131 class _Tp,
132 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
133 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
134_LIBCPP_HIDE_FROM_ABI void replace_copy(
135 _ExecutionPolicy&& __policy,
136 _ForwardIterator __first,
137 _ForwardIterator __last,
138 _ForwardOutIterator __result,
139 const _Tp& __old_value,
140 const _Tp& __new_value) {
141 std::__pstl_frontend_dispatch(
142 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy),
143 [&__policy](_ForwardIterator __g_first,
144 _ForwardIterator __g_last,
145 _ForwardOutIterator __g_result,
146 const _Tp& __g_old_value,
147 const _Tp& __g_new_value) {
148 return std::replace_copy_if(
149 __policy,
150 std::move(__g_first),
151 std::move(__g_last),
152 std::move(__g_result),
153 [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; },
154 __g_new_value);
155 },
156 std::move(__first),
157 std::move(__last),
158 std::move(__result),
159 __old_value,
160 __new_value);
161}
162
163_LIBCPP_END_NAMESPACE_STD
164
165#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
166
167#endif // _LIBCPP___ALGORITHM_PSTL_REPLACE_H
lib/libcxx/include/__algorithm/pstl_sort.h created+63
......@@ -0,0 +1,63 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_SORT_H
10#define _LIBCPP___ALGORITHM_PSTL_SORT_H
11
12#include <__algorithm/pstl_backend.h>
13#include <__algorithm/pstl_frontend_dispatch.h>
14#include <__algorithm/pstl_stable_sort.h>
15#include <__config>
16#include <__functional/operations.h>
17#include <__type_traits/is_execution_policy.h>
18#include <__type_traits/remove_cvref.h>
19#include <__utility/forward.h>
20#include <__utility/move.h>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23# pragma GCC system_header
24#endif
25
26#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30template <class>
31void __pstl_sort();
32
33template <class _ExecutionPolicy,
34 class _RandomAccessIterator,
35 class _Comp,
36 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
37 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
38_LIBCPP_HIDE_FROM_ABI void
39sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
40 std::__pstl_frontend_dispatch(
41 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_sort),
42 [&__policy](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) {
43 std::stable_sort(__policy, std::move(__g_first), std::move(__g_last), std::move(__g_comp));
44 },
45 std::move(__first),
46 std::move(__last),
47 std::move(__comp));
48}
49
50template <class _ExecutionPolicy,
51 class _RandomAccessIterator,
52 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
53 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
54_LIBCPP_HIDE_FROM_ABI void
55sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
56 std::sort(std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
57}
58
59_LIBCPP_END_NAMESPACE_STD
60
61#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
62
63#endif // _LIBCPP___ALGORITHM_PSTL_SORT_H
lib/libcxx/include/__algorithm/pstl_stable_sort.h created+43
......@@ -0,0 +1,43 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
10#define _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
11
12#include <__algorithm/pstl_backend.h>
13#include <__config>
14#include <__functional/operations.h>
15#include <__type_traits/enable_if.h>
16#include <__type_traits/is_execution_policy.h>
17#include <__type_traits/remove_cvref.h>
18#include <__utility/move.h>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21# pragma GCC system_header
22#endif
23
24#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _ExecutionPolicy,
29 class _RandomAccessIterator,
30 class _Comp = less<>,
31 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
32 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
33_LIBCPP_HIDE_FROM_ABI void
34stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp = {}) {
35 using _Backend = typename __select_backend<_RawPolicy>::type;
36 std::__pstl_stable_sort<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__comp));
37}
38
39_LIBCPP_END_NAMESPACE_STD
40
41#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
42
43#endif // _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
lib/libcxx/include/__algorithm/pstl_transform.h created+77
......@@ -0,0 +1,77 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H
10#define _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H
11
12#include <__algorithm/pstl_backend.h>
13#include <__config>
14#include <__iterator/cpp17_iterator_concepts.h>
15#include <__iterator/iterator_traits.h>
16#include <__type_traits/enable_if.h>
17#include <__type_traits/is_execution_policy.h>
18#include <__type_traits/remove_cvref.h>
19#include <__utility/move.h>
20#include <__utility/terminate_on_exception.h>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23# pragma GCC system_header
24#endif
25
26#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30template <class _ExecutionPolicy,
31 class _ForwardIterator,
32 class _ForwardOutIterator,
33 class _UnaryOperation,
34 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
35 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
36_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
37 _ExecutionPolicy&&,
38 _ForwardIterator __first,
39 _ForwardIterator __last,
40 _ForwardOutIterator __result,
41 _UnaryOperation __op) {
42 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
43 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
44 _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first)));
45 using _Backend = typename __select_backend<_RawPolicy>::type;
46 return std::__pstl_transform<_RawPolicy>(
47 _Backend{}, std::move(__first), std::move(__last), std::move(__result), std::move(__op));
48}
49
50template <class _ExecutionPolicy,
51 class _ForwardIterator1,
52 class _ForwardIterator2,
53 class _ForwardOutIterator,
54 class _BinaryOperation,
55 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
56 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
57_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
58 _ExecutionPolicy&&,
59 _ForwardIterator1 __first1,
60 _ForwardIterator1 __last1,
61 _ForwardIterator2 __first2,
62 _ForwardOutIterator __result,
63 _BinaryOperation __op) {
64 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
65 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
66 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
67 _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first1, *__first2)));
68 using _Backend = typename __select_backend<_RawPolicy>::type;
69 return std::__pstl_transform<_RawPolicy>(
70 _Backend{}, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__result), std::move(__op));
71}
72
73_LIBCPP_END_NAMESPACE_STD
74
75#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
76
77#endif // _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H
lib/libcxx/include/__algorithm/push_heap.h+8-3
......@@ -14,13 +14,17 @@
1414#include <__algorithm/iterator_operations.h>
1515#include <__config>
1616#include <__iterator/iterator_traits.h>
17#include <__type_traits/is_copy_assignable.h>
18#include <__type_traits/is_copy_constructible.h>
1719#include <__utility/move.h>
18#include <type_traits>
1920
2021#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2122# pragma GCC system_header
2223#endif
2324
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
2428_LIBCPP_BEGIN_NAMESPACE_STD
2529
2630template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
......@@ -68,10 +72,11 @@ void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
6872template <class _RandomAccessIterator>
6973inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
7074void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
71 std::push_heap(std::move(__first), std::move(__last),
72 __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
75 std::push_heap(std::move(__first), std::move(__last), __less<>());
7376}
7477
7578_LIBCPP_END_NAMESPACE_STD
7679
80_LIBCPP_POP_MACROS
81
7782#endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H
lib/libcxx/include/__algorithm/ranges_adjacent_find.h+14-14
......@@ -24,17 +24,16 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
3131namespace ranges {
3232namespace __adjacent_find {
3333struct __fn {
34
3534 template <class _Iter, class _Sent, class _Proj, class _Pred>
36 _LIBCPP_HIDE_FROM_ABI constexpr static
37 _Iter __adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
35 _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
36 __adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
3837 if (__first == __last)
3938 return __first;
4039
......@@ -47,32 +46,33 @@ struct __fn {
4746 return __i;
4847 }
4948
50 template <forward_iterator _Iter, sentinel_for<_Iter> _Sent,
51 class _Proj = identity,
49 template <forward_iterator _Iter,
50 sentinel_for<_Iter> _Sent,
51 class _Proj = identity,
5252 indirect_binary_predicate<projected<_Iter, _Proj>, projected<_Iter, _Proj>> _Pred = ranges::equal_to>
53 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
54 _Iter operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
53 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter
54 operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
5555 return __adjacent_find_impl(std::move(__first), std::move(__last), __pred, __proj);
5656 }
5757
5858 template <forward_range _Range,
5959 class _Proj = identity,
60 indirect_binary_predicate<projected<iterator_t<_Range>, _Proj>,
61 projected<iterator_t<_Range>, _Proj>> _Pred = ranges::equal_to>
62 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
63 borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const {
60 indirect_binary_predicate<projected<iterator_t<_Range>, _Proj>, projected<iterator_t<_Range>, _Proj>>
61 _Pred = ranges::equal_to>
62 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
63 operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const {
6464 return __adjacent_find_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
6565 }
6666};
6767} // namespace __adjacent_find
6868
6969inline namespace __cpo {
70 inline constexpr auto adjacent_find = __adjacent_find::__fn{};
70inline constexpr auto adjacent_find = __adjacent_find::__fn{};
7171} // namespace __cpo
7272} // namespace ranges
7373
7474_LIBCPP_END_NAMESPACE_STD
7575
76#endif // _LIBCPP_STD_VER > 17
76#endif // _LIBCPP_STD_VER >= 20
7777
7878#endif // _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H
lib/libcxx/include/__algorithm/ranges_all_of.h+13-12
......@@ -22,17 +22,15 @@
2222# pragma GCC system_header
2323#endif
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727_LIBCPP_BEGIN_NAMESPACE_STD
2828
2929namespace ranges {
3030namespace __all_of {
3131struct __fn {
32
3332 template <class _Iter, class _Sent, class _Proj, class _Pred>
34 _LIBCPP_HIDE_FROM_ABI constexpr static
35 bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
33 _LIBCPP_HIDE_FROM_ABI constexpr static bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
3634 for (; __first != __last; ++__first) {
3735 if (!std::invoke(__pred, std::invoke(__proj, *__first)))
3836 return false;
......@@ -40,29 +38,32 @@ struct __fn {
4038 return true;
4139 }
4240
43 template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
41 template <input_iterator _Iter,
42 sentinel_for<_Iter> _Sent,
43 class _Proj = identity,
4444 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
45 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
46 bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
45 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
46 operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
4747 return __all_of_impl(std::move(__first), std::move(__last), __pred, __proj);
4848 }
4949
50 template <input_range _Range, class _Proj = identity,
50 template <input_range _Range,
51 class _Proj = identity,
5152 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
52 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
53 bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
53 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
54 operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
5455 return __all_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
5556 }
5657};
5758} // namespace __all_of
5859
5960inline namespace __cpo {
60 inline constexpr auto all_of = __all_of::__fn{};
61inline constexpr auto all_of = __all_of::__fn{};
6162} // namespace __cpo
6263} // namespace ranges
6364
6465_LIBCPP_END_NAMESPACE_STD
6566
66#endif // _LIBCPP_STD_VER > 17
67#endif // _LIBCPP_STD_VER >= 20
6768
6869#endif // _LIBCPP___ALGORITHM_RANGES_ALL_OF_H
lib/libcxx/include/__algorithm/ranges_any_of.h+13-12
......@@ -22,17 +22,15 @@
2222# pragma GCC system_header
2323#endif
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727_LIBCPP_BEGIN_NAMESPACE_STD
2828
2929namespace ranges {
3030namespace __any_of {
3131struct __fn {
32
3332 template <class _Iter, class _Sent, class _Proj, class _Pred>
34 _LIBCPP_HIDE_FROM_ABI constexpr static
35 bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
33 _LIBCPP_HIDE_FROM_ABI constexpr static bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
3634 for (; __first != __last; ++__first) {
3735 if (std::invoke(__pred, std::invoke(__proj, *__first)))
3836 return true;
......@@ -40,29 +38,32 @@ struct __fn {
4038 return false;
4139 }
4240
43 template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
41 template <input_iterator _Iter,
42 sentinel_for<_Iter> _Sent,
43 class _Proj = identity,
4444 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
45 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
46 bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
45 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
46 operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
4747 return __any_of_impl(std::move(__first), std::move(__last), __pred, __proj);
4848 }
4949
50 template <input_range _Range, class _Proj = identity,
50 template <input_range _Range,
51 class _Proj = identity,
5152 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
52 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
53 bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
53 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
54 operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
5455 return __any_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
5556 }
5657};
5758} // namespace __any_of
5859
5960inline namespace __cpo {
60 inline constexpr auto any_of = __any_of::__fn{};
61inline constexpr auto any_of = __any_of::__fn{};
6162} // namespace __cpo
6263} // namespace ranges
6364
6465_LIBCPP_END_NAMESPACE_STD
6566
66#endif // _LIBCPP_STD_VER > 17
67#endif // _LIBCPP_STD_VER >= 20
6768
6869#endif // _LIBCPP___ALGORITHM_RANGES_ANY_OF_H
lib/libcxx/include/__algorithm/ranges_binary_search.h+17-12
......@@ -24,40 +24,45 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
3131namespace ranges {
3232namespace __binary_search {
3333struct __fn {
34 template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity,
34 template <forward_iterator _Iter,
35 sentinel_for<_Iter> _Sent,
36 class _Type,
37 class _Proj = identity,
3538 indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
36 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
37 bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
38 auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
39 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
40 operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
41 auto __ret = std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
3942 return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret));
4043 }
4144
42 template <forward_range _Range, class _Type, class _Proj = identity,
45 template <forward_range _Range,
46 class _Type,
47 class _Proj = identity,
4348 indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
44 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
45 bool operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
49 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
50 operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
4651 auto __first = ranges::begin(__r);
47 auto __last = ranges::end(__r);
48 auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
52 auto __last = ranges::end(__r);
53 auto __ret = std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
4954 return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret));
5055 }
5156};
5257} // namespace __binary_search
5358
5459inline namespace __cpo {
55 inline constexpr auto binary_search = __binary_search::__fn{};
60inline constexpr auto binary_search = __binary_search::__fn{};
5661} // namespace __cpo
5762} // namespace ranges
5863
5964_LIBCPP_END_NAMESPACE_STD
6065
61#endif // _LIBCPP_STD_VER > 17
66#endif // _LIBCPP_STD_VER >= 20
6267
6368#endif // _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H
lib/libcxx/include/__algorithm/ranges_clamp.h+8-14
......@@ -22,25 +22,20 @@
2222# pragma GCC system_header
2323#endif
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727_LIBCPP_BEGIN_NAMESPACE_STD
2828
2929namespace ranges {
3030namespace __clamp {
3131struct __fn {
32
3332 template <class _Type,
34 class _Proj = identity,
33 class _Proj = identity,
3534 indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less>
36 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
37 const _Type& operator()(const _Type& __value,
38 const _Type& __low,
39 const _Type& __high,
40 _Comp __comp = {},
41 _Proj __proj = {}) const {
42 _LIBCPP_ASSERT(!bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))),
43 "Bad bounds passed to std::ranges::clamp");
35 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Type& operator()(
36 const _Type& __value, const _Type& __low, const _Type& __high, _Comp __comp = {}, _Proj __proj = {}) const {
37 _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))),
38 "Bad bounds passed to std::ranges::clamp");
4439
4540 if (std::invoke(__comp, std::invoke(__proj, __value), std::invoke(__proj, __low)))
4641 return __low;
......@@ -49,17 +44,16 @@ struct __fn {
4944 else
5045 return __value;
5146 }
52
5347};
5448} // namespace __clamp
5549
5650inline namespace __cpo {
57 inline constexpr auto clamp = __clamp::__fn{};
51inline constexpr auto clamp = __clamp::__fn{};
5852} // namespace __cpo
5953} // namespace ranges
6054
6155_LIBCPP_END_NAMESPACE_STD
6256
63#endif // _LIBCPP_STD_VER > 17
57#endif // _LIBCPP_STD_VER >= 20
6458
6559#endif // _LIBCPP___ALGORITHM_RANGES_CLAMP_H
lib/libcxx/include/__algorithm/ranges_copy.h+7-8
......@@ -25,7 +25,7 @@
2525# pragma GCC system_header
2626#endif
2727
28#if _LIBCPP_STD_VER > 17
28#if _LIBCPP_STD_VER >= 20
2929
3030_LIBCPP_BEGIN_NAMESPACE_STD
3131
......@@ -36,19 +36,18 @@ using copy_result = in_out_result<_InIter, _OutIter>;
3636
3737namespace __copy {
3838struct __fn {
39
4039 template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
4140 requires indirectly_copyable<_InIter, _OutIter>
42 _LIBCPP_HIDE_FROM_ABI constexpr
43 copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
41 _LIBCPP_HIDE_FROM_ABI constexpr copy_result<_InIter, _OutIter>
42 operator()(_InIter __first, _Sent __last, _OutIter __result) const {
4443 auto __ret = std::__copy<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
4544 return {std::move(__ret.first), std::move(__ret.second)};
4645 }
4746
4847 template <input_range _Range, weakly_incrementable _OutIter>
4948 requires indirectly_copyable<iterator_t<_Range>, _OutIter>
50 _LIBCPP_HIDE_FROM_ABI constexpr
51 copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __r, _OutIter __result) const {
49 _LIBCPP_HIDE_FROM_ABI constexpr copy_result<borrowed_iterator_t<_Range>, _OutIter>
50 operator()(_Range&& __r, _OutIter __result) const {
5251 auto __ret = std::__copy<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result));
5352 return {std::move(__ret.first), std::move(__ret.second)};
5453 }
......@@ -56,12 +55,12 @@ struct __fn {
5655} // namespace __copy
5756
5857inline namespace __cpo {
59 inline constexpr auto copy = __copy::__fn{};
58inline constexpr auto copy = __copy::__fn{};
6059} // namespace __cpo
6160} // namespace ranges
6261
6362_LIBCPP_END_NAMESPACE_STD
6463
65#endif // _LIBCPP_STD_VER > 17
64#endif // _LIBCPP_STD_VER >= 20
6665
6766#endif // _LIBCPP___ALGORITHM_RANGES_COPY_H
lib/libcxx/include/__algorithm/ranges_copy_backward.h+8-9
......@@ -23,30 +23,29 @@
2323# pragma GCC system_header
2424#endif
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
3030namespace ranges {
3131
32template<class _Ip, class _Op>
32template <class _Ip, class _Op>
3333using copy_backward_result = in_out_result<_Ip, _Op>;
3434
3535namespace __copy_backward {
3636struct __fn {
37
3837 template <bidirectional_iterator _InIter1, sentinel_for<_InIter1> _Sent1, bidirectional_iterator _InIter2>
3938 requires indirectly_copyable<_InIter1, _InIter2>
40 _LIBCPP_HIDE_FROM_ABI constexpr
41 copy_backward_result<_InIter1, _InIter2> operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const {
39 _LIBCPP_HIDE_FROM_ABI constexpr copy_backward_result<_InIter1, _InIter2>
40 operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const {
4241 auto __ret = std::__copy_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
4342 return {std::move(__ret.first), std::move(__ret.second)};
4443 }
4544
4645 template <bidirectional_range _Range, bidirectional_iterator _Iter>
4746 requires indirectly_copyable<iterator_t<_Range>, _Iter>
48 _LIBCPP_HIDE_FROM_ABI constexpr
49 copy_backward_result<borrowed_iterator_t<_Range>, _Iter> operator()(_Range&& __r, _Iter __result) const {
47 _LIBCPP_HIDE_FROM_ABI constexpr copy_backward_result<borrowed_iterator_t<_Range>, _Iter>
48 operator()(_Range&& __r, _Iter __result) const {
5049 auto __ret = std::__copy_backward<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result));
5150 return {std::move(__ret.first), std::move(__ret.second)};
5251 }
......@@ -54,12 +53,12 @@ struct __fn {
5453} // namespace __copy_backward
5554
5655inline namespace __cpo {
57 inline constexpr auto copy_backward = __copy_backward::__fn{};
56inline constexpr auto copy_backward = __copy_backward::__fn{};
5857} // namespace __cpo
5958} // namespace ranges
6059
6160_LIBCPP_END_NAMESPACE_STD
6261
63#endif // _LIBCPP_STD_VER > 17
62#endif // _LIBCPP_STD_VER >= 20
6463
6564#endif // _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H
lib/libcxx/include/__algorithm/ranges_copy_if.h+14-13
......@@ -24,21 +24,19 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
3131namespace ranges {
3232
33template<class _Ip, class _Op>
33template <class _Ip, class _Op>
3434using copy_if_result = in_out_result<_Ip, _Op>;
3535
3636namespace __copy_if {
3737struct __fn {
38
3938 template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred>
40 _LIBCPP_HIDE_FROM_ABI static constexpr
41 copy_if_result <_InIter, _OutIter>
39 _LIBCPP_HIDE_FROM_ABI static constexpr copy_if_result<_InIter, _OutIter>
4240 __copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) {
4341 for (; __first != __last; ++__first) {
4442 if (std::invoke(__pred, std::invoke(__proj, *__first))) {
......@@ -49,20 +47,23 @@ struct __fn {
4947 return {std::move(__first), std::move(__result)};
5048 }
5149
52 template <input_iterator _Iter, sentinel_for<_Iter> _Sent, weakly_incrementable _OutIter, class _Proj = identity,
50 template <input_iterator _Iter,
51 sentinel_for<_Iter> _Sent,
52 weakly_incrementable _OutIter,
53 class _Proj = identity,
5354 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
5455 requires indirectly_copyable<_Iter, _OutIter>
55 _LIBCPP_HIDE_FROM_ABI constexpr
56 copy_if_result<_Iter, _OutIter>
56 _LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<_Iter, _OutIter>
5757 operator()(_Iter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
5858 return __copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
5959 }
6060
61 template <input_range _Range, weakly_incrementable _OutIter, class _Proj = identity,
61 template <input_range _Range,
62 weakly_incrementable _OutIter,
63 class _Proj = identity,
6264 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
6365 requires indirectly_copyable<iterator_t<_Range>, _OutIter>
64 _LIBCPP_HIDE_FROM_ABI constexpr
65 copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
66 _LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
6667 operator()(_Range&& __r, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
6768 return __copy_if_impl(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj);
6869 }
......@@ -70,12 +71,12 @@ struct __fn {
7071} // namespace __copy_if
7172
7273inline namespace __cpo {
73 inline constexpr auto copy_if = __copy_if::__fn{};
74inline constexpr auto copy_if = __copy_if::__fn{};
7475} // namespace __cpo
7576} // namespace ranges
7677
7778_LIBCPP_END_NAMESPACE_STD
7879
79#endif // _LIBCPP_STD_VER > 17
80#endif // _LIBCPP_STD_VER >= 20
8081
8182#endif // _LIBCPP___ALGORITHM_RANGES_COPY_IF_H
lib/libcxx/include/__algorithm/ranges_copy_n.h+9-10
......@@ -27,7 +27,7 @@
2727
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232namespace ranges {
3333
......@@ -36,10 +36,9 @@ using copy_n_result = in_out_result<_Ip, _Op>;
3636
3737namespace __copy_n {
3838struct __fn {
39
4039 template <class _InIter, class _DiffType, class _OutIter>
41 _LIBCPP_HIDE_FROM_ABI constexpr static
42 copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) {
40 _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
41 __go(_InIter __first, _DiffType __n, _OutIter __result) {
4342 while (__n != 0) {
4443 *__result = *__first;
4544 ++__first;
......@@ -50,27 +49,27 @@ struct __fn {
5049 }
5150
5251 template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter>
53 _LIBCPP_HIDE_FROM_ABI constexpr static
54 copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) {
52 _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
53 __go(_InIter __first, _DiffType __n, _OutIter __result) {
5554 auto __ret = std::__copy<_RangeAlgPolicy>(__first, __first + __n, __result);
5655 return {__ret.first, __ret.second};
5756 }
5857
5958 template <input_iterator _Ip, weakly_incrementable _Op>
6059 requires indirectly_copyable<_Ip, _Op>
61 _LIBCPP_HIDE_FROM_ABI constexpr
62 copy_n_result<_Ip, _Op> operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
60 _LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op>
61 operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
6362 return __go(std::move(__first), __n, std::move(__result));
6463 }
6564};
6665} // namespace __copy_n
6766
6867inline namespace __cpo {
69 inline constexpr auto copy_n = __copy_n::__fn{};
68inline constexpr auto copy_n = __copy_n::__fn{};
7069} // namespace __cpo
7170} // namespace ranges
7271
73#endif // _LIBCPP_STD_VER > 17
72#endif // _LIBCPP_STD_VER >= 20
7473
7574_LIBCPP_END_NAMESPACE_STD
7675
lib/libcxx/include/__algorithm/ranges_count.h+7-7
......@@ -25,7 +25,7 @@
2525# pragma GCC system_header
2626#endif
2727
28#if _LIBCPP_STD_VER > 17
28#if _LIBCPP_STD_VER >= 20
2929
3030_LIBCPP_BEGIN_NAMESPACE_STD
3131
......@@ -34,16 +34,16 @@ namespace __count {
3434struct __fn {
3535 template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity>
3636 requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type*>
37 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
38 iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
37 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
38 operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
3939 auto __pred = [&](auto&& __e) { return __e == __value; };
4040 return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj);
4141 }
4242
4343 template <input_range _Range, class _Type, class _Proj = identity>
4444 requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
45 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
46 range_difference_t<_Range> operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const {
45 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range>
46 operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const {
4747 auto __pred = [&](auto&& __e) { return __e == __value; };
4848 return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
4949 }
......@@ -51,12 +51,12 @@ struct __fn {
5151} // namespace __count
5252
5353inline namespace __cpo {
54 inline constexpr auto count = __count::__fn{};
54inline constexpr auto count = __count::__fn{};
5555} // namespace __cpo
5656} // namespace ranges
5757
5858_LIBCPP_END_NAMESPACE_STD
5959
60#endif // _LIBCPP_STD_VER > 17
60#endif // _LIBCPP_STD_VER >= 20
6161
6262#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_H
lib/libcxx/include/__algorithm/ranges_count_if.h+14-12
......@@ -25,15 +25,14 @@
2525# pragma GCC system_header
2626#endif
2727
28#if _LIBCPP_STD_VER > 17
28#if _LIBCPP_STD_VER >= 20
2929
3030_LIBCPP_BEGIN_NAMESPACE_STD
3131
3232namespace ranges {
3333template <class _Iter, class _Sent, class _Proj, class _Pred>
34_LIBCPP_HIDE_FROM_ABI constexpr
35iter_difference_t<_Iter> __count_if_impl(_Iter __first, _Sent __last,
36 _Pred& __pred, _Proj& __proj) {
34_LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
35__count_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
3736 iter_difference_t<_Iter> __counter(0);
3837 for (; __first != __last; ++__first) {
3938 if (std::invoke(__pred, std::invoke(__proj, *__first)))
......@@ -44,29 +43,32 @@ iter_difference_t<_Iter> __count_if_impl(_Iter __first, _Sent __last,
4443
4544namespace __count_if {
4645struct __fn {
47 template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
46 template <input_iterator _Iter,
47 sentinel_for<_Iter> _Sent,
48 class _Proj = identity,
4849 indirect_unary_predicate<projected<_Iter, _Proj>> _Predicate>
49 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
50 iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const {
50 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
51 operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const {
5152 return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj);
5253 }
5354
54 template <input_range _Range, class _Proj = identity,
55 template <input_range _Range,
56 class _Proj = identity,
5557 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Predicate>
56 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
57 range_difference_t<_Range> operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const {
58 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range>
59 operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const {
5860 return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
5961 }
6062};
6163} // namespace __count_if
6264
6365inline namespace __cpo {
64 inline constexpr auto count_if = __count_if::__fn{};
66inline constexpr auto count_if = __count_if::__fn{};
6567} // namespace __cpo
6668} // namespace ranges
6769
6870_LIBCPP_END_NAMESPACE_STD
6971
70#endif // _LIBCPP_STD_VER > 17
72#endif // _LIBCPP_STD_VER >= 20
7173
7274#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H
lib/libcxx/include/__algorithm/ranges_equal.h+41-52
......@@ -9,6 +9,8 @@
99#ifndef _LIBCPP___ALGORITHM_RANGES_EQUAL_H
1010#define _LIBCPP___ALGORITHM_RANGES_EQUAL_H
1111
12#include <__algorithm/equal.h>
13#include <__algorithm/unwrap_range.h>
1214#include <__config>
1315#include <__functional/identity.h>
1416#include <__functional/invoke.h>
......@@ -24,92 +26,79 @@
2426# pragma GCC system_header
2527#endif
2628
27#if _LIBCPP_STD_VER > 17
29#if _LIBCPP_STD_VER >= 20
2830
2931_LIBCPP_BEGIN_NAMESPACE_STD
3032
3133namespace ranges {
3234namespace __equal {
3335struct __fn {
34private:
35 template <class _Iter1, class _Sent1,
36 class _Iter2, class _Sent2,
37 class _Pred,
38 class _Proj1,
39 class _Proj2>
40 _LIBCPP_HIDE_FROM_ABI constexpr static
41 bool __equal_impl(_Iter1 __first1, _Sent1 __last1,
42 _Iter2 __first2, _Sent2 __last2,
43 _Pred& __pred,
44 _Proj1& __proj1,
45 _Proj2& __proj2) {
46 while (__first1 != __last1 && __first2 != __last2) {
47 if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2)))
48 return false;
49 ++__first1;
50 ++__first2;
51 }
52 return __first1 == __last1 && __first2 == __last2;
53 }
54
55public:
56
57 template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
58 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
59 class _Pred = ranges::equal_to,
36 template <input_iterator _Iter1,
37 sentinel_for<_Iter1> _Sent1,
38 input_iterator _Iter2,
39 sentinel_for<_Iter2> _Sent2,
40 class _Pred = ranges::equal_to,
6041 class _Proj1 = identity,
6142 class _Proj2 = identity>
6243 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
63 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
64 bool operator()(_Iter1 __first1, _Sent1 __last1,
65 _Iter2 __first2, _Sent2 __last2,
66 _Pred __pred = {},
67 _Proj1 __proj1 = {},
68 _Proj2 __proj2 = {}) const {
44 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
45 _Iter1 __first1,
46 _Sent1 __last1,
47 _Iter2 __first2,
48 _Sent2 __last2,
49 _Pred __pred = {},
50 _Proj1 __proj1 = {},
51 _Proj2 __proj2 = {}) const {
6952 if constexpr (sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>) {
7053 if (__last1 - __first1 != __last2 - __first2)
7154 return false;
7255 }
73 return __equal_impl(std::move(__first1), std::move(__last1),
74 std::move(__first2), std::move(__last2),
75 __pred,
76 __proj1,
77 __proj2);
56 auto __unwrapped1 = std::__unwrap_range(std::move(__first1), std::move(__last1));
57 auto __unwrapped2 = std::__unwrap_range(std::move(__first2), std::move(__last2));
58 return std::__equal_impl(
59 std::move(__unwrapped1.first),
60 std::move(__unwrapped1.second),
61 std::move(__unwrapped2.first),
62 std::move(__unwrapped2.second),
63 __pred,
64 __proj1,
65 __proj2);
7866 }
7967
8068 template <input_range _Range1,
8169 input_range _Range2,
82 class _Pred = ranges::equal_to,
70 class _Pred = ranges::equal_to,
8371 class _Proj1 = identity,
8472 class _Proj2 = identity>
8573 requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
86 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
87 bool operator()(_Range1&& __range1,
88 _Range2&& __range2,
89 _Pred __pred = {},
90 _Proj1 __proj1 = {},
91 _Proj2 __proj2 = {}) const {
74 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
75 _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
9276 if constexpr (sized_range<_Range1> && sized_range<_Range2>) {
9377 if (ranges::distance(__range1) != ranges::distance(__range2))
9478 return false;
9579 }
96 return __equal_impl(ranges::begin(__range1), ranges::end(__range1),
97 ranges::begin(__range2), ranges::end(__range2),
98 __pred,
99 __proj1,
100 __proj2);
80 auto __unwrapped1 = std::__unwrap_range(ranges::begin(__range1), ranges::end(__range1));
81 auto __unwrapped2 = std::__unwrap_range(ranges::begin(__range2), ranges::end(__range2));
82 return std::__equal_impl(
83 std::move(__unwrapped1.first),
84 std::move(__unwrapped1.second),
85 std::move(__unwrapped2.first),
86 std::move(__unwrapped2.second),
87 __pred,
88 __proj1,
89 __proj2);
10190 return false;
10291 }
10392};
10493} // namespace __equal
10594
10695inline namespace __cpo {
107 inline constexpr auto equal = __equal::__fn{};
96inline constexpr auto equal = __equal::__fn{};
10897} // namespace __cpo
10998} // namespace ranges
11099
111100_LIBCPP_END_NAMESPACE_STD
112101
113#endif // _LIBCPP_STD_VER > 17
102#endif // _LIBCPP_STD_VER >= 20
114103
115104#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_H
lib/libcxx/include/__algorithm/ranges_equal_range.h+15-18
......@@ -30,7 +30,7 @@
3030# pragma GCC system_header
3131#endif
3232
33#if _LIBCPP_STD_VER > 17
33#if _LIBCPP_STD_VER >= 20
3434
3535_LIBCPP_BEGIN_NAMESPACE_STD
3636
......@@ -38,28 +38,25 @@ namespace ranges {
3838namespace __equal_range {
3939
4040struct __fn {
41 template <
42 forward_iterator _Iter,
43 sentinel_for<_Iter> _Sent,
44 class _Tp,
45 class _Proj = identity,
46 indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>> _Comp = ranges::less>
41 template <forward_iterator _Iter,
42 sentinel_for<_Iter> _Sent,
43 class _Tp,
44 class _Proj = identity,
45 indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>> _Comp = ranges::less>
4746 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
4847 operator()(_Iter __first, _Sent __last, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const {
49 auto __ret = std::__equal_range<_RangeAlgPolicy>(
50 std::move(__first), std::move(__last), __value, __comp, __proj);
48 auto __ret = std::__equal_range<_RangeAlgPolicy>(std::move(__first), std::move(__last), __value, __comp, __proj);
5149 return {std::move(__ret.first), std::move(__ret.second)};
5250 }
5351
54 template <
55 forward_range _Range,
56 class _Tp,
57 class _Proj = identity,
58 indirect_strict_weak_order<const _Tp*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
52 template <forward_range _Range,
53 class _Tp,
54 class _Proj = identity,
55 indirect_strict_weak_order<const _Tp*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
5956 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
6057 operator()(_Range&& __range, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const {
61 auto __ret = std::__equal_range<_RangeAlgPolicy>(
62 ranges::begin(__range), ranges::end(__range), __value, __comp, __proj);
58 auto __ret =
59 std::__equal_range<_RangeAlgPolicy>(ranges::begin(__range), ranges::end(__range), __value, __comp, __proj);
6360 return {std::move(__ret.first), std::move(__ret.second)};
6461 }
6562};
......@@ -67,12 +64,12 @@ struct __fn {
6764} // namespace __equal_range
6865
6966inline namespace __cpo {
70 inline constexpr auto equal_range = __equal_range::__fn{};
67inline constexpr auto equal_range = __equal_range::__fn{};
7168} // namespace __cpo
7269} // namespace ranges
7370
7471_LIBCPP_END_NAMESPACE_STD
7572
76#endif // _LIBCPP_STD_VER > 17
73#endif // _LIBCPP_STD_VER >= 20
7774
7875#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H
lib/libcxx/include/__algorithm/ranges_fill.h+6-8
......@@ -20,7 +20,7 @@
2020# pragma GCC system_header
2121#endif
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
......@@ -28,9 +28,8 @@ namespace ranges {
2828namespace __fill {
2929struct __fn {
3030 template <class _Type, output_iterator<const _Type&> _Iter, sentinel_for<_Iter> _Sent>
31 _LIBCPP_HIDE_FROM_ABI constexpr
32 _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const {
33 if constexpr(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) {
31 _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const {
32 if constexpr (random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) {
3433 return ranges::fill_n(__first, __last - __first, __value);
3534 } else {
3635 for (; __first != __last; ++__first)
......@@ -40,20 +39,19 @@ struct __fn {
4039 }
4140
4241 template <class _Type, output_range<const _Type&> _Range>
43 _LIBCPP_HIDE_FROM_ABI constexpr
44 borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const {
42 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const {
4543 return (*this)(ranges::begin(__range), ranges::end(__range), __value);
4644 }
4745};
4846} // namespace __fill
4947
5048inline namespace __cpo {
51 inline constexpr auto fill = __fill::__fn{};
49inline constexpr auto fill = __fill::__fn{};
5250} // namespace __cpo
5351} // namespace ranges
5452
5553_LIBCPP_END_NAMESPACE_STD
5654
57#endif // _LIBCPP_STD_VER > 17
55#endif // _LIBCPP_STD_VER >= 20
5856
5957#endif // _LIBCPP___ALGORITHM_RANGES_FILL_H
lib/libcxx/include/__algorithm/ranges_fill_n.h+5-5
......@@ -17,7 +17,7 @@
1717# pragma GCC system_header
1818#endif
1919
20#if _LIBCPP_STD_VER > 17
20#if _LIBCPP_STD_VER >= 20
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
......@@ -25,8 +25,8 @@ namespace ranges {
2525namespace __fill_n {
2626struct __fn {
2727 template <class _Type, output_iterator<const _Type&> _Iter>
28 _LIBCPP_HIDE_FROM_ABI constexpr
29 _Iter operator()(_Iter __first, iter_difference_t<_Iter> __n, const _Type& __value) const {
28 _LIBCPP_HIDE_FROM_ABI constexpr _Iter
29 operator()(_Iter __first, iter_difference_t<_Iter> __n, const _Type& __value) const {
3030 for (; __n != 0; --__n) {
3131 *__first = __value;
3232 ++__first;
......@@ -37,12 +37,12 @@ struct __fn {
3737} // namespace __fill_n
3838
3939inline namespace __cpo {
40 inline constexpr auto fill_n = __fill_n::__fn{};
40inline constexpr auto fill_n = __fill_n::__fn{};
4141} // namespace __cpo
4242} // namespace ranges
4343
4444_LIBCPP_END_NAMESPACE_STD
4545
46#endif // _LIBCPP_STD_VER > 17
46#endif // _LIBCPP_STD_VER >= 20
4747
4848#endif // _LIBCPP___ALGORITHM_RANGES_FILL_N_H
lib/libcxx/include/__algorithm/ranges_find.h+23-11
......@@ -9,7 +9,9 @@
99#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_H
1010#define _LIBCPP___ALGORITHM_RANGES_FIND_H
1111
12#include <__algorithm/find.h>
1213#include <__algorithm/ranges_find_if.h>
14#include <__algorithm/unwrap_range.h>
1315#include <__config>
1416#include <__functional/identity.h>
1517#include <__functional/invoke.h>
......@@ -26,38 +28,48 @@
2628# pragma GCC system_header
2729#endif
2830
29#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
3032
3133_LIBCPP_BEGIN_NAMESPACE_STD
3234
3335namespace ranges {
3436namespace __find {
3537struct __fn {
38 template <class _Iter, class _Sent, class _Tp, class _Proj>
39 _LIBCPP_HIDE_FROM_ABI static constexpr _Iter
40 __find_unwrap(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
41 if constexpr (forward_iterator<_Iter>) {
42 auto [__first_un, __last_un] = std::__unwrap_range(__first, std::move(__last));
43 return std::__rewrap_range<_Sent>(
44 std::move(__first), std::__find_impl(std::move(__first_un), std::move(__last_un), __value, __proj));
45 } else {
46 return std::__find_impl(std::move(__first), std::move(__last), __value, __proj);
47 }
48 }
49
3650 template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Tp, class _Proj = identity>
3751 requires indirect_binary_predicate<ranges::equal_to, projected<_Ip, _Proj>, const _Tp*>
38 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
39 _Ip operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const {
40 auto __pred = [&](auto&& __e) { return std::forward<decltype(__e)>(__e) == __value; };
41 return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj);
52 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip
53 operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const {
54 return __find_unwrap(std::move(__first), std::move(__last), __value, __proj);
4255 }
4356
4457 template <input_range _Rp, class _Tp, class _Proj = identity>
4558 requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Rp>, _Proj>, const _Tp*>
46 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
47 borrowed_iterator_t<_Rp> operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const {
48 auto __pred = [&](auto&& __e) { return std::forward<decltype(__e)>(__e) == __value; };
49 return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
59 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
60 operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const {
61 return __find_unwrap(ranges::begin(__r), ranges::end(__r), __value, __proj);
5062 }
5163};
5264} // namespace __find
5365
5466inline namespace __cpo {
55 inline constexpr auto find = __find::__fn{};
67inline constexpr auto find = __find::__fn{};
5668} // namespace __cpo
5769} // namespace ranges
5870
5971_LIBCPP_END_NAMESPACE_STD
6072
61#endif // _LIBCPP_STD_VER > 17
73#endif // _LIBCPP_STD_VER >= 20
6274
6375#endif // _LIBCPP___ALGORITHM_RANGES_FIND_H
lib/libcxx/include/__algorithm/ranges_find_end.h+19-19
......@@ -27,25 +27,29 @@
2727# pragma GCC system_header
2828#endif
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_BEGIN_NAMESPACE_STD
3333
3434namespace ranges {
3535namespace __find_end {
3636struct __fn {
37 template <forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
38 forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
39 class _Pred = ranges::equal_to,
37 template <forward_iterator _Iter1,
38 sentinel_for<_Iter1> _Sent1,
39 forward_iterator _Iter2,
40 sentinel_for<_Iter2> _Sent2,
41 class _Pred = ranges::equal_to,
4042 class _Proj1 = identity,
4143 class _Proj2 = identity>
4244 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
43 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
44 subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1,
45 _Iter2 __first2, _Sent2 __last2,
46 _Pred __pred = {},
47 _Proj1 __proj1 = {},
48 _Proj2 __proj2 = {}) const {
45 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()(
46 _Iter1 __first1,
47 _Sent1 __last1,
48 _Iter2 __first2,
49 _Sent2 __last2,
50 _Pred __pred = {},
51 _Proj1 __proj1 = {},
52 _Proj2 __proj2 = {}) const {
4953 auto __ret = std::__find_end_impl<_RangeAlgPolicy>(
5054 __first1,
5155 __last1,
......@@ -61,16 +65,12 @@ struct __fn {
6165
6266 template <forward_range _Range1,
6367 forward_range _Range2,
64 class _Pred = ranges::equal_to,
68 class _Pred = ranges::equal_to,
6569 class _Proj1 = identity,
6670 class _Proj2 = identity>
6771 requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
68 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
69 borrowed_subrange_t<_Range1> operator()(_Range1&& __range1,
70 _Range2&& __range2,
71 _Pred __pred = {},
72 _Proj1 __proj1 = {},
73 _Proj2 __proj2 = {}) const {
72 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()(
73 _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
7474 auto __ret = std::__find_end_impl<_RangeAlgPolicy>(
7575 ranges::begin(__range1),
7676 ranges::end(__range1),
......@@ -87,12 +87,12 @@ struct __fn {
8787} // namespace __find_end
8888
8989inline namespace __cpo {
90 inline constexpr auto find_end = __find_end::__fn{};
90inline constexpr auto find_end = __find_end::__fn{};
9191} // namespace __cpo
9292} // namespace ranges
9393
9494_LIBCPP_END_NAMESPACE_STD
9595
96#endif // _LIBCPP_STD_VER > 17
96#endif // _LIBCPP_STD_VER >= 20
9797
9898#endif // _LIBCPP___ALGORITHM_RANGES_FIND_END_H
lib/libcxx/include/__algorithm/ranges_find_first_of.h+37-37
......@@ -24,21 +24,22 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
3131namespace ranges {
3232namespace __find_first_of {
3333struct __fn {
34
3534 template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
36 _LIBCPP_HIDE_FROM_ABI constexpr static
37 _Iter1 __find_first_of_impl(_Iter1 __first1, _Sent1 __last1,
38 _Iter2 __first2, _Sent2 __last2,
39 _Pred& __pred,
40 _Proj1& __proj1,
41 _Proj2& __proj2) {
35 _LIBCPP_HIDE_FROM_ABI constexpr static _Iter1 __find_first_of_impl(
36 _Iter1 __first1,
37 _Sent1 __last1,
38 _Iter2 __first2,
39 _Sent2 __last2,
40 _Pred& __pred,
41 _Proj1& __proj1,
42 _Proj2& __proj2) {
4243 for (; __first1 != __last1; ++__first1) {
4344 for (auto __j = __first2; __j != __last2; ++__j) {
4445 if (std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__j)))
......@@ -48,54 +49,53 @@ struct __fn {
4849 return __first1;
4950 }
5051
51 template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
52 forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
53 class _Pred = ranges::equal_to,
52 template <input_iterator _Iter1,
53 sentinel_for<_Iter1> _Sent1,
54 forward_iterator _Iter2,
55 sentinel_for<_Iter2> _Sent2,
56 class _Pred = ranges::equal_to,
5457 class _Proj1 = identity,
5558 class _Proj2 = identity>
5659 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
57 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
58 _Iter1 operator()(_Iter1 __first1, _Sent1 __last1,
59 _Iter2 __first2, _Sent2 __last2,
60 _Pred __pred = {},
61 _Proj1 __proj1 = {},
62 _Proj2 __proj2 = {}) const {
63 return __find_first_of_impl(std::move(__first1), std::move(__last1),
64 std::move(__first2), std::move(__last2),
65 __pred,
66 __proj1,
67 __proj2);
60 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter1 operator()(
61 _Iter1 __first1,
62 _Sent1 __last1,
63 _Iter2 __first2,
64 _Sent2 __last2,
65 _Pred __pred = {},
66 _Proj1 __proj1 = {},
67 _Proj2 __proj2 = {}) const {
68 return __find_first_of_impl(
69 std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);
6870 }
6971
7072 template <input_range _Range1,
7173 forward_range _Range2,
72 class _Pred = ranges::equal_to,
74 class _Pred = ranges::equal_to,
7375 class _Proj1 = identity,
7476 class _Proj2 = identity>
7577 requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
76 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
77 borrowed_iterator_t<_Range1> operator()(_Range1&& __range1,
78 _Range2&& __range2,
79 _Pred __pred = {},
80 _Proj1 __proj1 = {},
81 _Proj2 __proj2 = {}) const {
82 return __find_first_of_impl(ranges::begin(__range1), ranges::end(__range1),
83 ranges::begin(__range2), ranges::end(__range2),
84 __pred,
85 __proj1,
86 __proj2);
78 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range1> operator()(
79 _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
80 return __find_first_of_impl(
81 ranges::begin(__range1),
82 ranges::end(__range1),
83 ranges::begin(__range2),
84 ranges::end(__range2),
85 __pred,
86 __proj1,
87 __proj2);
8788 }
88
8989};
9090} // namespace __find_first_of
9191
9292inline namespace __cpo {
93 inline constexpr auto find_first_of = __find_first_of::__fn{};
93inline constexpr auto find_first_of = __find_first_of::__fn{};
9494} // namespace __cpo
9595} // namespace ranges
9696
9797_LIBCPP_END_NAMESPACE_STD
9898
99#endif // _LIBCPP_STD_VER > 17
99#endif // _LIBCPP_STD_VER >= 20
100100
101101#endif // _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H
lib/libcxx/include/__algorithm/ranges_find_if.h+12-13
......@@ -24,15 +24,14 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
3131namespace ranges {
3232
3333template <class _Ip, class _Sp, class _Pred, class _Proj>
34_LIBCPP_HIDE_FROM_ABI static constexpr
35_Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) {
34_LIBCPP_HIDE_FROM_ABI constexpr _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) {
3635 for (; __first != __last; ++__first) {
3736 if (std::invoke(__pred, std::invoke(__proj, *__first)))
3837 break;
......@@ -42,30 +41,30 @@ _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) {
4241
4342namespace __find_if {
4443struct __fn {
45
46 template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
44 template <input_iterator _Ip,
45 sentinel_for<_Ip> _Sp,
46 class _Proj = identity,
4747 indirect_unary_predicate<projected<_Ip, _Proj>> _Pred>
48 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
49 _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
48 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip
49 operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
5050 return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj);
5151 }
5252
53 template <input_range _Rp, class _Proj = identity,
54 indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
55 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
56 borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
53 template <input_range _Rp, class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
54 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
55 operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
5756 return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
5857 }
5958};
6059} // namespace __find_if
6160
6261inline namespace __cpo {
63 inline constexpr auto find_if = __find_if::__fn{};
62inline constexpr auto find_if = __find_if::__fn{};
6463} // namespace __cpo
6564} // namespace ranges
6665
6766_LIBCPP_END_NAMESPACE_STD
6867
69#endif // _LIBCPP_STD_VER > 17
68#endif // _LIBCPP_STD_VER >= 20
7069
7170#endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_H
lib/libcxx/include/__algorithm/ranges_find_if_not.h+11-10
......@@ -26,25 +26,26 @@
2626# pragma GCC system_header
2727#endif
2828
29#if _LIBCPP_STD_VER > 17
29#if _LIBCPP_STD_VER >= 20
3030
3131_LIBCPP_BEGIN_NAMESPACE_STD
3232
3333namespace ranges {
3434namespace __find_if_not {
3535struct __fn {
36 template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
36 template <input_iterator _Ip,
37 sentinel_for<_Ip> _Sp,
38 class _Proj = identity,
3739 indirect_unary_predicate<projected<_Ip, _Proj>> _Pred>
38 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
39 _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
40 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip
41 operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
4042 auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); };
4143 return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred2, __proj);
4244 }
4345
44 template <input_range _Rp, class _Proj = identity,
45 indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
46 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
47 borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
46 template <input_range _Rp, class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
47 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
48 operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
4849 auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); };
4950 return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred2, __proj);
5051 }
......@@ -52,12 +53,12 @@ struct __fn {
5253} // namespace __find_if_not
5354
5455inline namespace __cpo {
55 inline constexpr auto find_if_not = __find_if_not::__fn{};
56inline constexpr auto find_if_not = __find_if_not::__fn{};
5657} // namespace __cpo
5758} // namespace ranges
5859
5960_LIBCPP_END_NAMESPACE_STD
6061
61#endif // _LIBCPP_STD_VER > 17
62#endif // _LIBCPP_STD_VER >= 20
6263
6364#endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H
lib/libcxx/include/__algorithm/ranges_for_each.h+11-13
......@@ -24,7 +24,7 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
......@@ -37,42 +37,40 @@ namespace __for_each {
3737struct __fn {
3838private:
3939 template <class _Iter, class _Sent, class _Proj, class _Func>
40 _LIBCPP_HIDE_FROM_ABI constexpr static
41 for_each_result<_Iter, _Func> __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) {
40 _LIBCPP_HIDE_FROM_ABI constexpr static for_each_result<_Iter, _Func>
41 __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) {
4242 for (; __first != __last; ++__first)
4343 std::invoke(__func, std::invoke(__proj, *__first));
4444 return {std::move(__first), std::move(__func)};
4545 }
4646
4747public:
48 template <input_iterator _Iter, sentinel_for<_Iter> _Sent,
48 template <input_iterator _Iter,
49 sentinel_for<_Iter> _Sent,
4950 class _Proj = identity,
5051 indirectly_unary_invocable<projected<_Iter, _Proj>> _Func>
51 _LIBCPP_HIDE_FROM_ABI constexpr
52 for_each_result<_Iter, _Func> operator()(_Iter __first, _Sent __last, _Func __func, _Proj __proj = {}) const {
52 _LIBCPP_HIDE_FROM_ABI constexpr for_each_result<_Iter, _Func>
53 operator()(_Iter __first, _Sent __last, _Func __func, _Proj __proj = {}) const {
5354 return __for_each_impl(std::move(__first), std::move(__last), __func, __proj);
5455 }
5556
5657 template <input_range _Range,
5758 class _Proj = identity,
5859 indirectly_unary_invocable<projected<iterator_t<_Range>, _Proj>> _Func>
59 _LIBCPP_HIDE_FROM_ABI constexpr
60 for_each_result<borrowed_iterator_t<_Range>, _Func> operator()(_Range&& __range,
61 _Func __func,
62 _Proj __proj = {}) const {
60 _LIBCPP_HIDE_FROM_ABI constexpr for_each_result<borrowed_iterator_t<_Range>, _Func>
61 operator()(_Range&& __range, _Func __func, _Proj __proj = {}) const {
6362 return __for_each_impl(ranges::begin(__range), ranges::end(__range), __func, __proj);
6463 }
65
6664};
6765} // namespace __for_each
6866
6967inline namespace __cpo {
70 inline constexpr auto for_each = __for_each::__fn{};
68inline constexpr auto for_each = __for_each::__fn{};
7169} // namespace __cpo
7270} // namespace ranges
7371
7472_LIBCPP_END_NAMESPACE_STD
7573
76#endif // _LIBCPP_STD_VER > 17
74#endif // _LIBCPP_STD_VER >= 20
7775
7876#endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H
lib/libcxx/include/__algorithm/ranges_for_each_n.h+6-13
......@@ -24,7 +24,7 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
......@@ -35,32 +35,25 @@ using for_each_n_result = in_fun_result<_Iter, _Func>;
3535
3636namespace __for_each_n {
3737struct __fn {
38
39 template <input_iterator _Iter,
40 class _Proj = identity,
41 indirectly_unary_invocable<projected<_Iter, _Proj>> _Func>
42 _LIBCPP_HIDE_FROM_ABI constexpr
43 for_each_n_result<_Iter, _Func> operator()(_Iter __first,
44 iter_difference_t<_Iter> __count,
45 _Func __func,
46 _Proj __proj = {}) const {
38 template <input_iterator _Iter, class _Proj = identity, indirectly_unary_invocable<projected<_Iter, _Proj>> _Func>
39 _LIBCPP_HIDE_FROM_ABI constexpr for_each_n_result<_Iter, _Func>
40 operator()(_Iter __first, iter_difference_t<_Iter> __count, _Func __func, _Proj __proj = {}) const {
4741 while (__count-- > 0) {
4842 std::invoke(__func, std::invoke(__proj, *__first));
4943 ++__first;
5044 }
5145 return {std::move(__first), std::move(__func)};
5246 }
53
5447};
5548} // namespace __for_each_n
5649
5750inline namespace __cpo {
58 inline constexpr auto for_each_n = __for_each_n::__fn{};
51inline constexpr auto for_each_n = __for_each_n::__fn{};
5952} // namespace __cpo
6053} // namespace ranges
6154
6255_LIBCPP_END_NAMESPACE_STD
6356
64#endif // _LIBCPP_STD_VER > 17
57#endif // _LIBCPP_STD_VER >= 20
6558
6659#endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H
lib/libcxx/include/__algorithm/ranges_generate.h+8-13
......@@ -24,7 +24,7 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
......@@ -32,10 +32,8 @@ namespace ranges {
3232namespace __generate {
3333
3434struct __fn {
35
3635 template <class _OutIter, class _Sent, class _Func>
37 _LIBCPP_HIDE_FROM_ABI constexpr
38 static _OutIter __generate_fn_impl(_OutIter __first, _Sent __last, _Func& __gen) {
36 _LIBCPP_HIDE_FROM_ABI constexpr static _OutIter __generate_fn_impl(_OutIter __first, _Sent __last, _Func& __gen) {
3937 for (; __first != __last; ++__first) {
4038 *__first = __gen();
4139 }
......@@ -44,30 +42,27 @@ struct __fn {
4442 }
4543
4644 template <input_or_output_iterator _OutIter, sentinel_for<_OutIter> _Sent, copy_constructible _Func>
47 requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>>
48 _LIBCPP_HIDE_FROM_ABI constexpr
49 _OutIter operator()(_OutIter __first, _Sent __last, _Func __gen) const {
45 requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>>
46 _LIBCPP_HIDE_FROM_ABI constexpr _OutIter operator()(_OutIter __first, _Sent __last, _Func __gen) const {
5047 return __generate_fn_impl(std::move(__first), std::move(__last), __gen);
5148 }
5249
5350 template <class _Range, copy_constructible _Func>
54 requires invocable<_Func&> && output_range<_Range, invoke_result_t<_Func&>>
55 _LIBCPP_HIDE_FROM_ABI constexpr
56 borrowed_iterator_t<_Range> operator()(_Range&& __range, _Func __gen) const {
51 requires invocable<_Func&> && output_range<_Range, invoke_result_t<_Func&>>
52 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, _Func __gen) const {
5753 return __generate_fn_impl(ranges::begin(__range), ranges::end(__range), __gen);
5854 }
59
6055};
6156
6257} // namespace __generate
6358
6459inline namespace __cpo {
65 inline constexpr auto generate = __generate::__fn{};
60inline constexpr auto generate = __generate::__fn{};
6661} // namespace __cpo
6762} // namespace ranges
6863
6964_LIBCPP_END_NAMESPACE_STD
7065
71#endif // _LIBCPP_STD_VER > 17
66#endif // _LIBCPP_STD_VER >= 20
7267
7368#endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_H
lib/libcxx/include/__algorithm/ranges_generate_n.h+6-8
......@@ -25,7 +25,7 @@
2525# pragma GCC system_header
2626#endif
2727
28#if _LIBCPP_STD_VER > 17
28#if _LIBCPP_STD_VER >= 20
2929
3030_LIBCPP_BEGIN_NAMESPACE_STD
3131
......@@ -33,11 +33,10 @@ namespace ranges {
3333namespace __generate_n {
3434
3535struct __fn {
36
3736 template <input_or_output_iterator _OutIter, copy_constructible _Func>
38 requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>>
39 _LIBCPP_HIDE_FROM_ABI constexpr
40 _OutIter operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const {
37 requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>>
38 _LIBCPP_HIDE_FROM_ABI constexpr _OutIter
39 operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const {
4140 for (; __n > 0; --__n) {
4241 *__first = __gen();
4342 ++__first;
......@@ -45,18 +44,17 @@ struct __fn {
4544
4645 return __first;
4746 }
48
4947};
5048
5149} // namespace __generate_n
5250
5351inline namespace __cpo {
54 inline constexpr auto generate_n = __generate_n::__fn{};
52inline constexpr auto generate_n = __generate_n::__fn{};
5553} // namespace __cpo
5654} // namespace ranges
5755
5856_LIBCPP_END_NAMESPACE_STD
5957
60#endif // _LIBCPP_STD_VER > 17
58#endif // _LIBCPP_STD_VER >= 20
6159
6260#endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H
lib/libcxx/include/__algorithm/ranges_includes.h+16-18
......@@ -27,7 +27,7 @@
2727# pragma GCC system_header
2828#endif
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_BEGIN_NAMESPACE_STD
3333
......@@ -35,14 +35,13 @@ namespace ranges {
3535namespace __includes {
3636
3737struct __fn {
38 template <
39 input_iterator _Iter1,
40 sentinel_for<_Iter1> _Sent1,
41 input_iterator _Iter2,
42 sentinel_for<_Iter2> _Sent2,
43 class _Proj1 = identity,
44 class _Proj2 = identity,
45 indirect_strict_weak_order<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Comp = ranges::less>
38 template <input_iterator _Iter1,
39 sentinel_for<_Iter1> _Sent1,
40 input_iterator _Iter2,
41 sentinel_for<_Iter2> _Sent2,
42 class _Proj1 = identity,
43 class _Proj2 = identity,
44 indirect_strict_weak_order<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Comp = ranges::less>
4645 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
4746 _Iter1 __first1,
4847 _Sent1 __last1,
......@@ -61,13 +60,12 @@ struct __fn {
6160 std::move(__proj2));
6261 }
6362
64 template <
65 input_range _Range1,
66 input_range _Range2,
67 class _Proj1 = identity,
68 class _Proj2 = identity,
69 indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>>
70 _Comp = ranges::less>
63 template <input_range _Range1,
64 input_range _Range2,
65 class _Proj1 = identity,
66 class _Proj2 = identity,
67 indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>>
68 _Comp = ranges::less>
7169 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
7270 _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
7371 return std::__includes(
......@@ -84,12 +82,12 @@ struct __fn {
8482} // namespace __includes
8583
8684inline namespace __cpo {
87 inline constexpr auto includes = __includes::__fn{};
85inline constexpr auto includes = __includes::__fn{};
8886} // namespace __cpo
8987} // namespace ranges
9088
9189_LIBCPP_END_NAMESPACE_STD
9290
93#endif // _LIBCPP_STD_VER > 17
91#endif // _LIBCPP_STD_VER >= 20
9492
9593#endif // _LIBCPP___ALGORITHM_RANGES_INCLUDES_H
lib/libcxx/include/__algorithm/ranges_inplace_merge.h+27-33
......@@ -31,55 +31,49 @@
3131# pragma GCC system_header
3232#endif
3333
34#if _LIBCPP_STD_VER > 17
34#if _LIBCPP_STD_VER >= 20
3535
3636_LIBCPP_BEGIN_NAMESPACE_STD
3737
3838namespace ranges {
3939namespace __inplace_merge {
4040
41 struct __fn {
42 template <class _Iter, class _Sent, class _Comp, class _Proj>
43 _LIBCPP_HIDE_FROM_ABI static constexpr auto
44 __inplace_merge_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
45 auto __last_iter = ranges::next(__middle, __last);
46 std::__inplace_merge<_RangeAlgPolicy>(
47 std::move(__first), std::move(__middle), __last_iter, std::__make_projected(__comp, __proj));
48 return __last_iter;
49 }
41struct __fn {
42 template <class _Iter, class _Sent, class _Comp, class _Proj>
43 _LIBCPP_HIDE_FROM_ABI static constexpr auto
44 __inplace_merge_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
45 auto __last_iter = ranges::next(__middle, __last);
46 std::__inplace_merge<_RangeAlgPolicy>(
47 std::move(__first), std::move(__middle), __last_iter, std::__make_projected(__comp, __proj));
48 return __last_iter;
49 }
5050
51 template <
52 bidirectional_iterator _Iter,
53 sentinel_for<_Iter> _Sent,
54 class _Comp = ranges::less,
55 class _Proj = identity>
56 requires sortable<_Iter, _Comp, _Proj>
57 _LIBCPP_HIDE_FROM_ABI _Iter
58 operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
59 return __inplace_merge_impl(
60 std::move(__first), std::move(__middle), std::move(__last), std::move(__comp), std::move(__proj));
61 }
51 template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
52 requires sortable<_Iter, _Comp, _Proj>
53 _LIBCPP_HIDE_FROM_ABI _Iter
54 operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
55 return __inplace_merge_impl(
56 std::move(__first), std::move(__middle), std::move(__last), std::move(__comp), std::move(__proj));
57 }
6258
63 template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity>
64 requires sortable<
65 iterator_t<_Range>,
66 _Comp,
67 _Proj> _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range>
68 operator()(_Range&& __range, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const {
69 return __inplace_merge_impl(
70 ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__comp), std::move(__proj));
71 }
72 };
59 template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity>
60 requires sortable<iterator_t<_Range>, _Comp, _Proj>
61 _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range>
62 operator()(_Range&& __range, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const {
63 return __inplace_merge_impl(
64 ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__comp), std::move(__proj));
65 }
66};
7367
7468} // namespace __inplace_merge
7569
7670inline namespace __cpo {
77 inline constexpr auto inplace_merge = __inplace_merge::__fn{};
71inline constexpr auto inplace_merge = __inplace_merge::__fn{};
7872} // namespace __cpo
7973} // namespace ranges
8074
8175_LIBCPP_END_NAMESPACE_STD
8276
83#endif // _LIBCPP_STD_VER > 17
77#endif // _LIBCPP_STD_VER >= 20
8478
8579#endif // _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H
lib/libcxx/include/__algorithm/ranges_is_heap.h+15-13
......@@ -26,7 +26,7 @@
2626# pragma GCC system_header
2727#endif
2828
29#if _LIBCPP_STD_VER > 17
29#if _LIBCPP_STD_VER >= 20
3030
3131_LIBCPP_BEGIN_NAMESPACE_STD
3232
......@@ -34,28 +34,30 @@ namespace ranges {
3434namespace __is_heap {
3535
3636struct __fn {
37
3837 template <class _Iter, class _Sent, class _Proj, class _Comp>
39 _LIBCPP_HIDE_FROM_ABI constexpr
40 static bool __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
41 auto __last_iter = ranges::next(__first, __last);
38 _LIBCPP_HIDE_FROM_ABI constexpr static bool
39 __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
40 auto __last_iter = ranges::next(__first, __last);
4241 auto&& __projected_comp = std::__make_projected(__comp, __proj);
4342
4443 auto __result = std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp);
4544 return __result == __last;
4645 }
4746
48 template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
47 template <random_access_iterator _Iter,
48 sentinel_for<_Iter> _Sent,
49 class _Proj = identity,
4950 indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less>
50 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
51 bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
51 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
52 operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
5253 return __is_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
5354 }
5455
55 template <random_access_range _Range, class _Proj = identity,
56 template <random_access_range _Range,
57 class _Proj = identity,
5658 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
57 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
58 bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
59 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
60 operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
5961 return __is_heap_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj);
6062 }
6163};
......@@ -63,12 +65,12 @@ struct __fn {
6365} // namespace __is_heap
6466
6567inline namespace __cpo {
66 inline constexpr auto is_heap = __is_heap::__fn{};
68inline constexpr auto is_heap = __is_heap::__fn{};
6769} // namespace __cpo
6870} // namespace ranges
6971
7072_LIBCPP_END_NAMESPACE_STD
7173
72#endif // _LIBCPP_STD_VER > 17
74#endif // _LIBCPP_STD_VER >= 20
7375
7476#endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H
lib/libcxx/include/__algorithm/ranges_is_heap_until.h+15-14
......@@ -27,7 +27,7 @@
2727# pragma GCC system_header
2828#endif
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_BEGIN_NAMESPACE_STD
3333
......@@ -35,41 +35,42 @@ namespace ranges {
3535namespace __is_heap_until {
3636
3737struct __fn {
38
3938 template <class _Iter, class _Sent, class _Proj, class _Comp>
40 _LIBCPP_HIDE_FROM_ABI constexpr
41 static _Iter __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
42 auto __last_iter = ranges::next(__first, __last);
39 _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
40 __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
41 auto __last_iter = ranges::next(__first, __last);
4342 auto&& __projected_comp = std::__make_projected(__comp, __proj);
4443
4544 return std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp);
4645 }
4746
48 template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
47 template <random_access_iterator _Iter,
48 sentinel_for<_Iter> _Sent,
49 class _Proj = identity,
4950 indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less>
50 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
51 _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
51 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter
52 operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
5253 return __is_heap_until_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
5354 }
5455
55 template <random_access_range _Range, class _Proj = identity,
56 template <random_access_range _Range,
57 class _Proj = identity,
5658 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
57 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
58 borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
59 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
60 operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
5961 return __is_heap_until_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj);
6062 }
61
6263};
6364
6465} // namespace __is_heap_until
6566
6667inline namespace __cpo {
67 inline constexpr auto is_heap_until = __is_heap_until::__fn{};
68inline constexpr auto is_heap_until = __is_heap_until::__fn{};
6869} // namespace __cpo
6970} // namespace ranges
7071
7172_LIBCPP_END_NAMESPACE_STD
7273
73#endif // _LIBCPP_STD_VER > 17
74#endif // _LIBCPP_STD_VER >= 20
7475
7576#endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H
lib/libcxx/include/__algorithm/ranges_is_partitioned.h+13-13
......@@ -23,17 +23,16 @@
2323# pragma GCC system_header
2424#endif
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
3030namespace ranges {
3131namespace __is_partitioned {
3232struct __fn {
33
3433 template <class _Iter, class _Sent, class _Proj, class _Pred>
35 _LIBCPP_HIDE_FROM_ABI constexpr static
36 bool __is_parititioned_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
34 _LIBCPP_HIDE_FROM_ABI constexpr static bool
35 __is_partitioned_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
3736 for (; __first != __last; ++__first) {
3837 if (!std::invoke(__pred, std::invoke(__proj, *__first)))
3938 break;
......@@ -51,31 +50,32 @@ struct __fn {
5150 return true;
5251 }
5352
54 template <input_iterator _Iter, sentinel_for<_Iter> _Sent,
53 template <input_iterator _Iter,
54 sentinel_for<_Iter> _Sent,
5555 class _Proj = identity,
5656 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
57 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
58 bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
59 return __is_parititioned_impl(std::move(__first), std::move(__last), __pred, __proj);
57 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
58 operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
59 return __is_partitioned_impl(std::move(__first), std::move(__last), __pred, __proj);
6060 }
6161
6262 template <input_range _Range,
6363 class _Proj = identity,
6464 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
65 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
66 bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
67 return __is_parititioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
65 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
66 operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
67 return __is_partitioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
6868 }
6969};
7070} // namespace __is_partitioned
7171
7272inline namespace __cpo {
73 inline constexpr auto is_partitioned = __is_partitioned::__fn{};
73inline constexpr auto is_partitioned = __is_partitioned::__fn{};
7474} // namespace __cpo
7575} // namespace ranges
7676
7777_LIBCPP_END_NAMESPACE_STD
7878
79#endif // _LIBCPP_STD_VER > 17
79#endif // _LIBCPP_STD_VER >= 20
8080
8181#endif // _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H
lib/libcxx/include/__algorithm/ranges_is_permutation.h+43-30
......@@ -25,65 +25,78 @@
2525# pragma GCC system_header
2626#endif
2727
28#if _LIBCPP_STD_VER > 17
28#if _LIBCPP_STD_VER >= 20
2929
3030_LIBCPP_BEGIN_NAMESPACE_STD
3131
3232namespace ranges {
3333namespace __is_permutation {
3434struct __fn {
35
36 template <class _Iter1, class _Sent1, class _Iter2, class _Sent2,
37 class _Proj1, class _Proj2, class _Pred>
38 _LIBCPP_HIDE_FROM_ABI constexpr static
39 bool __is_permutation_func_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
40 _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
35 template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Proj1, class _Proj2, class _Pred>
36 _LIBCPP_HIDE_FROM_ABI constexpr static bool __is_permutation_func_impl(
37 _Iter1 __first1,
38 _Sent1 __last1,
39 _Iter2 __first2,
40 _Sent2 __last2,
41 _Pred& __pred,
42 _Proj1& __proj1,
43 _Proj2& __proj2) {
4144 return std::__is_permutation<_RangeAlgPolicy>(
42 std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
43 __pred, __proj1, __proj2);
45 std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);
4446 }
4547
46 template <forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
47 forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
48 class _Proj1 = identity,
49 class _Proj2 = identity,
50 indirect_equivalence_relation<projected<_Iter1, _Proj1>,
51 projected<_Iter2, _Proj2>> _Pred = ranges::equal_to>
52 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
53 bool operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
54 _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
48 template <
49 forward_iterator _Iter1,
50 sentinel_for<_Iter1> _Sent1,
51 forward_iterator _Iter2,
52 sentinel_for<_Iter2> _Sent2,
53 class _Proj1 = identity,
54 class _Proj2 = identity,
55 indirect_equivalence_relation<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Pred = ranges::equal_to>
56 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
57 _Iter1 __first1,
58 _Sent1 __last1,
59 _Iter2 __first2,
60 _Sent2 __last2,
61 _Pred __pred = {},
62 _Proj1 __proj1 = {},
63 _Proj2 __proj2 = {}) const {
5564 return __is_permutation_func_impl(
56 std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
57 __pred, __proj1, __proj2);
65 std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);
5866 }
5967
6068 template <forward_range _Range1,
6169 forward_range _Range2,
62 class _Proj1 = identity,
63 class _Proj2 = identity,
64 indirect_equivalence_relation<projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>> _Pred = ranges::equal_to>
65 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
66 bool operator()(_Range1&& __range1, _Range2&& __range2,
67 _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
70 class _Proj1 = identity,
71 class _Proj2 = identity,
72 indirect_equivalence_relation<projected<iterator_t<_Range1>, _Proj1>,
73 projected<iterator_t<_Range2>, _Proj2>> _Pred = ranges::equal_to>
74 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
75 _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
6876 if constexpr (sized_range<_Range1> && sized_range<_Range2>) {
6977 if (ranges::distance(__range1) != ranges::distance(__range2))
7078 return false;
7179 }
7280
7381 return __is_permutation_func_impl(
74 ranges::begin(__range1), ranges::end(__range1), ranges::begin(__range2), ranges::end(__range2),
75 __pred, __proj1, __proj2);
82 ranges::begin(__range1),
83 ranges::end(__range1),
84 ranges::begin(__range2),
85 ranges::end(__range2),
86 __pred,
87 __proj1,
88 __proj2);
7689 }
7790};
7891} // namespace __is_permutation
7992
8093inline namespace __cpo {
81 inline constexpr auto is_permutation = __is_permutation::__fn{};
94inline constexpr auto is_permutation = __is_permutation::__fn{};
8295} // namespace __cpo
8396} // namespace ranges
8497
8598_LIBCPP_END_NAMESPACE_STD
8699
87#endif // _LIBCPP_STD_VER > 17
100#endif // _LIBCPP_STD_VER >= 20
88101
89102#endif // _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H
lib/libcxx/include/__algorithm/ranges_is_sorted.h+11-10
......@@ -23,26 +23,27 @@
2323# pragma GCC system_header
2424#endif
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
3030namespace ranges {
3131namespace __is_sorted {
3232struct __fn {
33 template <forward_iterator _Iter, sentinel_for<_Iter> _Sent,
34 class _Proj = identity,
33 template <forward_iterator _Iter,
34 sentinel_for<_Iter> _Sent,
35 class _Proj = identity,
3536 indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less>
36 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
37 bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
37 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
38 operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
3839 return ranges::__is_sorted_until_impl(std::move(__first), __last, __comp, __proj) == __last;
3940 }
4041
4142 template <forward_range _Range,
42 class _Proj = identity,
43 class _Proj = identity,
4344 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
44 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
45 bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
45 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
46 operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
4647 auto __last = ranges::end(__range);
4748 return ranges::__is_sorted_until_impl(ranges::begin(__range), __last, __comp, __proj) == __last;
4849 }
......@@ -50,12 +51,12 @@ struct __fn {
5051} // namespace __is_sorted
5152
5253inline namespace __cpo {
53 inline constexpr auto is_sorted = __is_sorted::__fn{};
54inline constexpr auto is_sorted = __is_sorted::__fn{};
5455} // namespace __cpo
5556} // namespace ranges
5657
5758_LIBCPP_END_NAMESPACE_STD
5859
59#endif // _LIBCPP_STD_VER > 17
60#endif // _LIBCPP_STD_VER >= 20
6061
6162#endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H
lib/libcxx/include/__algorithm/ranges_is_sorted_until.h+13-12
......@@ -24,15 +24,15 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
3131namespace ranges {
3232
3333template <class _Iter, class _Sent, class _Proj, class _Comp>
34_LIBCPP_HIDE_FROM_ABI constexpr
35_Iter __is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
34_LIBCPP_HIDE_FROM_ABI constexpr _Iter
35__is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
3636 if (__first == __last)
3737 return __first;
3838 auto __i = __first;
......@@ -46,31 +46,32 @@ _Iter __is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj&
4646
4747namespace __is_sorted_until {
4848struct __fn {
49 template <forward_iterator _Iter, sentinel_for<_Iter> _Sent,
50 class _Proj = identity,
49 template <forward_iterator _Iter,
50 sentinel_for<_Iter> _Sent,
51 class _Proj = identity,
5152 indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less>
52 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
53 _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
53 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter
54 operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
5455 return ranges::__is_sorted_until_impl(std::move(__first), std::move(__last), __comp, __proj);
5556 }
5657
5758 template <forward_range _Range,
58 class _Proj = identity,
59 class _Proj = identity,
5960 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
60 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
61 borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
61 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
62 operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
6263 return ranges::__is_sorted_until_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj);
6364 }
6465};
6566} // namespace __is_sorted_until
6667
6768inline namespace __cpo {
68 inline constexpr auto is_sorted_until = __is_sorted_until::__fn{};
69inline constexpr auto is_sorted_until = __is_sorted_until::__fn{};
6970} // namespace __cpo
7071} // namespace ranges
7172
7273_LIBCPP_END_NAMESPACE_STD
7374
74#endif // _LIBCPP_STD_VER > 17
75#endif // _LIBCPP_STD_VER >= 20
7576
7677#endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H
lib/libcxx/include/__algorithm/ranges_iterator_concept.h+2-2
......@@ -18,7 +18,7 @@
1818# pragma GCC system_header
1919#endif
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
......@@ -46,6 +46,6 @@ using __iterator_concept = decltype(__get_iterator_concept<_Iter>());
4646} // namespace ranges
4747_LIBCPP_END_NAMESPACE_STD
4848
49#endif // _LIBCPP_STD_VER > 17
49#endif // _LIBCPP_STD_VER >= 20
5050
5151#endif // _LIBCPP___ALGORITHM_RANGES_ITERATOR_CONCEPT_H
lib/libcxx/include/__algorithm/ranges_lexicographical_compare.h+40-37
......@@ -23,24 +23,24 @@
2323# pragma GCC system_header
2424#endif
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
3030namespace ranges {
3131namespace __lexicographical_compare {
3232struct __fn {
33
3433 template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Proj1, class _Proj2, class _Comp>
35 _LIBCPP_HIDE_FROM_ABI constexpr static
36 bool __lexicographical_compare_impl(_Iter1 __first1, _Sent1 __last1,
37 _Iter2 __first2, _Sent2 __last2,
38 _Comp& __comp,
39 _Proj1& __proj1,
40 _Proj2& __proj2) {
34 _LIBCPP_HIDE_FROM_ABI constexpr static bool __lexicographical_compare_impl(
35 _Iter1 __first1,
36 _Sent1 __last1,
37 _Iter2 __first2,
38 _Sent2 __last2,
39 _Comp& __comp,
40 _Proj1& __proj1,
41 _Proj2& __proj2) {
4142 while (__first2 != __last2) {
42 if (__first1 == __last1
43 || std::invoke(__comp, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2)))
43 if (__first1 == __last1 || std::invoke(__comp, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2)))
4444 return true;
4545 if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1)))
4646 return false;
......@@ -50,49 +50,52 @@ struct __fn {
5050 return false;
5151 }
5252
53 template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
54 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
55 class _Proj1 = identity,
56 class _Proj2 = identity,
53 template <input_iterator _Iter1,
54 sentinel_for<_Iter1> _Sent1,
55 input_iterator _Iter2,
56 sentinel_for<_Iter2> _Sent2,
57 class _Proj1 = identity,
58 class _Proj2 = identity,
5759 indirect_strict_weak_order<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Comp = ranges::less>
58 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
59 bool operator()(_Iter1 __first1, _Sent1 __last1,
60 _Iter2 __first2, _Sent2 __last2,
61 _Comp __comp = {},
62 _Proj1 __proj1 = {},
63 _Proj2 __proj2 = {}) const {
64 return __lexicographical_compare_impl(std::move(__first1), std::move(__last1),
65 std::move(__first2), std::move(__last2),
66 __comp,
67 __proj1,
68 __proj2);
60 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
61 _Iter1 __first1,
62 _Sent1 __last1,
63 _Iter2 __first2,
64 _Sent2 __last2,
65 _Comp __comp = {},
66 _Proj1 __proj1 = {},
67 _Proj2 __proj2 = {}) const {
68 return __lexicographical_compare_impl(
69 std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __comp, __proj1, __proj2);
6970 }
7071
7172 template <input_range _Range1,
7273 input_range _Range2,
7374 class _Proj1 = identity,
7475 class _Proj2 = identity,
75 indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>,
76 projected<iterator_t<_Range2>, _Proj2>> _Comp = ranges::less>
77 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
78 bool operator()(_Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
79 return __lexicographical_compare_impl(ranges::begin(__range1), ranges::end(__range1),
80 ranges::begin(__range2), ranges::end(__range2),
81 __comp,
82 __proj1,
83 __proj2);
76 indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>>
77 _Comp = ranges::less>
78 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
79 _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
80 return __lexicographical_compare_impl(
81 ranges::begin(__range1),
82 ranges::end(__range1),
83 ranges::begin(__range2),
84 ranges::end(__range2),
85 __comp,
86 __proj1,
87 __proj2);
8488 }
85
8689};
8790} // namespace __lexicographical_compare
8891
8992inline namespace __cpo {
90 inline constexpr auto lexicographical_compare = __lexicographical_compare::__fn{};
93inline constexpr auto lexicographical_compare = __lexicographical_compare::__fn{};
9194} // namespace __cpo
9295} // namespace ranges
9396
9497_LIBCPP_END_NAMESPACE_STD
9598
96#endif // _LIBCPP_STD_VER > 17
99#endif // _LIBCPP_STD_VER >= 20
97100
98101#endif // _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H
lib/libcxx/include/__algorithm/ranges_lower_bound.h+16-14
......@@ -27,7 +27,7 @@
2727# pragma GCC system_header
2828#endif
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_BEGIN_NAMESPACE_STD
3333
......@@ -35,32 +35,34 @@ namespace ranges {
3535
3636namespace __lower_bound {
3737struct __fn {
38 template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity,
38 template <forward_iterator _Iter,
39 sentinel_for<_Iter> _Sent,
40 class _Type,
41 class _Proj = identity,
3942 indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
40 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
41 _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
42 return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
43 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter
44 operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
45 return std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
4346 }
4447
45 template <forward_range _Range, class _Type, class _Proj = identity,
48 template <forward_range _Range,
49 class _Type,
50 class _Proj = identity,
4651 indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
47 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
48 borrowed_iterator_t<_Range> operator()(_Range&& __r,
49 const _Type& __value,
50 _Comp __comp = {},
51 _Proj __proj = {}) const {
52 return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj);
52 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
53 operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
54 return std::__lower_bound<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj);
5355 }
5456};
5557} // namespace __lower_bound
5658
5759inline namespace __cpo {
58 inline constexpr auto lower_bound = __lower_bound::__fn{};
60inline constexpr auto lower_bound = __lower_bound::__fn{};
5961} // namespace __cpo
6062} // namespace ranges
6163
6264_LIBCPP_END_NAMESPACE_STD
6365
64#endif // _LIBCPP_STD_VER > 17
66#endif // _LIBCPP_STD_VER >= 20
6567
6668#endif // _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H
lib/libcxx/include/__algorithm/ranges_make_heap.h+9-9
......@@ -32,7 +32,7 @@
3232# pragma GCC system_header
3333#endif
3434
35#if _LIBCPP_STD_VER > 17
35#if _LIBCPP_STD_VER >= 20
3636
3737_LIBCPP_BEGIN_NAMESPACE_STD
3838
......@@ -41,8 +41,8 @@ namespace __make_heap {
4141
4242struct __fn {
4343 template <class _Iter, class _Sent, class _Comp, class _Proj>
44 _LIBCPP_HIDE_FROM_ABI constexpr static
45 _Iter __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
44 _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
45 __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
4646 auto __last_iter = ranges::next(__first, __last);
4747
4848 auto&& __projected_comp = std::__make_projected(__comp, __proj);
......@@ -53,15 +53,15 @@ struct __fn {
5353
5454 template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
5555 requires sortable<_Iter, _Comp, _Proj>
56 _LIBCPP_HIDE_FROM_ABI constexpr
57 _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
56 _LIBCPP_HIDE_FROM_ABI constexpr _Iter
57 operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
5858 return __make_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
5959 }
6060
6161 template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
6262 requires sortable<iterator_t<_Range>, _Comp, _Proj>
63 _LIBCPP_HIDE_FROM_ABI constexpr
64 borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
63 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
64 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
6565 return __make_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
6666 }
6767};
......@@ -69,12 +69,12 @@ struct __fn {
6969} // namespace __make_heap
7070
7171inline namespace __cpo {
72 inline constexpr auto make_heap = __make_heap::__fn{};
72inline constexpr auto make_heap = __make_heap::__fn{};
7373} // namespace __cpo
7474} // namespace ranges
7575
7676_LIBCPP_END_NAMESPACE_STD
7777
78#endif // _LIBCPP_STD_VER > 17
78#endif // _LIBCPP_STD_VER >= 20
7979
8080#endif // _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H
lib/libcxx/include/__algorithm/ranges_max.h+24-17
......@@ -20,6 +20,7 @@
2020#include <__iterator/projected.h>
2121#include <__ranges/access.h>
2222#include <__ranges/concepts.h>
23#include <__type_traits/is_trivially_copyable.h>
2324#include <__utility/move.h>
2425#include <initializer_list>
2526
......@@ -27,44 +28,50 @@
2728# pragma GCC system_header
2829#endif
2930
30#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
3132
3233_LIBCPP_PUSH_MACROS
33#include <__undef_macros>
34# include <__undef_macros>
3435
3536_LIBCPP_BEGIN_NAMESPACE_STD
3637
3738namespace ranges {
3839namespace __max {
3940struct __fn {
40 template <class _Tp, class _Proj = identity,
41 template <class _Tp,
42 class _Proj = identity,
4143 indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less>
42 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
43 const _Tp& operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const {
44 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&
45 operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a,
46 _LIBCPP_LIFETIMEBOUND const _Tp& __b,
47 _Comp __comp = {},
48 _Proj __proj = {}) const {
4449 return std::invoke(__comp, std::invoke(__proj, __a), std::invoke(__proj, __b)) ? __b : __a;
4550 }
4651
47 template <copyable _Tp, class _Proj = identity,
52 template <copyable _Tp,
53 class _Proj = identity,
4854 indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less>
49 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
50 _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const {
51 _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element");
55 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp
56 operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const {
57 _LIBCPP_ASSERT_UNCATEGORIZED(__il.begin() != __il.end(), "initializer_list must contain at least one element");
5258
5359 auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
5460 return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp_lhs_rhs_swapped, __proj);
5561 }
5662
57 template <input_range _Rp, class _Proj = identity,
63 template <input_range _Rp,
64 class _Proj = identity,
5865 indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
5966 requires indirectly_copyable_storable<iterator_t<_Rp>, range_value_t<_Rp>*>
60 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
61 range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
67 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp>
68 operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
6269 auto __first = ranges::begin(__r);
63 auto __last = ranges::end(__r);
70 auto __last = ranges::end(__r);
6471
65 _LIBCPP_ASSERT(__first != __last, "range must contain at least one element");
72 _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "range must contain at least one element");
6673
67 if constexpr (forward_range<_Rp>) {
74 if constexpr (forward_range<_Rp> && !__is_cheap_to_copy<range_value_t<_Rp>>) {
6875 auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
6976 return *ranges::__min_element_impl(std::move(__first), std::move(__last), __comp_lhs_rhs_swapped, __proj);
7077 } else {
......@@ -80,7 +87,7 @@ struct __fn {
8087} // namespace __max
8188
8289inline namespace __cpo {
83 inline constexpr auto max = __max::__fn{};
90inline constexpr auto max = __max::__fn{};
8491} // namespace __cpo
8592} // namespace ranges
8693
......@@ -88,6 +95,6 @@ _LIBCPP_END_NAMESPACE_STD
8895
8996_LIBCPP_POP_MACROS
9097
91#endif // _LIBCPP_STD_VER > 17 &&
98#endif // _LIBCPP_STD_VER >= 20 &&
9299
93100#endif // _LIBCPP___ALGORITHM_RANGES_MAX_H
lib/libcxx/include/__algorithm/ranges_max_element.h+12-9
......@@ -24,25 +24,28 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
3131namespace ranges {
3232namespace __max_element {
3333struct __fn {
34 template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
34 template <forward_iterator _Ip,
35 sentinel_for<_Ip> _Sp,
36 class _Proj = identity,
3537 indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less>
36 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
37 _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
38 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip
39 operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
3840 auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
3941 return ranges::__min_element_impl(__first, __last, __comp_lhs_rhs_swapped, __proj);
4042 }
4143
42 template <forward_range _Rp, class _Proj = identity,
44 template <forward_range _Rp,
45 class _Proj = identity,
4346 indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
44 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
45 borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
47 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
48 operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
4649 auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
4750 return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp_lhs_rhs_swapped, __proj);
4851 }
......@@ -50,12 +53,12 @@ struct __fn {
5053} // namespace __max_element
5154
5255inline namespace __cpo {
53 inline constexpr auto max_element = __max_element::__fn{};
56inline constexpr auto max_element = __max_element::__fn{};
5457} // namespace __cpo
5558} // namespace ranges
5659
5760_LIBCPP_END_NAMESPACE_STD
5861
59#endif // _LIBCPP_STD_VER > 17
62#endif // _LIBCPP_STD_VER >= 20
6063
6164#endif // _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H
lib/libcxx/include/__algorithm/ranges_merge.h+44-53
......@@ -20,14 +20,14 @@
2020#include <__ranges/access.h>
2121#include <__ranges/concepts.h>
2222#include <__ranges/dangling.h>
23#include <__type_traits/remove_cvref.h>
2324#include <__utility/move.h>
24#include <type_traits>
2525
2626#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2727# pragma GCC system_header
2828#endif
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_BEGIN_NAMESPACE_STD
3333
......@@ -38,25 +38,25 @@ using merge_result = in_in_out_result<_InIter1, _InIter2, _OutIter>;
3838
3939namespace __merge {
4040
41template <
42 class _InIter1,
43 class _Sent1,
44 class _InIter2,
45 class _Sent2,
46 class _OutIter,
47 class _Comp,
48 class _Proj1,
49 class _Proj2>
50_LIBCPP_HIDE_FROM_ABI constexpr merge_result<__remove_cvref_t<_InIter1>, __remove_cvref_t<_InIter2>, __remove_cvref_t<_OutIter>>
51__merge_impl(
52 _InIter1&& __first1,
53 _Sent1&& __last1,
54 _InIter2&& __first2,
55 _Sent2&& __last2,
56 _OutIter&& __result,
57 _Comp&& __comp,
58 _Proj1&& __proj1,
59 _Proj2&& __proj2) {
41template < class _InIter1,
42 class _Sent1,
43 class _InIter2,
44 class _Sent2,
45 class _OutIter,
46 class _Comp,
47 class _Proj1,
48 class _Proj2>
49_LIBCPP_HIDE_FROM_ABI constexpr merge_result<__remove_cvref_t<_InIter1>,
50 __remove_cvref_t<_InIter2>,
51 __remove_cvref_t<_OutIter>>
52__merge_impl(_InIter1&& __first1,
53 _Sent1&& __last1,
54 _InIter2&& __first2,
55 _Sent2&& __last2,
56 _OutIter&& __result,
57 _Comp&& __comp,
58 _Proj1&& __proj1,
59 _Proj2&& __proj2) {
6060 for (; __first1 != __last1 && __first2 != __last2; ++__result) {
6161 if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1))) {
6262 *__result = *__first2;
......@@ -72,15 +72,14 @@ __merge_impl(
7272}
7373
7474struct __fn {
75 template <
76 input_iterator _InIter1,
77 sentinel_for<_InIter1> _Sent1,
78 input_iterator _InIter2,
79 sentinel_for<_InIter2> _Sent2,
80 weakly_incrementable _OutIter,
81 class _Comp = less,
82 class _Proj1 = identity,
83 class _Proj2 = identity>
75 template <input_iterator _InIter1,
76 sentinel_for<_InIter1> _Sent1,
77 input_iterator _InIter2,
78 sentinel_for<_InIter2> _Sent2,
79 weakly_incrementable _OutIter,
80 class _Comp = less,
81 class _Proj1 = identity,
82 class _Proj2 = identity>
8483 requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
8584 _LIBCPP_HIDE_FROM_ABI constexpr merge_result<_InIter1, _InIter2, _OutIter> operator()(
8685 _InIter1 __first1,
......@@ -94,28 +93,20 @@ struct __fn {
9493 return __merge::__merge_impl(__first1, __last1, __first2, __last2, __result, __comp, __proj1, __proj2);
9594 }
9695
97 template <
98 input_range _Range1,
99 input_range _Range2,
100 weakly_incrementable _OutIter,
101 class _Comp = less,
102 class _Proj1 = identity,
103 class _Proj2 = identity>
104 requires mergeable<
105 iterator_t<_Range1>,
106 iterator_t<_Range2>,
107 _OutIter,
108 _Comp,
109 _Proj1,
110 _Proj2>
96 template <input_range _Range1,
97 input_range _Range2,
98 weakly_incrementable _OutIter,
99 class _Comp = less,
100 class _Proj1 = identity,
101 class _Proj2 = identity>
102 requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2>
111103 _LIBCPP_HIDE_FROM_ABI constexpr merge_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>, _OutIter>
112 operator()(
113 _Range1&& __range1,
114 _Range2&& __range2,
115 _OutIter __result,
116 _Comp __comp = {},
117 _Proj1 __proj1 = {},
118 _Proj2 __proj2 = {}) const {
104 operator()(_Range1&& __range1,
105 _Range2&& __range2,
106 _OutIter __result,
107 _Comp __comp = {},
108 _Proj1 __proj1 = {},
109 _Proj2 __proj2 = {}) const {
119110 return __merge::__merge_impl(
120111 ranges::begin(__range1),
121112 ranges::end(__range1),
......@@ -131,12 +122,12 @@ struct __fn {
131122} // namespace __merge
132123
133124inline namespace __cpo {
134 inline constexpr auto merge = __merge::__fn{};
125inline constexpr auto merge = __merge::__fn{};
135126} // namespace __cpo
136127} // namespace ranges
137128
138129_LIBCPP_END_NAMESPACE_STD
139130
140#endif // _LIBCPP_STD_VER > 17
131#endif // _LIBCPP_STD_VER >= 20
141132
142133#endif // _LIBCPP___ALGORITHM_RANGES_MERGE_H
lib/libcxx/include/__algorithm/ranges_min.h+24-19
......@@ -20,48 +20,53 @@
2020#include <__iterator/projected.h>
2121#include <__ranges/access.h>
2222#include <__ranges/concepts.h>
23#include <__type_traits/is_trivially_copyable.h>
2324#include <initializer_list>
2425
2526#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2627# pragma GCC system_header
2728#endif
2829
29#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3031
3132_LIBCPP_PUSH_MACROS
32#include <__undef_macros>
33# include <__undef_macros>
3334
3435_LIBCPP_BEGIN_NAMESPACE_STD
3536
3637namespace ranges {
3738namespace __min {
3839struct __fn {
39 template <class _Tp, class _Proj = identity,
40 template <class _Tp,
41 class _Proj = identity,
4042 indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less>
41 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
42 const _Tp& operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const {
43 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&
44 operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a,
45 _LIBCPP_LIFETIMEBOUND const _Tp& __b,
46 _Comp __comp = {},
47 _Proj __proj = {}) const {
4348 return std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a)) ? __b : __a;
4449 }
4550
46 template <copyable _Tp, class _Proj = identity,
51 template <copyable _Tp,
52 class _Proj = identity,
4753 indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less>
48 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
49 _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const {
50 _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element");
54 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp
55 operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const {
56 _LIBCPP_ASSERT_UNCATEGORIZED(__il.begin() != __il.end(), "initializer_list must contain at least one element");
5157 return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp, __proj);
5258 }
5359
54 template <input_range _Rp, class _Proj = identity,
60 template <input_range _Rp,
61 class _Proj = identity,
5562 indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
5663 requires indirectly_copyable_storable<iterator_t<_Rp>, range_value_t<_Rp>*>
57 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
58 range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
64 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp>
65 operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
5966 auto __first = ranges::begin(__r);
60 auto __last = ranges::end(__r);
61
62 _LIBCPP_ASSERT(__first != __last, "range must contain at least one element");
63
64 if constexpr (forward_range<_Rp>) {
67 auto __last = ranges::end(__r);
68 _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "range must contain at least one element");
69 if constexpr (forward_range<_Rp> && !__is_cheap_to_copy<range_value_t<_Rp>>) {
6570 return *ranges::__min_element_impl(__first, __last, __comp, __proj);
6671 } else {
6772 range_value_t<_Rp> __result = *__first;
......@@ -76,7 +81,7 @@ struct __fn {
7681} // namespace __min
7782
7883inline namespace __cpo {
79 inline constexpr auto min = __min::__fn{};
84inline constexpr auto min = __min::__fn{};
8085} // namespace __cpo
8186} // namespace ranges
8287
......@@ -84,6 +89,6 @@ _LIBCPP_END_NAMESPACE_STD
8489
8590_LIBCPP_POP_MACROS
8691
87#endif // _LIBCPP_STD_VER > 17 &&
92#endif // _LIBCPP_STD_VER >= 20 &&
8893
8994#endif // _LIBCPP___ALGORITHM_RANGES_MIN_H
lib/libcxx/include/__algorithm/ranges_min_element.h+13-11
......@@ -24,7 +24,7 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
......@@ -32,8 +32,7 @@ namespace ranges {
3232
3333// TODO(ranges): `ranges::min_element` can now simply delegate to `std::__min_element`.
3434template <class _Ip, class _Sp, class _Proj, class _Comp>
35_LIBCPP_HIDE_FROM_ABI static constexpr
36_Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) {
35_LIBCPP_HIDE_FROM_ABI constexpr _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) {
3736 if (__first == __last)
3837 return __first;
3938
......@@ -46,29 +45,32 @@ _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) {
4645
4746namespace __min_element {
4847struct __fn {
49 template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
48 template <forward_iterator _Ip,
49 sentinel_for<_Ip> _Sp,
50 class _Proj = identity,
5051 indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less>
51 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
52 _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
52 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip
53 operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
5354 return ranges::__min_element_impl(__first, __last, __comp, __proj);
5455 }
5556
56 template <forward_range _Rp, class _Proj = identity,
57 template <forward_range _Rp,
58 class _Proj = identity,
5759 indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
58 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
59 borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
60 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
61 operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
6062 return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
6163 }
6264};
6365} // namespace __min_element
6466
6567inline namespace __cpo {
66 inline constexpr auto min_element = __min_element::__fn{};
68inline constexpr auto min_element = __min_element::__fn{};
6769} // namespace __cpo
6870} // namespace ranges
6971
7072_LIBCPP_END_NAMESPACE_STD
7173
72#endif // _LIBCPP_STD_VER > 17
74#endif // _LIBCPP_STD_VER >= 20
7375
7476#endif // _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H
lib/libcxx/include/__algorithm/ranges_minmax.h+44-19
......@@ -13,14 +13,18 @@
1313#include <__algorithm/minmax_element.h>
1414#include <__assert>
1515#include <__concepts/copyable.h>
16#include <__concepts/same_as.h>
1617#include <__config>
1718#include <__functional/identity.h>
1819#include <__functional/invoke.h>
1920#include <__functional/ranges_operations.h>
2021#include <__iterator/concepts.h>
22#include <__iterator/next.h>
2123#include <__iterator/projected.h>
2224#include <__ranges/access.h>
2325#include <__ranges/concepts.h>
26#include <__type_traits/is_reference.h>
27#include <__type_traits/remove_cvref.h>
2428#include <__utility/forward.h>
2529#include <__utility/move.h>
2630#include <__utility/pair.h>
......@@ -30,10 +34,10 @@
3034# pragma GCC system_header
3135#endif
3236
33#if _LIBCPP_STD_VER > 17
37#if _LIBCPP_STD_VER >= 20
3438
3539_LIBCPP_PUSH_MACROS
36#include <__undef_macros>
40# include <__undef_macros>
3741
3842_LIBCPP_BEGIN_NAMESPACE_STD
3943
......@@ -43,46 +47,67 @@ using minmax_result = min_max_result<_T1>;
4347
4448namespace __minmax {
4549struct __fn {
46 template <class _Type, class _Proj = identity,
50 template <class _Type,
51 class _Proj = identity,
4752 indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less>
4853 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<const _Type&>
49 operator()(const _Type& __a, const _Type& __b, _Comp __comp = {}, _Proj __proj = {}) const {
54 operator()(_LIBCPP_LIFETIMEBOUND const _Type& __a,
55 _LIBCPP_LIFETIMEBOUND const _Type& __b,
56 _Comp __comp = {},
57 _Proj __proj = {}) const {
5058 if (std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a)))
5159 return {__b, __a};
5260 return {__a, __b};
5361 }
5462
55 template <copyable _Type, class _Proj = identity,
63 template <copyable _Type,
64 class _Proj = identity,
5665 indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less>
57 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
58 ranges::minmax_result<_Type> operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const {
59 _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list has to contain at least one element");
66 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<_Type>
67 operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const {
68 _LIBCPP_ASSERT_UNCATEGORIZED(__il.begin() != __il.end(), "initializer_list has to contain at least one element");
6069 auto __iters = std::__minmax_element_impl(__il.begin(), __il.end(), __comp, __proj);
61 return ranges::minmax_result<_Type> { *__iters.first, *__iters.second };
70 return ranges::minmax_result<_Type>{*__iters.first, *__iters.second};
6271 }
6372
64 template <input_range _Range, class _Proj = identity,
73 template <input_range _Range,
74 class _Proj = identity,
6575 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
6676 requires indirectly_copyable_storable<iterator_t<_Range>, range_value_t<_Range>*>
67 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
68 ranges::minmax_result<range_value_t<_Range>> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
69 auto __first = ranges::begin(__r);
70 auto __last = ranges::end(__r);
77 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<range_value_t<_Range>>
78 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
79 auto __first = ranges::begin(__r);
80 auto __last = ranges::end(__r);
7181 using _ValueT = range_value_t<_Range>;
7282
73 _LIBCPP_ASSERT(__first != __last, "range has to contain at least one element");
83 _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "range has to contain at least one element");
7484
7585 if constexpr (forward_range<_Range>) {
86 // Special-case the one element case. Avoid repeatedly initializing objects from the result of an iterator
87 // dereference when doing so might not be idempotent. The `if constexpr` avoids the extra branch in cases where
88 // it's not needed.
89 if constexpr (!same_as<remove_cvref_t<range_reference_t<_Range>>, _ValueT> ||
90 is_rvalue_reference_v<range_reference_t<_Range>>) {
91 if (ranges::next(__first) == __last) {
92 // During initialization, members are allowed to refer to already initialized members
93 // (see http://eel.is/c++draft/dcl.init.aggr#6)
94 minmax_result<_ValueT> __result = {*__first, __result.min};
95 return __result;
96 }
97 }
7698 auto __result = std::__minmax_element_impl(__first, __last, __comp, __proj);
7799 return {*__result.first, *__result.second};
78100 } else {
79101 // input_iterators can't be copied, so the implementation for input_iterators has to store
80102 // the values instead of a pointer to the correct values
81103 auto __less = [&](auto&& __a, auto&& __b) -> bool {
82 return std::invoke(__comp, std::invoke(__proj, std::forward<decltype(__a)>(__a)),
83 std::invoke(__proj, std::forward<decltype(__b)>(__b)));
104 return std::invoke(__comp,
105 std::invoke(__proj, std::forward<decltype(__a)>(__a)),
106 std::invoke(__proj, std::forward<decltype(__b)>(__b)));
84107 };
85108
109 // During initialization, members are allowed to refer to already initialized members
110 // (see http://eel.is/c++draft/dcl.init.aggr#6)
86111 ranges::minmax_result<_ValueT> __result = {*__first, __result.min};
87112 if (__first == __last || ++__first == __last)
88113 return __result;
......@@ -121,7 +146,7 @@ struct __fn {
121146} // namespace __minmax
122147
123148inline namespace __cpo {
124 inline constexpr auto minmax = __minmax::__fn{};
149inline constexpr auto minmax = __minmax::__fn{};
125150} // namespace __cpo
126151} // namespace ranges
127152
......@@ -129,6 +154,6 @@ _LIBCPP_END_NAMESPACE_STD
129154
130155_LIBCPP_POP_MACROS
131156
132#endif // _LIBCPP_STD_VER > 17
157#endif // _LIBCPP_STD_VER >= 20
133158
134159#endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H
lib/libcxx/include/__algorithm/ranges_minmax_element.h+11-10
......@@ -23,13 +23,12 @@
2323#include <__utility/forward.h>
2424#include <__utility/move.h>
2525#include <__utility/pair.h>
26#include <type_traits>
2726
2827#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2928# pragma GCC system_header
3029#endif
3130
32#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
3332
3433_LIBCPP_BEGIN_NAMESPACE_STD
3534
......@@ -40,18 +39,20 @@ using minmax_element_result = min_max_result<_T1>;
4039
4140namespace __minmax_element {
4241struct __fn {
43 template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
42 template <forward_iterator _Ip,
43 sentinel_for<_Ip> _Sp,
44 class _Proj = identity,
4445 indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less>
45 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
46 ranges::minmax_element_result<_Ip> operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
46 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result<_Ip>
47 operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
4748 auto __ret = std::__minmax_element_impl(std::move(__first), std::move(__last), __comp, __proj);
4849 return {__ret.first, __ret.second};
4950 }
5051
51 template <forward_range _Rp, class _Proj = identity,
52 template <forward_range _Rp,
53 class _Proj = identity,
5254 indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
53 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
54 ranges::minmax_element_result<borrowed_iterator_t<_Rp>>
55 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result<borrowed_iterator_t<_Rp>>
5556 operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
5657 auto __ret = std::__minmax_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
5758 return {__ret.first, __ret.second};
......@@ -60,13 +61,13 @@ struct __fn {
6061} // namespace __minmax_element
6162
6263inline namespace __cpo {
63 inline constexpr auto minmax_element = __minmax_element::__fn{};
64inline constexpr auto minmax_element = __minmax_element::__fn{};
6465} // namespace __cpo
6566
6667} // namespace ranges
6768
6869_LIBCPP_END_NAMESPACE_STD
6970
70#endif // _LIBCPP_STD_VER > 17
71#endif // _LIBCPP_STD_VER >= 20
7172
7273#endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H
lib/libcxx/include/__algorithm/ranges_mismatch.h+25-21
......@@ -27,7 +27,7 @@
2727
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232namespace ranges {
3333
......@@ -36,12 +36,9 @@ using mismatch_result = in_in_result<_I1, _I2>;
3636
3737namespace __mismatch {
3838struct __fn {
39 template <class _I1, class _S1, class _I2, class _S2,
40 class _Pred, class _Proj1, class _Proj2>
41 static _LIBCPP_HIDE_FROM_ABI constexpr
42 mismatch_result<_I1, _I2>
43 __go(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2,
44 _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
39 template <class _I1, class _S1, class _I2, class _S2, class _Pred, class _Proj1, class _Proj2>
40 static _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<_I1, _I2>
41 __go(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
4542 while (__first1 != __last1 && __first2 != __last2) {
4643 if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2)))
4744 break;
......@@ -51,34 +48,41 @@ struct __fn {
5148 return {std::move(__first1), std::move(__first2)};
5249 }
5350
54 template <input_iterator _I1, sentinel_for<_I1> _S1,
55 input_iterator _I2, sentinel_for<_I2> _S2,
56 class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity>
51 template <input_iterator _I1,
52 sentinel_for<_I1> _S1,
53 input_iterator _I2,
54 sentinel_for<_I2> _S2,
55 class _Pred = ranges::equal_to,
56 class _Proj1 = identity,
57 class _Proj2 = identity>
5758 requires indirectly_comparable<_I1, _I2, _Pred, _Proj1, _Proj2>
58 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
59 mismatch_result<_I1, _I2> operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2,
60 _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
59 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<_I1, _I2> operator()(
60 _I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
61 const {
6162 return __go(std::move(__first1), __last1, std::move(__first2), __last2, __pred, __proj1, __proj2);
6263 }
6364
64 template <input_range _R1, input_range _R2,
65 class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity>
65 template <input_range _R1,
66 input_range _R2,
67 class _Pred = ranges::equal_to,
68 class _Proj1 = identity,
69 class _Proj2 = identity>
6670 requires indirectly_comparable<iterator_t<_R1>, iterator_t<_R2>, _Pred, _Proj1, _Proj2>
67 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
68 mismatch_result<borrowed_iterator_t<_R1>, borrowed_iterator_t<_R2>>
71 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<borrowed_iterator_t<_R1>,
72 borrowed_iterator_t<_R2>>
6973 operator()(_R1&& __r1, _R2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
70 return __go(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2),
71 __pred, __proj1, __proj2);
74 return __go(
75 ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), __pred, __proj1, __proj2);
7276 }
7377};
7478} // namespace __mismatch
7579
7680inline namespace __cpo {
77 constexpr inline auto mismatch = __mismatch::__fn{};
81constexpr inline auto mismatch = __mismatch::__fn{};
7882} // namespace __cpo
7983} // namespace ranges
8084
81#endif // _LIBCPP_STD_VER > 17
85#endif // _LIBCPP_STD_VER >= 20
8286
8387_LIBCPP_END_NAMESPACE_STD
8488
lib/libcxx/include/__algorithm/ranges_move.h+9-11
......@@ -23,7 +23,7 @@
2323# pragma GCC system_header
2424#endif
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
......@@ -34,38 +34,36 @@ using move_result = in_out_result<_InIter, _OutIter>;
3434
3535namespace __move {
3636struct __fn {
37
3837 template <class _InIter, class _Sent, class _OutIter>
39 _LIBCPP_HIDE_FROM_ABI constexpr static
40 move_result<_InIter, _OutIter> __move_impl(_InIter __first, _Sent __last, _OutIter __result) {
38 _LIBCPP_HIDE_FROM_ABI constexpr static move_result<_InIter, _OutIter>
39 __move_impl(_InIter __first, _Sent __last, _OutIter __result) {
4140 auto __ret = std::__move<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
4241 return {std::move(__ret.first), std::move(__ret.second)};
4342 }
4443
4544 template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
4645 requires indirectly_movable<_InIter, _OutIter>
47 _LIBCPP_HIDE_FROM_ABI constexpr
48 move_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
46 _LIBCPP_HIDE_FROM_ABI constexpr move_result<_InIter, _OutIter>
47 operator()(_InIter __first, _Sent __last, _OutIter __result) const {
4948 return __move_impl(std::move(__first), std::move(__last), std::move(__result));
5049 }
5150
5251 template <input_range _Range, weakly_incrementable _OutIter>
5352 requires indirectly_movable<iterator_t<_Range>, _OutIter>
54 _LIBCPP_HIDE_FROM_ABI constexpr
55 move_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __range, _OutIter __result) const {
53 _LIBCPP_HIDE_FROM_ABI constexpr move_result<borrowed_iterator_t<_Range>, _OutIter>
54 operator()(_Range&& __range, _OutIter __result) const {
5655 return __move_impl(ranges::begin(__range), ranges::end(__range), std::move(__result));
5756 }
58
5957};
6058} // namespace __move
6159
6260inline namespace __cpo {
63 inline constexpr auto move = __move::__fn{};
61inline constexpr auto move = __move::__fn{};
6462} // namespace __cpo
6563} // namespace ranges
6664
6765_LIBCPP_END_NAMESPACE_STD
6866
69#endif // _LIBCPP_STD_VER > 17
67#endif // _LIBCPP_STD_VER >= 20
7068
7169#endif // _LIBCPP___ALGORITHM_RANGES_MOVE_H
lib/libcxx/include/__algorithm/ranges_move_backward.h+9-11
......@@ -25,7 +25,7 @@
2525# pragma GCC system_header
2626#endif
2727
28#if _LIBCPP_STD_VER > 17
28#if _LIBCPP_STD_VER >= 20
2929
3030_LIBCPP_BEGIN_NAMESPACE_STD
3131
......@@ -36,38 +36,36 @@ using move_backward_result = in_out_result<_InIter, _OutIter>;
3636
3737namespace __move_backward {
3838struct __fn {
39
4039 template <class _InIter, class _Sent, class _OutIter>
41 _LIBCPP_HIDE_FROM_ABI constexpr static
42 move_backward_result<_InIter, _OutIter> __move_backward_impl(_InIter __first, _Sent __last, _OutIter __result) {
40 _LIBCPP_HIDE_FROM_ABI constexpr static move_backward_result<_InIter, _OutIter>
41 __move_backward_impl(_InIter __first, _Sent __last, _OutIter __result) {
4342 auto __ret = std::__move_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
4443 return {std::move(__ret.first), std::move(__ret.second)};
4544 }
4645
4746 template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, bidirectional_iterator _OutIter>
4847 requires indirectly_movable<_InIter, _OutIter>
49 _LIBCPP_HIDE_FROM_ABI constexpr
50 move_backward_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
48 _LIBCPP_HIDE_FROM_ABI constexpr move_backward_result<_InIter, _OutIter>
49 operator()(_InIter __first, _Sent __last, _OutIter __result) const {
5150 return __move_backward_impl(std::move(__first), std::move(__last), std::move(__result));
5251 }
5352
5453 template <bidirectional_range _Range, bidirectional_iterator _Iter>
5554 requires indirectly_movable<iterator_t<_Range>, _Iter>
56 _LIBCPP_HIDE_FROM_ABI constexpr
57 move_backward_result<borrowed_iterator_t<_Range>, _Iter> operator()(_Range&& __range, _Iter __result) const {
55 _LIBCPP_HIDE_FROM_ABI constexpr move_backward_result<borrowed_iterator_t<_Range>, _Iter>
56 operator()(_Range&& __range, _Iter __result) const {
5857 return __move_backward_impl(ranges::begin(__range), ranges::end(__range), std::move(__result));
5958 }
60
6159};
6260} // namespace __move_backward
6361
6462inline namespace __cpo {
65 inline constexpr auto move_backward = __move_backward::__fn{};
63inline constexpr auto move_backward = __move_backward::__fn{};
6664} // namespace __cpo
6765} // namespace ranges
6866
6967_LIBCPP_END_NAMESPACE_STD
7068
71#endif // _LIBCPP_STD_VER > 17
69#endif // _LIBCPP_STD_VER >= 20
7270
7371#endif // _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H
lib/libcxx/include/__algorithm/ranges_next_permutation.h+2-2
......@@ -28,7 +28,7 @@
2828# pragma GCC system_header
2929#endif
3030
31#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
3232
3333_LIBCPP_BEGIN_NAMESPACE_STD
3434
......@@ -68,6 +68,6 @@ constexpr inline auto next_permutation = __next_permutation::__fn{};
6868
6969_LIBCPP_END_NAMESPACE_STD
7070
71#endif // _LIBCPP_STD_VER > 17
71#endif // _LIBCPP_STD_VER >= 20
7272
7373#endif // _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H
lib/libcxx/include/__algorithm/ranges_none_of.h+14-12
......@@ -22,17 +22,16 @@
2222# pragma GCC system_header
2323#endif
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727_LIBCPP_BEGIN_NAMESPACE_STD
2828
2929namespace ranges {
3030namespace __none_of {
3131struct __fn {
32
3332 template <class _Iter, class _Sent, class _Proj, class _Pred>
34 _LIBCPP_HIDE_FROM_ABI constexpr static
35 bool __none_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
33 _LIBCPP_HIDE_FROM_ABI constexpr static bool
34 __none_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
3635 for (; __first != __last; ++__first) {
3736 if (std::invoke(__pred, std::invoke(__proj, *__first)))
3837 return false;
......@@ -40,29 +39,32 @@ struct __fn {
4039 return true;
4140 }
4241
43 template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
42 template <input_iterator _Iter,
43 sentinel_for<_Iter> _Sent,
44 class _Proj = identity,
4445 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
45 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
46 bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
46 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
47 operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
4748 return __none_of_impl(std::move(__first), std::move(__last), __pred, __proj);
4849 }
4950
50 template <input_range _Range, class _Proj = identity,
51 template <input_range _Range,
52 class _Proj = identity,
5153 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
52 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
53 bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
54 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
55 operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
5456 return __none_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
5557 }
5658};
5759} // namespace __none_of
5860
5961inline namespace __cpo {
60 inline constexpr auto none_of = __none_of::__fn{};
62inline constexpr auto none_of = __none_of::__fn{};
6163} // namespace __cpo
6264} // namespace ranges
6365
6466_LIBCPP_END_NAMESPACE_STD
6567
66#endif // _LIBCPP_STD_VER > 17
68#endif // _LIBCPP_STD_VER >= 20
6769
6870#endif // _LIBCPP___ALGORITHM_RANGES_NONE_OF_H
lib/libcxx/include/__algorithm/ranges_nth_element.h+9-10
......@@ -31,7 +31,7 @@
3131# pragma GCC system_header
3232#endif
3333
34#if _LIBCPP_STD_VER > 17
34#if _LIBCPP_STD_VER >= 20
3535
3636_LIBCPP_BEGIN_NAMESPACE_STD
3737
......@@ -40,8 +40,8 @@ namespace __nth_element {
4040
4141struct __fn {
4242 template <class _Iter, class _Sent, class _Comp, class _Proj>
43 _LIBCPP_HIDE_FROM_ABI constexpr static
44 _Iter __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) {
43 _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
44 __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) {
4545 auto __last_iter = ranges::next(__first, __last);
4646
4747 auto&& __projected_comp = std::__make_projected(__comp, __proj);
......@@ -52,16 +52,15 @@ struct __fn {
5252
5353 template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
5454 requires sortable<_Iter, _Comp, _Proj>
55 _LIBCPP_HIDE_FROM_ABI constexpr
56 _Iter operator()(_Iter __first, _Iter __nth, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
55 _LIBCPP_HIDE_FROM_ABI constexpr _Iter
56 operator()(_Iter __first, _Iter __nth, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
5757 return __nth_element_fn_impl(std::move(__first), std::move(__nth), std::move(__last), __comp, __proj);
5858 }
5959
6060 template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
6161 requires sortable<iterator_t<_Range>, _Comp, _Proj>
62 _LIBCPP_HIDE_FROM_ABI constexpr
63 borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __nth, _Comp __comp = {},
64 _Proj __proj = {}) const {
62 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
63 operator()(_Range&& __r, iterator_t<_Range> __nth, _Comp __comp = {}, _Proj __proj = {}) const {
6564 return __nth_element_fn_impl(ranges::begin(__r), std::move(__nth), ranges::end(__r), __comp, __proj);
6665 }
6766};
......@@ -69,12 +68,12 @@ struct __fn {
6968} // namespace __nth_element
7069
7170inline namespace __cpo {
72 inline constexpr auto nth_element = __nth_element::__fn{};
71inline constexpr auto nth_element = __nth_element::__fn{};
7372} // namespace __cpo
7473} // namespace ranges
7574
7675_LIBCPP_END_NAMESPACE_STD
7776
78#endif // _LIBCPP_STD_VER > 17
77#endif // _LIBCPP_STD_VER >= 20
7978
8079#endif // _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H
lib/libcxx/include/__algorithm/ranges_partial_sort.h+9-10
......@@ -33,7 +33,7 @@
3333# pragma GCC system_header
3434#endif
3535
36#if _LIBCPP_STD_VER > 17
36#if _LIBCPP_STD_VER >= 20
3737
3838_LIBCPP_BEGIN_NAMESPACE_STD
3939
......@@ -42,24 +42,23 @@ namespace __partial_sort {
4242
4343struct __fn {
4444 template <class _Iter, class _Sent, class _Comp, class _Proj>
45 _LIBCPP_HIDE_FROM_ABI constexpr static
46 _Iter __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp& __comp, _Proj& __proj) {
45 _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
46 __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp& __comp, _Proj& __proj) {
4747 auto&& __projected_comp = std::__make_projected(__comp, __proj);
4848 return std::__partial_sort<_RangeAlgPolicy>(std::move(__first), std::move(__middle), __last, __projected_comp);
4949 }
5050
5151 template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
5252 requires sortable<_Iter, _Comp, _Proj>
53 _LIBCPP_HIDE_FROM_ABI constexpr
54 _Iter operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
53 _LIBCPP_HIDE_FROM_ABI constexpr _Iter
54 operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
5555 return __partial_sort_fn_impl(std::move(__first), std::move(__middle), std::move(__last), __comp, __proj);
5656 }
5757
5858 template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
5959 requires sortable<iterator_t<_Range>, _Comp, _Proj>
60 _LIBCPP_HIDE_FROM_ABI constexpr
61 borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __middle, _Comp __comp = {},
62 _Proj __proj = {}) const {
60 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
61 operator()(_Range&& __r, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const {
6362 return __partial_sort_fn_impl(ranges::begin(__r), std::move(__middle), ranges::end(__r), __comp, __proj);
6463 }
6564};
......@@ -67,12 +66,12 @@ struct __fn {
6766} // namespace __partial_sort
6867
6968inline namespace __cpo {
70 inline constexpr auto partial_sort = __partial_sort::__fn{};
69inline constexpr auto partial_sort = __partial_sort::__fn{};
7170} // namespace __cpo
7271} // namespace ranges
7372
7473_LIBCPP_END_NAMESPACE_STD
7574
76#endif // _LIBCPP_STD_VER > 17
75#endif // _LIBCPP_STD_VER >= 20
7776
7877#endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_H
lib/libcxx/include/__algorithm/ranges_partial_sort_copy.h+47-30
......@@ -30,7 +30,7 @@
3030# pragma GCC system_header
3131#endif
3232
33#if _LIBCPP_STD_VER > 17
33#if _LIBCPP_STD_VER >= 20
3434
3535_LIBCPP_BEGIN_NAMESPACE_STD
3636
......@@ -42,51 +42,68 @@ using partial_sort_copy_result = in_out_result<_InIter, _OutIter>;
4242namespace __partial_sort_copy {
4343
4444struct __fn {
45
46 template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
47 random_access_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
48 class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity>
49 requires indirectly_copyable<_Iter1, _Iter2> && sortable<_Iter2, _Comp, _Proj2> &&
50 indirect_strict_weak_order<_Comp, projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>>
51 _LIBCPP_HIDE_FROM_ABI constexpr
52 partial_sort_copy_result<_Iter1, _Iter2>
53 operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result_first, _Sent2 __result_last,
54 _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
45 template <input_iterator _Iter1,
46 sentinel_for<_Iter1> _Sent1,
47 random_access_iterator _Iter2,
48 sentinel_for<_Iter2> _Sent2,
49 class _Comp = ranges::less,
50 class _Proj1 = identity,
51 class _Proj2 = identity>
52 requires indirectly_copyable<_Iter1, _Iter2> && sortable<_Iter2, _Comp, _Proj2> &&
53 indirect_strict_weak_order<_Comp, projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>>
54 _LIBCPP_HIDE_FROM_ABI constexpr partial_sort_copy_result<_Iter1, _Iter2> operator()(
55 _Iter1 __first,
56 _Sent1 __last,
57 _Iter2 __result_first,
58 _Sent2 __result_last,
59 _Comp __comp = {},
60 _Proj1 __proj1 = {},
61 _Proj2 __proj2 = {}) const {
5562 auto __result = std::__partial_sort_copy<_RangeAlgPolicy>(
56 std::move(__first), std::move(__last), std::move(__result_first), std::move(__result_last),
57 __comp, __proj1, __proj2
58 );
63 std::move(__first),
64 std::move(__last),
65 std::move(__result_first),
66 std::move(__result_last),
67 __comp,
68 __proj1,
69 __proj2);
5970 return {std::move(__result.first), std::move(__result.second)};
6071 }
6172
62 template <input_range _Range1, random_access_range _Range2, class _Comp = ranges::less,
63 class _Proj1 = identity, class _Proj2 = identity>
64 requires indirectly_copyable<iterator_t<_Range1>, iterator_t<_Range2>> &&
65 sortable<iterator_t<_Range2>, _Comp, _Proj2> &&
66 indirect_strict_weak_order<_Comp, projected<iterator_t<_Range1>, _Proj1>,
67 projected<iterator_t<_Range2>, _Proj2>>
68 _LIBCPP_HIDE_FROM_ABI constexpr
69 partial_sort_copy_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>>
70 operator()(_Range1&& __range, _Range2&& __result_range, _Comp __comp = {},
71 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
73 template <input_range _Range1,
74 random_access_range _Range2,
75 class _Comp = ranges::less,
76 class _Proj1 = identity,
77 class _Proj2 = identity>
78 requires indirectly_copyable<iterator_t<_Range1>, iterator_t<_Range2>> &&
79 sortable<iterator_t<_Range2>, _Comp, _Proj2> &&
80 indirect_strict_weak_order<_Comp,
81 projected<iterator_t<_Range1>, _Proj1>,
82 projected<iterator_t<_Range2>, _Proj2>>
83 _LIBCPP_HIDE_FROM_ABI constexpr partial_sort_copy_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>>
84 operator()(
85 _Range1&& __range, _Range2&& __result_range, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
7286 auto __result = std::__partial_sort_copy<_RangeAlgPolicy>(
73 ranges::begin(__range), ranges::end(__range), ranges::begin(__result_range), ranges::end(__result_range),
74 __comp, __proj1, __proj2
75 );
87 ranges::begin(__range),
88 ranges::end(__range),
89 ranges::begin(__result_range),
90 ranges::end(__result_range),
91 __comp,
92 __proj1,
93 __proj2);
7694 return {std::move(__result.first), std::move(__result.second)};
7795 }
78
7996};
8097
8198} // namespace __partial_sort_copy
8299
83100inline namespace __cpo {
84 inline constexpr auto partial_sort_copy = __partial_sort_copy::__fn{};
101inline constexpr auto partial_sort_copy = __partial_sort_copy::__fn{};
85102} // namespace __cpo
86103} // namespace ranges
87104
88105_LIBCPP_END_NAMESPACE_STD
89106
90#endif // _LIBCPP_STD_VER > 17
107#endif // _LIBCPP_STD_VER >= 20
91108
92109#endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H
lib/libcxx/include/__algorithm/ranges_partition.h+16-16
......@@ -27,13 +27,12 @@
2727#include <__utility/forward.h>
2828#include <__utility/move.h>
2929#include <__utility/pair.h>
30#include <type_traits>
3130
3231#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3332# pragma GCC system_header
3433#endif
3534
36#if _LIBCPP_STD_VER > 17
35#if _LIBCPP_STD_VER >= 20
3736
3837_LIBCPP_BEGIN_NAMESPACE_STD
3938
......@@ -41,43 +40,44 @@ namespace ranges {
4140namespace __partition {
4241
4342struct __fn {
44
4543 template <class _Iter, class _Sent, class _Proj, class _Pred>
46 _LIBCPP_HIDE_FROM_ABI static constexpr
47 subrange<__remove_cvref_t<_Iter>> __partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) {
44 _LIBCPP_HIDE_FROM_ABI static constexpr subrange<__remove_cvref_t<_Iter>>
45 __partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) {
4846 auto&& __projected_pred = std::__make_projected(__pred, __proj);
49 auto __result = std::__partition<_RangeAlgPolicy>(
47 auto __result = std::__partition<_RangeAlgPolicy>(
5048 std::move(__first), std::move(__last), __projected_pred, __iterator_concept<_Iter>());
5149
5250 return {std::move(__result.first), std::move(__result.second)};
5351 }
5452
55 template <permutable _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
53 template <permutable _Iter,
54 sentinel_for<_Iter> _Sent,
55 class _Proj = identity,
5656 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
57 _LIBCPP_HIDE_FROM_ABI constexpr
58 subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
57 _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
58 operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
5959 return __partition_fn_impl(__first, __last, __pred, __proj);
6060 }
6161
62 template <forward_range _Range, class _Proj = identity,
62 template <forward_range _Range,
63 class _Proj = identity,
6364 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
64 requires permutable<iterator_t<_Range>>
65 _LIBCPP_HIDE_FROM_ABI constexpr
66 borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
65 requires permutable<iterator_t<_Range>>
66 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
67 operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
6768 return __partition_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
6869 }
69
7070};
7171
7272} // namespace __partition
7373
7474inline namespace __cpo {
75 inline constexpr auto partition = __partition::__fn{};
75inline constexpr auto partition = __partition::__fn{};
7676} // namespace __cpo
7777} // namespace ranges
7878
7979_LIBCPP_END_NAMESPACE_STD
8080
81#endif // _LIBCPP_STD_VER > 17
81#endif // _LIBCPP_STD_VER >= 20
8282
8383#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_H
lib/libcxx/include/__algorithm/ranges_partition_copy.h+31-24
......@@ -19,14 +19,14 @@
1919#include <__ranges/access.h>
2020#include <__ranges/concepts.h>
2121#include <__ranges/dangling.h>
22#include <__type_traits/remove_cvref.h>
2223#include <__utility/move.h>
23#include <type_traits>
2424
2525#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2626# pragma GCC system_header
2727#endif
2828
29#if _LIBCPP_STD_VER > 17
29#if _LIBCPP_STD_VER >= 20
3030
3131_LIBCPP_BEGIN_NAMESPACE_STD
3232
......@@ -38,14 +38,18 @@ using partition_copy_result = in_out_out_result<_InIter, _OutIter1, _OutIter2>;
3838namespace __partition_copy {
3939
4040struct __fn {
41
4241 // TODO(ranges): delegate to the classic algorithm.
4342 template <class _InIter, class _Sent, class _OutIter1, class _OutIter2, class _Proj, class _Pred>
44 _LIBCPP_HIDE_FROM_ABI constexpr
45 static partition_copy_result<
46 __remove_cvref_t<_InIter>, __remove_cvref_t<_OutIter1>, __remove_cvref_t<_OutIter2>
47 > __partition_copy_fn_impl( _InIter&& __first, _Sent&& __last, _OutIter1&& __out_true, _OutIter2&& __out_false,
48 _Pred& __pred, _Proj& __proj) {
43 _LIBCPP_HIDE_FROM_ABI constexpr static partition_copy_result<__remove_cvref_t<_InIter>,
44 __remove_cvref_t<_OutIter1>,
45 __remove_cvref_t<_OutIter2> >
46 __partition_copy_fn_impl(
47 _InIter&& __first,
48 _Sent&& __last,
49 _OutIter1&& __out_true,
50 _OutIter2&& __out_false,
51 _Pred& __pred,
52 _Proj& __proj) {
4953 for (; __first != __last; ++__first) {
5054 if (std::invoke(__pred, std::invoke(__proj, *__first))) {
5155 *__out_true = *__first;
......@@ -60,39 +64,42 @@ struct __fn {
6064 return {std::move(__first), std::move(__out_true), std::move(__out_false)};
6165 }
6266
63 template <input_iterator _InIter, sentinel_for<_InIter> _Sent,
64 weakly_incrementable _OutIter1, weakly_incrementable _OutIter2,
65 class _Proj = identity, indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
66 requires indirectly_copyable<_InIter, _OutIter1> && indirectly_copyable<_InIter, _OutIter2>
67 _LIBCPP_HIDE_FROM_ABI constexpr
68 partition_copy_result<_InIter, _OutIter1, _OutIter2>
69 operator()(_InIter __first, _Sent __last, _OutIter1 __out_true, _OutIter2 __out_false,
70 _Pred __pred, _Proj __proj = {}) const {
67 template <input_iterator _InIter,
68 sentinel_for<_InIter> _Sent,
69 weakly_incrementable _OutIter1,
70 weakly_incrementable _OutIter2,
71 class _Proj = identity,
72 indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
73 requires indirectly_copyable<_InIter, _OutIter1> && indirectly_copyable<_InIter, _OutIter2>
74 _LIBCPP_HIDE_FROM_ABI constexpr partition_copy_result<_InIter, _OutIter1, _OutIter2> operator()(
75 _InIter __first, _Sent __last, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {})
76 const {
7177 return __partition_copy_fn_impl(
7278 std::move(__first), std::move(__last), std::move(__out_true), std::move(__out_false), __pred, __proj);
7379 }
7480
75 template <input_range _Range, weakly_incrementable _OutIter1, weakly_incrementable _OutIter2,
76 class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
77 requires indirectly_copyable<iterator_t<_Range>, _OutIter1> && indirectly_copyable<iterator_t<_Range>, _OutIter2>
78 _LIBCPP_HIDE_FROM_ABI constexpr
79 partition_copy_result<borrowed_iterator_t<_Range>, _OutIter1, _OutIter2>
81 template <input_range _Range,
82 weakly_incrementable _OutIter1,
83 weakly_incrementable _OutIter2,
84 class _Proj = identity,
85 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
86 requires indirectly_copyable<iterator_t<_Range>, _OutIter1> && indirectly_copyable<iterator_t<_Range>, _OutIter2>
87 _LIBCPP_HIDE_FROM_ABI constexpr partition_copy_result<borrowed_iterator_t<_Range>, _OutIter1, _OutIter2>
8088 operator()(_Range&& __range, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {}) const {
8189 return __partition_copy_fn_impl(
8290 ranges::begin(__range), ranges::end(__range), std::move(__out_true), std::move(__out_false), __pred, __proj);
8391 }
84
8592};
8693
8794} // namespace __partition_copy
8895
8996inline namespace __cpo {
90 inline constexpr auto partition_copy = __partition_copy::__fn{};
97inline constexpr auto partition_copy = __partition_copy::__fn{};
9198} // namespace __cpo
9299} // namespace ranges
93100
94101_LIBCPP_END_NAMESPACE_STD
95102
96#endif // _LIBCPP_STD_VER > 17
103#endif // _LIBCPP_STD_VER >= 20
97104
98105#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H
lib/libcxx/include/__algorithm/ranges_partition_point.h+14-14
......@@ -27,7 +27,7 @@
2727# pragma GCC system_header
2828#endif
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_BEGIN_NAMESPACE_STD
3333
......@@ -35,16 +35,15 @@ namespace ranges {
3535namespace __partition_point {
3636
3737struct __fn {
38
3938 // TODO(ranges): delegate to the classic algorithm.
4039 template <class _Iter, class _Sent, class _Proj, class _Pred>
41 _LIBCPP_HIDE_FROM_ABI constexpr
42 static _Iter __partition_point_fn_impl(_Iter&& __first, _Sent&& __last, _Pred& __pred, _Proj& __proj) {
40 _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
41 __partition_point_fn_impl(_Iter&& __first, _Sent&& __last, _Pred& __pred, _Proj& __proj) {
4342 auto __len = ranges::distance(__first, __last);
4443
4544 while (__len != 0) {
4645 auto __half_len = std::__half_positive(__len);
47 auto __mid = ranges::next(__first, __half_len);
46 auto __mid = ranges::next(__first, __half_len);
4847
4948 if (std::invoke(__pred, std::invoke(__proj, *__mid))) {
5049 __first = ++__mid;
......@@ -58,31 +57,32 @@ struct __fn {
5857 return __first;
5958 }
6059
61 template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
60 template <forward_iterator _Iter,
61 sentinel_for<_Iter> _Sent,
62 class _Proj = identity,
6263 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
63 _LIBCPP_HIDE_FROM_ABI constexpr
64 _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
64 _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
6565 return __partition_point_fn_impl(std::move(__first), std::move(__last), __pred, __proj);
6666 }
6767
68 template <forward_range _Range, class _Proj = identity,
68 template <forward_range _Range,
69 class _Proj = identity,
6970 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
70 _LIBCPP_HIDE_FROM_ABI constexpr
71 borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
71 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
72 operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
7273 return __partition_point_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
7374 }
74
7575};
7676
7777} // namespace __partition_point
7878
7979inline namespace __cpo {
80 inline constexpr auto partition_point = __partition_point::__fn{};
80inline constexpr auto partition_point = __partition_point::__fn{};
8181} // namespace __cpo
8282} // namespace ranges
8383
8484_LIBCPP_END_NAMESPACE_STD
8585
86#endif // _LIBCPP_STD_VER > 17
86#endif // _LIBCPP_STD_VER >= 20
8787
8888#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H
lib/libcxx/include/__algorithm/ranges_pop_heap.h+10-10
......@@ -32,7 +32,7 @@
3232# pragma GCC system_header
3333#endif
3434
35#if _LIBCPP_STD_VER > 17
35#if _LIBCPP_STD_VER >= 20
3636
3737_LIBCPP_BEGIN_NAMESPACE_STD
3838
......@@ -41,10 +41,10 @@ namespace __pop_heap {
4141
4242struct __fn {
4343 template <class _Iter, class _Sent, class _Comp, class _Proj>
44 _LIBCPP_HIDE_FROM_ABI constexpr static
45 _Iter __pop_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
44 _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
45 __pop_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
4646 auto __last_iter = ranges::next(__first, __last);
47 auto __len = __last_iter - __first;
47 auto __len = __last_iter - __first;
4848
4949 auto&& __projected_comp = std::__make_projected(__comp, __proj);
5050 std::__pop_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp, __len);
......@@ -54,15 +54,15 @@ struct __fn {
5454
5555 template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
5656 requires sortable<_Iter, _Comp, _Proj>
57 _LIBCPP_HIDE_FROM_ABI constexpr
58 _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
57 _LIBCPP_HIDE_FROM_ABI constexpr _Iter
58 operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
5959 return __pop_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
6060 }
6161
6262 template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
6363 requires sortable<iterator_t<_Range>, _Comp, _Proj>
64 _LIBCPP_HIDE_FROM_ABI constexpr
65 borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
64 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
65 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
6666 return __pop_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
6767 }
6868};
......@@ -70,12 +70,12 @@ struct __fn {
7070} // namespace __pop_heap
7171
7272inline namespace __cpo {
73 inline constexpr auto pop_heap = __pop_heap::__fn{};
73inline constexpr auto pop_heap = __pop_heap::__fn{};
7474} // namespace __cpo
7575} // namespace ranges
7676
7777_LIBCPP_END_NAMESPACE_STD
7878
79#endif // _LIBCPP_STD_VER > 17
79#endif // _LIBCPP_STD_VER >= 20
8080
8181#endif // _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H
lib/libcxx/include/__algorithm/ranges_prev_permutation.h+4-8
......@@ -28,7 +28,7 @@
2828# pragma GCC system_header
2929#endif
3030
31#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
3232
3333_LIBCPP_BEGIN_NAMESPACE_STD
3434
......@@ -40,9 +40,7 @@ using prev_permutation_result = in_found_result<_InIter>;
4040namespace __prev_permutation {
4141
4242struct __fn {
43
44 template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
45 class _Comp = ranges::less, class _Proj = identity>
43 template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
4644 requires sortable<_Iter, _Comp, _Proj>
4745 _LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result<_Iter>
4846 operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
......@@ -51,8 +49,7 @@ struct __fn {
5149 return {std::move(__result.first), std::move(__result.second)};
5250 }
5351
54 template <bidirectional_range _Range,
55 class _Comp = ranges::less, class _Proj = identity>
52 template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity>
5653 requires sortable<iterator_t<_Range>, _Comp, _Proj>
5754 _LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result<borrowed_iterator_t<_Range>>
5855 operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
......@@ -60,7 +57,6 @@ struct __fn {
6057 ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj));
6158 return {std::move(__result.first), std::move(__result.second)};
6259 }
63
6460};
6561
6662} // namespace __prev_permutation
......@@ -72,6 +68,6 @@ constexpr inline auto prev_permutation = __prev_permutation::__fn{};
7268
7369_LIBCPP_END_NAMESPACE_STD
7470
75#endif // _LIBCPP_STD_VER > 17
71#endif // _LIBCPP_STD_VER >= 20
7672
7773#endif // _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H
lib/libcxx/include/__algorithm/ranges_push_heap.h+9-9
......@@ -32,7 +32,7 @@
3232# pragma GCC system_header
3333#endif
3434
35#if _LIBCPP_STD_VER > 17
35#if _LIBCPP_STD_VER >= 20
3636
3737_LIBCPP_BEGIN_NAMESPACE_STD
3838
......@@ -41,8 +41,8 @@ namespace __push_heap {
4141
4242struct __fn {
4343 template <class _Iter, class _Sent, class _Comp, class _Proj>
44 _LIBCPP_HIDE_FROM_ABI constexpr static
45 _Iter __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
44 _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
45 __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
4646 auto __last_iter = ranges::next(__first, __last);
4747
4848 auto&& __projected_comp = std::__make_projected(__comp, __proj);
......@@ -53,15 +53,15 @@ struct __fn {
5353
5454 template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
5555 requires sortable<_Iter, _Comp, _Proj>
56 _LIBCPP_HIDE_FROM_ABI constexpr
57 _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
56 _LIBCPP_HIDE_FROM_ABI constexpr _Iter
57 operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
5858 return __push_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
5959 }
6060
6161 template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
6262 requires sortable<iterator_t<_Range>, _Comp, _Proj>
63 _LIBCPP_HIDE_FROM_ABI constexpr
64 borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
63 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
64 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
6565 return __push_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
6666 }
6767};
......@@ -69,12 +69,12 @@ struct __fn {
6969} // namespace __push_heap
7070
7171inline namespace __cpo {
72 inline constexpr auto push_heap = __push_heap::__fn{};
72inline constexpr auto push_heap = __push_heap::__fn{};
7373} // namespace __cpo
7474} // namespace ranges
7575
7676_LIBCPP_END_NAMESPACE_STD
7777
78#endif // _LIBCPP_STD_VER > 17
78#endif // _LIBCPP_STD_VER >= 20
7979
8080#endif // _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H
lib/libcxx/include/__algorithm/ranges_remove.h+9-10
......@@ -25,27 +25,26 @@
2525# pragma GCC system_header
2626#endif
2727
28#if _LIBCPP_STD_VER > 17
28#if _LIBCPP_STD_VER >= 20
2929
3030_LIBCPP_BEGIN_NAMESPACE_STD
3131
3232namespace ranges {
3333namespace __remove {
3434struct __fn {
35
3635 template <permutable _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity>
3736 requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type*>
38 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
39 subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
37 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
38 operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
4039 auto __pred = [&](auto&& __other) { return __value == __other; };
4140 return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj);
4241 }
4342
4443 template <forward_range _Range, class _Type, class _Proj = identity>
45 requires permutable<iterator_t<_Range>>
46 && indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
47 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
48 borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const {
44 requires permutable<iterator_t<_Range>> &&
45 indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
46 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
47 operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const {
4948 auto __pred = [&](auto&& __other) { return __value == __other; };
5049 return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
5150 }
......@@ -53,12 +52,12 @@ struct __fn {
5352} // namespace __remove
5453
5554inline namespace __cpo {
56 inline constexpr auto remove = __remove::__fn{};
55inline constexpr auto remove = __remove::__fn{};
5756} // namespace __cpo
5857} // namespace ranges
5958
6059_LIBCPP_END_NAMESPACE_STD
6160
62#endif // _LIBCPP_STD_VER > 17
61#endif // _LIBCPP_STD_VER >= 20
6362
6463#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_H
lib/libcxx/include/__algorithm/ranges_remove_copy.h+26-26
......@@ -26,7 +26,7 @@
2626# pragma GCC system_header
2727#endif
2828
29#if _LIBCPP_STD_VER > 17
29#if _LIBCPP_STD_VER >= 20
3030
3131_LIBCPP_BEGIN_NAMESPACE_STD
3232
......@@ -37,40 +37,40 @@ using remove_copy_result = in_out_result<_InIter, _OutIter>;
3737
3838namespace __remove_copy {
3939
40 struct __fn {
41 template <input_iterator _InIter,
42 sentinel_for<_InIter> _Sent,
43 weakly_incrementable _OutIter,
44 class _Type,
45 class _Proj = identity>
46 requires indirectly_copyable<_InIter, _OutIter> &&
47 indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _Type*>
48 _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<_InIter, _OutIter>
49 operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
50 auto __pred = [&](auto&& __val) { return __value == __val; };
51 return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
52 }
40struct __fn {
41 template <input_iterator _InIter,
42 sentinel_for<_InIter> _Sent,
43 weakly_incrementable _OutIter,
44 class _Type,
45 class _Proj = identity>
46 requires indirectly_copyable<_InIter, _OutIter> &&
47 indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _Type*>
48 _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<_InIter, _OutIter>
49 operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
50 auto __pred = [&](auto&& __val) { return __value == __val; };
51 return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
52 }
5353
54 template <input_range _Range, weakly_incrementable _OutIter, class _Type, class _Proj = identity>
55 requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
56 indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
57 _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<borrowed_iterator_t<_Range>, _OutIter>
58 operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
59 auto __pred = [&](auto&& __val) { return __value == __val; };
60 return ranges::__remove_copy_if_impl(
61 ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj);
62 }
63 };
54 template <input_range _Range, weakly_incrementable _OutIter, class _Type, class _Proj = identity>
55 requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
56 indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
57 _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<borrowed_iterator_t<_Range>, _OutIter>
58 operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
59 auto __pred = [&](auto&& __val) { return __value == __val; };
60 return ranges::__remove_copy_if_impl(
61 ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj);
62 }
63};
6464
6565} // namespace __remove_copy
6666
6767inline namespace __cpo {
68 inline constexpr auto remove_copy = __remove_copy::__fn{};
68inline constexpr auto remove_copy = __remove_copy::__fn{};
6969} // namespace __cpo
7070} // namespace ranges
7171
7272_LIBCPP_END_NAMESPACE_STD
7373
74#endif // _LIBCPP_STD_VER > 17
74#endif // _LIBCPP_STD_VER >= 20
7575
7676#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H
lib/libcxx/include/__algorithm/ranges_remove_copy_if.h+25-25
......@@ -29,7 +29,7 @@
2929# pragma GCC system_header
3030#endif
3131
32#if _LIBCPP_STD_VER > 17
32#if _LIBCPP_STD_VER >= 20
3333
3434_LIBCPP_BEGIN_NAMESPACE_STD
3535
......@@ -52,39 +52,39 @@ __remove_copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& _
5252
5353namespace __remove_copy_if {
5454
55 struct __fn {
56 template <input_iterator _InIter,
57 sentinel_for<_InIter> _Sent,
58 weakly_incrementable _OutIter,
59 class _Proj = identity,
60 indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
61 requires indirectly_copyable<_InIter, _OutIter>
62 _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<_InIter, _OutIter>
63 operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
64 return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
65 }
55struct __fn {
56 template <input_iterator _InIter,
57 sentinel_for<_InIter> _Sent,
58 weakly_incrementable _OutIter,
59 class _Proj = identity,
60 indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
61 requires indirectly_copyable<_InIter, _OutIter>
62 _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<_InIter, _OutIter>
63 operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
64 return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
65 }
6666
67 template <input_range _Range,
68 weakly_incrementable _OutIter,
69 class _Proj = identity,
70 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
71 requires indirectly_copyable<iterator_t<_Range>, _OutIter>
72 _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
73 operator()(_Range&& __range, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
74 return ranges::__remove_copy_if_impl(
75 ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj);
76 }
77 };
67 template <input_range _Range,
68 weakly_incrementable _OutIter,
69 class _Proj = identity,
70 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
71 requires indirectly_copyable<iterator_t<_Range>, _OutIter>
72 _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
73 operator()(_Range&& __range, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
74 return ranges::__remove_copy_if_impl(
75 ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj);
76 }
77};
7878
7979} // namespace __remove_copy_if
8080
8181inline namespace __cpo {
82 inline constexpr auto remove_copy_if = __remove_copy_if::__fn{};
82inline constexpr auto remove_copy_if = __remove_copy_if::__fn{};
8383} // namespace __cpo
8484} // namespace ranges
8585
8686_LIBCPP_END_NAMESPACE_STD
8787
88#endif // _LIBCPP_STD_VER > 17
88#endif // _LIBCPP_STD_VER >= 20
8989
9090#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H
lib/libcxx/include/__algorithm/ranges_remove_if.h+11-12
......@@ -27,15 +27,15 @@
2727# pragma GCC system_header
2828#endif
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_BEGIN_NAMESPACE_STD
3333
3434namespace ranges {
3535
3636template <class _Iter, class _Sent, class _Proj, class _Pred>
37_LIBCPP_HIDE_FROM_ABI constexpr
38subrange<_Iter> __remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
37_LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
38__remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
3939 auto __new_end = ranges::__find_if_impl(__first, __last, __pred, __proj);
4040 if (__new_end == __last)
4141 return {__new_end, __new_end};
......@@ -52,12 +52,12 @@ subrange<_Iter> __remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Pr
5252
5353namespace __remove_if {
5454struct __fn {
55
56 template <permutable _Iter, sentinel_for<_Iter> _Sent,
55 template <permutable _Iter,
56 sentinel_for<_Iter> _Sent,
5757 class _Proj = identity,
5858 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
59 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
60 subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
59 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
60 operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
6161 return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj);
6262 }
6363
......@@ -65,21 +65,20 @@ struct __fn {
6565 class _Proj = identity,
6666 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
6767 requires permutable<iterator_t<_Range>>
68 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
69 borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
68 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
69 operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
7070 return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
7171 }
72
7372};
7473} // namespace __remove_if
7574
7675inline namespace __cpo {
77 inline constexpr auto remove_if = __remove_if::__fn{};
76inline constexpr auto remove_if = __remove_if::__fn{};
7877} // namespace __cpo
7978} // namespace ranges
8079
8180_LIBCPP_END_NAMESPACE_STD
8281
83#endif // _LIBCPP_STD_VER > 17
82#endif // _LIBCPP_STD_VER >= 20
8483
8584#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H
lib/libcxx/include/__algorithm/ranges_replace.h+11-22
......@@ -24,51 +24,40 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
3131namespace ranges {
3232namespace __replace {
3333struct __fn {
34
35 template <input_iterator _Iter, sentinel_for<_Iter> _Sent,
36 class _Type1,
37 class _Type2,
38 class _Proj = identity>
39 requires indirectly_writable<_Iter, const _Type2&>
40 && indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type1*>
41 _LIBCPP_HIDE_FROM_ABI constexpr
42 _Iter operator()(_Iter __first, _Sent __last,
43 const _Type1& __old_value,
44 const _Type2& __new_value,
45 _Proj __proj = {}) const {
34 template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type1, class _Type2, class _Proj = identity>
35 requires indirectly_writable<_Iter, const _Type2&> &&
36 indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type1*>
37 _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(
38 _Iter __first, _Sent __last, const _Type1& __old_value, const _Type2& __new_value, _Proj __proj = {}) const {
4639 auto __pred = [&](const auto& __val) { return __val == __old_value; };
4740 return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj);
4841 }
4942
50 template <input_range _Range,
51 class _Type1,
52 class _Type2,
53 class _Proj = identity>
54 requires indirectly_writable<iterator_t<_Range>, const _Type2&>
55 && indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type1*>
43 template <input_range _Range, class _Type1, class _Type2, class _Proj = identity>
44 requires indirectly_writable<iterator_t<_Range>, const _Type2&> &&
45 indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type1*>
5646 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
5747 operator()(_Range&& __range, const _Type1& __old_value, const _Type2& __new_value, _Proj __proj = {}) const {
5848 auto __pred = [&](auto&& __val) { return __val == __old_value; };
5949 return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj);
6050 }
61
6251};
6352} // namespace __replace
6453
6554inline namespace __cpo {
66 inline constexpr auto replace = __replace::__fn{};
55inline constexpr auto replace = __replace::__fn{};
6756} // namespace __cpo
6857} // namespace ranges
6958
7059_LIBCPP_END_NAMESPACE_STD
7160
72#endif // _LIBCPP_STD_VER > 17
61#endif // _LIBCPP_STD_VER >= 20
7362
7463#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_H
lib/libcxx/include/__algorithm/ranges_replace_copy.h+38-41
......@@ -26,7 +26,7 @@
2626# pragma GCC system_header
2727#endif
2828
29#if _LIBCPP_STD_VER > 17
29#if _LIBCPP_STD_VER >= 20
3030
3131_LIBCPP_BEGIN_NAMESPACE_STD
3232
......@@ -37,55 +37,52 @@ using replace_copy_result = in_out_result<_InIter, _OutIter>;
3737
3838namespace __replace_copy {
3939
40 struct __fn {
41 template <input_iterator _InIter,
42 sentinel_for<_InIter> _Sent,
43 class _OldType,
44 class _NewType,
45 output_iterator<const _NewType&> _OutIter,
46 class _Proj = identity>
47 requires indirectly_copyable<_InIter, _OutIter> &&
48 indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _OldType*>
49 _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<_InIter, _OutIter>
50 operator()(_InIter __first,
51 _Sent __last,
52 _OutIter __result,
53 const _OldType& __old_value,
54 const _NewType& __new_value,
55 _Proj __proj = {}) const {
56 auto __pred = [&](const auto& __value) { return __value == __old_value; };
57 return ranges::__replace_copy_if_impl(
58 std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj);
59 }
40struct __fn {
41 template <input_iterator _InIter,
42 sentinel_for<_InIter> _Sent,
43 class _OldType,
44 class _NewType,
45 output_iterator<const _NewType&> _OutIter,
46 class _Proj = identity>
47 requires indirectly_copyable<_InIter, _OutIter> &&
48 indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _OldType*>
49 _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<_InIter, _OutIter>
50 operator()(_InIter __first,
51 _Sent __last,
52 _OutIter __result,
53 const _OldType& __old_value,
54 const _NewType& __new_value,
55 _Proj __proj = {}) const {
56 auto __pred = [&](const auto& __value) { return __value == __old_value; };
57 return ranges::__replace_copy_if_impl(
58 std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj);
59 }
6060
61 template <input_range _Range,
62 class _OldType,
63 class _NewType,
64 output_iterator<const _NewType&> _OutIter,
65 class _Proj = identity>
66 requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
67 indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _OldType*>
68 _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<borrowed_iterator_t<_Range>, _OutIter>
69 operator()(_Range&& __range,
70 _OutIter __result,
71 const _OldType& __old_value,
72 const _NewType& __new_value,
73 _Proj __proj = {}) const {
74 auto __pred = [&](const auto& __value) { return __value == __old_value; };
75 return ranges::__replace_copy_if_impl(
76 ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj);
77 }
78 };
61 template <input_range _Range,
62 class _OldType,
63 class _NewType,
64 output_iterator<const _NewType&> _OutIter,
65 class _Proj = identity>
66 requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
67 indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _OldType*>
68 _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(
69 _Range&& __range, _OutIter __result, const _OldType& __old_value, const _NewType& __new_value, _Proj __proj = {})
70 const {
71 auto __pred = [&](const auto& __value) { return __value == __old_value; };
72 return ranges::__replace_copy_if_impl(
73 ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj);
74 }
75};
7976
8077} // namespace __replace_copy
8178
8279inline namespace __cpo {
83 inline constexpr auto replace_copy = __replace_copy::__fn{};
80inline constexpr auto replace_copy = __replace_copy::__fn{};
8481} // namespace __cpo
8582} // namespace ranges
8683
8784_LIBCPP_END_NAMESPACE_STD
8885
89#endif // _LIBCPP_STD_VER > 17
86#endif // _LIBCPP_STD_VER >= 20
9087
9188#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H
lib/libcxx/include/__algorithm/ranges_replace_copy_if.h+30-30
......@@ -24,7 +24,7 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
......@@ -51,43 +51,43 @@ _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> __repl
5151
5252namespace __replace_copy_if {
5353
54 struct __fn {
55 template <input_iterator _InIter,
56 sentinel_for<_InIter> _Sent,
57 class _Type,
58 output_iterator<const _Type&> _OutIter,
59 class _Proj = identity,
60 indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
61 requires indirectly_copyable<_InIter, _OutIter>
62 _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> operator()(
63 _InIter __first, _Sent __last, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {})
64 const {
65 return ranges::__replace_copy_if_impl(
66 std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj);
67 }
68
69 template <input_range _Range,
70 class _Type,
71 output_iterator<const _Type&> _OutIter,
72 class _Proj = identity,
73 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
74 requires indirectly_copyable<iterator_t<_Range>, _OutIter>
75 _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
76 operator()(_Range&& __range, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
77 return ranges::__replace_copy_if_impl(
78 ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj);
79 }
80 };
54struct __fn {
55 template <input_iterator _InIter,
56 sentinel_for<_InIter> _Sent,
57 class _Type,
58 output_iterator<const _Type&> _OutIter,
59 class _Proj = identity,
60 indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
61 requires indirectly_copyable<_InIter, _OutIter>
62 _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> operator()(
63 _InIter __first, _Sent __last, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {})
64 const {
65 return ranges::__replace_copy_if_impl(
66 std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj);
67 }
68
69 template <input_range _Range,
70 class _Type,
71 output_iterator<const _Type&> _OutIter,
72 class _Proj = identity,
73 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
74 requires indirectly_copyable<iterator_t<_Range>, _OutIter>
75 _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
76 operator()(_Range&& __range, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
77 return ranges::__replace_copy_if_impl(
78 ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj);
79 }
80};
8181
8282} // namespace __replace_copy_if
8383
8484inline namespace __cpo {
85 inline constexpr auto replace_copy_if = __replace_copy_if::__fn{};
85inline constexpr auto replace_copy_if = __replace_copy_if::__fn{};
8686} // namespace __cpo
8787} // namespace ranges
8888
8989_LIBCPP_END_NAMESPACE_STD
9090
91#endif // _LIBCPP_STD_VER > 17
91#endif // _LIBCPP_STD_VER >= 20
9292
9393#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H
lib/libcxx/include/__algorithm/ranges_replace_if.h+9-10
......@@ -23,15 +23,15 @@
2323# pragma GCC system_header
2424#endif
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
3030namespace ranges {
3131
3232template <class _Iter, class _Sent, class _Type, class _Proj, class _Pred>
33_LIBCPP_HIDE_FROM_ABI constexpr
34_Iter __replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& __new_value, _Proj& __proj) {
33_LIBCPP_HIDE_FROM_ABI constexpr _Iter
34__replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& __new_value, _Proj& __proj) {
3535 for (; __first != __last; ++__first) {
3636 if (std::invoke(__pred, std::invoke(__proj, *__first)))
3737 *__first = __new_value;
......@@ -41,14 +41,14 @@ _Iter __replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type&
4141
4242namespace __replace_if {
4343struct __fn {
44
45 template <input_iterator _Iter, sentinel_for<_Iter> _Sent,
44 template <input_iterator _Iter,
45 sentinel_for<_Iter> _Sent,
4646 class _Type,
4747 class _Proj = identity,
4848 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
4949 requires indirectly_writable<_Iter, const _Type&>
50 _LIBCPP_HIDE_FROM_ABI constexpr
51 _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
50 _LIBCPP_HIDE_FROM_ABI constexpr _Iter
51 operator()(_Iter __first, _Sent __last, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
5252 return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj);
5353 }
5454
......@@ -61,17 +61,16 @@ struct __fn {
6161 operator()(_Range&& __range, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
6262 return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj);
6363 }
64
6564};
6665} // namespace __replace_if
6766
6867inline namespace __cpo {
69 inline constexpr auto replace_if = __replace_if::__fn{};
68inline constexpr auto replace_if = __replace_if::__fn{};
7069} // namespace __cpo
7170} // namespace ranges
7271
7372_LIBCPP_END_NAMESPACE_STD
7473
75#endif // _LIBCPP_STD_VER > 17
74#endif // _LIBCPP_STD_VER >= 20
7675
7776#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H
lib/libcxx/include/__algorithm/ranges_reverse.h+5-9
......@@ -22,18 +22,16 @@
2222# pragma GCC system_header
2323#endif
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727_LIBCPP_BEGIN_NAMESPACE_STD
2828
2929namespace ranges {
3030namespace __reverse {
3131struct __fn {
32
3332 template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent>
3433 requires permutable<_Iter>
35 _LIBCPP_HIDE_FROM_ABI constexpr
36 _Iter operator()(_Iter __first, _Sent __last) const {
34 _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last) const {
3735 if constexpr (random_access_iterator<_Iter>) {
3836 if (__first == __last)
3937 return __first;
......@@ -63,21 +61,19 @@ struct __fn {
6361
6462 template <bidirectional_range _Range>
6563 requires permutable<iterator_t<_Range>>
66 _LIBCPP_HIDE_FROM_ABI constexpr
67 borrowed_iterator_t<_Range> operator()(_Range&& __range) const {
64 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range) const {
6865 return (*this)(ranges::begin(__range), ranges::end(__range));
6966 }
70
7167};
7268} // namespace __reverse
7369
7470inline namespace __cpo {
75 inline constexpr auto reverse = __reverse::__fn{};
71inline constexpr auto reverse = __reverse::__fn{};
7672} // namespace __cpo
7773} // namespace ranges
7874
7975_LIBCPP_END_NAMESPACE_STD
8076
81#endif // _LIBCPP_STD_VER > 17
77#endif // _LIBCPP_STD_VER >= 20
8278
8379#endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_H
lib/libcxx/include/__algorithm/ranges_reverse_copy.h+7-9
......@@ -25,7 +25,7 @@
2525# pragma GCC system_header
2626#endif
2727
28#if _LIBCPP_STD_VER > 17
28#if _LIBCPP_STD_VER >= 20
2929
3030_LIBCPP_BEGIN_NAMESPACE_STD
3131
......@@ -36,32 +36,30 @@ using reverse_copy_result = in_out_result<_InIter, _OutIter>;
3636
3737namespace __reverse_copy {
3838struct __fn {
39
4039 template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
4140 requires indirectly_copyable<_InIter, _OutIter>
42 _LIBCPP_HIDE_FROM_ABI constexpr
43 reverse_copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
41 _LIBCPP_HIDE_FROM_ABI constexpr reverse_copy_result<_InIter, _OutIter>
42 operator()(_InIter __first, _Sent __last, _OutIter __result) const {
4443 return (*this)(subrange(std::move(__first), std::move(__last)), std::move(__result));
4544 }
4645
4746 template <bidirectional_range _Range, weakly_incrementable _OutIter>
4847 requires indirectly_copyable<iterator_t<_Range>, _OutIter>
49 _LIBCPP_HIDE_FROM_ABI constexpr
50 reverse_copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __range, _OutIter __result) const {
48 _LIBCPP_HIDE_FROM_ABI constexpr reverse_copy_result<borrowed_iterator_t<_Range>, _OutIter>
49 operator()(_Range&& __range, _OutIter __result) const {
5150 auto __ret = ranges::copy(std::__reverse_range(__range), std::move(__result));
5251 return {ranges::next(ranges::begin(__range), ranges::end(__range)), std::move(__ret.out)};
5352 }
54
5553};
5654} // namespace __reverse_copy
5755
5856inline namespace __cpo {
59 inline constexpr auto reverse_copy = __reverse_copy::__fn{};
57inline constexpr auto reverse_copy = __reverse_copy::__fn{};
6058} // namespace __cpo
6159} // namespace ranges
6260
6361_LIBCPP_END_NAMESPACE_STD
6462
65#endif // _LIBCPP_STD_VER > 17
63#endif // _LIBCPP_STD_VER >= 20
6664
6765#endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H
lib/libcxx/include/__algorithm/ranges_rotate.h+9-14
......@@ -25,7 +25,7 @@
2525# pragma GCC system_header
2626#endif
2727
28#if _LIBCPP_STD_VER > 17
28#if _LIBCPP_STD_VER >= 20
2929
3030_LIBCPP_BEGIN_NAMESPACE_STD
3131
......@@ -33,39 +33,34 @@ namespace ranges {
3333namespace __rotate {
3434
3535struct __fn {
36
3736 template <class _Iter, class _Sent>
38 _LIBCPP_HIDE_FROM_ABI constexpr
39 static subrange<_Iter> __rotate_fn_impl(_Iter __first, _Iter __middle, _Sent __last) {
40 auto __ret = std::__rotate<_RangeAlgPolicy>(
41 std::move(__first), std::move(__middle), std::move(__last));
37 _LIBCPP_HIDE_FROM_ABI constexpr static subrange<_Iter> __rotate_fn_impl(_Iter __first, _Iter __middle, _Sent __last) {
38 auto __ret = std::__rotate<_RangeAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last));
4239 return {std::move(__ret.first), std::move(__ret.second)};
4340 }
4441
4542 template <permutable _Iter, sentinel_for<_Iter> _Sent>
46 _LIBCPP_HIDE_FROM_ABI constexpr
47 subrange<_Iter> operator()(_Iter __first, _Iter __middle, _Sent __last) const {
43 _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Iter __middle, _Sent __last) const {
4844 return __rotate_fn_impl(std::move(__first), std::move(__middle), std::move(__last));
4945 }
5046
5147 template <forward_range _Range>
52 requires permutable<iterator_t<_Range>>
53 _LIBCPP_HIDE_FROM_ABI constexpr
54 borrowed_subrange_t<_Range> operator()(_Range&& __range, iterator_t<_Range> __middle) const {
48 requires permutable<iterator_t<_Range>>
49 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
50 operator()(_Range&& __range, iterator_t<_Range> __middle) const {
5551 return __rotate_fn_impl(ranges::begin(__range), std::move(__middle), ranges::end(__range));
5652 }
57
5853};
5954
6055} // namespace __rotate
6156
6257inline namespace __cpo {
63 inline constexpr auto rotate = __rotate::__fn{};
58inline constexpr auto rotate = __rotate::__fn{};
6459} // namespace __cpo
6560} // namespace ranges
6661
6762_LIBCPP_END_NAMESPACE_STD
6863
69#endif // _LIBCPP_STD_VER > 17
64#endif // _LIBCPP_STD_VER >= 20
7065
7166#endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_H
lib/libcxx/include/__algorithm/ranges_rotate_copy.h+5-9
......@@ -23,7 +23,7 @@
2323# pragma GCC system_header
2424#endif
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
......@@ -34,11 +34,9 @@ using rotate_copy_result = in_out_result<_InIter, _OutIter>;
3434
3535namespace __rotate_copy {
3636struct __fn {
37
3837 template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
3938 requires indirectly_copyable<_InIter, _OutIter>
40 _LIBCPP_HIDE_FROM_ABI constexpr
41 rotate_copy_result<_InIter, _OutIter>
39 _LIBCPP_HIDE_FROM_ABI constexpr rotate_copy_result<_InIter, _OutIter>
4240 operator()(_InIter __first, _InIter __middle, _Sent __last, _OutIter __result) const {
4341 auto __res1 = ranges::copy(__middle, __last, std::move(__result));
4442 auto __res2 = ranges::copy(__first, __middle, std::move(__res1.out));
......@@ -47,22 +45,20 @@ struct __fn {
4745
4846 template <bidirectional_range _Range, weakly_incrementable _OutIter>
4947 requires indirectly_copyable<iterator_t<_Range>, _OutIter>
50 _LIBCPP_HIDE_FROM_ABI constexpr
51 rotate_copy_result<borrowed_iterator_t<_Range>, _OutIter>
48 _LIBCPP_HIDE_FROM_ABI constexpr rotate_copy_result<borrowed_iterator_t<_Range>, _OutIter>
5249 operator()(_Range&& __range, iterator_t<_Range> __middle, _OutIter __result) const {
5350 return (*this)(ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__result));
5451 }
55
5652};
5753} // namespace __rotate_copy
5854
5955inline namespace __cpo {
60 inline constexpr auto rotate_copy = __rotate_copy::__fn{};
56inline constexpr auto rotate_copy = __rotate_copy::__fn{};
6157} // namespace __cpo
6258} // namespace ranges
6359
6460_LIBCPP_END_NAMESPACE_STD
6561
66#endif // _LIBCPP_STD_VER > 17
62#endif // _LIBCPP_STD_VER >= 20
6763
6864#endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H
lib/libcxx/include/__algorithm/ranges_sample.h+14-19
......@@ -19,15 +19,15 @@
1919#include <__random/uniform_random_bit_generator.h>
2020#include <__ranges/access.h>
2121#include <__ranges/concepts.h>
22#include <__type_traits/remove_reference.h>
2223#include <__utility/forward.h>
2324#include <__utility/move.h>
24#include <type_traits>
2525
2626#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2727# pragma GCC system_header
2828#endif
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_BEGIN_NAMESPACE_STD
3333
......@@ -35,40 +35,35 @@ namespace ranges {
3535namespace __sample {
3636
3737struct __fn {
38
3938 template <input_iterator _Iter, sentinel_for<_Iter> _Sent, weakly_incrementable _OutIter, class _Gen>
40 requires (forward_iterator<_Iter> || random_access_iterator<_OutIter>) &&
41 indirectly_copyable<_Iter, _OutIter> &&
42 uniform_random_bit_generator<remove_reference_t<_Gen>>
43 _LIBCPP_HIDE_FROM_ABI
44 _OutIter operator()(_Iter __first, _Sent __last,
45 _OutIter __out_first, iter_difference_t<_Iter> __n, _Gen&& __gen) const {
39 requires(forward_iterator<_Iter> || random_access_iterator<_OutIter>) && indirectly_copyable<_Iter, _OutIter> &&
40 uniform_random_bit_generator<remove_reference_t<_Gen>>
41 _LIBCPP_HIDE_FROM_ABI _OutIter
42 operator()(_Iter __first, _Sent __last, _OutIter __out_first, iter_difference_t<_Iter> __n, _Gen&& __gen) const {
4643 _ClassicGenAdaptor<_Gen> __adapted_gen(__gen);
4744 return std::__sample<_RangeAlgPolicy>(
4845 std::move(__first), std::move(__last), std::move(__out_first), __n, __adapted_gen);
4946 }
5047
5148 template <input_range _Range, weakly_incrementable _OutIter, class _Gen>
52 requires (forward_range<_Range> || random_access_iterator<_OutIter>) &&
53 indirectly_copyable<iterator_t<_Range>, _OutIter> &&
54 uniform_random_bit_generator<remove_reference_t<_Gen>>
55 _LIBCPP_HIDE_FROM_ABI
56 _OutIter operator()(_Range&& __range, _OutIter __out_first, range_difference_t<_Range> __n, _Gen&& __gen) const {
57 return (*this)(ranges::begin(__range), ranges::end(__range),
58 std::move(__out_first), __n, std::forward<_Gen>(__gen));
49 requires(forward_range<_Range> || random_access_iterator<_OutIter>) &&
50 indirectly_copyable<iterator_t<_Range>, _OutIter> && uniform_random_bit_generator<remove_reference_t<_Gen>>
51 _LIBCPP_HIDE_FROM_ABI _OutIter
52 operator()(_Range&& __range, _OutIter __out_first, range_difference_t<_Range> __n, _Gen&& __gen) const {
53 return (*this)(
54 ranges::begin(__range), ranges::end(__range), std::move(__out_first), __n, std::forward<_Gen>(__gen));
5955 }
60
6156};
6257
6358} // namespace __sample
6459
6560inline namespace __cpo {
66 inline constexpr auto sample = __sample::__fn{};
61inline constexpr auto sample = __sample::__fn{};
6762} // namespace __cpo
6863} // namespace ranges
6964
7065_LIBCPP_END_NAMESPACE_STD
7166
72#endif // _LIBCPP_STD_VER > 17
67#endif // _LIBCPP_STD_VER >= 20
7368
7469#endif // _LIBCPP___ALGORITHM_RANGES_SAMPLE_H
lib/libcxx/include/__algorithm/ranges_search.h+19-20
......@@ -28,7 +28,7 @@
2828# pragma GCC system_header
2929#endif
3030
31#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
3232
3333_LIBCPP_BEGIN_NAMESPACE_STD
3434
......@@ -69,33 +69,33 @@ struct __fn {
6969 return {__ret.first, __ret.second};
7070 }
7171
72 template <forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
73 forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
74 class _Pred = ranges::equal_to,
72 template <forward_iterator _Iter1,
73 sentinel_for<_Iter1> _Sent1,
74 forward_iterator _Iter2,
75 sentinel_for<_Iter2> _Sent2,
76 class _Pred = ranges::equal_to,
7577 class _Proj1 = identity,
7678 class _Proj2 = identity>
7779 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
78 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
79 subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1,
80 _Iter2 __first2, _Sent2 __last2,
81 _Pred __pred = {},
82 _Proj1 __proj1 = {},
83 _Proj2 __proj2 = {}) const {
80 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()(
81 _Iter1 __first1,
82 _Sent1 __last1,
83 _Iter2 __first2,
84 _Sent2 __last2,
85 _Pred __pred = {},
86 _Proj1 __proj1 = {},
87 _Proj2 __proj2 = {}) const {
8488 return __ranges_search_impl(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2);
8589 }
8690
8791 template <forward_range _Range1,
8892 forward_range _Range2,
89 class _Pred = ranges::equal_to,
93 class _Pred = ranges::equal_to,
9094 class _Proj1 = identity,
9195 class _Proj2 = identity>
9296 requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
93 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
94 borrowed_subrange_t<_Range1> operator()(_Range1&& __range1,
95 _Range2&& __range2,
96 _Pred __pred = {},
97 _Proj1 __proj1 = {},
98 _Proj2 __proj2 = {}) const {
97 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()(
98 _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
9999 auto __first1 = ranges::begin(__range1);
100100 if constexpr (sized_range<_Range2>) {
101101 auto __size2 = ranges::size(__range2);
......@@ -119,17 +119,16 @@ struct __fn {
119119 __proj1,
120120 __proj2);
121121 }
122
123122};
124123} // namespace __search
125124
126125inline namespace __cpo {
127 inline constexpr auto search = __search::__fn{};
126inline constexpr auto search = __search::__fn{};
128127} // namespace __cpo
129128} // namespace ranges
130129
131130_LIBCPP_END_NAMESPACE_STD
132131
133#endif // _LIBCPP_STD_VER > 17
132#endif // _LIBCPP_STD_VER >= 20
134133
135134#endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_H
lib/libcxx/include/__algorithm/ranges_search_n.h+16-22
......@@ -31,14 +31,13 @@
3131# pragma GCC system_header
3232#endif
3333
34#if _LIBCPP_STD_VER > 17
34#if _LIBCPP_STD_VER >= 20
3535
3636_LIBCPP_BEGIN_NAMESPACE_STD
3737
3838namespace ranges {
3939namespace __search_n {
4040struct __fn {
41
4241 template <class _Iter1, class _Sent1, class _SizeT, class _Type, class _Pred, class _Proj>
4342 _LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Iter1> __ranges_search_n_impl(
4443 _Iter1 __first, _Sent1 __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) {
......@@ -59,36 +58,31 @@ struct __fn {
5958 }
6059 }
6160
62 auto __ret = std::__search_n_forward_impl<_RangeAlgPolicy>(__first, __last,
63 __count,
64 __value,
65 __pred,
66 __proj);
61 auto __ret = std::__search_n_forward_impl<_RangeAlgPolicy>(__first, __last, __count, __value, __pred, __proj);
6762 return {std::move(__ret.first), std::move(__ret.second)};
6863 }
6964
70 template <forward_iterator _Iter, sentinel_for<_Iter> _Sent,
65 template <forward_iterator _Iter,
66 sentinel_for<_Iter> _Sent,
7167 class _Type,
7268 class _Pred = ranges::equal_to,
7369 class _Proj = identity>
7470 requires indirectly_comparable<_Iter, const _Type*, _Pred, _Proj>
75 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
76 subrange<_Iter> operator()(_Iter __first, _Sent __last,
77 iter_difference_t<_Iter> __count,
78 const _Type& __value,
79 _Pred __pred = {},
80 _Proj __proj = _Proj{}) const {
71 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
72 operator()(_Iter __first,
73 _Sent __last,
74 iter_difference_t<_Iter> __count,
75 const _Type& __value,
76 _Pred __pred = {},
77 _Proj __proj = _Proj{}) const {
8178 return __ranges_search_n_impl(__first, __last, __count, __value, __pred, __proj);
8279 }
8380
8481 template <forward_range _Range, class _Type, class _Pred = ranges::equal_to, class _Proj = identity>
8582 requires indirectly_comparable<iterator_t<_Range>, const _Type*, _Pred, _Proj>
86 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
87 borrowed_subrange_t<_Range> operator()(_Range&& __range,
88 range_difference_t<_Range> __count,
89 const _Type& __value,
90 _Pred __pred = {},
91 _Proj __proj = {}) const {
83 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()(
84 _Range&& __range, range_difference_t<_Range> __count, const _Type& __value, _Pred __pred = {}, _Proj __proj = {})
85 const {
9286 auto __first = ranges::begin(__range);
9387 if (__count <= 0)
9488 return {__first, __first};
......@@ -106,12 +100,12 @@ struct __fn {
106100} // namespace __search_n
107101
108102inline namespace __cpo {
109 inline constexpr auto search_n = __search_n::__fn{};
103inline constexpr auto search_n = __search_n::__fn{};
110104} // namespace __cpo
111105} // namespace ranges
112106
113107_LIBCPP_END_NAMESPACE_STD
114108
115#endif // _LIBCPP_STD_VER > 17
109#endif // _LIBCPP_STD_VER >= 20
116110
117111#endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H
lib/libcxx/include/__algorithm/ranges_set_difference.h+23-26
......@@ -30,7 +30,7 @@
3030# pragma GCC system_header
3131#endif
3232
33#if _LIBCPP_STD_VER > 17
33#if _LIBCPP_STD_VER >= 20
3434
3535_LIBCPP_BEGIN_NAMESPACE_STD
3636
......@@ -42,15 +42,14 @@ using set_difference_result = in_out_result<_InIter, _OutIter>;
4242namespace __set_difference {
4343
4444struct __fn {
45 template <
46 input_iterator _InIter1,
47 sentinel_for<_InIter1> _Sent1,
48 input_iterator _InIter2,
49 sentinel_for<_InIter2> _Sent2,
50 weakly_incrementable _OutIter,
51 class _Comp = less,
52 class _Proj1 = identity,
53 class _Proj2 = identity>
45 template <input_iterator _InIter1,
46 sentinel_for<_InIter1> _Sent1,
47 input_iterator _InIter2,
48 sentinel_for<_InIter2> _Sent2,
49 weakly_incrementable _OutIter,
50 class _Comp = less,
51 class _Proj1 = identity,
52 class _Proj2 = identity>
5453 requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
5554 _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result<_InIter1, _OutIter> operator()(
5655 _InIter1 __first1,
......@@ -66,22 +65,20 @@ struct __fn {
6665 return {std::move(__ret.first), std::move(__ret.second)};
6766 }
6867
69 template <
70 input_range _Range1,
71 input_range _Range2,
72 weakly_incrementable _OutIter,
73 class _Comp = less,
74 class _Proj1 = identity,
75 class _Proj2 = identity>
68 template <input_range _Range1,
69 input_range _Range2,
70 weakly_incrementable _OutIter,
71 class _Comp = less,
72 class _Proj1 = identity,
73 class _Proj2 = identity>
7674 requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2>
7775 _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result<borrowed_iterator_t<_Range1>, _OutIter>
78 operator()(
79 _Range1&& __range1,
80 _Range2&& __range2,
81 _OutIter __result,
82 _Comp __comp = {},
83 _Proj1 __proj1 = {},
84 _Proj2 __proj2 = {}) const {
76 operator()(_Range1&& __range1,
77 _Range2&& __range2,
78 _OutIter __result,
79 _Comp __comp = {},
80 _Proj1 __proj1 = {},
81 _Proj2 __proj2 = {}) const {
8582 auto __ret = std::__set_difference<_RangeAlgPolicy>(
8683 ranges::begin(__range1),
8784 ranges::end(__range1),
......@@ -96,11 +93,11 @@ struct __fn {
9693} // namespace __set_difference
9794
9895inline namespace __cpo {
99 inline constexpr auto set_difference = __set_difference::__fn{};
96inline constexpr auto set_difference = __set_difference::__fn{};
10097} // namespace __cpo
10198} // namespace ranges
10299
103100_LIBCPP_END_NAMESPACE_STD
104101
105#endif // _LIBCPP_STD_VER > 17
102#endif // _LIBCPP_STD_VER >= 20
106103#endif // _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H
lib/libcxx/include/__algorithm/ranges_set_intersection.h+27-36
......@@ -28,7 +28,7 @@
2828# pragma GCC system_header
2929#endif
3030
31#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
3232
3333_LIBCPP_BEGIN_NAMESPACE_STD
3434
......@@ -40,15 +40,14 @@ using set_intersection_result = in_in_out_result<_InIter1, _InIter2, _OutIter>;
4040namespace __set_intersection {
4141
4242struct __fn {
43 template <
44 input_iterator _InIter1,
45 sentinel_for<_InIter1> _Sent1,
46 input_iterator _InIter2,
47 sentinel_for<_InIter2> _Sent2,
48 weakly_incrementable _OutIter,
49 class _Comp = less,
50 class _Proj1 = identity,
51 class _Proj2 = identity>
43 template <input_iterator _InIter1,
44 sentinel_for<_InIter1> _Sent1,
45 input_iterator _InIter2,
46 sentinel_for<_InIter2> _Sent2,
47 weakly_incrementable _OutIter,
48 class _Comp = less,
49 class _Proj1 = identity,
50 class _Proj2 = identity>
5251 requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
5352 _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<_InIter1, _InIter2, _OutIter> operator()(
5453 _InIter1 __first1,
......@@ -69,30 +68,22 @@ struct __fn {
6968 return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)};
7069 }
7170
72 template <
73 input_range _Range1,
74 input_range _Range2,
75 weakly_incrementable _OutIter,
76 class _Comp = less,
77 class _Proj1 = identity,
78 class _Proj2 = identity>
79 requires mergeable<
80 iterator_t<_Range1>,
81 iterator_t<_Range2>,
82 _OutIter,
83 _Comp,
84 _Proj1,
85 _Proj2>
86 _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<borrowed_iterator_t<_Range1>,
87 borrowed_iterator_t<_Range2>,
88 _OutIter>
89 operator()(
90 _Range1&& __range1,
91 _Range2&& __range2,
92 _OutIter __result,
93 _Comp __comp = {},
94 _Proj1 __proj1 = {},
95 _Proj2 __proj2 = {}) const {
71 template <input_range _Range1,
72 input_range _Range2,
73 weakly_incrementable _OutIter,
74 class _Comp = less,
75 class _Proj1 = identity,
76 class _Proj2 = identity>
77 requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2>
78 _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<borrowed_iterator_t<_Range1>,
79 borrowed_iterator_t<_Range2>,
80 _OutIter>
81 operator()(_Range1&& __range1,
82 _Range2&& __range2,
83 _OutIter __result,
84 _Comp __comp = {},
85 _Proj1 __proj1 = {},
86 _Proj2 __proj2 = {}) const {
9687 auto __ret = std::__set_intersection<_RangeAlgPolicy>(
9788 ranges::begin(__range1),
9889 ranges::end(__range1),
......@@ -107,11 +98,11 @@ struct __fn {
10798} // namespace __set_intersection
10899
109100inline namespace __cpo {
110 inline constexpr auto set_intersection = __set_intersection::__fn{};
101inline constexpr auto set_intersection = __set_intersection::__fn{};
111102} // namespace __cpo
112103} // namespace ranges
113104
114105_LIBCPP_END_NAMESPACE_STD
115106
116#endif // _LIBCPP_STD_VER > 17
107#endif // _LIBCPP_STD_VER >= 20
117108#endif // _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H
lib/libcxx/include/__algorithm/ranges_set_symmetric_difference.h+24-33
......@@ -28,7 +28,7 @@
2828# pragma GCC system_header
2929#endif
3030
31#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
3232
3333_LIBCPP_BEGIN_NAMESPACE_STD
3434
......@@ -40,15 +40,14 @@ using set_symmetric_difference_result = in_in_out_result<_InIter1, _InIter2, _Ou
4040namespace __set_symmetric_difference {
4141
4242struct __fn {
43 template <
44 input_iterator _InIter1,
45 sentinel_for<_InIter1> _Sent1,
46 input_iterator _InIter2,
47 sentinel_for<_InIter2> _Sent2,
48 weakly_incrementable _OutIter,
49 class _Comp = ranges::less,
50 class _Proj1 = identity,
51 class _Proj2 = identity>
43 template <input_iterator _InIter1,
44 sentinel_for<_InIter1> _Sent1,
45 input_iterator _InIter2,
46 sentinel_for<_InIter2> _Sent2,
47 weakly_incrementable _OutIter,
48 class _Comp = ranges::less,
49 class _Proj1 = identity,
50 class _Proj2 = identity>
5251 requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
5352 _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result<_InIter1, _InIter2, _OutIter> operator()(
5453 _InIter1 __first1,
......@@ -69,30 +68,22 @@ struct __fn {
6968 return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)};
7069 }
7170
72 template <
73 input_range _Range1,
74 input_range _Range2,
75 weakly_incrementable _OutIter,
76 class _Comp = ranges::less,
77 class _Proj1 = identity,
78 class _Proj2 = identity>
79 requires mergeable<
80 iterator_t<_Range1>,
81 iterator_t<_Range2>,
82 _OutIter,
83 _Comp,
84 _Proj1,
85 _Proj2>
71 template <input_range _Range1,
72 input_range _Range2,
73 weakly_incrementable _OutIter,
74 class _Comp = ranges::less,
75 class _Proj1 = identity,
76 class _Proj2 = identity>
77 requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2>
8678 _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result<borrowed_iterator_t<_Range1>,
8779 borrowed_iterator_t<_Range2>,
8880 _OutIter>
89 operator()(
90 _Range1&& __range1,
91 _Range2&& __range2,
92 _OutIter __result,
93 _Comp __comp = {},
94 _Proj1 __proj1 = {},
95 _Proj2 __proj2 = {}) const {
81 operator()(_Range1&& __range1,
82 _Range2&& __range2,
83 _OutIter __result,
84 _Comp __comp = {},
85 _Proj1 __proj1 = {},
86 _Proj2 __proj2 = {}) const {
9687 auto __ret = std::__set_symmetric_difference<_RangeAlgPolicy>(
9788 ranges::begin(__range1),
9889 ranges::end(__range1),
......@@ -107,11 +98,11 @@ struct __fn {
10798} // namespace __set_symmetric_difference
10899
109100inline namespace __cpo {
110 inline constexpr auto set_symmetric_difference = __set_symmetric_difference::__fn{};
101inline constexpr auto set_symmetric_difference = __set_symmetric_difference::__fn{};
111102} // namespace __cpo
112103} // namespace ranges
113104
114105_LIBCPP_END_NAMESPACE_STD
115106
116#endif // _LIBCPP_STD_VER > 17
107#endif // _LIBCPP_STD_VER >= 20
117108#endif // _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H
lib/libcxx/include/__algorithm/ranges_set_union.h+25-36
......@@ -31,7 +31,7 @@
3131# pragma GCC system_header
3232#endif
3333
34#if _LIBCPP_STD_VER > 17
34#if _LIBCPP_STD_VER >= 20
3535
3636_LIBCPP_BEGIN_NAMESPACE_STD
3737
......@@ -43,15 +43,14 @@ using set_union_result = in_in_out_result<_InIter1, _InIter2, _OutIter>;
4343namespace __set_union {
4444
4545struct __fn {
46 template <
47 input_iterator _InIter1,
48 sentinel_for<_InIter1> _Sent1,
49 input_iterator _InIter2,
50 sentinel_for<_InIter2> _Sent2,
51 weakly_incrementable _OutIter,
52 class _Comp = ranges::less,
53 class _Proj1 = identity,
54 class _Proj2 = identity>
46 template <input_iterator _InIter1,
47 sentinel_for<_InIter1> _Sent1,
48 input_iterator _InIter2,
49 sentinel_for<_InIter2> _Sent2,
50 weakly_incrementable _OutIter,
51 class _Comp = ranges::less,
52 class _Proj1 = identity,
53 class _Proj2 = identity>
5554 requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
5655 _LIBCPP_HIDE_FROM_ABI constexpr set_union_result<_InIter1, _InIter2, _OutIter> operator()(
5756 _InIter1 __first1,
......@@ -72,30 +71,20 @@ struct __fn {
7271 return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)};
7372 }
7473
75 template <
76 input_range _Range1,
77 input_range _Range2,
78 weakly_incrementable _OutIter,
79 class _Comp = ranges::less,
80 class _Proj1 = identity,
81 class _Proj2 = identity>
82 requires mergeable<
83 iterator_t<_Range1>,
84 iterator_t<_Range2>,
85 _OutIter,
86 _Comp,
87 _Proj1,
88 _Proj2>
89 _LIBCPP_HIDE_FROM_ABI constexpr set_union_result<borrowed_iterator_t<_Range1>,
90 borrowed_iterator_t<_Range2>,
91 _OutIter>
92 operator()(
93 _Range1&& __range1,
94 _Range2&& __range2,
95 _OutIter __result,
96 _Comp __comp = {},
97 _Proj1 __proj1 = {},
98 _Proj2 __proj2 = {}) const {
74 template <input_range _Range1,
75 input_range _Range2,
76 weakly_incrementable _OutIter,
77 class _Comp = ranges::less,
78 class _Proj1 = identity,
79 class _Proj2 = identity>
80 requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2>
81 _LIBCPP_HIDE_FROM_ABI constexpr set_union_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>, _OutIter>
82 operator()(_Range1&& __range1,
83 _Range2&& __range2,
84 _OutIter __result,
85 _Comp __comp = {},
86 _Proj1 __proj1 = {},
87 _Proj2 __proj2 = {}) const {
9988 auto __ret = std::__set_union<_RangeAlgPolicy>(
10089 ranges::begin(__range1),
10190 ranges::end(__range1),
......@@ -110,12 +99,12 @@ struct __fn {
11099} // namespace __set_union
111100
112101inline namespace __cpo {
113 inline constexpr auto set_union = __set_union::__fn{};
102inline constexpr auto set_union = __set_union::__fn{};
114103} // namespace __cpo
115104} // namespace ranges
116105
117106_LIBCPP_END_NAMESPACE_STD
118107
119#endif // _LIBCPP_STD_VER > 17
108#endif // _LIBCPP_STD_VER >= 20
120109
121110#endif // _LIBCPP___ALGORITHM_RANGES_SET_UNION_H
lib/libcxx/include/__algorithm/ranges_shuffle.h+9-13
......@@ -23,15 +23,15 @@
2323#include <__ranges/access.h>
2424#include <__ranges/concepts.h>
2525#include <__ranges/dangling.h>
26#include <__type_traits/remove_reference.h>
2627#include <__utility/forward.h>
2728#include <__utility/move.h>
28#include <type_traits>
2929
3030#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3131# pragma GCC system_header
3232#endif
3333
34#if _LIBCPP_STD_VER > 17
34#if _LIBCPP_STD_VER >= 20
3535
3636_LIBCPP_BEGIN_NAMESPACE_STD
3737
......@@ -39,33 +39,29 @@ namespace ranges {
3939namespace __shuffle {
4040
4141struct __fn {
42
4342 template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Gen>
44 requires permutable<_Iter> && uniform_random_bit_generator<remove_reference_t<_Gen>>
45 _LIBCPP_HIDE_FROM_ABI
46 _Iter operator()(_Iter __first, _Sent __last, _Gen&& __gen) const {
43 requires permutable<_Iter> && uniform_random_bit_generator<remove_reference_t<_Gen>>
44 _LIBCPP_HIDE_FROM_ABI _Iter operator()(_Iter __first, _Sent __last, _Gen&& __gen) const {
4745 _ClassicGenAdaptor<_Gen> __adapted_gen(__gen);
4846 return std::__shuffle<_RangeAlgPolicy>(std::move(__first), std::move(__last), __adapted_gen);
4947 }
5048
51 template<random_access_range _Range, class _Gen>
52 requires permutable<iterator_t<_Range>> && uniform_random_bit_generator<remove_reference_t<_Gen>>
53 _LIBCPP_HIDE_FROM_ABI
54 borrowed_iterator_t<_Range> operator()(_Range&& __range, _Gen&& __gen) const {
49 template <random_access_range _Range, class _Gen>
50 requires permutable<iterator_t<_Range>> && uniform_random_bit_generator<remove_reference_t<_Gen>>
51 _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range> operator()(_Range&& __range, _Gen&& __gen) const {
5552 return (*this)(ranges::begin(__range), ranges::end(__range), std::forward<_Gen>(__gen));
5653 }
57
5854};
5955
6056} // namespace __shuffle
6157
6258inline namespace __cpo {
63 inline constexpr auto shuffle = __shuffle::__fn{};
59inline constexpr auto shuffle = __shuffle::__fn{};
6460} // namespace __cpo
6561} // namespace ranges
6662
6763_LIBCPP_END_NAMESPACE_STD
6864
69#endif // _LIBCPP_STD_VER > 17
65#endif // _LIBCPP_STD_VER >= 20
7066
7167#endif // _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H
lib/libcxx/include/__algorithm/ranges_sort.h+9-9
......@@ -31,7 +31,7 @@
3131# pragma GCC system_header
3232#endif
3333
34#if _LIBCPP_STD_VER > 17
34#if _LIBCPP_STD_VER >= 20
3535
3636_LIBCPP_BEGIN_NAMESPACE_STD
3737
......@@ -40,8 +40,8 @@ namespace __sort {
4040
4141struct __fn {
4242 template <class _Iter, class _Sent, class _Comp, class _Proj>
43 _LIBCPP_HIDE_FROM_ABI constexpr static
44 _Iter __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
43 _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
44 __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
4545 auto __last_iter = ranges::next(__first, __last);
4646
4747 auto&& __projected_comp = std::__make_projected(__comp, __proj);
......@@ -52,15 +52,15 @@ struct __fn {
5252
5353 template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
5454 requires sortable<_Iter, _Comp, _Proj>
55 _LIBCPP_HIDE_FROM_ABI constexpr
56 _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
55 _LIBCPP_HIDE_FROM_ABI constexpr _Iter
56 operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
5757 return __sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
5858 }
5959
6060 template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
6161 requires sortable<iterator_t<_Range>, _Comp, _Proj>
62 _LIBCPP_HIDE_FROM_ABI constexpr
63 borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
62 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
63 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
6464 return __sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
6565 }
6666};
......@@ -68,12 +68,12 @@ struct __fn {
6868} // namespace __sort
6969
7070inline namespace __cpo {
71 inline constexpr auto sort = __sort::__fn{};
71inline constexpr auto sort = __sort::__fn{};
7272} // namespace __cpo
7373} // namespace ranges
7474
7575_LIBCPP_END_NAMESPACE_STD
7676
77#endif // _LIBCPP_STD_VER > 17
77#endif // _LIBCPP_STD_VER >= 20
7878
7979#endif // _LIBCPP___ALGORITHM_RANGES_SORT_H
lib/libcxx/include/__algorithm/ranges_sort_heap.h+9-9
......@@ -32,7 +32,7 @@
3232# pragma GCC system_header
3333#endif
3434
35#if _LIBCPP_STD_VER > 17
35#if _LIBCPP_STD_VER >= 20
3636
3737_LIBCPP_BEGIN_NAMESPACE_STD
3838
......@@ -41,8 +41,8 @@ namespace __sort_heap {
4141
4242struct __fn {
4343 template <class _Iter, class _Sent, class _Comp, class _Proj>
44 _LIBCPP_HIDE_FROM_ABI constexpr static
45 _Iter __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
44 _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
45 __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
4646 auto __last_iter = ranges::next(__first, __last);
4747
4848 auto&& __projected_comp = std::__make_projected(__comp, __proj);
......@@ -53,15 +53,15 @@ struct __fn {
5353
5454 template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
5555 requires sortable<_Iter, _Comp, _Proj>
56 _LIBCPP_HIDE_FROM_ABI constexpr
57 _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
56 _LIBCPP_HIDE_FROM_ABI constexpr _Iter
57 operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
5858 return __sort_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
5959 }
6060
6161 template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
6262 requires sortable<iterator_t<_Range>, _Comp, _Proj>
63 _LIBCPP_HIDE_FROM_ABI constexpr
64 borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
63 _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
64 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
6565 return __sort_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
6666 }
6767};
......@@ -69,12 +69,12 @@ struct __fn {
6969} // namespace __sort_heap
7070
7171inline namespace __cpo {
72 inline constexpr auto sort_heap = __sort_heap::__fn{};
72inline constexpr auto sort_heap = __sort_heap::__fn{};
7373} // namespace __cpo
7474} // namespace ranges
7575
7676_LIBCPP_END_NAMESPACE_STD
7777
78#endif // _LIBCPP_STD_VER > 17
78#endif // _LIBCPP_STD_VER >= 20
7979
8080#endif // _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H
lib/libcxx/include/__algorithm/ranges_stable_partition.h+17-18
......@@ -26,15 +26,15 @@
2626#include <__ranges/concepts.h>
2727#include <__ranges/dangling.h>
2828#include <__ranges/subrange.h>
29#include <__type_traits/remove_cvref.h>
2930#include <__utility/forward.h>
3031#include <__utility/move.h>
31#include <type_traits>
3232
3333#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3434# pragma GCC system_header
3535#endif
3636
37#if _LIBCPP_STD_VER > 17
37#if _LIBCPP_STD_VER >= 20
3838
3939_LIBCPP_BEGIN_NAMESPACE_STD
4040
......@@ -42,47 +42,46 @@ namespace ranges {
4242namespace __stable_partition {
4343
4444struct __fn {
45
4645 template <class _Iter, class _Sent, class _Proj, class _Pred>
47 _LIBCPP_HIDE_FROM_ABI static
48 subrange<__remove_cvref_t<_Iter>> __stable_partition_fn_impl(
49 _Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) {
46 _LIBCPP_HIDE_FROM_ABI static subrange<__remove_cvref_t<_Iter>>
47 __stable_partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) {
5048 auto __last_iter = ranges::next(__first, __last);
5149
5250 auto&& __projected_pred = std::__make_projected(__pred, __proj);
53 auto __result = std::__stable_partition<_RangeAlgPolicy>(
51 auto __result = std::__stable_partition<_RangeAlgPolicy>(
5452 std::move(__first), __last_iter, __projected_pred, __iterator_concept<_Iter>());
5553
5654 return {std::move(__result), std::move(__last_iter)};
5755 }
5856
59 template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
57 template <bidirectional_iterator _Iter,
58 sentinel_for<_Iter> _Sent,
59 class _Proj = identity,
6060 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
61 requires permutable<_Iter>
62 _LIBCPP_HIDE_FROM_ABI
63 subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
61 requires permutable<_Iter>
62 _LIBCPP_HIDE_FROM_ABI subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
6463 return __stable_partition_fn_impl(__first, __last, __pred, __proj);
6564 }
6665
67 template <bidirectional_range _Range, class _Proj = identity,
66 template <bidirectional_range _Range,
67 class _Proj = identity,
6868 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
69 requires permutable<iterator_t<_Range>>
70 _LIBCPP_HIDE_FROM_ABI
71 borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
69 requires permutable<iterator_t<_Range>>
70 _LIBCPP_HIDE_FROM_ABI borrowed_subrange_t<_Range>
71 operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
7272 return __stable_partition_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
7373 }
74
7574};
7675
7776} // namespace __stable_partition
7877
7978inline namespace __cpo {
80 inline constexpr auto stable_partition = __stable_partition::__fn{};
79inline constexpr auto stable_partition = __stable_partition::__fn{};
8180} // namespace __cpo
8281} // namespace ranges
8382
8483_LIBCPP_END_NAMESPACE_STD
8584
86#endif // _LIBCPP_STD_VER > 17
85#endif // _LIBCPP_STD_VER >= 20
8786
8887#endif // _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H
lib/libcxx/include/__algorithm/ranges_stable_sort.h+7-9
......@@ -31,7 +31,7 @@
3131# pragma GCC system_header
3232#endif
3333
34#if _LIBCPP_STD_VER > 17
34#if _LIBCPP_STD_VER >= 20
3535
3636_LIBCPP_BEGIN_NAMESPACE_STD
3737
......@@ -40,8 +40,7 @@ namespace __stable_sort {
4040
4141struct __fn {
4242 template <class _Iter, class _Sent, class _Comp, class _Proj>
43 _LIBCPP_HIDE_FROM_ABI
44 static _Iter __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
43 _LIBCPP_HIDE_FROM_ABI static _Iter __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
4544 auto __last_iter = ranges::next(__first, __last);
4645
4746 auto&& __projected_comp = std::__make_projected(__comp, __proj);
......@@ -52,15 +51,14 @@ struct __fn {
5251
5352 template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
5453 requires sortable<_Iter, _Comp, _Proj>
55 _LIBCPP_HIDE_FROM_ABI
56 _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
54 _LIBCPP_HIDE_FROM_ABI _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
5755 return __stable_sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
5856 }
5957
6058 template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
6159 requires sortable<iterator_t<_Range>, _Comp, _Proj>
62 _LIBCPP_HIDE_FROM_ABI
63 borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
60 _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range>
61 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
6462 return __stable_sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
6563 }
6664};
......@@ -68,12 +66,12 @@ struct __fn {
6866} // namespace __stable_sort
6967
7068inline namespace __cpo {
71 inline constexpr auto stable_sort = __stable_sort::__fn{};
69inline constexpr auto stable_sort = __stable_sort::__fn{};
7270} // namespace __cpo
7371} // namespace ranges
7472
7573_LIBCPP_END_NAMESPACE_STD
7674
77#endif // _LIBCPP_STD_VER > 17
75#endif // _LIBCPP_STD_VER >= 20
7876
7977#endif // _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H
lib/libcxx/include/__algorithm/ranges_starts_with.h created+90
......@@ -0,0 +1,90 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H
10#define _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H
11
12#include <__algorithm/in_in_result.h>
13#include <__algorithm/ranges_mismatch.h>
14#include <__config>
15#include <__functional/identity.h>
16#include <__functional/ranges_operations.h>
17#include <__iterator/concepts.h>
18#include <__iterator/indirectly_comparable.h>
19#include <__ranges/access.h>
20#include <__ranges/concepts.h>
21#include <__utility/move.h>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24# pragma GCC system_header
25#endif
26
27#if _LIBCPP_STD_VER >= 23
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31namespace ranges {
32namespace __starts_with {
33struct __fn {
34 template <input_iterator _Iter1,
35 sentinel_for<_Iter1> _Sent1,
36 input_iterator _Iter2,
37 sentinel_for<_Iter2> _Sent2,
38 class _Pred = ranges::equal_to,
39 class _Proj1 = identity,
40 class _Proj2 = identity>
41 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
42 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
43 _Iter1 __first1,
44 _Sent1 __last1,
45 _Iter2 __first2,
46 _Sent2 __last2,
47 _Pred __pred = {},
48 _Proj1 __proj1 = {},
49 _Proj2 __proj2 = {}) const {
50 return __mismatch::__fn::__go(
51 std::move(__first1),
52 std::move(__last1),
53 std::move(__first2),
54 std::move(__last2),
55 __pred,
56 __proj1,
57 __proj2)
58 .in2 == __last2;
59 }
60
61 template <input_range _Range1,
62 input_range _Range2,
63 class _Pred = ranges::equal_to,
64 class _Proj1 = identity,
65 class _Proj2 = identity>
66 requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
67 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
68 _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
69 return __mismatch::__fn::__go(
70 ranges::begin(__range1),
71 ranges::end(__range1),
72 ranges::begin(__range2),
73 ranges::end(__range2),
74 __pred,
75 __proj1,
76 __proj2)
77 .in2 == ranges::end(__range2);
78 }
79};
80} // namespace __starts_with
81inline namespace __cpo {
82inline constexpr auto starts_with = __starts_with::__fn{};
83} // namespace __cpo
84} // namespace ranges
85
86_LIBCPP_END_NAMESPACE_STD
87
88#endif // _LIBCPP_STD_VER >= 23
89
90#endif // _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H
lib/libcxx/include/__algorithm/ranges_swap_ranges.h+6-9
......@@ -24,7 +24,7 @@
2424# pragma GCC system_header
2525#endif
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
......@@ -35,8 +35,7 @@ using swap_ranges_result = in_in_result<_I1, _I2>;
3535
3636namespace __swap_ranges {
3737struct __fn {
38 template <input_iterator _I1, sentinel_for<_I1> _S1,
39 input_iterator _I2, sentinel_for<_I2> _S2>
38 template <input_iterator _I1, sentinel_for<_I1> _S1, input_iterator _I2, sentinel_for<_I2> _S2>
4039 requires indirectly_swappable<_I1, _I2>
4140 _LIBCPP_HIDE_FROM_ABI constexpr swap_ranges_result<_I1, _I2>
4241 operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2) const {
......@@ -47,22 +46,20 @@ struct __fn {
4746
4847 template <input_range _R1, input_range _R2>
4948 requires indirectly_swappable<iterator_t<_R1>, iterator_t<_R2>>
50 _LIBCPP_HIDE_FROM_ABI constexpr
51 swap_ranges_result<borrowed_iterator_t<_R1>, borrowed_iterator_t<_R2>>
49 _LIBCPP_HIDE_FROM_ABI constexpr swap_ranges_result<borrowed_iterator_t<_R1>, borrowed_iterator_t<_R2>>
5250 operator()(_R1&& __r1, _R2&& __r2) const {
53 return operator()(ranges::begin(__r1), ranges::end(__r1),
54 ranges::begin(__r2), ranges::end(__r2));
51 return operator()(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2));
5552 }
5653};
5754} // namespace __swap_ranges
5855
5956inline namespace __cpo {
60 inline constexpr auto swap_ranges = __swap_ranges::__fn{};
57inline constexpr auto swap_ranges = __swap_ranges::__fn{};
6158} // namespace __cpo
6259} // namespace ranges
6360
6461_LIBCPP_END_NAMESPACE_STD
6562
66#endif // _LIBCPP_STD_VER > 17
63#endif // _LIBCPP_STD_VER >= 20
6764
6865#endif // _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H
lib/libcxx/include/__algorithm/ranges_transform.h+63-61
......@@ -26,7 +26,7 @@
2626# pragma GCC system_header
2727#endif
2828
29#if _LIBCPP_STD_VER > 17
29#if _LIBCPP_STD_VER >= 20
3030
3131_LIBCPP_BEGIN_NAMESPACE_STD
3232
......@@ -41,15 +41,9 @@ using binary_transform_result = in_in_out_result<_I1, _I2, _O1>;
4141namespace __transform {
4242struct __fn {
4343private:
44 template <class _InIter, class _Sent,
45 class _OutIter,
46 class _Func,
47 class _Proj>
48 _LIBCPP_HIDE_FROM_ABI static constexpr
49 unary_transform_result<_InIter, _OutIter> __unary(_InIter __first, _Sent __last,
50 _OutIter __result,
51 _Func& __operation,
52 _Proj& __projection) {
44 template <class _InIter, class _Sent, class _OutIter, class _Func, class _Proj>
45 _LIBCPP_HIDE_FROM_ABI static constexpr unary_transform_result<_InIter, _OutIter>
46 __unary(_InIter __first, _Sent __last, _OutIter __result, _Func& __operation, _Proj& __projection) {
5347 while (__first != __last) {
5448 *__result = std::invoke(__operation, std::invoke(__projection, *__first));
5549 ++__first;
......@@ -59,76 +53,80 @@ private:
5953 return {std::move(__first), std::move(__result)};
6054 }
6155
62 template <class _InIter1, class _Sent1,
63 class _InIter2, class _Sent2,
56 template <class _InIter1,
57 class _Sent1,
58 class _InIter2,
59 class _Sent2,
6460 class _OutIter,
6561 class _Func,
6662 class _Proj1,
6763 class _Proj2>
6864 _LIBCPP_HIDE_FROM_ABI static constexpr binary_transform_result<_InIter1, _InIter2, _OutIter>
69 __binary(_InIter1 __first1, _Sent1 __last1,
70 _InIter2 __first2, _Sent2 __last2,
65 __binary(_InIter1 __first1,
66 _Sent1 __last1,
67 _InIter2 __first2,
68 _Sent2 __last2,
7169 _OutIter __result,
7270 _Func& __binary_operation,
7371 _Proj1& __projection1,
7472 _Proj2& __projection2) {
7573 while (__first1 != __last1 && __first2 != __last2) {
76 *__result = std::invoke(__binary_operation, std::invoke(__projection1, *__first1),
77 std::invoke(__projection2, *__first2));
74 *__result =
75 std::invoke(__binary_operation, std::invoke(__projection1, *__first1), std::invoke(__projection2, *__first2));
7876 ++__first1;
7977 ++__first2;
8078 ++__result;
8179 }
8280 return {std::move(__first1), std::move(__first2), std::move(__result)};
8381 }
82
8483public:
85 template <input_iterator _InIter, sentinel_for<_InIter> _Sent,
84 template <input_iterator _InIter,
85 sentinel_for<_InIter> _Sent,
8686 weakly_incrementable _OutIter,
8787 copy_constructible _Func,
8888 class _Proj = identity>
8989 requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter, _Proj>>>
90 _LIBCPP_HIDE_FROM_ABI constexpr
91 unary_transform_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last,
92 _OutIter __result,
93 _Func __operation,
94 _Proj __proj = {}) const {
90 _LIBCPP_HIDE_FROM_ABI constexpr unary_transform_result<_InIter, _OutIter>
91 operator()(_InIter __first, _Sent __last, _OutIter __result, _Func __operation, _Proj __proj = {}) const {
9592 return __unary(std::move(__first), std::move(__last), std::move(__result), __operation, __proj);
9693 }
9794
98 template <input_range _Range,
99 weakly_incrementable _OutIter,
100 copy_constructible _Func,
101 class _Proj = identity>
95 template <input_range _Range, weakly_incrementable _OutIter, copy_constructible _Func, class _Proj = identity>
10296 requires indirectly_writable<_OutIter, indirect_result_t<_Func, projected<iterator_t<_Range>, _Proj>>>
103 _LIBCPP_HIDE_FROM_ABI constexpr
104 unary_transform_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __range,
105 _OutIter __result,
106 _Func __operation,
107 _Proj __projection = {}) const {
97 _LIBCPP_HIDE_FROM_ABI constexpr unary_transform_result<borrowed_iterator_t<_Range>, _OutIter>
98 operator()(_Range&& __range, _OutIter __result, _Func __operation, _Proj __projection = {}) const {
10899 return __unary(ranges::begin(__range), ranges::end(__range), std::move(__result), __operation, __projection);
109100 }
110101
111 template <input_iterator _InIter1, sentinel_for<_InIter1> _Sent1,
112 input_iterator _InIter2, sentinel_for<_InIter2> _Sent2,
102 template <input_iterator _InIter1,
103 sentinel_for<_InIter1> _Sent1,
104 input_iterator _InIter2,
105 sentinel_for<_InIter2> _Sent2,
113106 weakly_incrementable _OutIter,
114107 copy_constructible _Func,
115108 class _Proj1 = identity,
116109 class _Proj2 = identity>
117 requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter1, _Proj1>,
118 projected<_InIter2, _Proj2>>>
119 _LIBCPP_HIDE_FROM_ABI constexpr
120 binary_transform_result<_InIter1, _InIter2, _OutIter> operator()(_InIter1 __first1, _Sent1 __last1,
121 _InIter2 __first2, _Sent2 __last2,
122 _OutIter __result,
123 _Func __binary_operation,
124 _Proj1 __projection1 = {},
125 _Proj2 __projection2 = {}) const {
126 return __binary(std::move(__first1), std::move(__last1),
127 std::move(__first2), std::move(__last2),
128 std::move(__result),
129 __binary_operation,
130 __projection1,
131 __projection2);
110 requires indirectly_writable<_OutIter,
111 indirect_result_t<_Func&, projected<_InIter1, _Proj1>, projected<_InIter2, _Proj2>>>
112 _LIBCPP_HIDE_FROM_ABI constexpr binary_transform_result<_InIter1, _InIter2, _OutIter> operator()(
113 _InIter1 __first1,
114 _Sent1 __last1,
115 _InIter2 __first2,
116 _Sent2 __last2,
117 _OutIter __result,
118 _Func __binary_operation,
119 _Proj1 __projection1 = {},
120 _Proj2 __projection2 = {}) const {
121 return __binary(
122 std::move(__first1),
123 std::move(__last1),
124 std::move(__first2),
125 std::move(__last2),
126 std::move(__result),
127 __binary_operation,
128 __projection1,
129 __projection2);
132130 }
133131
134132 template <input_range _Range1,
......@@ -137,34 +135,38 @@ public:
137135 copy_constructible _Func,
138136 class _Proj1 = identity,
139137 class _Proj2 = identity>
140 requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<iterator_t<_Range1>, _Proj1>,
141 projected<iterator_t<_Range2>, _Proj2>>>
142 _LIBCPP_HIDE_FROM_ABI constexpr
143 binary_transform_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>, _OutIter>
138 requires indirectly_writable<
139 _OutIter,
140 indirect_result_t<_Func&, projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>>>
141 _LIBCPP_HIDE_FROM_ABI constexpr binary_transform_result<borrowed_iterator_t<_Range1>,
142 borrowed_iterator_t<_Range2>,
143 _OutIter>
144144 operator()(_Range1&& __range1,
145145 _Range2&& __range2,
146146 _OutIter __result,
147147 _Func __binary_operation,
148148 _Proj1 __projection1 = {},
149149 _Proj2 __projection2 = {}) const {
150 return __binary(ranges::begin(__range1), ranges::end(__range1),
151 ranges::begin(__range2), ranges::end(__range2),
152 std::move(__result),
153 __binary_operation,
154 __projection1,
155 __projection2);
150 return __binary(
151 ranges::begin(__range1),
152 ranges::end(__range1),
153 ranges::begin(__range2),
154 ranges::end(__range2),
155 std::move(__result),
156 __binary_operation,
157 __projection1,
158 __projection2);
156159 }
157
158160};
159161} // namespace __transform
160162
161163inline namespace __cpo {
162 inline constexpr auto transform = __transform::__fn{};
164inline constexpr auto transform = __transform::__fn{};
163165} // namespace __cpo
164166} // namespace ranges
165167
166168_LIBCPP_END_NAMESPACE_STD
167169
168#endif // _LIBCPP_STD_VER > 17
170#endif // _LIBCPP_STD_VER >= 20
169171
170172#endif // _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H
lib/libcxx/include/__algorithm/ranges_unique.h+25-27
......@@ -32,48 +32,46 @@
3232# pragma GCC system_header
3333#endif
3434
35#if _LIBCPP_STD_VER > 17
35#if _LIBCPP_STD_VER >= 20
3636
3737_LIBCPP_BEGIN_NAMESPACE_STD
3838
3939namespace ranges {
4040namespace __unique {
4141
42 struct __fn {
43 template <
44 permutable _Iter,
45 sentinel_for<_Iter> _Sent,
46 class _Proj = identity,
47 indirect_equivalence_relation<projected<_Iter, _Proj>> _Comp = ranges::equal_to>
48 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
49 operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
50 auto __ret = std::__unique<_RangeAlgPolicy>(
51 std::move(__first), std::move(__last), std::__make_projected(__comp, __proj));
52 return {std::move(__ret.first), std::move(__ret.second)};
53 }
42struct __fn {
43 template <permutable _Iter,
44 sentinel_for<_Iter> _Sent,
45 class _Proj = identity,
46 indirect_equivalence_relation<projected<_Iter, _Proj>> _Comp = ranges::equal_to>
47 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
48 operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
49 auto __ret =
50 std::__unique<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::__make_projected(__comp, __proj));
51 return {std::move(__ret.first), std::move(__ret.second)};
52 }
5453
55 template <
56 forward_range _Range,
57 class _Proj = identity,
58 indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
59 requires permutable<iterator_t<_Range>>
60 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
61 operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
62 auto __ret = std::__unique<_RangeAlgPolicy>(
63 ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj));
64 return {std::move(__ret.first), std::move(__ret.second)};
65 }
66 };
54 template <forward_range _Range,
55 class _Proj = identity,
56 indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
57 requires permutable<iterator_t<_Range>>
58 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
59 operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
60 auto __ret = std::__unique<_RangeAlgPolicy>(
61 ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj));
62 return {std::move(__ret.first), std::move(__ret.second)};
63 }
64};
6765
6866} // namespace __unique
6967
7068inline namespace __cpo {
71 inline constexpr auto unique = __unique::__fn{};
69inline constexpr auto unique = __unique::__fn{};
7270} // namespace __cpo
7371} // namespace ranges
7472
7573_LIBCPP_END_NAMESPACE_STD
7674
77#endif // _LIBCPP_STD_VER > 17
75#endif // _LIBCPP_STD_VER >= 20
7876
7977#endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_H
lib/libcxx/include/__algorithm/ranges_unique_copy.h+5-6
......@@ -21,7 +21,6 @@
2121#include <__iterator/concepts.h>
2222#include <__iterator/iterator_traits.h>
2323#include <__iterator/projected.h>
24#include <__iterator/readable_traits.h>
2524#include <__ranges/access.h>
2625#include <__ranges/concepts.h>
2726#include <__ranges/dangling.h>
......@@ -33,7 +32,7 @@
3332# pragma GCC system_header
3433#endif
3534
36#if _LIBCPP_STD_VER > 17
35#if _LIBCPP_STD_VER >= 20
3736
3837_LIBCPP_BEGIN_NAMESPACE_STD
3938
......@@ -87,9 +86,9 @@ struct __fn {
8786 class _Proj = identity,
8887 indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
8988 requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
90 (forward_iterator<iterator_t<_Range>> ||
91 (input_iterator<_OutIter> && same_as<range_value_t<_Range>, iter_value_t<_OutIter>>) ||
92 indirectly_copyable_storable<iterator_t<_Range>, _OutIter>)
89 (forward_iterator<iterator_t<_Range>> ||
90 (input_iterator<_OutIter> && same_as<range_value_t<_Range>, iter_value_t<_OutIter>>) ||
91 indirectly_copyable_storable<iterator_t<_Range>, _OutIter>)
9392 _LIBCPP_HIDE_FROM_ABI constexpr unique_copy_result<borrowed_iterator_t<_Range>, _OutIter>
9493 operator()(_Range&& __range, _OutIter __result, _Comp __comp = {}, _Proj __proj = {}) const {
9594 auto __ret = std::__unique_copy<_RangeAlgPolicy>(
......@@ -111,6 +110,6 @@ inline constexpr auto unique_copy = __unique_copy::__fn{};
111110
112111_LIBCPP_END_NAMESPACE_STD
113112
114#endif // _LIBCPP_STD_VER > 17
113#endif // _LIBCPP_STD_VER >= 20
115114
116115#endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H
lib/libcxx/include/__algorithm/ranges_upper_bound.h+17-18
......@@ -25,51 +25,50 @@
2525# pragma GCC system_header
2626#endif
2727
28#if _LIBCPP_STD_VER > 17
28#if _LIBCPP_STD_VER >= 20
2929
3030_LIBCPP_BEGIN_NAMESPACE_STD
3131
3232namespace ranges {
3333namespace __upper_bound {
3434struct __fn {
35 template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity,
35 template <forward_iterator _Iter,
36 sentinel_for<_Iter> _Sent,
37 class _Type,
38 class _Proj = identity,
3639 indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
37 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
38 _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
40 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter
41 operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
3942 auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) {
4043 return !std::invoke(__comp, __rhs, __lhs);
4144 };
4245
43 return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj);
46 return std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj);
4447 }
4548
46 template <forward_range _Range, class _Type, class _Proj = identity,
49 template <forward_range _Range,
50 class _Type,
51 class _Proj = identity,
4752 indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
48 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
49 borrowed_iterator_t<_Range> operator()(_Range&& __r,
50 const _Type& __value,
51 _Comp __comp = {},
52 _Proj __proj = {}) const {
53 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
54 operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
5355 auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) {
5456 return !std::invoke(__comp, __rhs, __lhs);
5557 };
5658
57 return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r),
58 ranges::end(__r),
59 __value,
60 __comp_lhs_rhs_swapped,
61 __proj);
59 return std::__lower_bound<_RangeAlgPolicy>(
60 ranges::begin(__r), ranges::end(__r), __value, __comp_lhs_rhs_swapped, __proj);
6261 }
6362};
6463} // namespace __upper_bound
6564
6665inline namespace __cpo {
67 inline constexpr auto upper_bound = __upper_bound::__fn{};
66inline constexpr auto upper_bound = __upper_bound::__fn{};
6867} // namespace __cpo
6968} // namespace ranges
7069
7170_LIBCPP_END_NAMESPACE_STD
7271
73#endif // _LIBCPP_STD_VER > 17
72#endif // _LIBCPP_STD_VER >= 20
7473
7574#endif // _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H
lib/libcxx/include/__algorithm/rotate.h+1-1
......@@ -15,9 +15,9 @@
1515#include <__algorithm/swap_ranges.h>
1616#include <__config>
1717#include <__iterator/iterator_traits.h>
18#include <__type_traits/is_trivially_move_assignable.h>
1819#include <__utility/move.h>
1920#include <__utility/pair.h>
20#include <type_traits>
2121
2222#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2323# pragma GCC system_header
lib/libcxx/include/__algorithm/sample.h+6-6
......@@ -16,8 +16,8 @@
1616#include <__iterator/distance.h>
1717#include <__iterator/iterator_traits.h>
1818#include <__random/uniform_int_distribution.h>
19#include <__type_traits/common_type.h>
1920#include <__utility/move.h>
20#include <type_traits>
2121
2222#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2323# pragma GCC system_header
......@@ -77,7 +77,7 @@ _LIBCPP_INLINE_VISIBILITY
7777_SampleIterator __sample(_PopulationIterator __first,
7878 _PopulationSentinel __last, _SampleIterator __output_iter,
7979 _Distance __n, _UniformRandomNumberGenerator& __g) {
80 _LIBCPP_ASSERT(__n >= 0, "N must be a positive number.");
80 _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0, "N must be a positive number.");
8181
8282 using _PopIterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_PopulationIterator>;
8383 using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>;
......@@ -88,22 +88,22 @@ _SampleIterator __sample(_PopulationIterator __first,
8888 __g, _PopIterCategory());
8989}
9090
91#if _LIBCPP_STD_VER > 14
91#if _LIBCPP_STD_VER >= 17
9292template <class _PopulationIterator, class _SampleIterator, class _Distance,
9393 class _UniformRandomNumberGenerator>
9494inline _LIBCPP_INLINE_VISIBILITY
9595_SampleIterator sample(_PopulationIterator __first,
9696 _PopulationIterator __last, _SampleIterator __output_iter,
9797 _Distance __n, _UniformRandomNumberGenerator&& __g) {
98 static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value ||
99 __is_cpp17_random_access_iterator<_SampleIterator>::value,
98 static_assert(__has_forward_iterator_category<_PopulationIterator>::value ||
99 __has_random_access_iterator_category<_SampleIterator>::value,
100100 "SampleIterator must meet the requirements of RandomAccessIterator");
101101
102102 return std::__sample<_ClassicAlgPolicy>(
103103 std::move(__first), std::move(__last), std::move(__output_iter), __n, __g);
104104}
105105
106#endif // _LIBCPP_STD_VER > 14
106#endif // _LIBCPP_STD_VER >= 17
107107
108108_LIBCPP_END_NAMESPACE_STD
109109
lib/libcxx/include/__algorithm/search.h+9-8
......@@ -14,12 +14,13 @@
1414#include <__algorithm/iterator_operations.h>
1515#include <__config>
1616#include <__functional/identity.h>
17#include <__functional/invoke.h>
1718#include <__iterator/advance.h>
1819#include <__iterator/concepts.h>
1920#include <__iterator/iterator_traits.h>
21#include <__type_traits/enable_if.h>
2022#include <__type_traits/is_callable.h>
2123#include <__utility/pair.h>
22#include <type_traits>
2324
2425#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2526# pragma GCC system_header
......@@ -126,8 +127,8 @@ pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1,
126127 _Pred& __pred,
127128 _Proj1& __proj1,
128129 _Proj2& __proj2,
129 __enable_if_t<__is_cpp17_random_access_iterator<_Iter1>::value
130 && __is_cpp17_random_access_iterator<_Iter2>::value>* = nullptr) {
130 __enable_if_t<__has_random_access_iterator_category<_Iter1>::value
131 && __has_random_access_iterator_category<_Iter2>::value>* = nullptr) {
131132
132133 auto __size2 = __last2 - __first2;
133134 if (__size2 == 0)
......@@ -158,10 +159,10 @@ pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1,
158159 _Pred& __pred,
159160 _Proj1& __proj1,
160161 _Proj2& __proj2,
161 __enable_if_t<__is_cpp17_forward_iterator<_Iter1>::value
162 && __is_cpp17_forward_iterator<_Iter2>::value
163 && !(__is_cpp17_random_access_iterator<_Iter1>::value
164 && __is_cpp17_random_access_iterator<_Iter2>::value)>* = nullptr) {
162 __enable_if_t<__has_forward_iterator_category<_Iter1>::value
163 && __has_forward_iterator_category<_Iter2>::value
164 && !(__has_random_access_iterator_category<_Iter1>::value
165 && __has_random_access_iterator_category<_Iter2>::value)>* = nullptr) {
165166 return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1,
166167 __first2, __last2,
167168 __pred,
......@@ -187,7 +188,7 @@ _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
187188 return std::search(__first1, __last1, __first2, __last2, __equal_to());
188189}
189190
190#if _LIBCPP_STD_VER > 14
191#if _LIBCPP_STD_VER >= 17
191192template <class _ForwardIterator, class _Searcher>
192193_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
193194search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher& __s) {
lib/libcxx/include/__algorithm/search_n.h+5-4
......@@ -14,14 +14,15 @@
1414#include <__algorithm/iterator_operations.h>
1515#include <__config>
1616#include <__functional/identity.h>
17#include <__functional/invoke.h>
1718#include <__iterator/advance.h>
1819#include <__iterator/concepts.h>
1920#include <__iterator/distance.h>
2021#include <__iterator/iterator_traits.h>
2122#include <__ranges/concepts.h>
23#include <__type_traits/is_callable.h>
2224#include <__utility/convert_to_integral.h>
2325#include <__utility/pair.h>
24#include <type_traits> // __convert_to_integral
2526
2627#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2728# pragma GCC system_header
......@@ -129,7 +130,7 @@ pair<_Iter, _Iter> __search_n_impl(_Iter __first, _Sent __last,
129130 const _Type& __value,
130131 _Pred& __pred,
131132 _Proj& __proj,
132 __enable_if_t<__is_cpp17_random_access_iterator<_Iter>::value>* = nullptr) {
133 __enable_if_t<__has_random_access_iterator_category<_Iter>::value>* = nullptr) {
133134 return std::__search_n_random_access_impl<_ClassicAlgPolicy>(__first, __last,
134135 __count,
135136 __value,
......@@ -149,8 +150,8 @@ pair<_Iter1, _Iter1> __search_n_impl(_Iter1 __first, _Sent1 __last,
149150 const _Type& __value,
150151 _Pred& __pred,
151152 _Proj& __proj,
152 __enable_if_t<__is_cpp17_forward_iterator<_Iter1>::value
153 && !__is_cpp17_random_access_iterator<_Iter1>::value>* = nullptr) {
153 __enable_if_t<__has_forward_iterator_category<_Iter1>::value
154 && !__has_random_access_iterator_category<_Iter1>::value>* = nullptr) {
154155 return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last,
155156 __count,
156157 __value,
lib/libcxx/include/__algorithm/set_difference.h+2-9
......@@ -17,9 +17,9 @@
1717#include <__functional/identity.h>
1818#include <__functional/invoke.h>
1919#include <__iterator/iterator_traits.h>
20#include <__type_traits/remove_cvref.h>
2021#include <__utility/move.h>
2122#include <__utility/pair.h>
22#include <type_traits>
2323
2424#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2525# pragma GCC system_header
......@@ -66,14 +66,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_d
6666 _InputIterator2 __first2,
6767 _InputIterator2 __last2,
6868 _OutputIterator __result) {
69 return std::__set_difference<_ClassicAlgPolicy>(
70 __first1,
71 __last1,
72 __first2,
73 __last2,
74 __result,
75 __less<typename iterator_traits<_InputIterator1>::value_type,
76 typename iterator_traits<_InputIterator2>::value_type>()).second;
69 return std::__set_difference<_ClassicAlgPolicy>(__first1, __last1, __first2, __last2, __result, __less<>()).second;
7770}
7871
7972_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/set_intersection.h+1-2
......@@ -89,8 +89,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_i
8989 std::move(__first2),
9090 std::move(__last2),
9191 std::move(__result),
92 __less<typename iterator_traits<_InputIterator1>::value_type,
93 typename iterator_traits<_InputIterator2>::value_type>())
92 __less<>())
9493 .__out_;
9594}
9695
lib/libcxx/include/__algorithm/set_symmetric_difference.h+1-2
......@@ -96,8 +96,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_symmetri
9696 std::move(__first2),
9797 std::move(__last2),
9898 std::move(__result),
99 __less<typename iterator_traits<_InputIterator1>::value_type,
100 typename iterator_traits<_InputIterator2>::value_type>());
99 __less<>());
101100}
102101
103102_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/set_union.h+1-2
......@@ -92,8 +92,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_union(
9292 std::move(__first2),
9393 std::move(__last2),
9494 std::move(__result),
95 __less<typename iterator_traits<_InputIterator1>::value_type,
96 typename iterator_traits<_InputIterator2>::value_type>());
95 __less<>());
9796}
9897
9998_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/shift_left.h+3-4
......@@ -12,7 +12,6 @@
1212#include <__algorithm/move.h>
1313#include <__config>
1414#include <__iterator/iterator_traits.h>
15#include <type_traits>
1615
1716#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1817# pragma GCC system_header
......@@ -20,7 +19,7 @@
2019
2120_LIBCPP_BEGIN_NAMESPACE_STD
2221
23#if _LIBCPP_STD_VER > 17
22#if _LIBCPP_STD_VER >= 20
2423
2524template <class _ForwardIterator>
2625inline _LIBCPP_INLINE_VISIBILITY constexpr
......@@ -33,7 +32,7 @@ shift_left(_ForwardIterator __first, _ForwardIterator __last,
3332 }
3433
3534 _ForwardIterator __m = __first;
36 if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) {
35 if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
3736 if (__n >= __last - __first) {
3837 return __first;
3938 }
......@@ -49,7 +48,7 @@ shift_left(_ForwardIterator __first, _ForwardIterator __last,
4948 return _VSTD::move(__m, __last, __first);
5049}
5150
52#endif // _LIBCPP_STD_VER > 17
51#endif // _LIBCPP_STD_VER >= 20
5352
5453_LIBCPP_END_NAMESPACE_STD
5554
lib/libcxx/include/__algorithm/shift_right.h+4-5
......@@ -15,7 +15,6 @@
1515#include <__config>
1616#include <__iterator/iterator_traits.h>
1717#include <__utility/swap.h>
18#include <type_traits>
1918
2019#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2120# pragma GCC system_header
......@@ -23,7 +22,7 @@
2322
2423_LIBCPP_BEGIN_NAMESPACE_STD
2524
26#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2726
2827template <class _ForwardIterator>
2928inline _LIBCPP_INLINE_VISIBILITY constexpr
......@@ -35,14 +34,14 @@ shift_right(_ForwardIterator __first, _ForwardIterator __last,
3534 return __first;
3635 }
3736
38 if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) {
37 if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
3938 decltype(__n) __d = __last - __first;
4039 if (__n >= __d) {
4140 return __last;
4241 }
4342 _ForwardIterator __m = __first + (__d - __n);
4443 return _VSTD::move_backward(__first, __m, __last);
45 } else if constexpr (__is_cpp17_bidirectional_iterator<_ForwardIterator>::value) {
44 } else if constexpr (__has_bidirectional_iterator_category<_ForwardIterator>::value) {
4645 _ForwardIterator __m = __last;
4746 for (; __n > 0; --__n) {
4847 if (__m == __first) {
......@@ -95,7 +94,7 @@ shift_right(_ForwardIterator __first, _ForwardIterator __last,
9594 }
9695}
9796
98#endif // _LIBCPP_STD_VER > 17
97#endif // _LIBCPP_STD_VER >= 20
9998
10099_LIBCPP_END_NAMESPACE_STD
101100
lib/libcxx/include/__algorithm/shuffle.h+9-10
......@@ -11,7 +11,6 @@
1111
1212#include <__algorithm/iterator_operations.h>
1313#include <__config>
14#include <__debug>
1514#include <__iterator/iterator_traits.h>
1615#include <__random/uniform_int_distribution.h>
1716#include <__utility/forward.h>
......@@ -29,9 +28,9 @@ _LIBCPP_PUSH_MACROS
2928
3029_LIBCPP_BEGIN_NAMESPACE_STD
3130
32class _LIBCPP_TYPE_VIS __libcpp_debug_randomizer {
31class _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_randomizer {
3332public:
34 __libcpp_debug_randomizer() {
33 _LIBCPP_HIDE_FROM_ABI __libcpp_debug_randomizer() {
3534 __state_ = __seed();
3635 __inc_ = __state_ + 0xda3e39cb94b95bdbULL;
3736 __inc_ = (__inc_ << 1) | 1;
......@@ -65,11 +64,11 @@ private:
6564
6665#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \
6766 || defined(_LIBCPP_BUILDING_LIBRARY)
68class _LIBCPP_TYPE_VIS __rs_default;
67class _LIBCPP_EXPORTED_FROM_ABI __rs_default;
6968
70_LIBCPP_FUNC_VIS __rs_default __rs_get();
69_LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get();
7170
72class _LIBCPP_TYPE_VIS __rs_default
71class _LIBCPP_EXPORTED_FROM_ABI __rs_default
7372{
7473 static unsigned __c_;
7574
......@@ -85,13 +84,13 @@ public:
8584
8685 result_type operator()();
8786
88 static _LIBCPP_CONSTEXPR result_type min() {return _Min;}
89 static _LIBCPP_CONSTEXPR result_type max() {return _Max;}
87 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() {return _Min;}
88 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() {return _Max;}
9089
91 friend _LIBCPP_FUNC_VIS __rs_default __rs_get();
90 friend _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get();
9291};
9392
94_LIBCPP_FUNC_VIS __rs_default __rs_get();
93_LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get();
9594
9695template <class _RandomAccessIterator>
9796_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void
lib/libcxx/include/__algorithm/sift_down.h+6-1
......@@ -19,6 +19,9 @@
1919# pragma GCC system_header
2020#endif
2121
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
2225_LIBCPP_BEGIN_NAMESPACE_STD
2326
2427template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
......@@ -83,7 +86,7 @@ __floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp,
8386 typename iterator_traits<_RandomAccessIterator>::difference_type __len)
8487{
8588 using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
86 _LIBCPP_ASSERT(__len >= 2, "shouldn't be called unless __len >= 2");
89 _LIBCPP_ASSERT_UNCATEGORIZED(__len >= 2, "shouldn't be called unless __len >= 2");
8790
8891 _RandomAccessIterator __hole = __first;
8992 _RandomAccessIterator __child_i = __first;
......@@ -111,4 +114,6 @@ __floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp,
111114
112115_LIBCPP_END_NAMESPACE_STD
113116
117_LIBCPP_POP_MACROS
118
114119#endif // _LIBCPP___ALGORITHM_SIFT_DOWN_H
lib/libcxx/include/__algorithm/sort.h+575-327
......@@ -11,23 +11,27 @@
1111
1212#include <__algorithm/comp.h>
1313#include <__algorithm/comp_ref_type.h>
14#include <__algorithm/iter_swap.h>
1415#include <__algorithm/iterator_operations.h>
1516#include <__algorithm/min_element.h>
1617#include <__algorithm/partial_sort.h>
1718#include <__algorithm/unwrap_iter.h>
19#include <__assert>
20#include <__bit/blsr.h>
21#include <__bit/countl.h>
22#include <__bit/countr.h>
1823#include <__config>
19#include <__debug>
2024#include <__debug_utils/randomize_range.h>
25#include <__debug_utils/strict_weak_ordering_check.h>
2126#include <__functional/operations.h>
2227#include <__functional/ranges_operations.h>
2328#include <__iterator/iterator_traits.h>
24#include <__memory/destruct_n.h>
25#include <__memory/unique_ptr.h>
29#include <__type_traits/conditional.h>
30#include <__type_traits/disjunction.h>
2631#include <__type_traits/is_arithmetic.h>
27#include <__type_traits/is_trivially_copy_assignable.h>
28#include <__type_traits/is_trivially_copy_constructible.h>
32#include <__type_traits/is_constant_evaluated.h>
2933#include <__utility/move.h>
30#include <bit>
34#include <__utility/pair.h>
3135#include <climits>
3236#include <cstdint>
3337
......@@ -37,52 +41,6 @@
3741
3842_LIBCPP_BEGIN_NAMESPACE_STD
3943
40// Wraps an algorithm policy tag and a comparator in a single struct, used to pass the policy tag around without
41// changing the number of template arguments (to keep the ABI stable). This is only used for the "range" policy tag.
42//
43// To create an object of this type, use `_WrapAlgPolicy<T, C>::type` -- see the specialization below for the rationale.
44template <class _PolicyT, class _CompT, class = void>
45struct _WrapAlgPolicy {
46 using type = _WrapAlgPolicy;
47
48 using _AlgPolicy = _PolicyT;
49 using _Comp = _CompT;
50 _Comp& __comp;
51
52 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
53 _WrapAlgPolicy(_Comp& __c) : __comp(__c) {}
54};
55
56// Specialization for the "classic" policy tag that avoids creating a struct and simply defines an alias for the
57// comparator. When unwrapping, a pristine comparator is always considered to have the "classic" tag attached. Passing
58// the pristine comparator where possible allows using template instantiations from the dylib.
59template <class _PolicyT, class _CompT>
60struct _WrapAlgPolicy<_PolicyT, _CompT, __enable_if_t<std::is_same<_PolicyT, _ClassicAlgPolicy>::value> > {
61 using type = _CompT;
62};
63
64// Unwraps a pristine functor (e.g. `std::less`) as if it were wrapped using `_WrapAlgPolicy`. The policy tag is always
65// set to "classic".
66template <class _CompT>
67struct _UnwrapAlgPolicy {
68 using _AlgPolicy = _ClassicAlgPolicy;
69 using _Comp = _CompT;
70
71 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static
72 _Comp __get_comp(_Comp __comp) { return __comp; }
73};
74
75// Unwraps a `_WrapAlgPolicy` struct.
76template <class... _Ts>
77struct _UnwrapAlgPolicy<_WrapAlgPolicy<_Ts...> > {
78 using _Wrapped = _WrapAlgPolicy<_Ts...>;
79 using _AlgPolicy = typename _Wrapped::_AlgPolicy;
80 using _Comp = typename _Wrapped::_Comp;
81
82 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static
83 _Comp __get_comp(_Wrapped& __w) { return __w.__comp; }
84};
85
8644// stable, 2-3 compares, 0-2 swaps
8745
8846template <class _AlgPolicy, class _Compare, class _ForwardIterator>
......@@ -126,78 +84,53 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 unsigned __sort3(_ForwardIterator __x, _ForwardIte
12684
12785template <class _AlgPolicy, class _Compare, class _ForwardIterator>
12886_LIBCPP_HIDE_FROM_ABI
129unsigned __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4,
87void __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4,
13088 _Compare __c) {
131 using _Ops = _IterOps<_AlgPolicy>;
132
133 unsigned __r = std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c);
89 using _Ops = _IterOps<_AlgPolicy>;
90 std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c);
13491 if (__c(*__x4, *__x3)) {
13592 _Ops::iter_swap(__x3, __x4);
136 ++__r;
13793 if (__c(*__x3, *__x2)) {
13894 _Ops::iter_swap(__x2, __x3);
139 ++__r;
14095 if (__c(*__x2, *__x1)) {
14196 _Ops::iter_swap(__x1, __x2);
142 ++__r;
14397 }
14498 }
14599 }
146 return __r;
147100}
148101
149102// stable, 4-10 compares, 0-9 swaps
150103
151template <class _WrappedComp, class _ForwardIterator>
152_LIBCPP_HIDDEN unsigned __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
153 _ForwardIterator __x4, _ForwardIterator __x5, _WrappedComp __wrapped_comp) {
154 using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>;
155 using _AlgPolicy = typename _Unwrap::_AlgPolicy;
104template <class _AlgPolicy, class _Comp, class _ForwardIterator>
105_LIBCPP_HIDE_FROM_ABI void __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
106 _ForwardIterator __x4, _ForwardIterator __x5, _Comp __comp) {
156107 using _Ops = _IterOps<_AlgPolicy>;
157108
158 using _Compare = typename _Unwrap::_Comp;
159 _Compare __c = _Unwrap::__get_comp(__wrapped_comp);
160
161 unsigned __r = std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c);
162 if (__c(*__x5, *__x4)) {
109 std::__sort4<_AlgPolicy, _Comp>(__x1, __x2, __x3, __x4, __comp);
110 if (__comp(*__x5, *__x4)) {
163111 _Ops::iter_swap(__x4, __x5);
164 ++__r;
165 if (__c(*__x4, *__x3)) {
112 if (__comp(*__x4, *__x3)) {
166113 _Ops::iter_swap(__x3, __x4);
167 ++__r;
168 if (__c(*__x3, *__x2)) {
114 if (__comp(*__x3, *__x2)) {
169115 _Ops::iter_swap(__x2, __x3);
170 ++__r;
171 if (__c(*__x2, *__x1)) {
116 if (__comp(*__x2, *__x1)) {
172117 _Ops::iter_swap(__x1, __x2);
173 ++__r;
174118 }
175119 }
176120 }
177121 }
178 return __r;
179}
180
181template <class _AlgPolicy, class _Compare, class _ForwardIterator>
182_LIBCPP_HIDE_FROM_ABI unsigned __sort5_wrap_policy(
183 _ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, _ForwardIterator __x5,
184 _Compare __c) {
185 using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Compare>::type;
186 _WrappedComp __wrapped_comp(__c);
187 return std::__sort5<_WrappedComp>(
188 std::move(__x1), std::move(__x2), std::move(__x3), std::move(__x4), std::move(__x5), __wrapped_comp);
189122}
190123
191124// The comparator being simple is a prerequisite for using the branchless optimization.
192125template <class _Tp>
193126struct __is_simple_comparator : false_type {};
194template <class _Tp>
195struct __is_simple_comparator<__less<_Tp>&> : true_type {};
127template <>
128struct __is_simple_comparator<__less<>&> : true_type {};
196129template <class _Tp>
197130struct __is_simple_comparator<less<_Tp>&> : true_type {};
198131template <class _Tp>
199132struct __is_simple_comparator<greater<_Tp>&> : true_type {};
200#if _LIBCPP_STD_VER > 17
133#if _LIBCPP_STD_VER >= 20
201134template <>
202135struct __is_simple_comparator<ranges::less&> : true_type {};
203136template <>
......@@ -206,9 +139,16 @@ struct __is_simple_comparator<ranges::greater&> : true_type {};
206139
207140template <class _Compare, class _Iter, class _Tp = typename iterator_traits<_Iter>::value_type>
208141using __use_branchless_sort =
209 integral_constant<bool, __is_cpp17_contiguous_iterator<_Iter>::value && sizeof(_Tp) <= sizeof(void*) &&
142 integral_constant<bool, __libcpp_is_contiguous_iterator<_Iter>::value && sizeof(_Tp) <= sizeof(void*) &&
210143 is_arithmetic<_Tp>::value && __is_simple_comparator<_Compare>::value>;
211144
145namespace __detail {
146
147// Size in bits for the bitset in use.
148enum { __block_size = sizeof(uint64_t) * 8 };
149
150} // namespace __detail
151
212152// Ensures that __c(*__x, *__y) is true by swapping *__x and *__y if necessary.
213153template <class _Compare, class _RandomAccessIterator>
214154inline _LIBCPP_HIDE_FROM_ABI void __cond_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _Compare __c) {
......@@ -268,10 +208,15 @@ __sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2,
268208 std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c);
269209}
270210
271template <class, class _Compare, class _RandomAccessIterator>
211template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
272212inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void>
273__sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3,
274 _RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) {
213__sort5_maybe_branchless(
214 _RandomAccessIterator __x1,
215 _RandomAccessIterator __x2,
216 _RandomAccessIterator __x3,
217 _RandomAccessIterator __x4,
218 _RandomAccessIterator __x5,
219 _Compare __c) {
275220 std::__cond_swap<_Compare>(__x1, __x2, __c);
276221 std::__cond_swap<_Compare>(__x4, __x5, __c);
277222 std::__partially_sorted_swap<_Compare>(__x3, __x4, __x5, __c);
......@@ -284,7 +229,8 @@ template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
284229inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void>
285230__sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3,
286231 _RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) {
287 std::__sort5_wrap_policy<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __x5, __c);
232 std::__sort5<_AlgPolicy, _Compare, _RandomAccessIterator>(
233 std::move(__x1), std::move(__x2), std::move(__x3), std::move(__x4), std::move(__x5), __c);
288234}
289235
290236// Assumes size > 0
......@@ -300,34 +246,49 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 void __selection_sort(_BidirectionalIterator __fir
300246 }
301247}
302248
249// Sort the iterator range [__first, __last) using the comparator __comp using
250// the insertion sort algorithm.
303251template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
304252_LIBCPP_HIDE_FROM_ABI
305253void __insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
306254 using _Ops = _IterOps<_AlgPolicy>;
307255
308256 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
309 if (__first != __last) {
310 _BidirectionalIterator __i = __first;
311 for (++__i; __i != __last; ++__i) {
312 _BidirectionalIterator __j = __i;
313 value_type __t(_Ops::__iter_move(__j));
314 for (_BidirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j)
257 if (__first == __last)
258 return;
259 _BidirectionalIterator __i = __first;
260 for (++__i; __i != __last; ++__i) {
261 _BidirectionalIterator __j = __i;
262 --__j;
263 if (__comp(*__i, *__j)) {
264 value_type __t(_Ops::__iter_move(__i));
265 _BidirectionalIterator __k = __j;
266 __j = __i;
267 do {
315268 *__j = _Ops::__iter_move(__k);
269 __j = __k;
270 } while (__j != __first && __comp(__t, *--__k));
316271 *__j = std::move(__t);
317272 }
318273 }
319274}
320275
276// Sort the iterator range [__first, __last) using the comparator __comp using
277// the insertion sort algorithm. Insertion sort has two loops, outer and inner.
278// The implementation below has no bounds check (unguarded) for the inner loop.
279// Assumes that there is an element in the position (__first - 1) and that each
280// element in the input range is greater or equal to the element at __first - 1.
321281template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
322_LIBCPP_HIDE_FROM_ABI
323void __insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
282_LIBCPP_HIDE_FROM_ABI void
283__insertion_sort_unguarded(_RandomAccessIterator const __first, _RandomAccessIterator __last, _Compare __comp) {
324284 using _Ops = _IterOps<_AlgPolicy>;
325
326285 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
327286 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
328 _RandomAccessIterator __j = __first + difference_type(2);
329 std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), __j, __comp);
330 for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) {
287 if (__first == __last)
288 return;
289 const _RandomAccessIterator __leftmost = __first - difference_type(1); (void)__leftmost; // can be unused when assertions are disabled
290 for (_RandomAccessIterator __i = __first + difference_type(1); __i != __last; ++__i) {
291 _RandomAccessIterator __j = __i - difference_type(1);
331292 if (__comp(*__i, *__j)) {
332293 value_type __t(_Ops::__iter_move(__i));
333294 _RandomAccessIterator __k = __j;
......@@ -335,23 +296,20 @@ void __insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __l
335296 do {
336297 *__j = _Ops::__iter_move(__k);
337298 __j = __k;
338 } while (__j != __first && __comp(__t, *--__k));
299 _LIBCPP_ASSERT_UNCATEGORIZED(
300 __k != __leftmost,
301 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
302 } while (__comp(__t, *--__k)); // No need for bounds check due to the assumption stated above.
339303 *__j = std::move(__t);
340304 }
341 __j = __i;
342305 }
343306}
344307
345template <class _WrappedComp, class _RandomAccessIterator>
346_LIBCPP_HIDDEN bool __insertion_sort_incomplete(
347 _RandomAccessIterator __first, _RandomAccessIterator __last, _WrappedComp __wrapped_comp) {
348 using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>;
349 using _AlgPolicy = typename _Unwrap::_AlgPolicy;
308template <class _AlgPolicy, class _Comp, class _RandomAccessIterator>
309_LIBCPP_HIDE_FROM_ABI bool __insertion_sort_incomplete(
310 _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
350311 using _Ops = _IterOps<_AlgPolicy>;
351312
352 using _Compare = typename _Unwrap::_Comp;
353 _Compare __comp = _Unwrap::__get_comp(__wrapped_comp);
354
355313 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
356314 switch (__last - __first) {
357315 case 0:
......@@ -359,24 +317,24 @@ _LIBCPP_HIDDEN bool __insertion_sort_incomplete(
359317 return true;
360318 case 2:
361319 if (__comp(*--__last, *__first))
362 _IterOps<_AlgPolicy>::iter_swap(__first, __last);
320 _Ops::iter_swap(__first, __last);
363321 return true;
364322 case 3:
365 std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp);
323 std::__sort3_maybe_branchless<_AlgPolicy, _Comp>(__first, __first + difference_type(1), --__last, __comp);
366324 return true;
367325 case 4:
368 std::__sort4_maybe_branchless<_AlgPolicy, _Compare>(
326 std::__sort4_maybe_branchless<_AlgPolicy, _Comp>(
369327 __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp);
370328 return true;
371329 case 5:
372 std::__sort5_maybe_branchless<_AlgPolicy, _Compare>(
330 std::__sort5_maybe_branchless<_AlgPolicy, _Comp>(
373331 __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3),
374332 --__last, __comp);
375333 return true;
376334 }
377335 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
378336 _RandomAccessIterator __j = __first + difference_type(2);
379 std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), __j, __comp);
337 std::__sort3_maybe_branchless<_AlgPolicy, _Comp>(__first, __first + difference_type(1), __j, __comp);
380338 const unsigned __limit = 8;
381339 unsigned __count = 0;
382340 for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) {
......@@ -397,48 +355,380 @@ _LIBCPP_HIDDEN bool __insertion_sort_incomplete(
397355 return true;
398356}
399357
400template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
401_LIBCPP_HIDE_FROM_ABI
402void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1,
403 typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) {
358template <class _AlgPolicy, class _RandomAccessIterator>
359inline _LIBCPP_HIDE_FROM_ABI void __swap_bitmap_pos(
360 _RandomAccessIterator __first, _RandomAccessIterator __last, uint64_t& __left_bitset, uint64_t& __right_bitset) {
404361 using _Ops = _IterOps<_AlgPolicy>;
362 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
363 // Swap one pair on each iteration as long as both bitsets have at least one
364 // element for swapping.
365 while (__left_bitset != 0 && __right_bitset != 0) {
366 difference_type __tz_left = __libcpp_ctz(__left_bitset);
367 __left_bitset = __libcpp_blsr(__left_bitset);
368 difference_type __tz_right = __libcpp_ctz(__right_bitset);
369 __right_bitset = __libcpp_blsr(__right_bitset);
370 _Ops::iter_swap(__first + __tz_left, __last - __tz_right);
371 }
372}
405373
406 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
407 if (__first1 != __last1) {
408 __destruct_n __d(0);
409 unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
410 value_type* __last2 = __first2;
411 ::new ((void*)__last2) value_type(_Ops::__iter_move(__first1));
412 __d.template __incr<value_type>();
413 for (++__last2; ++__first1 != __last1; ++__last2) {
414 value_type* __j2 = __last2;
415 value_type* __i2 = __j2;
416 if (__comp(*__first1, *--__i2)) {
417 ::new ((void*)__j2) value_type(std::move(*__i2));
418 __d.template __incr<value_type>();
419 for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2)
420 *__j2 = std::move(*__i2);
421 *__j2 = _Ops::__iter_move(__first1);
422 } else {
423 ::new ((void*)__j2) value_type(_Ops::__iter_move(__first1));
424 __d.template __incr<value_type>();
374template <class _Compare,
375 class _RandomAccessIterator,
376 class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type>
377inline _LIBCPP_HIDE_FROM_ABI void
378__populate_left_bitset(_RandomAccessIterator __first, _Compare __comp, _ValueType& __pivot, uint64_t& __left_bitset) {
379 // Possible vectorization. With a proper "-march" flag, the following loop
380 // will be compiled into a set of SIMD instructions.
381 _RandomAccessIterator __iter = __first;
382 for (int __j = 0; __j < __detail::__block_size;) {
383 bool __comp_result = !__comp(*__iter, __pivot);
384 __left_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
385 __j++;
386 ++__iter;
387 }
388}
389
390template <class _Compare,
391 class _RandomAccessIterator,
392 class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type>
393inline _LIBCPP_HIDE_FROM_ABI void
394__populate_right_bitset(_RandomAccessIterator __lm1, _Compare __comp, _ValueType& __pivot, uint64_t& __right_bitset) {
395 // Possible vectorization. With a proper "-march" flag, the following loop
396 // will be compiled into a set of SIMD instructions.
397 _RandomAccessIterator __iter = __lm1;
398 for (int __j = 0; __j < __detail::__block_size;) {
399 bool __comp_result = __comp(*__iter, __pivot);
400 __right_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
401 __j++;
402 --__iter;
403 }
404}
405
406template <class _AlgPolicy,
407 class _Compare,
408 class _RandomAccessIterator,
409 class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type>
410inline _LIBCPP_HIDE_FROM_ABI void __bitset_partition_partial_blocks(
411 _RandomAccessIterator& __first,
412 _RandomAccessIterator& __lm1,
413 _Compare __comp,
414 _ValueType& __pivot,
415 uint64_t& __left_bitset,
416 uint64_t& __right_bitset) {
417 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
418 difference_type __remaining_len = __lm1 - __first + 1;
419 difference_type __l_size;
420 difference_type __r_size;
421 if (__left_bitset == 0 && __right_bitset == 0) {
422 __l_size = __remaining_len / 2;
423 __r_size = __remaining_len - __l_size;
424 } else if (__left_bitset == 0) {
425 // We know at least one side is a full block.
426 __l_size = __remaining_len - __detail::__block_size;
427 __r_size = __detail::__block_size;
428 } else { // if (__right_bitset == 0)
429 __l_size = __detail::__block_size;
430 __r_size = __remaining_len - __detail::__block_size;
431 }
432 // Record the comparison outcomes for the elements currently on the left side.
433 if (__left_bitset == 0) {
434 _RandomAccessIterator __iter = __first;
435 for (int __j = 0; __j < __l_size; __j++) {
436 bool __comp_result = !__comp(*__iter, __pivot);
437 __left_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
438 ++__iter;
439 }
440 }
441 // Record the comparison outcomes for the elements currently on the right
442 // side.
443 if (__right_bitset == 0) {
444 _RandomAccessIterator __iter = __lm1;
445 for (int __j = 0; __j < __r_size; __j++) {
446 bool __comp_result = __comp(*__iter, __pivot);
447 __right_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
448 --__iter;
449 }
450 }
451 std::__swap_bitmap_pos<_AlgPolicy, _RandomAccessIterator>(__first, __lm1, __left_bitset, __right_bitset);
452 __first += (__left_bitset == 0) ? __l_size : 0;
453 __lm1 -= (__right_bitset == 0) ? __r_size : 0;
454}
455
456template <class _AlgPolicy, class _RandomAccessIterator>
457inline _LIBCPP_HIDE_FROM_ABI void __swap_bitmap_pos_within(
458 _RandomAccessIterator& __first, _RandomAccessIterator& __lm1, uint64_t& __left_bitset, uint64_t& __right_bitset) {
459 using _Ops = _IterOps<_AlgPolicy>;
460 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
461 if (__left_bitset) {
462 // Swap within the left side. Need to find set positions in the reverse
463 // order.
464 while (__left_bitset != 0) {
465 difference_type __tz_left = __detail::__block_size - 1 - __libcpp_clz(__left_bitset);
466 __left_bitset &= (static_cast<uint64_t>(1) << __tz_left) - 1;
467 _RandomAccessIterator __it = __first + __tz_left;
468 if (__it != __lm1) {
469 _Ops::iter_swap(__it, __lm1);
425470 }
471 --__lm1;
472 }
473 __first = __lm1 + difference_type(1);
474 } else if (__right_bitset) {
475 // Swap within the right side. Need to find set positions in the reverse
476 // order.
477 while (__right_bitset != 0) {
478 difference_type __tz_right = __detail::__block_size - 1 - __libcpp_clz(__right_bitset);
479 __right_bitset &= (static_cast<uint64_t>(1) << __tz_right) - 1;
480 _RandomAccessIterator __it = __lm1 - __tz_right;
481 if (__it != __first) {
482 _Ops::iter_swap(__it, __first);
483 }
484 ++__first;
426485 }
427 __h.release();
428486 }
429487}
430488
431template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
432void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
433 typename iterator_traits<_RandomAccessIterator>::difference_type __depth) {
489// Partition [__first, __last) using the comparator __comp. *__first has the
490// chosen pivot. Elements that are equivalent are kept to the left of the
491// pivot. Returns the iterator for the pivot and a bool value which is true if
492// the provided range is already sorted, false otherwise. We assume that the
493// length of the range is at least three elements.
494//
495// __bitset_partition uses bitsets for storing outcomes of the comparisons
496// between the pivot and other elements.
497template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
498_LIBCPP_HIDE_FROM_ABI std::pair<_RandomAccessIterator, bool>
499__bitset_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
434500 using _Ops = _IterOps<_AlgPolicy>;
501 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
502 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
503 _LIBCPP_ASSERT_UNCATEGORIZED(__last - __first >= difference_type(3), "");
504 const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around
505 const _RandomAccessIterator __end = __last; (void)__end; //
506
507 value_type __pivot(_Ops::__iter_move(__first));
508 // Find the first element greater than the pivot.
509 if (__comp(__pivot, *(__last - difference_type(1)))) {
510 // Not guarded since we know the last element is greater than the pivot.
511 do {
512 ++__first;
513 _LIBCPP_ASSERT_UNCATEGORIZED(
514 __first != __end,
515 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
516 } while (!__comp(__pivot, *__first));
517 } else {
518 while (++__first < __last && !__comp(__pivot, *__first)) {
519 }
520 }
521 // Find the last element less than or equal to the pivot.
522 if (__first < __last) {
523 // It will be always guarded because __introsort will do the median-of-three
524 // before calling this.
525 do {
526 _LIBCPP_ASSERT_UNCATEGORIZED(
527 __last != __begin,
528 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
529 --__last;
530 } while (__comp(__pivot, *__last));
531 }
532 // If the first element greater than the pivot is at or after the
533 // last element less than or equal to the pivot, then we have covered the
534 // entire range without swapping elements. This implies the range is already
535 // partitioned.
536 bool __already_partitioned = __first >= __last;
537 if (!__already_partitioned) {
538 _Ops::iter_swap(__first, __last);
539 ++__first;
540 }
435541
542 // In [__first, __last) __last is not inclusive. From now on, it uses last
543 // minus one to be inclusive on both sides.
544 _RandomAccessIterator __lm1 = __last - difference_type(1);
545 uint64_t __left_bitset = 0;
546 uint64_t __right_bitset = 0;
547
548 // Reminder: length = __lm1 - __first + 1.
549 while (__lm1 - __first >= 2 * __detail::__block_size - 1) {
550 // Record the comparison outcomes for the elements currently on the left
551 // side.
552 if (__left_bitset == 0)
553 std::__populate_left_bitset<_Compare>(__first, __comp, __pivot, __left_bitset);
554 // Record the comparison outcomes for the elements currently on the right
555 // side.
556 if (__right_bitset == 0)
557 std::__populate_right_bitset<_Compare>(__lm1, __comp, __pivot, __right_bitset);
558 // Swap the elements recorded to be the candidates for swapping in the
559 // bitsets.
560 std::__swap_bitmap_pos<_AlgPolicy, _RandomAccessIterator>(__first, __lm1, __left_bitset, __right_bitset);
561 // Only advance the iterator if all the elements that need to be moved to
562 // other side were moved.
563 __first += (__left_bitset == 0) ? difference_type(__detail::__block_size) : difference_type(0);
564 __lm1 -= (__right_bitset == 0) ? difference_type(__detail::__block_size) : difference_type(0);
565 }
566 // Now, we have a less-than a block worth of elements on at least one of the
567 // sides.
568 std::__bitset_partition_partial_blocks<_AlgPolicy, _Compare>(
569 __first, __lm1, __comp, __pivot, __left_bitset, __right_bitset);
570 // At least one the bitsets would be empty. For the non-empty one, we need to
571 // properly partition the elements that appear within that bitset.
572 std::__swap_bitmap_pos_within<_AlgPolicy>(__first, __lm1, __left_bitset, __right_bitset);
573
574 // Move the pivot to its correct position.
575 _RandomAccessIterator __pivot_pos = __first - difference_type(1);
576 if (__begin != __pivot_pos) {
577 *__begin = _Ops::__iter_move(__pivot_pos);
578 }
579 *__pivot_pos = std::move(__pivot);
580 return std::make_pair(__pivot_pos, __already_partitioned);
581}
582
583// Partition [__first, __last) using the comparator __comp. *__first has the
584// chosen pivot. Elements that are equivalent are kept to the right of the
585// pivot. Returns the iterator for the pivot and a bool value which is true if
586// the provided range is already sorted, false otherwise. We assume that the
587// length of the range is at least three elements.
588template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
589_LIBCPP_HIDE_FROM_ABI std::pair<_RandomAccessIterator, bool>
590__partition_with_equals_on_right(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
591 using _Ops = _IterOps<_AlgPolicy>;
436592 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
437 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
438 const difference_type __limit =
439 is_trivially_copy_constructible<value_type>::value && is_trivially_copy_assignable<value_type>::value ? 30 : 6;
593 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
594 _LIBCPP_ASSERT_UNCATEGORIZED(__last - __first >= difference_type(3), "");
595 const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around
596 const _RandomAccessIterator __end = __last; (void)__end; //
597 value_type __pivot(_Ops::__iter_move(__first));
598 // Find the first element greater or equal to the pivot. It will be always
599 // guarded because __introsort will do the median-of-three before calling
600 // this.
601 do {
602 ++__first;
603 _LIBCPP_ASSERT_UNCATEGORIZED(
604 __first != __end,
605 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
606 } while (__comp(*__first, __pivot));
607
608 // Find the last element less than the pivot.
609 if (__begin == __first - difference_type(1)) {
610 while (__first < __last && !__comp(*--__last, __pivot))
611 ;
612 } else {
613 // Guarded.
614 do {
615 _LIBCPP_ASSERT_UNCATEGORIZED(
616 __last != __begin,
617 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
618 --__last;
619 } while (!__comp(*__last, __pivot));
620 }
621
622 // If the first element greater than or equal to the pivot is at or after the
623 // last element less than the pivot, then we have covered the entire range
624 // without swapping elements. This implies the range is already partitioned.
625 bool __already_partitioned = __first >= __last;
626 // Go through the remaining elements. Swap pairs of elements (one to the
627 // right of the pivot and the other to left of the pivot) that are not on the
628 // correct side of the pivot.
629 while (__first < __last) {
630 _Ops::iter_swap(__first, __last);
631 do {
632 ++__first;
633 _LIBCPP_ASSERT_UNCATEGORIZED(
634 __first != __end,
635 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
636 } while (__comp(*__first, __pivot));
637 do {
638 _LIBCPP_ASSERT_UNCATEGORIZED(
639 __last != __begin,
640 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
641 --__last;
642 } while (!__comp(*__last, __pivot));
643 }
644 // Move the pivot to its correct position.
645 _RandomAccessIterator __pivot_pos = __first - difference_type(1);
646 if (__begin != __pivot_pos) {
647 *__begin = _Ops::__iter_move(__pivot_pos);
648 }
649 *__pivot_pos = std::move(__pivot);
650 return std::make_pair(__pivot_pos, __already_partitioned);
651}
652
653// Similar to the above function. Elements equivalent to the pivot are put to
654// the left of the pivot. Returns the iterator to the pivot element.
655template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
656_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator
657__partition_with_equals_on_left(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
658 using _Ops = _IterOps<_AlgPolicy>;
659 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
660 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
661 // TODO(LLVM18): Make __begin const, see https://reviews.llvm.org/D147089#4349748
662 _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around
663 const _RandomAccessIterator __end = __last; (void)__end; //
664 value_type __pivot(_Ops::__iter_move(__first));
665 if (__comp(__pivot, *(__last - difference_type(1)))) {
666 // Guarded.
667 do {
668 ++__first;
669 _LIBCPP_ASSERT_UNCATEGORIZED(
670 __first != __end,
671 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
672 } while (!__comp(__pivot, *__first));
673 } else {
674 while (++__first < __last && !__comp(__pivot, *__first)) {
675 }
676 }
677
678 if (__first < __last) {
679 // It will be always guarded because __introsort will do the
680 // median-of-three before calling this.
681 do {
682 _LIBCPP_ASSERT_UNCATEGORIZED(
683 __last != __begin,
684 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
685 --__last;
686 } while (__comp(__pivot, *__last));
687 }
688 while (__first < __last) {
689 _Ops::iter_swap(__first, __last);
690 do {
691 ++__first;
692 _LIBCPP_ASSERT_UNCATEGORIZED(
693 __first != __end,
694 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
695 } while (!__comp(__pivot, *__first));
696 do {
697 _LIBCPP_ASSERT_UNCATEGORIZED(
698 __last != __begin,
699 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
700 --__last;
701 } while (__comp(__pivot, *__last));
702 }
703 _RandomAccessIterator __pivot_pos = __first - difference_type(1);
704 if (__begin != __pivot_pos) {
705 *__begin = _Ops::__iter_move(__pivot_pos);
706 }
707 *__pivot_pos = std::move(__pivot);
708 return __first;
709}
710
711// The main sorting function. Implements introsort combined with other ideas:
712// - option of using block quick sort for partitioning,
713// - guarded and unguarded insertion sort for small lengths,
714// - Tuckey's ninther technique for computing the pivot,
715// - check on whether partition was not required.
716// The implementation is partly based on Orson Peters' pattern-defeating
717// quicksort, published at: <https://github.com/orlp/pdqsort>.
718template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, bool _UseBitSetPartition>
719void __introsort(_RandomAccessIterator __first,
720 _RandomAccessIterator __last,
721 _Compare __comp,
722 typename iterator_traits<_RandomAccessIterator>::difference_type __depth,
723 bool __leftmost = true) {
724 using _Ops = _IterOps<_AlgPolicy>;
725 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
726 using _Comp_ref = __comp_ref_type<_Compare>;
727 // Upper bound for using insertion sort for sorting.
728 _LIBCPP_CONSTEXPR difference_type __limit = 24;
729 // Lower bound for using Tuckey's ninther technique for median computation.
730 _LIBCPP_CONSTEXPR difference_type __ninther_threshold = 128;
440731 while (true) {
441 __restart:
442732 difference_type __len = __last - __first;
443733 switch (__len) {
444734 case 0:
......@@ -446,7 +736,7 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C
446736 return;
447737 case 2:
448738 if (__comp(*--__last, *__first))
449 _IterOps<_AlgPolicy>::iter_swap(__first, __last);
739 _Ops::iter_swap(__first, __last);
450740 return;
451741 case 3:
452742 std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp);
......@@ -461,131 +751,62 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C
461751 --__last, __comp);
462752 return;
463753 }
464 if (__len <= __limit) {
465 std::__insertion_sort_3<_AlgPolicy, _Compare>(__first, __last, __comp);
754 // Use insertion sort if the length of the range is below the specified limit.
755 if (__len < __limit) {
756 if (__leftmost) {
757 std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp);
758 } else {
759 std::__insertion_sort_unguarded<_AlgPolicy, _Compare>(__first, __last, __comp);
760 }
466761 return;
467762 }
468 // __len > 5
469763 if (__depth == 0) {
470764 // Fallback to heap sort as Introsort suggests.
471765 std::__partial_sort<_AlgPolicy, _Compare>(__first, __last, __last, __comp);
472766 return;
473767 }
474768 --__depth;
475 _RandomAccessIterator __m = __first;
476 _RandomAccessIterator __lm1 = __last;
477 --__lm1;
478 unsigned __n_swaps;
479769 {
480 difference_type __delta;
481 if (__len >= 1000) {
482 __delta = __len / 2;
483 __m += __delta;
484 __delta /= 2;
485 __n_swaps = std::__sort5_wrap_policy<_AlgPolicy, _Compare>(
486 __first, __first + __delta, __m, __m + __delta, __lm1, __comp);
770 difference_type __half_len = __len / 2;
771 // Use Tuckey's ninther technique or median of 3 for pivot selection
772 // depending on the length of the range being sorted.
773 if (__len > __ninther_threshold) {
774 std::__sort3<_AlgPolicy, _Compare>(__first, __first + __half_len, __last - difference_type(1), __comp);
775 std::__sort3<_AlgPolicy, _Compare>(
776 __first + difference_type(1), __first + (__half_len - 1), __last - difference_type(2), __comp);
777 std::__sort3<_AlgPolicy, _Compare>(
778 __first + difference_type(2), __first + (__half_len + 1), __last - difference_type(3), __comp);
779 std::__sort3<_AlgPolicy, _Compare>(
780 __first + (__half_len - 1), __first + __half_len, __first + (__half_len + 1), __comp);
781 _Ops::iter_swap(__first, __first + __half_len);
487782 } else {
488 __delta = __len / 2;
489 __m += __delta;
490 __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, __lm1, __comp);
491 }
492 }
493 // *__m is median
494 // partition [__first, __m) < *__m and *__m <= [__m, __last)
495 // (this inhibits tossing elements equivalent to __m around unnecessarily)
496 _RandomAccessIterator __i = __first;
497 _RandomAccessIterator __j = __lm1;
498 // j points beyond range to be tested, *__m is known to be <= *__lm1
499 // The search going up is known to be guarded but the search coming down isn't.
500 // Prime the downward search with a guard.
501 if (!__comp(*__i, *__m)) // if *__first == *__m
502 {
503 // *__first == *__m, *__first doesn't go in first part
504 // manually guard downward moving __j against __i
505 while (true) {
506 if (__i == --__j) {
507 // *__first == *__m, *__m <= all other elements
508 // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)
509 ++__i; // __first + 1
510 __j = __last;
511 if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1)
512 {
513 while (true) {
514 if (__i == __j)
515 return; // [__first, __last) all equivalent elements
516 if (__comp(*__first, *__i)) {
517 _Ops::iter_swap(__i, __j);
518 ++__n_swaps;
519 ++__i;
520 break;
521 }
522 ++__i;
523 }
524 }
525 // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
526 if (__i == __j)
527 return;
528 while (true) {
529 while (!__comp(*__first, *__i))
530 ++__i;
531 while (__comp(*__first, *--__j))
532 ;
533 if (__i >= __j)
534 break;
535 _Ops::iter_swap(__i, __j);
536 ++__n_swaps;
537 ++__i;
538 }
539 // [__first, __i) == *__first and *__first < [__i, __last)
540 // The first part is sorted, sort the second part
541 // std::__sort<_Compare>(__i, __last, __comp);
542 __first = __i;
543 goto __restart;
544 }
545 if (__comp(*__j, *__m)) {
546 _Ops::iter_swap(__i, __j);
547 ++__n_swaps;
548 break; // found guard for downward moving __j, now use unguarded partition
549 }
550 }
551 }
552 // It is known that *__i < *__m
553 ++__i;
554 // j points beyond range to be tested, *__m is known to be <= *__lm1
555 // if not yet partitioned...
556 if (__i < __j) {
557 // known that *(__i - 1) < *__m
558 // known that __i <= __m
559 while (true) {
560 // __m still guards upward moving __i
561 while (__comp(*__i, *__m))
562 ++__i;
563 // It is now known that a guard exists for downward moving __j
564 while (!__comp(*--__j, *__m))
565 ;
566 if (__i > __j)
567 break;
568 _Ops::iter_swap(__i, __j);
569 ++__n_swaps;
570 // It is known that __m != __j
571 // If __m just moved, follow it
572 if (__m == __i)
573 __m = __j;
574 ++__i;
783 std::__sort3<_AlgPolicy, _Compare>(__first + __half_len, __first, __last - difference_type(1), __comp);
575784 }
576785 }
577 // [__first, __i) < *__m and *__m <= [__i, __last)
578 if (__i != __m && __comp(*__m, *__i)) {
579 _Ops::iter_swap(__i, __m);
580 ++__n_swaps;
786 // The elements to the left of the current iterator range are already
787 // sorted. If the current iterator range to be sorted is not the
788 // leftmost part of the entire iterator range and the pivot is same as
789 // the highest element in the range to the left, then we know that all
790 // the elements in the range [first, pivot] would be equal to the pivot,
791 // assuming the equal elements are put on the left side when
792 // partitioned. This also means that we do not need to sort the left
793 // side of the partition.
794 if (!__leftmost && !__comp(*(__first - difference_type(1)), *__first)) {
795 __first = std::__partition_with_equals_on_left<_AlgPolicy, _RandomAccessIterator, _Comp_ref>(
796 __first, __last, _Comp_ref(__comp));
797 continue;
581798 }
799 // Use bitset partition only if asked for.
800 auto __ret =
801 _UseBitSetPartition
802 ? std::__bitset_partition<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp)
803 : std::__partition_with_equals_on_right<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp);
804 _RandomAccessIterator __i = __ret.first;
582805 // [__first, __i) < *__i and *__i <= [__i+1, __last)
583806 // If we were given a perfect partition, see if insertion sort is quick...
584 if (__n_swaps == 0) {
585 using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Compare>::type;
586 _WrappedComp __wrapped_comp(__comp);
587 bool __fs = std::__insertion_sort_incomplete<_WrappedComp>(__first, __i, __wrapped_comp);
588 if (std::__insertion_sort_incomplete<_WrappedComp>(__i + difference_type(1), __last, __wrapped_comp)) {
807 if (__ret.second) {
808 bool __fs = std::__insertion_sort_incomplete<_AlgPolicy, _Compare>(__first, __i, __comp);
809 if (std::__insertion_sort_incomplete<_AlgPolicy, _Compare>(__i + difference_type(1), __last, __comp)) {
589810 if (__fs)
590811 return;
591812 __last = __i;
......@@ -597,14 +818,11 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C
597818 }
598819 }
599820 }
600 // sort smaller range with recursive call and larger with tail recursion elimination
601 if (__i - __first < __last - __i) {
602 std::__introsort<_AlgPolicy, _Compare>(__first, __i, __comp, __depth);
603 __first = ++__i;
604 } else {
605 std::__introsort<_AlgPolicy, _Compare>(__i + difference_type(1), __last, __comp, __depth);
606 __last = __i;
607 }
821 // Sort the left partiton recursively and the right partition with tail recursion elimination.
822 std::__introsort<_AlgPolicy, _Compare, _RandomAccessIterator, _UseBitSetPartition>(
823 __first, __i, __comp, __depth, __leftmost);
824 __leftmost = false;
825 __first = ++__i;
608826 }
609827}
610828
......@@ -627,77 +845,107 @@ inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) {
627845 return __log2;
628846}
629847
630template <class _WrappedComp, class _RandomAccessIterator>
631_LIBCPP_HIDDEN void __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _WrappedComp __wrapped_comp) {
848template <class _Comp, class _RandomAccessIterator>
849void __sort(_RandomAccessIterator, _RandomAccessIterator, _Comp);
850
851extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<char>&, char*>(char*, char*, __less<char>&);
852#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
853extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
854#endif
855extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
856extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
857extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<short>&, short*>(short*, short*, __less<short>&);
858extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
859extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<int>&, int*>(int*, int*, __less<int>&);
860extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);
861extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long>&, long*>(long*, long*, __less<long>&);
862extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
863extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
864extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&);
865extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<float>&, float*>(float*, float*, __less<float>&);
866extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<double>&, double*>(double*, double*, __less<double>&);
867extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
868
869template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
870_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
871__sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
632872 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
633873 difference_type __depth_limit = 2 * std::__log2i(__last - __first);
634874
635 using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>;
636 using _AlgPolicy = typename _Unwrap::_AlgPolicy;
637 using _Compare = typename _Unwrap::_Comp;
638 _Compare __comp = _Unwrap::__get_comp(__wrapped_comp);
639 std::__introsort<_AlgPolicy, _Compare>(__first, __last, __comp, __depth_limit);
875 // Only use bitset partitioning for arithmetic types. We should also check
876 // that the default comparator is in use so that we are sure that there are no
877 // branches in the comparator.
878 std::__introsort<_AlgPolicy,
879 _Comp&,
880 _RandomAccessIterator,
881 __use_branchless_sort<_Comp, _RandomAccessIterator>::value>(
882 __first, __last, __comp, __depth_limit);
640883}
641884
642template <class _Compare, class _Tp>
643inline _LIBCPP_INLINE_VISIBILITY void __sort(_Tp** __first, _Tp** __last, __less<_Tp*>&) {
644 __less<uintptr_t> __comp;
645 std::__sort<__less<uintptr_t>&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp);
646}
885template <class _Type, class... _Options>
886using __is_any_of = _Or<is_same<_Type, _Options>...>;
647887
648extern template _LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&);
888template <class _Type>
889using __sort_is_specialized_in_library = __is_any_of<
890 _Type,
891 char,
649892#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
650extern template _LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
893 wchar_t,
651894#endif
652extern template _LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
653extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
654extern template _LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&);
655extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
656extern template _LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&);
657extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);
658extern template _LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&);
659extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
660extern template _LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
661extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&);
662extern template _LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&);
663extern template _LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&);
664extern template _LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
665
666extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&);
667#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
668extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
895 signed char,
896 unsigned char,
897 short,
898 unsigned short,
899 int,
900 unsigned int,
901 long,
902 unsigned long,
903 long long,
904 unsigned long long,
905 float,
906 double,
907 long double>;
908
909template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
910_LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, __less<>&) {
911 __less<_Type> __comp;
912 std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
913}
914
915template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
916_LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, less<_Type>&) {
917 __less<_Type> __comp;
918 std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
919}
920
921#if _LIBCPP_STD_VER >= 14
922template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
923_LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, less<>&) {
924 __less<_Type> __comp;
925 std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
926}
927#endif
928
929#if _LIBCPP_STD_VER >= 20
930template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
931_LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, ranges::less&) {
932 __less<_Type> __comp;
933 std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
934}
669935#endif
670extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
671extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
672extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&);
673extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
674extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&);
675extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);
676extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&);
677extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
678extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
679extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&);
680extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&);
681extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&);
682extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
683
684extern template _LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&);
685936
686937template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
687938inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
688939void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
689940 std::__debug_randomize_range<_AlgPolicy>(__first, __last);
690941
691 using _Comp_ref = __comp_ref_type<_Comp>;
692942 if (__libcpp_is_constant_evaluated()) {
693 std::__partial_sort<_AlgPolicy>(__first, __last, __last, __comp);
694
943 std::__partial_sort<_AlgPolicy>(
944 std::__unwrap_iter(__first), std::__unwrap_iter(__last), std::__unwrap_iter(__last), __comp);
695945 } else {
696 using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Comp_ref>::type;
697 _Comp_ref __comp_ref(__comp);
698 _WrappedComp __wrapped_comp(__comp_ref);
699 std::__sort<_WrappedComp>(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __wrapped_comp);
946 std::__sort_dispatch<_AlgPolicy>(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __comp);
700947 }
948 std::__check_strict_weak_ordering_sorted(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __comp);
701949}
702950
703951template <class _RandomAccessIterator, class _Comp>
......@@ -709,7 +957,7 @@ void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __c
709957template <class _RandomAccessIterator>
710958inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
711959void sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
712 std::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
960 std::sort(__first, __last, __less<>());
713961}
714962
715963_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/sort_heap.h+6-3
......@@ -14,9 +14,11 @@
1414#include <__algorithm/iterator_operations.h>
1515#include <__algorithm/pop_heap.h>
1616#include <__config>
17#include <__debug_utils/strict_weak_ordering_check.h>
1718#include <__iterator/iterator_traits.h>
19#include <__type_traits/is_copy_assignable.h>
20#include <__type_traits/is_copy_constructible.h>
1821#include <__utility/move.h>
19#include <type_traits>
2022
2123#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2224# pragma GCC system_header
......@@ -27,11 +29,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2729template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
2830inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
2931void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) {
32 _RandomAccessIterator __saved_last = __last;
3033 __comp_ref_type<_Compare> __comp_ref = __comp;
3134
3235 using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
3336 for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n)
3437 std::__pop_heap<_AlgPolicy>(__first, __last, __comp_ref, __n);
38 std::__check_strict_weak_ordering_sorted(__first, __saved_last, __comp_ref);
3539}
3640
3741template <class _RandomAccessIterator, class _Compare>
......@@ -46,8 +50,7 @@ void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
4650template <class _RandomAccessIterator>
4751inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4852void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
49 std::sort_heap(std::move(__first), std::move(__last),
50 __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
53 std::sort_heap(std::move(__first), std::move(__last), __less<>());
5154}
5255
5356_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/stable_partition.h+4-4
......@@ -21,7 +21,6 @@
2121#include <__utility/move.h>
2222#include <__utility/pair.h>
2323#include <new>
24#include <type_traits>
2524
2625#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2726# pragma GCC system_header
......@@ -123,7 +122,10 @@ _LIBCPP_HIDE_FROM_ABI _ForwardIterator
123122__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
124123 forward_iterator_tag)
125124{
126 const unsigned __alloc_limit = 3; // might want to make this a function of trivial assignment
125 typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
126 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
127
128 const difference_type __alloc_limit = 3; // might want to make this a function of trivial assignment
127129 // Either prove all true and return __first or point to first false
128130 while (true)
129131 {
......@@ -135,8 +137,6 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred
135137 }
136138 // We now have a reduced range [__first, __last)
137139 // *__first is known to be false
138 typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
139 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
140140 difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last);
141141 pair<value_type*, ptrdiff_t> __p(0, 0);
142142 unique_ptr<value_type, __return_temporary_buffer> __h;
lib/libcxx/include/__algorithm/stable_sort.h+35-2
......@@ -15,14 +15,15 @@
1515#include <__algorithm/iterator_operations.h>
1616#include <__algorithm/sort.h>
1717#include <__config>
18#include <__debug_utils/strict_weak_ordering_check.h>
1819#include <__iterator/iterator_traits.h>
1920#include <__memory/destruct_n.h>
2021#include <__memory/temporary_buffer.h>
2122#include <__memory/unique_ptr.h>
23#include <__type_traits/is_trivially_copy_assignable.h>
2224#include <__utility/move.h>
2325#include <__utility/pair.h>
2426#include <new>
25#include <type_traits>
2627
2728#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2829# pragma GCC system_header
......@@ -30,6 +31,37 @@
3031
3132_LIBCPP_BEGIN_NAMESPACE_STD
3233
34template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
35_LIBCPP_HIDE_FROM_ABI
36void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1,
37 typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) {
38 using _Ops = _IterOps<_AlgPolicy>;
39
40 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
41 if (__first1 != __last1) {
42 __destruct_n __d(0);
43 unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
44 value_type* __last2 = __first2;
45 ::new ((void*)__last2) value_type(_Ops::__iter_move(__first1));
46 __d.template __incr<value_type>();
47 for (++__last2; ++__first1 != __last1; ++__last2) {
48 value_type* __j2 = __last2;
49 value_type* __i2 = __j2;
50 if (__comp(*__first1, *--__i2)) {
51 ::new ((void*)__j2) value_type(std::move(*__i2));
52 __d.template __incr<value_type>();
53 for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2)
54 *__j2 = std::move(*__i2);
55 *__j2 = _Ops::__iter_move(__first1);
56 } else {
57 ::new ((void*)__j2) value_type(_Ops::__iter_move(__first1));
58 __d.template __incr<value_type>();
59 }
60 }
61 __h.release();
62 }
63}
64
3365template <class _AlgPolicy, class _Compare, class _InputIterator1, class _InputIterator2>
3466_LIBCPP_HIDE_FROM_ABI void
3567__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1,
......@@ -228,6 +260,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
228260 }
229261
230262 std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second);
263 std::__check_strict_weak_ordering_sorted(__first, __last, __comp);
231264}
232265
233266template <class _RandomAccessIterator, class _Compare>
......@@ -239,7 +272,7 @@ void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C
239272template <class _RandomAccessIterator>
240273inline _LIBCPP_HIDE_FROM_ABI
241274void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
242 std::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
275 std::stable_sort(__first, __last, __less<>());
243276}
244277
245278_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/three_way_comp_ref_type.h created+73
......@@ -0,0 +1,73 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H
10#define _LIBCPP___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H
11
12#include <__compare/ordering.h>
13#include <__config>
14#include <__utility/declval.h>
15#include <__utility/forward.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18# pragma GCC system_header
19#endif
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23#if _LIBCPP_STD_VER >= 20
24
25template <class _Comp>
26struct __debug_three_way_comp {
27 _Comp& __comp_;
28 _LIBCPP_HIDE_FROM_ABI constexpr __debug_three_way_comp(_Comp& __c) : __comp_(__c) {}
29
30 template <class _Tp, class _Up>
31 _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(const _Tp& __x, const _Up& __y) {
32 auto __r = __comp_(__x, __y);
33 if constexpr (__comparison_category<decltype(__comp_(__x, __y))>)
34 __do_compare_assert(__y, __x, __r);
35 return __r;
36 }
37
38 template <class _Tp, class _Up>
39 _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __x, _Up& __y) {
40 auto __r = __comp_(__x, __y);
41 if constexpr (__comparison_category<decltype(__comp_(__x, __y))>)
42 __do_compare_assert(__y, __x, __r);
43 return __r;
44 }
45
46 template <class _LHS, class _RHS, class _Order>
47 _LIBCPP_HIDE_FROM_ABI constexpr void __do_compare_assert(_LHS& __l, _RHS& __r, _Order __o) {
48 _Order __expected = __o;
49 if (__o == _Order::less)
50 __expected = _Order::greater;
51 if (__o == _Order::greater)
52 __expected = _Order::less;
53 _LIBCPP_ASSERT(__comp_(__l, __r) == __expected, "Comparator does not induce a strict weak ordering");
54 (void)__l;
55 (void)__r;
56 }
57};
58
59// Pass the comparator by lvalue reference. Or in debug mode, using a
60// debugging wrapper that stores a reference.
61# if _LIBCPP_ENABLE_DEBUG_MODE
62template <class _Comp>
63using __three_way_comp_ref_type = __debug_three_way_comp<_Comp>;
64# else
65template <class _Comp>
66using __three_way_comp_ref_type = _Comp&;
67# endif
68
69#endif // _LIBCPP_STD_VER >= 20
70
71_LIBCPP_END_NAMESPACE_STD
72
73#endif // _LIBCPP___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H
lib/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h+3-3
......@@ -11,13 +11,13 @@
1111
1212#include <__config>
1313#include <__functional/invoke.h>
14#include <type_traits>
14#include <__type_traits/remove_cvref.h>
1515
1616#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1717# pragma GCC system_header
1818#endif
1919
20#if _LIBCPP_STD_VER > 17
20#if _LIBCPP_STD_VER >= 20
2121
2222_LIBCPP_PUSH_MACROS
2323#include <__undef_macros>
......@@ -57,6 +57,6 @@ _LIBCPP_END_NAMESPACE_STD
5757
5858_LIBCPP_POP_MACROS
5959
60#endif // _LIBCPP_STD_VER > 17
60#endif // _LIBCPP_STD_VER >= 20
6161
6262#endif // _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H
lib/libcxx/include/__algorithm/unwrap_iter.h+16-5
......@@ -21,24 +21,27 @@
2121# pragma GCC system_header
2222#endif
2323
24_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
2427_LIBCPP_BEGIN_NAMESPACE_STD
2528
2629// TODO: Change the name of __unwrap_iter_impl to something more appropriate
2730// The job of __unwrap_iter is to remove iterator wrappers (like reverse_iterator or __wrap_iter),
2831// to reduce the number of template instantiations and to enable pointer-based optimizations e.g. in std::copy.
29// In debug mode, we don't do this.
3032//
3133// Some algorithms (e.g. std::copy, but not std::sort) need to convert an
3234// "unwrapped" result back into the original iterator type. Doing that is the job of __rewrap_iter.
3335
3436// Default case - we can't unwrap anything
35template <class _Iter, bool = __is_cpp17_contiguous_iterator<_Iter>::value>
37template <class _Iter, bool = __libcpp_is_contiguous_iterator<_Iter>::value>
3638struct __unwrap_iter_impl {
3739 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap(_Iter, _Iter __iter) { return __iter; }
3840 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __unwrap(_Iter __i) _NOEXCEPT { return __i; }
3941};
4042
41#ifndef _LIBCPP_ENABLE_DEBUG_MODE
43// TODO(hardening): make sure that the following unwrapping doesn't unexpectedly turn hardened iterators into raw
44// pointers.
4245
4346// It's a contiguous iterator, so we can use a raw pointer instead
4447template <class _Iter>
......@@ -54,8 +57,6 @@ struct __unwrap_iter_impl<_Iter, true> {
5457 }
5558};
5659
57#endif // !_LIBCPP_ENABLE_DEBUG_MODE
58
5960template<class _Iter,
6061 class _Impl = __unwrap_iter_impl<_Iter>,
6162 __enable_if_t<is_copy_constructible<_Iter>::value, int> = 0>
......@@ -64,6 +65,14 @@ decltype(_Impl::__unwrap(std::declval<_Iter>())) __unwrap_iter(_Iter __i) _NOEXC
6465 return _Impl::__unwrap(__i);
6566}
6667
68// Allow input_iterators to be passed to __unwrap_iter (but not __rewrap_iter)
69#if _LIBCPP_STD_VER >= 20
70template <class _Iter, __enable_if_t<!is_copy_constructible<_Iter>::value, int> = 0>
71inline _LIBCPP_HIDE_FROM_ABI constexpr _Iter __unwrap_iter(_Iter __i) noexcept {
72 return __i;
73}
74#endif
75
6776template <class _OrigIter, class _Iter, class _Impl = __unwrap_iter_impl<_OrigIter> >
6877_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _OrigIter __rewrap_iter(_OrigIter __orig_iter, _Iter __iter) _NOEXCEPT {
6978 return _Impl::__rewrap(std::move(__orig_iter), std::move(__iter));
......@@ -71,4 +80,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _OrigIter __rewrap_iter(_OrigIter __orig
7180
7281_LIBCPP_END_NAMESPACE_STD
7382
83_LIBCPP_PUSH_MACROS
84
7485#endif // _LIBCPP___ALGORITHM_UNWRAP_ITER_H
lib/libcxx/include/__algorithm/unwrap_range.h+4-4
......@@ -28,7 +28,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2828// __unwrap_iter and __rewrap_iter don't work for this, because they assume that the iterator and sentinel have
2929// the same type. __unwrap_range tries to get two iterators and then forward to __unwrap_iter.
3030
31#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
3232template <class _Iter, class _Sent>
3333struct __unwrap_range_impl {
3434 _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __sent)
......@@ -43,7 +43,7 @@ struct __unwrap_range_impl {
4343 }
4444
4545 _LIBCPP_HIDE_FROM_ABI static constexpr auto
46 __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter)
46 __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(std::move(__orig_iter))) __iter)
4747 requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>
4848 {
4949 return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
......@@ -80,7 +80,7 @@ template <
8080_LIBCPP_HIDE_FROM_ABI constexpr _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) {
8181 return __unwrap_range_impl<_Iter, _Sent>::__rewrap(std::move(__orig_iter), std::move(__iter));
8282}
83#else // _LIBCPP_STD_VER > 17
83#else // _LIBCPP_STD_VER >= 20
8484template <class _Iter, class _Unwrapped = decltype(std::__unwrap_iter(std::declval<_Iter>()))>
8585_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair<_Unwrapped, _Unwrapped> __unwrap_range(_Iter __first, _Iter __last) {
8686 return std::make_pair(std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last)));
......@@ -90,7 +90,7 @@ template <class _Iter, class _Unwrapped = decltype(std::__unwrap_iter(std::declv
9090_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) {
9191 return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
9292}
93#endif // _LIBCPP_STD_VER > 17
93#endif // _LIBCPP_STD_VER >= 20
9494
9595_LIBCPP_END_NAMESPACE_STD
9696
lib/libcxx/include/__algorithm/upper_bound.h+7-7
......@@ -25,6 +25,9 @@
2525# pragma GCC system_header
2626#endif
2727
28_LIBCPP_PUSH_MACROS
29#include <__undef_macros>
30
2831_LIBCPP_BEGIN_NAMESPACE_STD
2932
3033template <class _AlgPolicy, class _Compare, class _Iter, class _Sent, class _Tp, class _Proj>
......@@ -47,8 +50,7 @@ __upper_bound(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp
4750template <class _ForwardIterator, class _Tp, class _Compare>
4851_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
4952upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) {
50 static_assert(is_copy_constructible<_ForwardIterator>::value,
51 "Iterator has to be copy constructible");
53 static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible");
5254 return std::__upper_bound<_ClassicAlgPolicy>(
5355 std::move(__first), std::move(__last), __value, std::move(__comp), std::__identity());
5456}
......@@ -56,13 +58,11 @@ upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu
5658template <class _ForwardIterator, class _Tp>
5759_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
5860upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
59 return std::upper_bound(
60 std::move(__first),
61 std::move(__last),
62 __value,
63 __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>());
61 return std::upper_bound(std::move(__first), std::move(__last), __value, __less<>());
6462}
6563
6664_LIBCPP_END_NAMESPACE_STD
6765
66_LIBCPP_POP_MACROS
67
6868#endif // _LIBCPP___ALGORITHM_UPPER_BOUND_H
lib/libcxx/include/__assert+14-32
......@@ -17,39 +17,21 @@
1717# pragma GCC system_header
1818#endif
1919
20// TODO: Remove in LLVM 17.
21#if defined(_LIBCPP_DEBUG)
22# error "Defining _LIBCPP_DEBUG is not supported anymore. Please use _LIBCPP_ENABLE_DEBUG_MODE instead."
23#endif
24
25// Automatically enable assertions when the debug mode is enabled.
26#if defined(_LIBCPP_ENABLE_DEBUG_MODE)
27# ifndef _LIBCPP_ENABLE_ASSERTIONS
28# define _LIBCPP_ENABLE_ASSERTIONS 1
29# endif
30#endif
31
32#ifndef _LIBCPP_ENABLE_ASSERTIONS
33# define _LIBCPP_ENABLE_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS_DEFAULT
34#endif
35
36#if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1
37# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1"
38#endif
39
40#if _LIBCPP_ENABLE_ASSERTIONS
41# define _LIBCPP_ASSERT(expression, message) \
42 (__builtin_expect(static_cast<bool>(expression), 1) ? \
43 (void)0 : \
44 _LIBCPP_VERBOSE_ABORT("%s:%d: assertion %s failed: %s", __FILE__, __LINE__, #expression, message))
45#elif !defined(_LIBCPP_ASSERTIONS_DISABLE_ASSUME) && __has_builtin(__builtin_assume)
46# define _LIBCPP_ASSERT(expression, message) \
47 (_LIBCPP_DIAGNOSTIC_PUSH \
48 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume") \
49 __builtin_assume(static_cast<bool>(expression)) \
50 _LIBCPP_DIAGNOSTIC_POP)
20#define _LIBCPP_ASSERT(expression, message) \
21 (__builtin_expect(static_cast<bool>(expression), 1) \
22 ? (void)0 \
23 : _LIBCPP_VERBOSE_ABORT( \
24 "%s:%d: assertion %s failed: %s\n", __builtin_FILE(), __builtin_LINE(), #expression, message))
25
26// TODO: __builtin_assume can currently inhibit optimizations. Until this has been fixed and we can add
27// assumptions without a clear optimization intent, disable that to avoid worsening the code generation.
28// See https://discourse.llvm.org/t/llvm-assume-blocks-optimization/71609 for a discussion.
29#if 0 && __has_builtin(__builtin_assume)
30# define _LIBCPP_ASSUME(expression) \
31 (_LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume") \
32 __builtin_assume(static_cast<bool>(expression)) _LIBCPP_DIAGNOSTIC_POP)
5133#else
52# define _LIBCPP_ASSERT(expression, message) ((void)0)
34# define _LIBCPP_ASSUME(expression) ((void)0)
5335#endif
5436
5537#endif // _LIBCPP___ASSERT
lib/libcxx/include/__atomic/aliases.h created+116
......@@ -0,0 +1,116 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_ALIASES_H
10#define _LIBCPP___ATOMIC_ALIASES_H
11
12#include <__atomic/atomic.h>
13#include <__atomic/atomic_lock_free.h>
14#include <__atomic/contention_t.h>
15#include <__atomic/is_always_lock_free.h>
16#include <__config>
17#include <__type_traits/conditional.h>
18#include <cstddef>
19#include <cstdint>
20#include <cstdlib>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23# pragma GCC system_header
24#endif
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28using atomic_bool = atomic<bool>;
29using atomic_char = atomic<char>;
30using atomic_schar = atomic<signed char>;
31using atomic_uchar = atomic<unsigned char>;
32using atomic_short = atomic<short>;
33using atomic_ushort = atomic<unsigned short>;
34using atomic_int = atomic<int>;
35using atomic_uint = atomic<unsigned int>;
36using atomic_long = atomic<long>;
37using atomic_ulong = atomic<unsigned long>;
38using atomic_llong = atomic<long long>;
39using atomic_ullong = atomic<unsigned long long>;
40#ifndef _LIBCPP_HAS_NO_CHAR8_T
41using atomic_char8_t = atomic<char8_t>;
42#endif
43using atomic_char16_t = atomic<char16_t>;
44using atomic_char32_t = atomic<char32_t>;
45#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
46using atomic_wchar_t = atomic<wchar_t>;
47#endif
48
49using atomic_int_least8_t = atomic<int_least8_t>;
50using atomic_uint_least8_t = atomic<uint_least8_t>;
51using atomic_int_least16_t = atomic<int_least16_t>;
52using atomic_uint_least16_t = atomic<uint_least16_t>;
53using atomic_int_least32_t = atomic<int_least32_t>;
54using atomic_uint_least32_t = atomic<uint_least32_t>;
55using atomic_int_least64_t = atomic<int_least64_t>;
56using atomic_uint_least64_t = atomic<uint_least64_t>;
57
58using atomic_int_fast8_t = atomic<int_fast8_t>;
59using atomic_uint_fast8_t = atomic<uint_fast8_t>;
60using atomic_int_fast16_t = atomic<int_fast16_t>;
61using atomic_uint_fast16_t = atomic<uint_fast16_t>;
62using atomic_int_fast32_t = atomic<int_fast32_t>;
63using atomic_uint_fast32_t = atomic<uint_fast32_t>;
64using atomic_int_fast64_t = atomic<int_fast64_t>;
65using atomic_uint_fast64_t = atomic<uint_fast64_t>;
66
67using atomic_int8_t = atomic< int8_t>;
68using atomic_uint8_t = atomic<uint8_t>;
69using atomic_int16_t = atomic< int16_t>;
70using atomic_uint16_t = atomic<uint16_t>;
71using atomic_int32_t = atomic< int32_t>;
72using atomic_uint32_t = atomic<uint32_t>;
73using atomic_int64_t = atomic< int64_t>;
74using atomic_uint64_t = atomic<uint64_t>;
75
76using atomic_intptr_t = atomic<intptr_t>;
77using atomic_uintptr_t = atomic<uintptr_t>;
78using atomic_size_t = atomic<size_t>;
79using atomic_ptrdiff_t = atomic<ptrdiff_t>;
80using atomic_intmax_t = atomic<intmax_t>;
81using atomic_uintmax_t = atomic<uintmax_t>;
82
83// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
84
85#if _LIBCPP_STD_VER >= 17
86# define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value
87#else
88# define _LIBCPP_CONTENTION_LOCK_FREE false
89#endif
90
91#if ATOMIC_LLONG_LOCK_FREE == 2
92using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>;
93using __libcpp_unsigned_lock_free =
94 __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>;
95#elif ATOMIC_INT_LOCK_FREE == 2
96using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>;
97using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>;
98#elif ATOMIC_SHORT_LOCK_FREE == 2
99using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>;
100using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>;
101#elif ATOMIC_CHAR_LOCK_FREE == 2
102using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>;
103using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>;
104#else
105// No signed/unsigned lock-free types
106# define _LIBCPP_NO_LOCK_FREE_TYPES
107#endif
108
109#if !defined(_LIBCPP_NO_LOCK_FREE_TYPES)
110using atomic_signed_lock_free = atomic<__libcpp_signed_lock_free>;
111using atomic_unsigned_lock_free = atomic<__libcpp_unsigned_lock_free>;
112#endif
113
114_LIBCPP_END_NAMESPACE_STD
115
116#endif // _LIBCPP___ATOMIC_ALIASES_H
lib/libcxx/include/__atomic/atomic.h created+664
......@@ -0,0 +1,664 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_ATOMIC_H
10#define _LIBCPP___ATOMIC_ATOMIC_H
11
12#include <__atomic/atomic_base.h>
13#include <__atomic/check_memory_order.h>
14#include <__atomic/cxx_atomic_impl.h>
15#include <__atomic/memory_order.h>
16#include <__config>
17#include <__memory/addressof.h>
18#include <__type_traits/is_function.h>
19#include <__type_traits/is_same.h>
20#include <__type_traits/remove_pointer.h>
21#include <cstddef>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24# pragma GCC system_header
25#endif
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29template <class _Tp>
30struct atomic
31 : public __atomic_base<_Tp>
32{
33 using __base = __atomic_base<_Tp>;
34 using value_type = _Tp;
35 using difference_type = value_type;
36
37#if _LIBCPP_STD_VER >= 20
38 _LIBCPP_HIDE_FROM_ABI
39 atomic() = default;
40#else
41 _LIBCPP_HIDE_FROM_ABI
42 atomic() _NOEXCEPT = default;
43#endif
44
45 _LIBCPP_HIDE_FROM_ABI
46 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
47
48 _LIBCPP_HIDE_FROM_ABI
49 _Tp operator=(_Tp __d) volatile _NOEXCEPT
50 {__base::store(__d); return __d;}
51 _LIBCPP_HIDE_FROM_ABI
52 _Tp operator=(_Tp __d) _NOEXCEPT
53 {__base::store(__d); return __d;}
54
55 atomic& operator=(const atomic&) = delete;
56 atomic& operator=(const atomic&) volatile = delete;
57};
58
59// atomic<T*>
60
61template <class _Tp>
62struct atomic<_Tp*>
63 : public __atomic_base<_Tp*>
64{
65 using __base = __atomic_base<_Tp*>;
66 using value_type = _Tp*;
67 using difference_type = ptrdiff_t;
68
69 _LIBCPP_HIDE_FROM_ABI
70 atomic() _NOEXCEPT = default;
71
72 _LIBCPP_HIDE_FROM_ABI
73 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
74
75 _LIBCPP_HIDE_FROM_ABI
76 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
77 {__base::store(__d); return __d;}
78 _LIBCPP_HIDE_FROM_ABI
79 _Tp* operator=(_Tp* __d) _NOEXCEPT
80 {__base::store(__d); return __d;}
81
82 _LIBCPP_HIDE_FROM_ABI
83 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
84 // __atomic_fetch_add accepts function pointers, guard against them.
85 static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
86 return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
87 }
88
89 _LIBCPP_HIDE_FROM_ABI
90 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
91 // __atomic_fetch_add accepts function pointers, guard against them.
92 static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
93 return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
94 }
95
96 _LIBCPP_HIDE_FROM_ABI
97 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
98 // __atomic_fetch_add accepts function pointers, guard against them.
99 static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
100 return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
101 }
102
103 _LIBCPP_HIDE_FROM_ABI
104 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
105 // __atomic_fetch_add accepts function pointers, guard against them.
106 static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
107 return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
108 }
109
110 _LIBCPP_HIDE_FROM_ABI
111 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
112 _LIBCPP_HIDE_FROM_ABI
113 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
114 _LIBCPP_HIDE_FROM_ABI
115 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
116 _LIBCPP_HIDE_FROM_ABI
117 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
118 _LIBCPP_HIDE_FROM_ABI
119 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
120 _LIBCPP_HIDE_FROM_ABI
121 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
122 _LIBCPP_HIDE_FROM_ABI
123 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
124 _LIBCPP_HIDE_FROM_ABI
125 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
126 _LIBCPP_HIDE_FROM_ABI
127 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
128 _LIBCPP_HIDE_FROM_ABI
129 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
130 _LIBCPP_HIDE_FROM_ABI
131 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
132 _LIBCPP_HIDE_FROM_ABI
133 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
134
135 atomic& operator=(const atomic&) = delete;
136 atomic& operator=(const atomic&) volatile = delete;
137};
138
139// atomic_is_lock_free
140
141template <class _Tp>
142_LIBCPP_HIDE_FROM_ABI
143bool
144atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
145{
146 return __o->is_lock_free();
147}
148
149template <class _Tp>
150_LIBCPP_HIDE_FROM_ABI
151bool
152atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
153{
154 return __o->is_lock_free();
155}
156
157// atomic_init
158
159template <class _Tp>
160_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI
161void
162atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
163{
164 std::__cxx_atomic_init(std::addressof(__o->__a_), __d);
165}
166
167template <class _Tp>
168_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI
169void
170atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
171{
172 std::__cxx_atomic_init(std::addressof(__o->__a_), __d);
173}
174
175// atomic_store
176
177template <class _Tp>
178_LIBCPP_HIDE_FROM_ABI
179void
180atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
181{
182 __o->store(__d);
183}
184
185template <class _Tp>
186_LIBCPP_HIDE_FROM_ABI
187void
188atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
189{
190 __o->store(__d);
191}
192
193// atomic_store_explicit
194
195template <class _Tp>
196_LIBCPP_HIDE_FROM_ABI
197void
198atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
199 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
200{
201 __o->store(__d, __m);
202}
203
204template <class _Tp>
205_LIBCPP_HIDE_FROM_ABI
206void
207atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
208 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
209{
210 __o->store(__d, __m);
211}
212
213// atomic_load
214
215template <class _Tp>
216_LIBCPP_HIDE_FROM_ABI
217_Tp
218atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
219{
220 return __o->load();
221}
222
223template <class _Tp>
224_LIBCPP_HIDE_FROM_ABI
225_Tp
226atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
227{
228 return __o->load();
229}
230
231// atomic_load_explicit
232
233template <class _Tp>
234_LIBCPP_HIDE_FROM_ABI
235_Tp
236atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
237 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
238{
239 return __o->load(__m);
240}
241
242template <class _Tp>
243_LIBCPP_HIDE_FROM_ABI
244_Tp
245atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
246 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
247{
248 return __o->load(__m);
249}
250
251// atomic_exchange
252
253template <class _Tp>
254_LIBCPP_HIDE_FROM_ABI
255_Tp
256atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
257{
258 return __o->exchange(__d);
259}
260
261template <class _Tp>
262_LIBCPP_HIDE_FROM_ABI
263_Tp
264atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
265{
266 return __o->exchange(__d);
267}
268
269// atomic_exchange_explicit
270
271template <class _Tp>
272_LIBCPP_HIDE_FROM_ABI
273_Tp
274atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
275{
276 return __o->exchange(__d, __m);
277}
278
279template <class _Tp>
280_LIBCPP_HIDE_FROM_ABI
281_Tp
282atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
283{
284 return __o->exchange(__d, __m);
285}
286
287// atomic_compare_exchange_weak
288
289template <class _Tp>
290_LIBCPP_HIDE_FROM_ABI
291bool
292atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
293{
294 return __o->compare_exchange_weak(*__e, __d);
295}
296
297template <class _Tp>
298_LIBCPP_HIDE_FROM_ABI
299bool
300atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
301{
302 return __o->compare_exchange_weak(*__e, __d);
303}
304
305// atomic_compare_exchange_strong
306
307template <class _Tp>
308_LIBCPP_HIDE_FROM_ABI
309bool
310atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
311{
312 return __o->compare_exchange_strong(*__e, __d);
313}
314
315template <class _Tp>
316_LIBCPP_HIDE_FROM_ABI
317bool
318atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
319{
320 return __o->compare_exchange_strong(*__e, __d);
321}
322
323// atomic_compare_exchange_weak_explicit
324
325template <class _Tp>
326_LIBCPP_HIDE_FROM_ABI
327bool
328atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
329 typename atomic<_Tp>::value_type __d,
330 memory_order __s, memory_order __f) _NOEXCEPT
331 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
332{
333 return __o->compare_exchange_weak(*__e, __d, __s, __f);
334}
335
336template <class _Tp>
337_LIBCPP_HIDE_FROM_ABI
338bool
339atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
340 memory_order __s, memory_order __f) _NOEXCEPT
341 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
342{
343 return __o->compare_exchange_weak(*__e, __d, __s, __f);
344}
345
346// atomic_compare_exchange_strong_explicit
347
348template <class _Tp>
349_LIBCPP_HIDE_FROM_ABI
350bool
351atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
352 typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
353 memory_order __s, memory_order __f) _NOEXCEPT
354 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
355{
356 return __o->compare_exchange_strong(*__e, __d, __s, __f);
357}
358
359template <class _Tp>
360_LIBCPP_HIDE_FROM_ABI
361bool
362atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
363 typename atomic<_Tp>::value_type __d,
364 memory_order __s, memory_order __f) _NOEXCEPT
365 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
366{
367 return __o->compare_exchange_strong(*__e, __d, __s, __f);
368}
369
370// atomic_wait
371
372template <class _Tp>
373_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
374void atomic_wait(const volatile atomic<_Tp>* __o,
375 typename atomic<_Tp>::value_type __v) _NOEXCEPT
376{
377 return __o->wait(__v);
378}
379
380template <class _Tp>
381_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
382void atomic_wait(const atomic<_Tp>* __o,
383 typename atomic<_Tp>::value_type __v) _NOEXCEPT
384{
385 return __o->wait(__v);
386}
387
388// atomic_wait_explicit
389
390template <class _Tp>
391_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
392void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
393 typename atomic<_Tp>::value_type __v,
394 memory_order __m) _NOEXCEPT
395 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
396{
397 return __o->wait(__v, __m);
398}
399
400template <class _Tp>
401_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
402void atomic_wait_explicit(const atomic<_Tp>* __o,
403 typename atomic<_Tp>::value_type __v,
404 memory_order __m) _NOEXCEPT
405 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
406{
407 return __o->wait(__v, __m);
408}
409
410// atomic_notify_one
411
412template <class _Tp>
413_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
414void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
415{
416 __o->notify_one();
417}
418template <class _Tp>
419_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
420void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
421{
422 __o->notify_one();
423}
424
425// atomic_notify_all
426
427template <class _Tp>
428_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
429void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
430{
431 __o->notify_all();
432}
433template <class _Tp>
434_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
435void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
436{
437 __o->notify_all();
438}
439
440// atomic_fetch_add
441
442template <class _Tp>
443_LIBCPP_HIDE_FROM_ABI
444_Tp
445atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
446{
447 return __o->fetch_add(__op);
448}
449
450template <class _Tp>
451_LIBCPP_HIDE_FROM_ABI
452_Tp
453atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
454{
455 return __o->fetch_add(__op);
456}
457
458// atomic_fetch_add_explicit
459
460template <class _Tp>
461_LIBCPP_HIDE_FROM_ABI
462_Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
463{
464 return __o->fetch_add(__op, __m);
465}
466
467template <class _Tp>
468_LIBCPP_HIDE_FROM_ABI
469_Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
470{
471 return __o->fetch_add(__op, __m);
472}
473
474// atomic_fetch_sub
475
476template <class _Tp>
477_LIBCPP_HIDE_FROM_ABI
478_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
479{
480 return __o->fetch_sub(__op);
481}
482
483template <class _Tp>
484_LIBCPP_HIDE_FROM_ABI
485_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
486{
487 return __o->fetch_sub(__op);
488}
489
490// atomic_fetch_sub_explicit
491
492template <class _Tp>
493_LIBCPP_HIDE_FROM_ABI
494_Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
495{
496 return __o->fetch_sub(__op, __m);
497}
498
499template <class _Tp>
500_LIBCPP_HIDE_FROM_ABI
501_Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
502{
503 return __o->fetch_sub(__op, __m);
504}
505
506// atomic_fetch_and
507
508template <class _Tp>
509_LIBCPP_HIDE_FROM_ABI
510typename enable_if
511<
512 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
513 _Tp
514>::type
515atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
516{
517 return __o->fetch_and(__op);
518}
519
520template <class _Tp>
521_LIBCPP_HIDE_FROM_ABI
522typename enable_if
523<
524 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
525 _Tp
526>::type
527atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
528{
529 return __o->fetch_and(__op);
530}
531
532// atomic_fetch_and_explicit
533
534template <class _Tp>
535_LIBCPP_HIDE_FROM_ABI
536typename enable_if
537<
538 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
539 _Tp
540>::type
541atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
542{
543 return __o->fetch_and(__op, __m);
544}
545
546template <class _Tp>
547_LIBCPP_HIDE_FROM_ABI
548typename enable_if
549<
550 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
551 _Tp
552>::type
553atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
554{
555 return __o->fetch_and(__op, __m);
556}
557
558// atomic_fetch_or
559
560template <class _Tp>
561_LIBCPP_HIDE_FROM_ABI
562typename enable_if
563<
564 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
565 _Tp
566>::type
567atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
568{
569 return __o->fetch_or(__op);
570}
571
572template <class _Tp>
573_LIBCPP_HIDE_FROM_ABI
574typename enable_if
575<
576 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
577 _Tp
578>::type
579atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
580{
581 return __o->fetch_or(__op);
582}
583
584// atomic_fetch_or_explicit
585
586template <class _Tp>
587_LIBCPP_HIDE_FROM_ABI
588typename enable_if
589<
590 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
591 _Tp
592>::type
593atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
594{
595 return __o->fetch_or(__op, __m);
596}
597
598template <class _Tp>
599_LIBCPP_HIDE_FROM_ABI
600typename enable_if
601<
602 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
603 _Tp
604>::type
605atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
606{
607 return __o->fetch_or(__op, __m);
608}
609
610// atomic_fetch_xor
611
612template <class _Tp>
613_LIBCPP_HIDE_FROM_ABI
614typename enable_if
615<
616 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
617 _Tp
618>::type
619atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
620{
621 return __o->fetch_xor(__op);
622}
623
624template <class _Tp>
625_LIBCPP_HIDE_FROM_ABI
626typename enable_if
627<
628 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
629 _Tp
630>::type
631atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
632{
633 return __o->fetch_xor(__op);
634}
635
636// atomic_fetch_xor_explicit
637
638template <class _Tp>
639_LIBCPP_HIDE_FROM_ABI
640typename enable_if
641<
642 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
643 _Tp
644>::type
645atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
646{
647 return __o->fetch_xor(__op, __m);
648}
649
650template <class _Tp>
651_LIBCPP_HIDE_FROM_ABI
652typename enable_if
653<
654 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
655 _Tp
656>::type
657atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
658{
659 return __o->fetch_xor(__op, __m);
660}
661
662_LIBCPP_END_NAMESPACE_STD
663
664#endif // _LIBCPP___ATOMIC_ATOMIC_H
lib/libcxx/include/__atomic/atomic_base.h created+232
......@@ -0,0 +1,232 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_ATOMIC_BASE_H
10#define _LIBCPP___ATOMIC_ATOMIC_BASE_H
11
12#include <__atomic/atomic_sync.h>
13#include <__atomic/check_memory_order.h>
14#include <__atomic/cxx_atomic_impl.h>
15#include <__atomic/is_always_lock_free.h>
16#include <__atomic/memory_order.h>
17#include <__availability>
18#include <__config>
19#include <__memory/addressof.h>
20#include <__type_traits/is_integral.h>
21#include <__type_traits/is_nothrow_default_constructible.h>
22#include <__type_traits/is_same.h>
23#include <version>
24
25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26# pragma GCC system_header
27#endif
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
32struct __atomic_base // false
33{
34 mutable __cxx_atomic_impl<_Tp> __a_;
35
36#if _LIBCPP_STD_VER >= 17
37 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value;
38#endif
39
40 _LIBCPP_HIDE_FROM_ABI
41 bool is_lock_free() const volatile _NOEXCEPT
42 {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
43 _LIBCPP_HIDE_FROM_ABI
44 bool is_lock_free() const _NOEXCEPT
45 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
46 _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
47 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
48 std::__cxx_atomic_store(std::addressof(__a_), __d, __m);
49 }
50 _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
51 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
52 std::__cxx_atomic_store(std::addressof(__a_), __d, __m);
53 }
54 _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
55 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
56 return std::__cxx_atomic_load(std::addressof(__a_), __m);
57 }
58 _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
59 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
60 return std::__cxx_atomic_load(std::addressof(__a_), __m);
61 }
62 _LIBCPP_HIDE_FROM_ABI
63 operator _Tp() const volatile _NOEXCEPT {return load();}
64 _LIBCPP_HIDE_FROM_ABI
65 operator _Tp() const _NOEXCEPT {return load();}
66 _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
67 return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);
68 }
69 _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
70 return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);
71 }
72 _LIBCPP_HIDE_FROM_ABI bool
73 compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
74 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
75 return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
76 }
77 _LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
78 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
79 return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
80 }
81 _LIBCPP_HIDE_FROM_ABI bool
82 compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
83 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
84 return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
85 }
86 _LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
87 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
88 return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
89 }
90 _LIBCPP_HIDE_FROM_ABI bool
91 compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
92 return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
93 }
94 _LIBCPP_HIDE_FROM_ABI bool
95 compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
96 return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
97 }
98 _LIBCPP_HIDE_FROM_ABI bool
99 compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
100 return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
101 }
102 _LIBCPP_HIDE_FROM_ABI bool
103 compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
104 return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
105 }
106
107 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const
108 volatile _NOEXCEPT {
109 std::__cxx_atomic_wait(std::addressof(__a_), __v, __m);
110 }
111 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
112 wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
113 std::__cxx_atomic_wait(std::addressof(__a_), __v, __m);
114 }
115 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
116 std::__cxx_atomic_notify_one(std::addressof(__a_));
117 }
118 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT {
119 std::__cxx_atomic_notify_one(std::addressof(__a_));
120 }
121 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
122 std::__cxx_atomic_notify_all(std::addressof(__a_));
123 }
124 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT {
125 std::__cxx_atomic_notify_all(std::addressof(__a_));
126 }
127
128#if _LIBCPP_STD_VER >= 20
129 _LIBCPP_HIDE_FROM_ABI constexpr
130 __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
131#else
132 _LIBCPP_HIDE_FROM_ABI
133 __atomic_base() _NOEXCEPT = default;
134#endif
135
136 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
137 __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
138
139 __atomic_base(const __atomic_base&) = delete;
140};
141
142#if _LIBCPP_STD_VER >= 17
143template <class _Tp, bool __b>
144_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
145#endif
146
147// atomic<Integral>
148
149template <class _Tp>
150struct __atomic_base<_Tp, true>
151 : public __atomic_base<_Tp, false>
152{
153 using __base = __atomic_base<_Tp, false>;
154
155 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
156 __atomic_base() _NOEXCEPT = default;
157
158 _LIBCPP_HIDE_FROM_ABI
159 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
160
161 _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
162 return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
163 }
164 _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
165 return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
166 }
167 _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
168 return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
169 }
170 _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
171 return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
172 }
173 _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
174 return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);
175 }
176 _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
177 return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);
178 }
179 _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
180 return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);
181 }
182 _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
183 return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);
184 }
185 _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
186 return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);
187 }
188 _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
189 return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);
190 }
191
192 _LIBCPP_HIDE_FROM_ABI
193 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
194 _LIBCPP_HIDE_FROM_ABI
195 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
196 _LIBCPP_HIDE_FROM_ABI
197 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
198 _LIBCPP_HIDE_FROM_ABI
199 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
200 _LIBCPP_HIDE_FROM_ABI
201 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
202 _LIBCPP_HIDE_FROM_ABI
203 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
204 _LIBCPP_HIDE_FROM_ABI
205 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
206 _LIBCPP_HIDE_FROM_ABI
207 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
208 _LIBCPP_HIDE_FROM_ABI
209 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
210 _LIBCPP_HIDE_FROM_ABI
211 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
212 _LIBCPP_HIDE_FROM_ABI
213 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
214 _LIBCPP_HIDE_FROM_ABI
215 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
216 _LIBCPP_HIDE_FROM_ABI
217 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
218 _LIBCPP_HIDE_FROM_ABI
219 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
220 _LIBCPP_HIDE_FROM_ABI
221 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
222 _LIBCPP_HIDE_FROM_ABI
223 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
224 _LIBCPP_HIDE_FROM_ABI
225 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
226 _LIBCPP_HIDE_FROM_ABI
227 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
228};
229
230_LIBCPP_END_NAMESPACE_STD
231
232#endif // _LIBCPP___ATOMIC_ATOMIC_BASE_H
lib/libcxx/include/__atomic/atomic_flag.h created+230
......@@ -0,0 +1,230 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_ATOMIC_FLAG_H
10#define _LIBCPP___ATOMIC_ATOMIC_FLAG_H
11
12#include <__atomic/atomic_sync.h>
13#include <__atomic/contention_t.h>
14#include <__atomic/cxx_atomic_impl.h>
15#include <__atomic/memory_order.h>
16#include <__chrono/duration.h>
17#include <__config>
18#include <__threading_support>
19#include <cstdint>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22# pragma GCC system_header
23#endif
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27struct atomic_flag
28{
29 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
30
31 _LIBCPP_HIDE_FROM_ABI
32 bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
33 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
34 _LIBCPP_HIDE_FROM_ABI
35 bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
36 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
37
38 _LIBCPP_HIDE_FROM_ABI
39 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
40 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
41 _LIBCPP_HIDE_FROM_ABI
42 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
43 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
44 _LIBCPP_HIDE_FROM_ABI
45 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
46 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
47 _LIBCPP_HIDE_FROM_ABI
48 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
49 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
50
51 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
52 void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
53 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
54 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
55 void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
56 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
57 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
58 void notify_one() volatile _NOEXCEPT
59 {__cxx_atomic_notify_one(&__a_);}
60 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
61 void notify_one() _NOEXCEPT
62 {__cxx_atomic_notify_one(&__a_);}
63 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
64 void notify_all() volatile _NOEXCEPT
65 {__cxx_atomic_notify_all(&__a_);}
66 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
67 void notify_all() _NOEXCEPT
68 {__cxx_atomic_notify_all(&__a_);}
69
70#if _LIBCPP_STD_VER >= 20
71 _LIBCPP_HIDE_FROM_ABI constexpr
72 atomic_flag() _NOEXCEPT : __a_(false) {}
73#else
74 atomic_flag() _NOEXCEPT = default;
75#endif
76
77 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
78 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
79
80 atomic_flag(const atomic_flag&) = delete;
81 atomic_flag& operator=(const atomic_flag&) = delete;
82 atomic_flag& operator=(const atomic_flag&) volatile = delete;
83
84};
85
86inline _LIBCPP_HIDE_FROM_ABI
87bool
88atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
89{
90 return __o->test();
91}
92
93inline _LIBCPP_HIDE_FROM_ABI
94bool
95atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
96{
97 return __o->test();
98}
99
100inline _LIBCPP_HIDE_FROM_ABI
101bool
102atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
103{
104 return __o->test(__m);
105}
106
107inline _LIBCPP_HIDE_FROM_ABI
108bool
109atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
110{
111 return __o->test(__m);
112}
113
114inline _LIBCPP_HIDE_FROM_ABI
115bool
116atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
117{
118 return __o->test_and_set();
119}
120
121inline _LIBCPP_HIDE_FROM_ABI
122bool
123atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
124{
125 return __o->test_and_set();
126}
127
128inline _LIBCPP_HIDE_FROM_ABI
129bool
130atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
131{
132 return __o->test_and_set(__m);
133}
134
135inline _LIBCPP_HIDE_FROM_ABI
136bool
137atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
138{
139 return __o->test_and_set(__m);
140}
141
142inline _LIBCPP_HIDE_FROM_ABI
143void
144atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
145{
146 __o->clear();
147}
148
149inline _LIBCPP_HIDE_FROM_ABI
150void
151atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
152{
153 __o->clear();
154}
155
156inline _LIBCPP_HIDE_FROM_ABI
157void
158atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
159{
160 __o->clear(__m);
161}
162
163inline _LIBCPP_HIDE_FROM_ABI
164void
165atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
166{
167 __o->clear(__m);
168}
169
170inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
171void
172atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
173{
174 __o->wait(__v);
175}
176
177inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
178void
179atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
180{
181 __o->wait(__v);
182}
183
184inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
185void
186atomic_flag_wait_explicit(const volatile atomic_flag* __o,
187 bool __v, memory_order __m) _NOEXCEPT
188{
189 __o->wait(__v, __m);
190}
191
192inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
193void
194atomic_flag_wait_explicit(const atomic_flag* __o,
195 bool __v, memory_order __m) _NOEXCEPT
196{
197 __o->wait(__v, __m);
198}
199
200inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
201void
202atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
203{
204 __o->notify_one();
205}
206
207inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
208void
209atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
210{
211 __o->notify_one();
212}
213
214inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
215void
216atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
217{
218 __o->notify_all();
219}
220
221inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
222void
223atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
224{
225 __o->notify_all();
226}
227
228_LIBCPP_END_NAMESPACE_STD
229
230#endif // _LIBCPP___ATOMIC_ATOMIC_FLAG_H
lib/libcxx/include/__atomic/atomic_init.h created+27
......@@ -0,0 +1,27 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_ATOMIC_INIT_H
10#define _LIBCPP___ATOMIC_ATOMIC_INIT_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15# pragma GCC system_header
16#endif
17
18#define ATOMIC_FLAG_INIT {false}
19#define ATOMIC_VAR_INIT(__v) {__v}
20
21#if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
22# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400
23# pragma clang deprecated(ATOMIC_VAR_INIT)
24# endif
25#endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
26
27#endif // _LIBCPP___ATOMIC_ATOMIC_INIT_H
lib/libcxx/include/__atomic/atomic_lock_free.h created+48
......@@ -0,0 +1,48 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H
10#define _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15# pragma GCC system_header
16#endif
17
18#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
19# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
20# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
21#ifndef _LIBCPP_HAS_NO_CHAR8_T
22# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
23#endif
24# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
25# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
26# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
27# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
28# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
29# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
30# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
31# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
32#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
33# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
34# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
35#ifndef _LIBCPP_HAS_NO_CHAR8_T
36# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
37#endif
38# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
39# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
40# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
41# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
42# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
43# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
44# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
45# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
46#endif
47
48#endif // _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H
lib/libcxx/include/__atomic/atomic_sync.h created+112
......@@ -0,0 +1,112 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_ATOMIC_SYNC_H
10#define _LIBCPP___ATOMIC_ATOMIC_SYNC_H
11
12#include <__atomic/contention_t.h>
13#include <__atomic/cxx_atomic_impl.h>
14#include <__atomic/memory_order.h>
15#include <__availability>
16#include <__chrono/duration.h>
17#include <__config>
18#include <__memory/addressof.h>
19#include <__thread/poll_with_backoff.h>
20#include <__threading_support>
21#include <__type_traits/decay.h>
22#include <cstring>
23
24#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25# pragma GCC system_header
26#endif
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30#ifndef _LIBCPP_HAS_NO_THREADS
31
32_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
33_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
34_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
35_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
36
37_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
38_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
39_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
40_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
41
42template <class _Atp, class _Fn>
43struct __libcpp_atomic_wait_backoff_impl {
44 _Atp* __a;
45 _Fn __test_fn;
46 _LIBCPP_AVAILABILITY_SYNC
47 _LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const
48 {
49 if(__elapsed > chrono::microseconds(64))
50 {
51 auto const __monitor = std::__libcpp_atomic_monitor(__a);
52 if(__test_fn())
53 return true;
54 std::__libcpp_atomic_wait(__a, __monitor);
55 }
56 else if(__elapsed > chrono::microseconds(4))
57 __libcpp_thread_yield();
58 else
59 {} // poll
60 return false;
61 }
62};
63
64template <class _Atp, class _Fn>
65_LIBCPP_AVAILABILITY_SYNC
66_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
67{
68 __libcpp_atomic_wait_backoff_impl<_Atp, __decay_t<_Fn> > __backoff_fn = {__a, __test_fn};
69 return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
70}
71
72#else // _LIBCPP_HAS_NO_THREADS
73
74template <class _Tp>
75_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
76template <class _Tp>
77_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
78template <class _Atp, class _Fn>
79_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
80{
81 return std::__libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy());
82}
83
84#endif // _LIBCPP_HAS_NO_THREADS
85
86template <typename _Tp> _LIBCPP_HIDE_FROM_ABI
87bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
88 return std::memcmp(std::addressof(__lhs), std::addressof(__rhs), sizeof(_Tp)) == 0;
89}
90
91template <class _Atp, class _Tp>
92struct __cxx_atomic_wait_test_fn_impl {
93 _Atp* __a;
94 _Tp __val;
95 memory_order __order;
96 _LIBCPP_HIDE_FROM_ABI bool operator()() const
97 {
98 return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val);
99 }
100};
101
102template <class _Atp, class _Tp>
103_LIBCPP_AVAILABILITY_SYNC
104_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
105{
106 __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
107 return std::__cxx_atomic_wait(__a, __test_fn);
108}
109
110_LIBCPP_END_NAMESPACE_STD
111
112#endif // _LIBCPP___ATOMIC_ATOMIC_SYNC_H
lib/libcxx/include/__atomic/check_memory_order.h created+34
......@@ -0,0 +1,34 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H
10#define _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15# pragma GCC system_header
16#endif
17
18#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
19 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
20 __m == memory_order_acquire || \
21 __m == memory_order_acq_rel, \
22 "memory order argument to atomic operation is invalid")
23
24#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
25 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
26 __m == memory_order_acq_rel, \
27 "memory order argument to atomic operation is invalid")
28
29#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
30 _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
31 __f == memory_order_acq_rel, \
32 "memory order argument to atomic operation is invalid")
33
34#endif // _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H
lib/libcxx/include/__atomic/contention_t.h created+32
......@@ -0,0 +1,32 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_CONTENTION_T_H
10#define _LIBCPP___ATOMIC_CONTENTION_T_H
11
12#include <__atomic/cxx_atomic_impl.h>
13#include <__config>
14#include <cstdint>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
23 using __cxx_contention_t = int32_t;
24#else
25 using __cxx_contention_t = int64_t;
26#endif // __linux__ || (_AIX && !__64BIT__)
27
28using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
29
30_LIBCPP_END_NAMESPACE_STD
31
32#endif // _LIBCPP___ATOMIC_CONTENTION_T_H
lib/libcxx/include/__atomic/cxx_atomic_impl.h created+831
......@@ -0,0 +1,831 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H
10#define _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H
11
12#include <__atomic/is_always_lock_free.h>
13#include <__atomic/memory_order.h>
14#include <__config>
15#include <__memory/addressof.h>
16#include <__type_traits/conditional.h>
17#include <__type_traits/is_assignable.h>
18#include <__type_traits/is_trivially_copyable.h>
19#include <__type_traits/remove_const.h>
20#include <cstddef>
21#include <cstring>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24# pragma GCC system_header
25#endif
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
30 defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
31
32// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
33// the default operator= in an object is not volatile, a byte-by-byte copy
34// is required.
35template <typename _Tp, typename _Tv> _LIBCPP_HIDE_FROM_ABI
36typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
37__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
38 __a_value = __val;
39}
40template <typename _Tp, typename _Tv> _LIBCPP_HIDE_FROM_ABI
41typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
42__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
43 volatile char* __to = reinterpret_cast<volatile char*>(std::addressof(__a_value));
44 volatile char* __end = __to + sizeof(_Tp);
45 volatile const char* __from = reinterpret_cast<volatile const char*>(std::addressof(__val));
46 while (__to != __end)
47 *__to++ = *__from++;
48}
49
50#endif
51
52#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
53
54template <typename _Tp>
55struct __cxx_atomic_base_impl {
56
57 _LIBCPP_HIDE_FROM_ABI
58#ifndef _LIBCPP_CXX03_LANG
59 __cxx_atomic_base_impl() _NOEXCEPT = default;
60#else
61 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
62#endif // _LIBCPP_CXX03_LANG
63 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
64 : __a_value(value) {}
65 _Tp __a_value;
66};
67
68_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
69 // Avoid switch statement to make this a constexpr.
70 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
71 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
72 (__order == memory_order_release ? __ATOMIC_RELEASE:
73 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
74 (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
75 __ATOMIC_CONSUME))));
76}
77
78_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
79 // Avoid switch statement to make this a constexpr.
80 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
81 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
82 (__order == memory_order_release ? __ATOMIC_RELAXED:
83 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
84 (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
85 __ATOMIC_CONSUME))));
86}
87
88template <typename _Tp>
89_LIBCPP_HIDE_FROM_ABI
90void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
91 __cxx_atomic_assign_volatile(__a->__a_value, __val);
92}
93
94template <typename _Tp>
95_LIBCPP_HIDE_FROM_ABI
96void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
97 __a->__a_value = __val;
98}
99
100_LIBCPP_HIDE_FROM_ABI inline
101void __cxx_atomic_thread_fence(memory_order __order) {
102 __atomic_thread_fence(__to_gcc_order(__order));
103}
104
105_LIBCPP_HIDE_FROM_ABI inline
106void __cxx_atomic_signal_fence(memory_order __order) {
107 __atomic_signal_fence(__to_gcc_order(__order));
108}
109
110template <typename _Tp>
111_LIBCPP_HIDE_FROM_ABI
112void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
113 memory_order __order) {
114 __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order));
115}
116
117template <typename _Tp>
118_LIBCPP_HIDE_FROM_ABI
119void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
120 memory_order __order) {
121 __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order));
122}
123
124template <typename _Tp>
125_LIBCPP_HIDE_FROM_ABI
126_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
127 memory_order __order) {
128 _Tp __ret;
129 __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order));
130 return __ret;
131}
132
133template <typename _Tp>
134_LIBCPP_HIDE_FROM_ABI
135_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
136 _Tp __ret;
137 __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order));
138 return __ret;
139}
140
141template <typename _Tp>
142_LIBCPP_HIDE_FROM_ABI
143_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
144 _Tp __value, memory_order __order) {
145 _Tp __ret;
146 __atomic_exchange(
147 std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order));
148 return __ret;
149}
150
151template <typename _Tp>
152_LIBCPP_HIDE_FROM_ABI
153_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
154 memory_order __order) {
155 _Tp __ret;
156 __atomic_exchange(
157 std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order));
158 return __ret;
159}
160
161template <typename _Tp>
162_LIBCPP_HIDE_FROM_ABI
163bool __cxx_atomic_compare_exchange_strong(
164 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
165 memory_order __success, memory_order __failure) {
166 return __atomic_compare_exchange(
167 std::addressof(__a->__a_value),
168 __expected,
169 std::addressof(__value),
170 false,
171 __to_gcc_order(__success),
172 __to_gcc_failure_order(__failure));
173}
174
175template <typename _Tp>
176_LIBCPP_HIDE_FROM_ABI
177bool __cxx_atomic_compare_exchange_strong(
178 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
179 memory_order __failure) {
180 return __atomic_compare_exchange(
181 std::addressof(__a->__a_value),
182 __expected,
183 std::addressof(__value),
184 false,
185 __to_gcc_order(__success),
186 __to_gcc_failure_order(__failure));
187}
188
189template <typename _Tp>
190_LIBCPP_HIDE_FROM_ABI
191bool __cxx_atomic_compare_exchange_weak(
192 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
193 memory_order __success, memory_order __failure) {
194 return __atomic_compare_exchange(
195 std::addressof(__a->__a_value),
196 __expected,
197 std::addressof(__value),
198 true,
199 __to_gcc_order(__success),
200 __to_gcc_failure_order(__failure));
201}
202
203template <typename _Tp>
204_LIBCPP_HIDE_FROM_ABI
205bool __cxx_atomic_compare_exchange_weak(
206 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
207 memory_order __failure) {
208 return __atomic_compare_exchange(
209 std::addressof(__a->__a_value),
210 __expected,
211 std::addressof(__value),
212 true,
213 __to_gcc_order(__success),
214 __to_gcc_failure_order(__failure));
215}
216
217template <typename _Tp>
218struct __skip_amt { enum {value = 1}; };
219
220template <typename _Tp>
221struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
222
223// FIXME: Haven't figured out what the spec says about using arrays with
224// atomic_fetch_add. Force a failure rather than creating bad behavior.
225template <typename _Tp>
226struct __skip_amt<_Tp[]> { };
227template <typename _Tp, int n>
228struct __skip_amt<_Tp[n]> { };
229
230template <typename _Tp, typename _Td>
231_LIBCPP_HIDE_FROM_ABI
232_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
233 _Td __delta, memory_order __order) {
234 return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
235}
236
237template <typename _Tp, typename _Td>
238_LIBCPP_HIDE_FROM_ABI
239_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
240 memory_order __order) {
241 return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
242}
243
244template <typename _Tp, typename _Td>
245_LIBCPP_HIDE_FROM_ABI
246_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
247 _Td __delta, memory_order __order) {
248 return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
249}
250
251template <typename _Tp, typename _Td>
252_LIBCPP_HIDE_FROM_ABI
253_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
254 memory_order __order) {
255 return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
256}
257
258template <typename _Tp>
259_LIBCPP_HIDE_FROM_ABI
260_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
261 _Tp __pattern, memory_order __order) {
262 return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
263}
264
265template <typename _Tp>
266_LIBCPP_HIDE_FROM_ABI
267_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
268 _Tp __pattern, memory_order __order) {
269 return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
270}
271
272template <typename _Tp>
273_LIBCPP_HIDE_FROM_ABI
274_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
275 _Tp __pattern, memory_order __order) {
276 return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
277}
278
279template <typename _Tp>
280_LIBCPP_HIDE_FROM_ABI
281_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
282 memory_order __order) {
283 return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
284}
285
286template <typename _Tp>
287_LIBCPP_HIDE_FROM_ABI
288_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
289 _Tp __pattern, memory_order __order) {
290 return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
291}
292
293template <typename _Tp>
294_LIBCPP_HIDE_FROM_ABI
295_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
296 memory_order __order) {
297 return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
298}
299
300#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
301
302#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
303
304template <typename _Tp>
305struct __cxx_atomic_base_impl {
306
307 _LIBCPP_HIDE_FROM_ABI
308#ifndef _LIBCPP_CXX03_LANG
309 __cxx_atomic_base_impl() _NOEXCEPT = default;
310#else
311 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
312#endif // _LIBCPP_CXX03_LANG
313 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT
314 : __a_value(__value) {}
315 _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
316};
317
318#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
319
320_LIBCPP_HIDE_FROM_ABI inline
321void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
322 __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
323}
324
325_LIBCPP_HIDE_FROM_ABI inline
326void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
327 __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
328}
329
330template<class _Tp>
331_LIBCPP_HIDE_FROM_ABI
332void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
333 __c11_atomic_init(std::addressof(__a->__a_value), __val);
334}
335template<class _Tp>
336_LIBCPP_HIDE_FROM_ABI
337void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
338 __c11_atomic_init(std::addressof(__a->__a_value), __val);
339}
340
341template<class _Tp>
342_LIBCPP_HIDE_FROM_ABI
343void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
344 __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));
345}
346template<class _Tp>
347_LIBCPP_HIDE_FROM_ABI
348void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
349 __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));
350}
351
352template<class _Tp>
353_LIBCPP_HIDE_FROM_ABI
354_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
355 using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
356 return __c11_atomic_load(
357 const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
358}
359template<class _Tp>
360_LIBCPP_HIDE_FROM_ABI
361_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
362 using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
363 return __c11_atomic_load(
364 const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
365}
366
367template<class _Tp>
368_LIBCPP_HIDE_FROM_ABI
369_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
370 return __c11_atomic_exchange(
371 std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));
372}
373template<class _Tp>
374_LIBCPP_HIDE_FROM_ABI
375_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
376 return __c11_atomic_exchange(
377 std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));
378}
379
380_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
381 // Avoid switch statement to make this a constexpr.
382 return __order == memory_order_release ? memory_order_relaxed:
383 (__order == memory_order_acq_rel ? memory_order_acquire:
384 __order);
385}
386
387template<class _Tp>
388_LIBCPP_HIDE_FROM_ABI
389bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
390 return __c11_atomic_compare_exchange_strong(
391 std::addressof(__a->__a_value),
392 __expected,
393 __value,
394 static_cast<__memory_order_underlying_t>(__success),
395 static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
396}
397template<class _Tp>
398_LIBCPP_HIDE_FROM_ABI
399bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
400 return __c11_atomic_compare_exchange_strong(
401 std::addressof(__a->__a_value),
402 __expected,
403 __value,
404 static_cast<__memory_order_underlying_t>(__success),
405 static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
406}
407
408template<class _Tp>
409_LIBCPP_HIDE_FROM_ABI
410bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
411 return __c11_atomic_compare_exchange_weak(
412 std::addressof(__a->__a_value),
413 __expected,
414 __value,
415 static_cast<__memory_order_underlying_t>(__success),
416 static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
417}
418template<class _Tp>
419_LIBCPP_HIDE_FROM_ABI
420bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
421 return __c11_atomic_compare_exchange_weak(
422 std::addressof(__a->__a_value),
423 __expected,
424 __value,
425 static_cast<__memory_order_underlying_t>(__success),
426 static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
427}
428
429template<class _Tp>
430_LIBCPP_HIDE_FROM_ABI
431_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
432 return __c11_atomic_fetch_add(
433 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
434}
435template<class _Tp>
436_LIBCPP_HIDE_FROM_ABI
437_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
438 return __c11_atomic_fetch_add(
439 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
440}
441
442template<class _Tp>
443_LIBCPP_HIDE_FROM_ABI
444_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
445 return __c11_atomic_fetch_add(
446 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
447}
448template<class _Tp>
449_LIBCPP_HIDE_FROM_ABI
450_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
451 return __c11_atomic_fetch_add(
452 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
453}
454
455template<class _Tp>
456_LIBCPP_HIDE_FROM_ABI
457_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
458 return __c11_atomic_fetch_sub(
459 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
460}
461template<class _Tp>
462_LIBCPP_HIDE_FROM_ABI
463_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
464 return __c11_atomic_fetch_sub(
465 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
466}
467template<class _Tp>
468_LIBCPP_HIDE_FROM_ABI
469_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
470 return __c11_atomic_fetch_sub(
471 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
472}
473template<class _Tp>
474_LIBCPP_HIDE_FROM_ABI
475_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
476 return __c11_atomic_fetch_sub(
477 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
478}
479
480template<class _Tp>
481_LIBCPP_HIDE_FROM_ABI
482_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
483 return __c11_atomic_fetch_and(
484 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
485}
486template<class _Tp>
487_LIBCPP_HIDE_FROM_ABI
488_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
489 return __c11_atomic_fetch_and(
490 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
491}
492
493template<class _Tp>
494_LIBCPP_HIDE_FROM_ABI
495_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
496 return __c11_atomic_fetch_or(
497 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
498}
499template<class _Tp>
500_LIBCPP_HIDE_FROM_ABI
501_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
502 return __c11_atomic_fetch_or(
503 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
504}
505
506template<class _Tp>
507_LIBCPP_HIDE_FROM_ABI
508_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
509 return __c11_atomic_fetch_xor(
510 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
511}
512template<class _Tp>
513_LIBCPP_HIDE_FROM_ABI
514_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
515 return __c11_atomic_fetch_xor(
516 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
517}
518
519#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
520
521#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
522
523template<typename _Tp>
524struct __cxx_atomic_lock_impl {
525
526 _LIBCPP_HIDE_FROM_ABI
527 __cxx_atomic_lock_impl() _NOEXCEPT
528 : __a_value(), __a_lock(0) {}
529 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit
530 __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
531 : __a_value(value), __a_lock(0) {}
532
533 _Tp __a_value;
534 mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
535
536 _LIBCPP_HIDE_FROM_ABI void __lock() const volatile {
537 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
538 /*spin*/;
539 }
540 _LIBCPP_HIDE_FROM_ABI void __lock() const {
541 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
542 /*spin*/;
543 }
544 _LIBCPP_HIDE_FROM_ABI void __unlock() const volatile {
545 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
546 }
547 _LIBCPP_HIDE_FROM_ABI void __unlock() const {
548 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
549 }
550 _LIBCPP_HIDE_FROM_ABI _Tp __read() const volatile {
551 __lock();
552 _Tp __old;
553 __cxx_atomic_assign_volatile(__old, __a_value);
554 __unlock();
555 return __old;
556 }
557 _LIBCPP_HIDE_FROM_ABI _Tp __read() const {
558 __lock();
559 _Tp __old = __a_value;
560 __unlock();
561 return __old;
562 }
563};
564
565template <typename _Tp>
566_LIBCPP_HIDE_FROM_ABI
567void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
568 __cxx_atomic_assign_volatile(__a->__a_value, __val);
569}
570template <typename _Tp>
571_LIBCPP_HIDE_FROM_ABI
572void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
573 __a->__a_value = __val;
574}
575
576template <typename _Tp>
577_LIBCPP_HIDE_FROM_ABI
578void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
579 __a->__lock();
580 __cxx_atomic_assign_volatile(__a->__a_value, __val);
581 __a->__unlock();
582}
583template <typename _Tp>
584_LIBCPP_HIDE_FROM_ABI
585void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
586 __a->__lock();
587 __a->__a_value = __val;
588 __a->__unlock();
589}
590
591template <typename _Tp>
592_LIBCPP_HIDE_FROM_ABI
593_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
594 return __a->__read();
595}
596template <typename _Tp>
597_LIBCPP_HIDE_FROM_ABI
598_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
599 return __a->__read();
600}
601
602template <typename _Tp>
603_LIBCPP_HIDE_FROM_ABI
604_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
605 __a->__lock();
606 _Tp __old;
607 __cxx_atomic_assign_volatile(__old, __a->__a_value);
608 __cxx_atomic_assign_volatile(__a->__a_value, __value);
609 __a->__unlock();
610 return __old;
611}
612template <typename _Tp>
613_LIBCPP_HIDE_FROM_ABI
614_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
615 __a->__lock();
616 _Tp __old = __a->__a_value;
617 __a->__a_value = __value;
618 __a->__unlock();
619 return __old;
620}
621
622template <typename _Tp>
623_LIBCPP_HIDE_FROM_ABI
624bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
625 _Tp* __expected, _Tp __value, memory_order, memory_order) {
626 _Tp __temp;
627 __a->__lock();
628 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
629 bool __ret = (std::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
630 if(__ret)
631 __cxx_atomic_assign_volatile(__a->__a_value, __value);
632 else
633 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
634 __a->__unlock();
635 return __ret;
636}
637template <typename _Tp>
638_LIBCPP_HIDE_FROM_ABI
639bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
640 _Tp* __expected, _Tp __value, memory_order, memory_order) {
641 __a->__lock();
642 bool __ret = (std::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
643 if(__ret)
644 std::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
645 else
646 std::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
647 __a->__unlock();
648 return __ret;
649}
650
651template <typename _Tp>
652_LIBCPP_HIDE_FROM_ABI
653bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
654 _Tp* __expected, _Tp __value, memory_order, memory_order) {
655 _Tp __temp;
656 __a->__lock();
657 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
658 bool __ret = (std::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
659 if(__ret)
660 __cxx_atomic_assign_volatile(__a->__a_value, __value);
661 else
662 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
663 __a->__unlock();
664 return __ret;
665}
666template <typename _Tp>
667_LIBCPP_HIDE_FROM_ABI
668bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
669 _Tp* __expected, _Tp __value, memory_order, memory_order) {
670 __a->__lock();
671 bool __ret = (std::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
672 if(__ret)
673 std::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
674 else
675 std::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
676 __a->__unlock();
677 return __ret;
678}
679
680template <typename _Tp, typename _Td>
681_LIBCPP_HIDE_FROM_ABI
682_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
683 _Td __delta, memory_order) {
684 __a->__lock();
685 _Tp __old;
686 __cxx_atomic_assign_volatile(__old, __a->__a_value);
687 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
688 __a->__unlock();
689 return __old;
690}
691template <typename _Tp, typename _Td>
692_LIBCPP_HIDE_FROM_ABI
693_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
694 _Td __delta, memory_order) {
695 __a->__lock();
696 _Tp __old = __a->__a_value;
697 __a->__a_value += __delta;
698 __a->__unlock();
699 return __old;
700}
701
702template <typename _Tp, typename _Td>
703_LIBCPP_HIDE_FROM_ABI
704_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
705 ptrdiff_t __delta, memory_order) {
706 __a->__lock();
707 _Tp* __old;
708 __cxx_atomic_assign_volatile(__old, __a->__a_value);
709 __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
710 __a->__unlock();
711 return __old;
712}
713template <typename _Tp, typename _Td>
714_LIBCPP_HIDE_FROM_ABI
715_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
716 ptrdiff_t __delta, memory_order) {
717 __a->__lock();
718 _Tp* __old = __a->__a_value;
719 __a->__a_value += __delta;
720 __a->__unlock();
721 return __old;
722}
723
724template <typename _Tp, typename _Td>
725_LIBCPP_HIDE_FROM_ABI
726_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
727 _Td __delta, memory_order) {
728 __a->__lock();
729 _Tp __old;
730 __cxx_atomic_assign_volatile(__old, __a->__a_value);
731 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
732 __a->__unlock();
733 return __old;
734}
735template <typename _Tp, typename _Td>
736_LIBCPP_HIDE_FROM_ABI
737_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
738 _Td __delta, memory_order) {
739 __a->__lock();
740 _Tp __old = __a->__a_value;
741 __a->__a_value -= __delta;
742 __a->__unlock();
743 return __old;
744}
745
746template <typename _Tp>
747_LIBCPP_HIDE_FROM_ABI
748_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
749 _Tp __pattern, memory_order) {
750 __a->__lock();
751 _Tp __old;
752 __cxx_atomic_assign_volatile(__old, __a->__a_value);
753 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
754 __a->__unlock();
755 return __old;
756}
757template <typename _Tp>
758_LIBCPP_HIDE_FROM_ABI
759_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
760 _Tp __pattern, memory_order) {
761 __a->__lock();
762 _Tp __old = __a->__a_value;
763 __a->__a_value &= __pattern;
764 __a->__unlock();
765 return __old;
766}
767
768template <typename _Tp>
769_LIBCPP_HIDE_FROM_ABI
770_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
771 _Tp __pattern, memory_order) {
772 __a->__lock();
773 _Tp __old;
774 __cxx_atomic_assign_volatile(__old, __a->__a_value);
775 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
776 __a->__unlock();
777 return __old;
778}
779template <typename _Tp>
780_LIBCPP_HIDE_FROM_ABI
781_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
782 _Tp __pattern, memory_order) {
783 __a->__lock();
784 _Tp __old = __a->__a_value;
785 __a->__a_value |= __pattern;
786 __a->__unlock();
787 return __old;
788}
789
790template <typename _Tp>
791_LIBCPP_HIDE_FROM_ABI
792_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
793 _Tp __pattern, memory_order) {
794 __a->__lock();
795 _Tp __old;
796 __cxx_atomic_assign_volatile(__old, __a->__a_value);
797 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
798 __a->__unlock();
799 return __old;
800}
801template <typename _Tp>
802_LIBCPP_HIDE_FROM_ABI
803_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
804 _Tp __pattern, memory_order) {
805 __a->__lock();
806 _Tp __old = __a->__a_value;
807 __a->__a_value ^= __pattern;
808 __a->__unlock();
809 return __old;
810}
811
812template <typename _Tp,
813 typename _Base = typename conditional<__libcpp_is_always_lock_free<_Tp>::__value,
814 __cxx_atomic_base_impl<_Tp>,
815 __cxx_atomic_lock_impl<_Tp> >::type>
816#else
817template <typename _Tp,
818 typename _Base = __cxx_atomic_base_impl<_Tp> >
819#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
820struct __cxx_atomic_impl : public _Base {
821 static_assert(is_trivially_copyable<_Tp>::value,
822 "std::atomic<T> requires that 'T' be a trivially copyable type");
823
824 _LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default;
825 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT
826 : _Base(__value) {}
827};
828
829_LIBCPP_END_NAMESPACE_STD
830
831#endif // _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H
lib/libcxx/include/__atomic/fence.h created+38
......@@ -0,0 +1,38 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_FENCE_H
10#define _LIBCPP___ATOMIC_FENCE_H
11
12#include <__atomic/cxx_atomic_impl.h>
13#include <__atomic/memory_order.h>
14#include <__config>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22inline _LIBCPP_HIDE_FROM_ABI
23void
24atomic_thread_fence(memory_order __m) _NOEXCEPT
25{
26 __cxx_atomic_thread_fence(__m);
27}
28
29inline _LIBCPP_HIDE_FROM_ABI
30void
31atomic_signal_fence(memory_order __m) _NOEXCEPT
32{
33 __cxx_atomic_signal_fence(__m);
34}
35
36_LIBCPP_END_NAMESPACE_STD
37
38#endif // _LIBCPP___ATOMIC_FENCE_H
lib/libcxx/include/__atomic/is_always_lock_free.h created+28
......@@ -0,0 +1,28 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_IS_ALWAYS_LOCK_FREE_H
10#define _LIBCPP___ATOMIC_IS_ALWAYS_LOCK_FREE_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15# pragma GCC system_header
16#endif
17
18_LIBCPP_BEGIN_NAMESPACE_STD
19
20template <class _Tp>
21struct __libcpp_is_always_lock_free {
22 // __atomic_always_lock_free is available in all Standard modes
23 static const bool __value = __atomic_always_lock_free(sizeof(_Tp), 0);
24};
25
26_LIBCPP_END_NAMESPACE_STD
27
28#endif // _LIBCPP___ATOMIC_IS_ALWAYS_LOCK_FREE_H
lib/libcxx/include/__atomic/kill_dependency.h created+29
......@@ -0,0 +1,29 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_KILL_DEPENDENCY_H
10#define _LIBCPP___ATOMIC_KILL_DEPENDENCY_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15# pragma GCC system_header
16#endif
17
18_LIBCPP_BEGIN_NAMESPACE_STD
19
20template <class _Tp>
21_LIBCPP_HIDE_FROM_ABI
22_Tp kill_dependency(_Tp __y) _NOEXCEPT
23{
24 return __y;
25}
26
27_LIBCPP_END_NAMESPACE_STD
28
29#endif // _LIBCPP___ATOMIC_KILL_DEPENDENCY_H
lib/libcxx/include/__atomic/memory_order.h created+72
......@@ -0,0 +1,72 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_MEMORY_ORDER_H
10#define _LIBCPP___ATOMIC_MEMORY_ORDER_H
11
12#include <__config>
13#include <__type_traits/is_same.h>
14#include <__type_traits/underlying_type.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22// Figure out what the underlying type for `memory_order` would be if it were
23// declared as an unscoped enum (accounting for -fshort-enums). Use this result
24// to pin the underlying type in C++20.
25enum __legacy_memory_order {
26 __mo_relaxed,
27 __mo_consume,
28 __mo_acquire,
29 __mo_release,
30 __mo_acq_rel,
31 __mo_seq_cst
32};
33
34using __memory_order_underlying_t = underlying_type<__legacy_memory_order>::type;
35
36#if _LIBCPP_STD_VER >= 20
37
38enum class memory_order : __memory_order_underlying_t {
39 relaxed = __mo_relaxed,
40 consume = __mo_consume,
41 acquire = __mo_acquire,
42 release = __mo_release,
43 acq_rel = __mo_acq_rel,
44 seq_cst = __mo_seq_cst
45};
46
47static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
48 "unexpected underlying type for std::memory_order");
49
50inline constexpr auto memory_order_relaxed = memory_order::relaxed;
51inline constexpr auto memory_order_consume = memory_order::consume;
52inline constexpr auto memory_order_acquire = memory_order::acquire;
53inline constexpr auto memory_order_release = memory_order::release;
54inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
55inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
56
57#else
58
59enum memory_order {
60 memory_order_relaxed = __mo_relaxed,
61 memory_order_consume = __mo_consume,
62 memory_order_acquire = __mo_acquire,
63 memory_order_release = __mo_release,
64 memory_order_acq_rel = __mo_acq_rel,
65 memory_order_seq_cst = __mo_seq_cst,
66};
67
68#endif // _LIBCPP_STD_VER >= 20
69
70_LIBCPP_END_NAMESPACE_STD
71
72#endif // _LIBCPP___ATOMIC_MEMORY_ORDER_H
lib/libcxx/include/__availability+144-58
......@@ -39,17 +39,23 @@
3939//
4040// This mechanism is general in nature, and any vendor can add their markup to
4141// the library (see below). Whenever a new feature is added that requires support
42// in the shared library, a macro should be added below to mark this feature
43// as unavailable. When vendors decide to ship the feature as part of their
44// shared library, they can update the markup appropriately.
42// in the shared library, two macros are added below to allow marking the feature
43// as unavailable:
44// 1. A macro named `_LIBCPP_AVAILABILITY_HAS_NO_<feature>` which must be defined
45// exactly when compiling for a target that doesn't support the feature.
46// 2. A macro named `_LIBCPP_AVAILABILITY_<feature>`, which must always be defined
47// and must expand to the proper availability attribute for the platform.
48//
49// When vendors decide to ship the feature as part of their shared library, they
50// can update these macros appropriately for their platform, and the library will
51// use those to provide an optimal user experience.
4552//
4653// Furthermore, many features in the standard library have corresponding
47// feature-test macros. When a feature is made unavailable on some deployment
48// target, a macro should be defined to signal that it is unavailable. That
49// macro can then be picked up when feature-test macros are generated (see
50// generate_feature_test_macro_components.py) to make sure that feature-test
51// macros don't announce a feature as being implemented if it has been marked
52// as unavailable.
54// feature-test macros. The `_LIBCPP_AVAILABILITY_HAS_NO_<feature>` macros
55// are checked by the corresponding feature-test macros generated by
56// generate_feature_test_macro_components.py to ensure that the library
57// doesn't announce a feature as being implemented if it is unavailable on
58// the deployment target.
5359//
5460// Note that this mechanism is disabled by default in the "upstream" libc++.
5561// Availability annotations are only meaningful when shipping libc++ inside
......@@ -83,9 +89,8 @@
8389
8490 // This controls the availability of std::shared_mutex and std::shared_timed_mutex,
8591 // which were added to the dylib later.
92// # define _LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX
8693# define _LIBCPP_AVAILABILITY_SHARED_MUTEX
87// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex
88// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex
8994
9095 // These macros control the availability of std::bad_optional_access and
9196 // other exception types. These were put in the shared library to prevent
......@@ -95,16 +100,23 @@
95100 // Note that when exceptions are disabled, the methods that normally throw
96101 // these exceptions can be used even on older deployment targets, but those
97102 // methods will abort instead of throwing.
103// # define _LIBCPP_AVAILABILITY_HAS_NO_BAD_OPTIONAL_ACCESS
98104# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
105
106// # define _LIBCPP_AVAILABILITY_HAS_NO_BAD_VARIANT_ACCESS
99107# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
108
109// # define _LIBCPP_AVAILABILITY_HAS_NO_BAD_ANY_CAST
100110# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST
101111
102112 // This controls the availability of std::uncaught_exceptions().
113// # define _LIBCPP_AVAILABILITY_HAS_NO_UNCAUGHT_EXCEPTIONS
103114# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS
104115
105116 // This controls the availability of the sized version of ::operator delete,
106117 // ::operator delete[], and their align_val_t variants, which were all added
107118 // in C++17, and hence not present in early dylibs.
119// # define _LIBCPP_AVAILABILITY_HAS_NO_SIZED_NEW_DELETE
108120# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE
109121
110122 // This controls the availability of the std::future_error exception.
......@@ -112,73 +124,83 @@
112124 // Note that when exceptions are disabled, the methods that normally throw
113125 // std::future_error can be used even on older deployment targets, but those
114126 // methods will abort instead of throwing.
127// # define _LIBCPP_AVAILABILITY_HAS_NO_FUTURE_ERROR
115128# define _LIBCPP_AVAILABILITY_FUTURE_ERROR
116129
117130 // This controls the availability of std::type_info's vtable.
118131 // I can't imagine how using std::type_info can work at all if
119132 // this isn't supported.
133// # define _LIBCPP_AVAILABILITY_HAS_NO_TYPEINFO_VTABLE
120134# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE
121135
122136 // This controls the availability of std::locale::category members
123137 // (e.g. std::locale::collate), which are defined in the dylib.
138// # define _LIBCPP_AVAILABILITY_HAS_NO_LOCALE_CATEGORY
124139# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
125140
126141 // This controls the availability of atomic operations on std::shared_ptr
127142 // (e.g. `std::atomic_store(std::shared_ptr)`), which require a shared
128143 // lock table located in the dylib.
144// # define _LIBCPP_AVAILABILITY_HAS_NO_ATOMIC_SHARED_PTR
129145# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
130146
131147 // These macros control the availability of all parts of <filesystem> that
132148 // depend on something in the dylib.
133# define _LIBCPP_AVAILABILITY_FILESYSTEM
134# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
135# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP
136// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
149// # define _LIBCPP_AVAILABILITY_HAS_NO_FILESYSTEM_LIBRARY
150# define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
151# define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
152# define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
137153
138154 // This controls the availability of floating-point std::to_chars functions.
139155 // These overloads were added later than the integer overloads.
156// # define _LIBCPP_AVAILABILITY_HAS_NO_TO_CHARS_FLOATING_POINT
140157# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT
141158
142159 // This controls the availability of the C++20 synchronization library,
143160 // which requires shared library support for various operations
144161 // (see libcxx/src/atomic.cpp). This includes <barier>, <latch>,
145162 // <semaphore>, and notification functions on std::atomic.
163// # define _LIBCPP_AVAILABILITY_HAS_NO_SYNC
146164# define _LIBCPP_AVAILABILITY_SYNC
147// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait
148// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier
149// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch
150// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore
151
152 // This controls the availability of the C++20 format library.
153 // The library is in development and not ABI stable yet. P2216 is
154 // retroactively accepted in C++20. This paper contains ABI breaking
155 // changes.
156# define _LIBCPP_AVAILABILITY_FORMAT
157// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
158165
159166 // This controls whether the library claims to provide a default verbose
160167 // termination function, and consequently whether the headers will try
161168 // to use it when the mechanism isn't overriden at compile-time.
162// # define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
169// # define _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT
170# define _LIBCPP_AVAILABILITY_VERBOSE_ABORT
171
172 // This controls the availability of the C++17 std::pmr library,
173 // which is implemented in large part in the built library.
174// # define _LIBCPP_AVAILABILITY_HAS_NO_PMR
175# define _LIBCPP_AVAILABILITY_PMR
163176
164177#elif defined(__APPLE__)
165178
166# define _LIBCPP_AVAILABILITY_SHARED_MUTEX \
167 __attribute__((availability(macos,strict,introduced=10.12))) \
168 __attribute__((availability(ios,strict,introduced=10.0))) \
169 __attribute__((availability(tvos,strict,introduced=10.0))) \
170 __attribute__((availability(watchos,strict,introduced=3.0)))
179 // shared_mutex and shared_timed_mutex
171180# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \
172181 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
173182 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \
174183 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
175# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex
176# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex
184# define _LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX
177185# endif
186# define _LIBCPP_AVAILABILITY_SHARED_MUTEX \
187 __attribute__((availability(macos,strict,introduced=10.12))) \
188 __attribute__((availability(ios,strict,introduced=10.0))) \
189 __attribute__((availability(tvos,strict,introduced=10.0))) \
190 __attribute__((availability(watchos,strict,introduced=3.0)))
178191
192 // bad_optional_access, bad_variant_access and bad_any_cast
179193 // Note: bad_optional_access & friends were not introduced in the matching
180194 // macOS and iOS versions, so the version mismatch between macOS and others
181195 // is intended.
196# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101300) || \
197 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 120000) || \
198 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 120000) || \
199 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 50000)
200# define _LIBCPP_AVAILABILITY_HAS_NO_BAD_OPTIONAL_ACCESS
201# define _LIBCPP_AVAILABILITY_HAS_NO_BAD_VARIANT_ACCESS
202# define _LIBCPP_AVAILABILITY_HAS_NO_BAD_ANY_CAST
203# endif
182204# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \
183205 __attribute__((availability(macos,strict,introduced=10.13))) \
184206 __attribute__((availability(ios,strict,introduced=12.0))) \
......@@ -189,78 +211,142 @@
189211# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \
190212 _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
191213
214 // uncaught_exceptions
215# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \
216 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
217 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \
218 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
219# define _LIBCPP_AVAILABILITY_HAS_NO_UNCAUGHT_EXCEPTIONS
220# endif
192221# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \
193222 __attribute__((availability(macos,strict,introduced=10.12))) \
194223 __attribute__((availability(ios,strict,introduced=10.0))) \
195224 __attribute__((availability(tvos,strict,introduced=10.0))) \
196225 __attribute__((availability(watchos,strict,introduced=3.0)))
197226
227 // sized operator new and sized operator delete
228# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \
229 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
230 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \
231 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
232# define _LIBCPP_AVAILABILITY_HAS_NO_SIZED_NEW_DELETE
233# endif
198234# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \
199235 __attribute__((availability(macos,strict,introduced=10.12))) \
200236 __attribute__((availability(ios,strict,introduced=10.0))) \
201237 __attribute__((availability(tvos,strict,introduced=10.0))) \
202238 __attribute__((availability(watchos,strict,introduced=3.0)))
203239
240 // future_error
241# if (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 60000)
242# define _LIBCPP_AVAILABILITY_HAS_NO_FUTURE_ERROR
243# endif
204244# define _LIBCPP_AVAILABILITY_FUTURE_ERROR \
205245 __attribute__((availability(ios,strict,introduced=6.0)))
206246
247 // type_info's vtable
248# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 100900) || \
249 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000)
250# define _LIBCPP_AVAILABILITY_HAS_NO_TYPEINFO_VTABLE
251# endif
207252# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \
208253 __attribute__((availability(macos,strict,introduced=10.9))) \
209254 __attribute__((availability(ios,strict,introduced=7.0)))
210255
256 // locale::category
257# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 100900) || \
258 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000)
259# define _LIBCPP_AVAILABILITY_HAS_NO_LOCALE_CATEGORY
260# endif
211261# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \
212262 __attribute__((availability(macos,strict,introduced=10.9))) \
213263 __attribute__((availability(ios,strict,introduced=7.0)))
214264
265 // atomic operations on shared_ptr
266# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 100900) || \
267 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000)
268# define _LIBCPP_AVAILABILITY_HAS_NO_ATOMIC_SHARED_PTR
269# endif
215270# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \
216271 __attribute__((availability(macos,strict,introduced=10.9))) \
217272 __attribute__((availability(ios,strict,introduced=7.0)))
218273
219# define _LIBCPP_AVAILABILITY_FILESYSTEM \
274 // <filesystem>
275# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \
276 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
277 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) || \
278 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000)
279# define _LIBCPP_AVAILABILITY_HAS_NO_FILESYSTEM_LIBRARY
280# endif
281# define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY \
220282 __attribute__((availability(macos,strict,introduced=10.15))) \
221283 __attribute__((availability(ios,strict,introduced=13.0))) \
222284 __attribute__((availability(tvos,strict,introduced=13.0))) \
223285 __attribute__((availability(watchos,strict,introduced=6.0)))
224# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH \
286# define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH \
225287 _Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \
226288 _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \
227289 _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \
228290 _Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))")
229# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP \
291# define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP \
230292 _Pragma("clang attribute pop") \
231293 _Pragma("clang attribute pop") \
232294 _Pragma("clang attribute pop") \
233295 _Pragma("clang attribute pop")
234# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \
235 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
236 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) || \
237 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000)
238# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
239# endif
240296
297 // std::to_chars(floating-point)
298# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 130300) || \
299 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 160300) || \
300 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 160300) || \
301 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 90300)
302# define _LIBCPP_AVAILABILITY_HAS_NO_TO_CHARS_FLOATING_POINT
303# endif
241304# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT \
242 __attribute__((unavailable))
305 __attribute__((availability(macos,strict,introduced=13.3))) \
306 __attribute__((availability(ios,strict,introduced=16.3))) \
307 __attribute__((availability(tvos,strict,introduced=16.3))) \
308 __attribute__((availability(watchos,strict,introduced=9.3)))
243309
244# define _LIBCPP_AVAILABILITY_SYNC \
245 __attribute__((availability(macos,strict,introduced=11.0))) \
246 __attribute__((availability(ios,strict,introduced=14.0))) \
247 __attribute__((availability(tvos,strict,introduced=14.0))) \
248 __attribute__((availability(watchos,strict,introduced=7.0)))
310 // c++20 synchronization library
249311# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) || \
250312 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \
251313 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 140000) || \
252314 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 70000)
253# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait
254# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier
255# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch
256# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore
315# define _LIBCPP_AVAILABILITY_HAS_NO_SYNC
257316# endif
317# define _LIBCPP_AVAILABILITY_SYNC \
318 __attribute__((availability(macos,strict,introduced=11.0))) \
319 __attribute__((availability(ios,strict,introduced=14.0))) \
320 __attribute__((availability(tvos,strict,introduced=14.0))) \
321 __attribute__((availability(watchos,strict,introduced=7.0)))
258322
259# define _LIBCPP_AVAILABILITY_FORMAT \
323 // __libcpp_verbose_abort
324# if 1 // TODO: Update once this is released
325# define _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT
326# endif
327# define _LIBCPP_AVAILABILITY_VERBOSE_ABORT \
260328 __attribute__((unavailable))
261# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
262329
263# define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
330 // std::pmr
331# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 140000) || \
332 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 170000) || \
333 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 170000) || \
334 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 100000)
335# define _LIBCPP_AVAILABILITY_HAS_NO_PMR
336# endif
337// TODO: Enable std::pmr markup once https://github.com/llvm/llvm-project/issues/40340 has been fixed
338// Until then, it is possible for folks to try to use `std::pmr` when back-deploying to targets that don't support
339// it and it'll be a load-time error, but we don't have a good alternative because the library won't compile if we
340// use availability annotations until that bug has been fixed.
341# if 0
342# define _LIBCPP_AVAILABILITY_PMR \
343 __attribute__((availability(macos, strict, introduced = 14.0))) \
344 __attribute__((availability(ios, strict, introduced = 17.0))) \
345 __attribute__((availability(tvos, strict, introduced = 17.0))) \
346 __attribute__((availability(watchos, strict, introduced = 10.0)))
347# else
348# define _LIBCPP_AVAILABILITY_PMR
349# endif
264350
265351#else
266352
......@@ -270,10 +356,10 @@
270356
271357#endif
272358
273// Define availability attributes that depend on _LIBCPP_NO_EXCEPTIONS.
359// Define availability attributes that depend on _LIBCPP_HAS_NO_EXCEPTIONS.
274360// Those are defined in terms of the availability attributes above, and
275361// should not be vendor-specific.
276#if defined(_LIBCPP_NO_EXCEPTIONS)
362#if defined(_LIBCPP_HAS_NO_EXCEPTIONS)
277363# define _LIBCPP_AVAILABILITY_FUTURE
278364# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
279365# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
lib/libcxx/include/__bit/bit_cast.h+2-2
......@@ -19,7 +19,7 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 17
22#if _LIBCPP_STD_VER >= 20
2323
2424template <class _ToType, class _FromType>
2525 requires(sizeof(_ToType) == sizeof(_FromType) &&
......@@ -29,7 +29,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _Fr
2929 return __builtin_bit_cast(_ToType, __from);
3030}
3131
32#endif // _LIBCPP_STD_VER > 17
32#endif // _LIBCPP_STD_VER >= 20
3333
3434_LIBCPP_END_NAMESPACE_STD
3535
lib/libcxx/include/__bit/bit_ceil.h+4-4
......@@ -24,18 +24,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2424#if _LIBCPP_STD_VER >= 20
2525
2626template <__libcpp_unsigned_integer _Tp>
27_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept {
27_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept {
2828 if (__t < 2)
2929 return 1;
3030 const unsigned __n = numeric_limits<_Tp>::digits - std::countl_zero((_Tp)(__t - 1u));
31 _LIBCPP_ASSERT(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil");
31 _LIBCPP_ASSERT_UNCATEGORIZED(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil");
3232
3333 if constexpr (sizeof(_Tp) >= sizeof(unsigned))
3434 return _Tp{1} << __n;
3535 else {
3636 const unsigned __extra = numeric_limits<unsigned>::digits - numeric_limits<_Tp>::digits;
37 const unsigned __retVal = 1u << (__n + __extra);
38 return (_Tp)(__retVal >> __extra);
37 const unsigned __ret_val = 1u << (__n + __extra);
38 return (_Tp)(__ret_val >> __extra);
3939 }
4040}
4141
lib/libcxx/include/__bit/bit_floor.h+1-1
......@@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2323#if _LIBCPP_STD_VER >= 20
2424
2525template <__libcpp_unsigned_integer _Tp>
26_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept {
26_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept {
2727 return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t);
2828}
2929
lib/libcxx/include/__bit/bit_width.h+1-1
......@@ -22,7 +22,7 @@
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
2424template <__libcpp_unsigned_integer _Tp>
25_LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept {
25_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept {
2626 return __t == 0 ? 0 : std::__bit_log2(__t) + 1;
2727}
2828
lib/libcxx/include/__bit/byteswap.h+3-4
......@@ -13,7 +13,6 @@
1313#include <__concepts/arithmetic.h>
1414#include <__config>
1515#include <cstdint>
16#include <cstdlib>
1716
1817#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1918# pragma GCC system_header
......@@ -21,10 +20,10 @@
2120
2221_LIBCPP_BEGIN_NAMESPACE_STD
2322
24#if _LIBCPP_STD_VER > 20
23#if _LIBCPP_STD_VER >= 23
2524
2625template <integral _Tp>
27_LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept {
26_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept {
2827
2928 if constexpr (sizeof(_Tp) == 1) {
3029 return __val;
......@@ -48,7 +47,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept {
4847 }
4948}
5049
51#endif // _LIBCPP_STD_VER > 20
50#endif // _LIBCPP_STD_VER >= 23
5251
5352_LIBCPP_END_NAMESPACE_STD
5453
lib/libcxx/include/__bit/countl.h+5-5
......@@ -24,13 +24,13 @@ _LIBCPP_PUSH_MACROS
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
27inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
27_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
2828int __libcpp_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); }
2929
30inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
30_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
3131int __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); }
3232
33inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
33_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
3434int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); }
3535
3636# ifndef _LIBCPP_HAS_NO_INT128
......@@ -86,12 +86,12 @@ int __countl_zero(_Tp __t) _NOEXCEPT
8686#if _LIBCPP_STD_VER >= 20
8787
8888template <__libcpp_unsigned_integer _Tp>
89_LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept {
89_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept {
9090 return std::__countl_zero(__t);
9191}
9292
9393template <__libcpp_unsigned_integer _Tp>
94_LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept {
94_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept {
9595 return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
9696}
9797
lib/libcxx/include/__bit/countr.h+5-5
......@@ -23,19 +23,19 @@ _LIBCPP_PUSH_MACROS
2323
2424_LIBCPP_BEGIN_NAMESPACE_STD
2525
26inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
26_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
2727int __libcpp_ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); }
2828
29inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
29_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
3030int __libcpp_ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); }
3131
32inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
32_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
3333int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); }
3434
3535#if _LIBCPP_STD_VER >= 20
3636
3737template <__libcpp_unsigned_integer _Tp>
38_LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept {
38_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept {
3939 if (__t == 0)
4040 return numeric_limits<_Tp>::digits;
4141
......@@ -57,7 +57,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept {
5757}
5858
5959template <__libcpp_unsigned_integer _Tp>
60_LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {
60_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {
6161 return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
6262}
6363
lib/libcxx/include/__bit/has_single_bit.h+1-1
......@@ -24,7 +24,7 @@ _LIBCPP_PUSH_MACROS
2424_LIBCPP_BEGIN_NAMESPACE_STD
2525
2626template <__libcpp_unsigned_integer _Tp>
27_LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
27_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
2828 return __t != 0 && (((__t & (__t - 1)) == 0));
2929}
3030
lib/libcxx/include/__bit/popcount.h+1-1
......@@ -35,7 +35,7 @@ int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popco
3535#if _LIBCPP_STD_VER >= 20
3636
3737template <__libcpp_unsigned_integer _Tp>
38_LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept {
38_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept {
3939 if (sizeof(_Tp) <= sizeof(unsigned int))
4040 return std::__libcpp_popcount(static_cast<unsigned int>(__t));
4141 else if (sizeof(_Tp) <= sizeof(unsigned long))
lib/libcxx/include/__bit/rotate.h+2-2
......@@ -34,7 +34,7 @@ _Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT
3434#if _LIBCPP_STD_VER >= 20
3535
3636template <__libcpp_unsigned_integer _Tp>
37_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept {
37[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept {
3838 const unsigned int __dig = numeric_limits<_Tp>::digits;
3939 if ((__cnt % __dig) == 0)
4040 return __t;
......@@ -42,7 +42,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept {
4242}
4343
4444template <__libcpp_unsigned_integer _Tp>
45_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept {
45[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept {
4646 return std::__rotr(__t, __cnt);
4747}
4848
lib/libcxx/include/__bit_reference+29-26
......@@ -19,8 +19,9 @@
1919#include <__iterator/iterator_traits.h>
2020#include <__memory/construct_at.h>
2121#include <__memory/pointer_traits.h>
22#include <__type_traits/conditional.h>
23#include <__utility/swap.h>
2224#include <cstring>
23#include <type_traits>
2425
2526#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2627# pragma GCC system_header
......@@ -75,7 +76,7 @@ public:
7576 return *this;
7677 }
7778
78#if _LIBCPP_STD_VER > 20
79#if _LIBCPP_STD_VER >= 23
7980 _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept {
8081 if (__x)
8182 *__seg_ |= __mask_;
......@@ -155,6 +156,8 @@ class __bit_const_reference
155156 friend typename _Cp::__self;
156157 friend class __bit_iterator<_Cp, true>;
157158public:
159 using __container = typename _Cp::__self;
160
158161 _LIBCPP_INLINE_VISIBILITY
159162 __bit_const_reference(const __bit_const_reference&) = default;
160163
......@@ -728,12 +731,12 @@ move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsCons
728731
729732// swap_ranges
730733
731template <class __C1, class __C2>
732_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false>
733__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
734 __bit_iterator<__C2, false> __result)
734template <class _Cl, class _Cr>
735_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false>
736__swap_ranges_aligned(__bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last,
737 __bit_iterator<_Cr, false> __result)
735738{
736 typedef __bit_iterator<__C1, false> _I1;
739 typedef __bit_iterator<_Cl, false> _I1;
737740 typedef typename _I1::difference_type difference_type;
738741 typedef typename _I1::__storage_type __storage_type;
739742 const int __bits_per_word = _I1::__bits_per_word;
......@@ -778,12 +781,12 @@ __swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1,
778781 return __result;
779782}
780783
781template <class __C1, class __C2>
782_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false>
783__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
784 __bit_iterator<__C2, false> __result)
784template <class _Cl, class _Cr>
785_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false>
786__swap_ranges_unaligned(__bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last,
787 __bit_iterator<_Cr, false> __result)
785788{
786 typedef __bit_iterator<__C1, false> _I1;
789 typedef __bit_iterator<_Cl, false> _I1;
787790 typedef typename _I1::difference_type difference_type;
788791 typedef typename _I1::__storage_type __storage_type;
789792 const int __bits_per_word = _I1::__bits_per_word;
......@@ -878,11 +881,11 @@ __swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1
878881 return __result;
879882}
880883
881template <class __C1, class __C2>
884template <class _Cl, class _Cr>
882885inline _LIBCPP_INLINE_VISIBILITY
883__bit_iterator<__C2, false>
884swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1,
885 __bit_iterator<__C2, false> __first2)
886__bit_iterator<_Cr, false>
887swap_ranges(__bit_iterator<_Cl, false> __first1, __bit_iterator<_Cl, false> __last1,
888 __bit_iterator<_Cr, false> __first2)
886889{
887890 if (__first1.__ctz_ == __first2.__ctz_)
888891 return _VSTD::__swap_ranges_aligned(__first1, __last1, __first2);
......@@ -1135,7 +1138,7 @@ private:
11351138
11361139public:
11371140 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT
1138#if _LIBCPP_STD_VER > 11
1141#if _LIBCPP_STD_VER >= 14
11391142 : __seg_(nullptr), __ctz_(0)
11401143#endif
11411144 {}
......@@ -1311,15 +1314,15 @@ private:
13111314 friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first,
13121315 __bit_iterator<_Dp, _IC> __last,
13131316 __bit_iterator<_Dp, false> __result);
1314 template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>,
1315 __bit_iterator<__C1, false>,
1316 __bit_iterator<__C2, false>);
1317 template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>,
1318 __bit_iterator<__C1, false>,
1319 __bit_iterator<__C2, false>);
1320 template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>,
1321 __bit_iterator<__C1, false>,
1322 __bit_iterator<__C2, false>);
1317 template <class _Cl, class _Cr>friend __bit_iterator<_Cr, false> __swap_ranges_aligned(__bit_iterator<_Cl, false>,
1318 __bit_iterator<_Cl, false>,
1319 __bit_iterator<_Cr, false>);
1320 template <class _Cl, class _Cr>friend __bit_iterator<_Cr, false> __swap_ranges_unaligned(__bit_iterator<_Cl, false>,
1321 __bit_iterator<_Cl, false>,
1322 __bit_iterator<_Cr, false>);
1323 template <class _Cl, class _Cr>friend __bit_iterator<_Cr, false> swap_ranges(__bit_iterator<_Cl, false>,
1324 __bit_iterator<_Cl, false>,
1325 __bit_iterator<_Cr, false>);
13231326 template <class _Dp>
13241327 _LIBCPP_CONSTEXPR_SINCE_CXX20
13251328 friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>,
lib/libcxx/include/__bsd_locale_defaults.h deleted-36
......@@ -1,36 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9// The BSDs have lots of *_l functions. We don't want to define those symbols
10// on other platforms though, for fear of conflicts with user code. So here,
11// we will define the mapping from an internal macro to the real BSD symbol.
12//===----------------------------------------------------------------------===//
13
14#ifndef _LIBCPP___BSD_LOCALE_DEFAULTS_H
15#define _LIBCPP___BSD_LOCALE_DEFAULTS_H
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18# pragma GCC system_header
19#endif
20
21#define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc)
22#define __libcpp_btowc_l(ch, loc) btowc_l(ch, loc)
23#define __libcpp_wctob_l(wch, loc) wctob_l(wch, loc)
24#define __libcpp_wcsnrtombs_l(dst, src, nwc, len, ps, loc) wcsnrtombs_l(dst, src, nwc, len, ps, loc)
25#define __libcpp_wcrtomb_l(src, wc, ps, loc) wcrtomb_l(src, wc, ps, loc)
26#define __libcpp_mbsnrtowcs_l(dst, src, nms, len, ps, loc) mbsnrtowcs_l(dst, src, nms, len, ps, loc)
27#define __libcpp_mbrtowc_l(pwc, s, n, ps, l) mbrtowc_l(pwc, s, n, ps, l)
28#define __libcpp_mbtowc_l(pwc, pmb, max, l) mbtowc_l(pwc, pmb, max, l)
29#define __libcpp_mbrlen_l(s, n, ps, l) mbrlen_l(s, n, ps, l)
30#define __libcpp_localeconv_l(l) localeconv_l(l)
31#define __libcpp_mbsrtowcs_l(dest, src, len, ps, l) mbsrtowcs_l(dest, src, len, ps, l)
32#define __libcpp_snprintf_l(...) snprintf_l(__VA_ARGS__)
33#define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__)
34#define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__)
35
36#endif // _LIBCPP___BSD_LOCALE_DEFAULTS_H
lib/libcxx/include/__bsd_locale_fallbacks.h deleted-142
......@@ -1,142 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9// The BSDs have lots of *_l functions. This file provides reimplementations
10// of those functions for non-BSD platforms.
11//===----------------------------------------------------------------------===//
12
13#ifndef _LIBCPP___BSD_LOCALE_FALLBACKS_H
14#define _LIBCPP___BSD_LOCALE_FALLBACKS_H
15
16#include <stdarg.h>
17#include <stdlib.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25inline _LIBCPP_INLINE_VISIBILITY
26decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l)
27{
28 __libcpp_locale_guard __current(__l);
29 return MB_CUR_MAX;
30}
31
32#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
33inline _LIBCPP_INLINE_VISIBILITY
34wint_t __libcpp_btowc_l(int __c, locale_t __l)
35{
36 __libcpp_locale_guard __current(__l);
37 return btowc(__c);
38}
39
40inline _LIBCPP_INLINE_VISIBILITY
41int __libcpp_wctob_l(wint_t __c, locale_t __l)
42{
43 __libcpp_locale_guard __current(__l);
44 return wctob(__c);
45}
46
47inline _LIBCPP_INLINE_VISIBILITY
48size_t __libcpp_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
49 size_t __len, mbstate_t *__ps, locale_t __l)
50{
51 __libcpp_locale_guard __current(__l);
52 return wcsnrtombs(__dest, __src, __nwc, __len, __ps);
53}
54
55inline _LIBCPP_INLINE_VISIBILITY
56size_t __libcpp_wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)
57{
58 __libcpp_locale_guard __current(__l);
59 return wcrtomb(__s, __wc, __ps);
60}
61
62inline _LIBCPP_INLINE_VISIBILITY
63size_t __libcpp_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
64 size_t __len, mbstate_t *__ps, locale_t __l)
65{
66 __libcpp_locale_guard __current(__l);
67 return mbsnrtowcs(__dest, __src, __nms, __len, __ps);
68}
69
70inline _LIBCPP_INLINE_VISIBILITY
71size_t __libcpp_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
72 mbstate_t *__ps, locale_t __l)
73{
74 __libcpp_locale_guard __current(__l);
75 return mbrtowc(__pwc, __s, __n, __ps);
76}
77
78inline _LIBCPP_INLINE_VISIBILITY
79int __libcpp_mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)
80{
81 __libcpp_locale_guard __current(__l);
82 return mbtowc(__pwc, __pmb, __max);
83}
84
85inline _LIBCPP_INLINE_VISIBILITY
86size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)
87{
88 __libcpp_locale_guard __current(__l);
89 return mbrlen(__s, __n, __ps);
90}
91#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
92
93inline _LIBCPP_INLINE_VISIBILITY
94lconv *__libcpp_localeconv_l(locale_t __l)
95{
96 __libcpp_locale_guard __current(__l);
97 return localeconv();
98}
99
100#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
101inline _LIBCPP_INLINE_VISIBILITY
102size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
103 mbstate_t *__ps, locale_t __l)
104{
105 __libcpp_locale_guard __current(__l);
106 return mbsrtowcs(__dest, __src, __len, __ps);
107}
108#endif
109
110inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5)
111int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) {
112 va_list __va;
113 va_start(__va, __format);
114 __libcpp_locale_guard __current(__l);
115 int __res = vsnprintf(__s, __n, __format, __va);
116 va_end(__va);
117 return __res;
118}
119
120inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
121int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) {
122 va_list __va;
123 va_start(__va, __format);
124 __libcpp_locale_guard __current(__l);
125 int __res = vasprintf(__s, __format, __va);
126 va_end(__va);
127 return __res;
128}
129
130inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4)
131int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {
132 va_list __va;
133 va_start(__va, __format);
134 __libcpp_locale_guard __current(__l);
135 int __res = vsscanf(__s, __format, __va);
136 va_end(__va);
137 return __res;
138}
139
140_LIBCPP_END_NAMESPACE_STD
141
142#endif // _LIBCPP___BSD_LOCALE_FALLBACKS_H
lib/libcxx/include/__charconv/chars_format.h+16-29
......@@ -19,58 +19,45 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 14
23
24enum class _LIBCPP_ENUM_VIS chars_format
25{
26 scientific = 0x1,
27 fixed = 0x2,
28 hex = 0x4,
29 general = fixed | scientific
30};
31
32inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format
33operator~(chars_format __x) {
34 return chars_format(~_VSTD::__to_underlying(__x));
22#if _LIBCPP_STD_VER >= 17
23
24enum class _LIBCPP_ENUM_VIS chars_format { scientific = 0x1, fixed = 0x2, hex = 0x4, general = fixed | scientific };
25
26inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator~(chars_format __x) {
27 return chars_format(~std::__to_underlying(__x));
3528}
3629
37inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format
38operator&(chars_format __x, chars_format __y) {
39 return chars_format(_VSTD::__to_underlying(__x) &
40 _VSTD::__to_underlying(__y));
30inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator&(chars_format __x, chars_format __y) {
31 return chars_format(std::__to_underlying(__x) & std::__to_underlying(__y));
4132}
4233
43inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format
44operator|(chars_format __x, chars_format __y) {
45 return chars_format(_VSTD::__to_underlying(__x) |
46 _VSTD::__to_underlying(__y));
34inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator|(chars_format __x, chars_format __y) {
35 return chars_format(std::__to_underlying(__x) | std::__to_underlying(__y));
4736}
4837
49inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format
50operator^(chars_format __x, chars_format __y) {
51 return chars_format(_VSTD::__to_underlying(__x) ^
52 _VSTD::__to_underlying(__y));
38inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator^(chars_format __x, chars_format __y) {
39 return chars_format(std::__to_underlying(__x) ^ std::__to_underlying(__y));
5340}
5441
55inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format&
42inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format&
5643operator&=(chars_format& __x, chars_format __y) {
5744 __x = __x & __y;
5845 return __x;
5946}
6047
61inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format&
48inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format&
6249operator|=(chars_format& __x, chars_format __y) {
6350 __x = __x | __y;
6451 return __x;
6552}
6653
67inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format&
54inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format&
6855operator^=(chars_format& __x, chars_format __y) {
6956 __x = __x ^ __y;
7057 return __x;
7158}
7259
73#endif // _LIBCPP_STD_VER > 14
60#endif // _LIBCPP_STD_VER >= 17
7461
7562_LIBCPP_END_NAMESPACE_STD
7663
lib/libcxx/include/__charconv/from_chars_integral.h created+239
......@@ -0,0 +1,239 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___CHARCONV_FROM_CHARS_INTEGRAL_H
11#define _LIBCPP___CHARCONV_FROM_CHARS_INTEGRAL_H
12
13#include <__algorithm/copy_n.h>
14#include <__charconv/from_chars_result.h>
15#include <__charconv/traits.h>
16#include <__config>
17#include <__memory/addressof.h>
18#include <__system_error/errc.h>
19#include <__type_traits/enable_if.h>
20#include <__type_traits/integral_constant.h>
21#include <__type_traits/is_integral.h>
22#include <__type_traits/is_unsigned.h>
23#include <__type_traits/make_unsigned.h>
24#include <limits>
25
26#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27# pragma GCC system_header
28#endif
29
30_LIBCPP_PUSH_MACROS
31#include <__undef_macros>
32
33_LIBCPP_BEGIN_NAMESPACE_STD
34
35#if _LIBCPP_STD_VER >= 17
36
37from_chars_result from_chars(const char*, const char*, bool, int = 10) = delete;
38
39template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
40inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
41__sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args) {
42 using __tl = numeric_limits<_Tp>;
43 decltype(std::__to_unsigned_like(__value)) __x;
44
45 bool __neg = (__first != __last && *__first == '-');
46 auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...);
47 switch (__r.ec) {
48 case errc::invalid_argument:
49 return {__first, __r.ec};
50 case errc::result_out_of_range:
51 return __r;
52 default:
53 break;
54 }
55
56 if (__neg) {
57 if (__x <= std::__complement(std::__to_unsigned_like(__tl::min()))) {
58 __x = std::__complement(__x);
59 std::copy_n(std::addressof(__x), 1, std::addressof(__value));
60 return __r;
61 }
62 } else {
63 if (__x <= std::__to_unsigned_like(__tl::max())) {
64 __value = __x;
65 return __r;
66 }
67 }
68
69 return {__r.ptr, errc::result_out_of_range};
70}
71
72template <typename _Tp>
73inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool __in_pattern(_Tp __c) {
74 return '0' <= __c && __c <= '9';
75}
76
77struct _LIBCPP_HIDDEN __in_pattern_result {
78 bool __ok;
79 int __val;
80
81 explicit _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI operator bool() const { return __ok; }
82};
83
84template <typename _Tp>
85inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __in_pattern_result __in_pattern(_Tp __c, int __base) {
86 if (__base <= 10)
87 return {'0' <= __c && __c < '0' + __base, __c - '0'};
88 else if (std::__in_pattern(__c))
89 return {true, __c - '0'};
90 else if ('a' <= __c && __c < 'a' + __base - 10)
91 return {true, __c - 'a' + 10};
92 else
93 return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10};
94}
95
96template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
97inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
98__subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args) {
99 auto __find_non_zero = [](_It __firstit, _It __lastit) {
100 for (; __firstit != __lastit; ++__firstit)
101 if (*__firstit != '0')
102 break;
103 return __firstit;
104 };
105
106 auto __p = __find_non_zero(__first, __last);
107 if (__p == __last || !std::__in_pattern(*__p, __args...)) {
108 if (__p == __first)
109 return {__first, errc::invalid_argument};
110 else {
111 __value = 0;
112 return {__p, {}};
113 }
114 }
115
116 auto __r = __f(__p, __last, __value, __args...);
117 if (__r.ec == errc::result_out_of_range) {
118 for (; __r.ptr != __last; ++__r.ptr) {
119 if (!std::__in_pattern(*__r.ptr, __args...))
120 break;
121 }
122 }
123
124 return __r;
125}
126
127template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
128inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
129__from_chars_atoi(const char* __first, const char* __last, _Tp& __value) {
130 using __tx = __itoa::__traits<_Tp>;
131 using __output_type = typename __tx::type;
132
133 return std::__subject_seq_combinator(
134 __first, __last, __value, [](const char* __f, const char* __l, _Tp& __val) -> from_chars_result {
135 __output_type __a, __b;
136 auto __p = __tx::__read(__f, __l, __a, __b);
137 if (__p == __l || !std::__in_pattern(*__p)) {
138 __output_type __m = numeric_limits<_Tp>::max();
139 if (__m >= __a && __m - __a >= __b) {
140 __val = __a + __b;
141 return {__p, {}};
142 }
143 }
144 return {__p, errc::result_out_of_range};
145 });
146}
147
148template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
149inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
150__from_chars_atoi(const char* __first, const char* __last, _Tp& __value) {
151 using __t = decltype(std::__to_unsigned_like(__value));
152 return std::__sign_combinator(__first, __last, __value, __from_chars_atoi<__t>);
153}
154
155/*
156// Code used to generate __from_chars_log2f_lut.
157#include <cmath>
158#include <format>
159#include <iostream>
160
161int main() {
162 for (int i = 2; i <= 36; ++i)
163 std::cout << std::format("{},\n", log2f(i));
164}
165*/
166/// log2f table for bases [2, 36].
167inline constexpr float __from_chars_log2f_lut[35] = {
168 1, 1.5849625, 2, 2.321928, 2.5849626, 2.807355, 3, 3.169925, 3.321928,
169 3.4594316, 3.5849626, 3.7004397, 3.807355, 3.9068906, 4, 4.087463, 4.169925, 4.2479277,
170 4.321928, 4.3923173, 4.4594316, 4.523562, 4.5849624, 4.643856, 4.70044, 4.7548876, 4.807355,
171 4.857981, 4.9068904, 4.9541965, 5, 5.044394, 5.087463, 5.129283, 5.169925};
172
173template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
174inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
175__from_chars_integral(const char* __first, const char* __last, _Tp& __value, int __base) {
176 if (__base == 10)
177 return std::__from_chars_atoi(__first, __last, __value);
178
179 return std::__subject_seq_combinator(
180 __first,
181 __last,
182 __value,
183 [](const char* __p, const char* __lastp, _Tp& __val, int __b) -> from_chars_result {
184 using __tl = numeric_limits<_Tp>;
185 // __base is always between 2 and 36 inclusive.
186 auto __digits = __tl::digits / __from_chars_log2f_lut[__b - 2];
187 _Tp __x = __in_pattern(*__p++, __b).__val, __y = 0;
188
189 for (int __i = 1; __p != __lastp; ++__i, ++__p) {
190 if (auto __c = __in_pattern(*__p, __b)) {
191 if (__i < __digits - 1)
192 __x = __x * __b + __c.__val;
193 else {
194 if (!__itoa::__mul_overflowed(__x, __b, __x))
195 ++__p;
196 __y = __c.__val;
197 break;
198 }
199 } else
200 break;
201 }
202
203 if (__p == __lastp || !__in_pattern(*__p, __b)) {
204 if (__tl::max() - __x >= __y) {
205 __val = __x + __y;
206 return {__p, {}};
207 }
208 }
209 return {__p, errc::result_out_of_range};
210 },
211 __base);
212}
213
214template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
215inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
216__from_chars_integral(const char* __first, const char* __last, _Tp& __value, int __base) {
217 using __t = decltype(std::__to_unsigned_like(__value));
218 return std::__sign_combinator(__first, __last, __value, __from_chars_integral<__t>, __base);
219}
220
221template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
222inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
223from_chars(const char* __first, const char* __last, _Tp& __value) {
224 return std::__from_chars_atoi(__first, __last, __value);
225}
226
227template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
228inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
229from_chars(const char* __first, const char* __last, _Tp& __value, int __base) {
230 _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base && __base <= 36, "base not in [2, 36]");
231 return std::__from_chars_integral(__first, __last, __value, __base);
232}
233#endif // _LIBCPP_STD_VER >= 17
234
235_LIBCPP_END_NAMESPACE_STD
236
237_LIBCPP_POP_MACROS
238
239#endif // _LIBCPP___CHARCONV_FROM_CHARS_INTEGRAL_H
lib/libcxx/include/__charconv/from_chars_result.h+8-9
......@@ -11,7 +11,7 @@
1111#define _LIBCPP___CHARCONV_FROM_CHARS_RESULT_H
1212
1313#include <__config>
14#include <__errc>
14#include <__system_error/errc.h>
1515
1616#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1717# pragma GCC system_header
......@@ -19,18 +19,17 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 14
22#if _LIBCPP_STD_VER >= 17
2323
24struct _LIBCPP_TYPE_VIS from_chars_result
25{
26 const char* ptr;
27 errc ec;
28# if _LIBCPP_STD_VER > 17
29 _LIBCPP_HIDE_FROM_ABI friend bool operator==(const from_chars_result&, const from_chars_result&) = default;
24struct _LIBCPP_EXPORTED_FROM_ABI from_chars_result {
25 const char* ptr;
26 errc ec;
27# if _LIBCPP_STD_VER >= 20
28 _LIBCPP_HIDE_FROM_ABI friend bool operator==(const from_chars_result&, const from_chars_result&) = default;
3029# endif
3130};
3231
33#endif // _LIBCPP_STD_VER > 14
32#endif // _LIBCPP_STD_VER >= 17
3433
3534_LIBCPP_END_NAMESPACE_STD
3635
lib/libcxx/include/__charconv/tables.h+35-26
......@@ -19,7 +19,7 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 14
22#if _LIBCPP_STD_VER >= 17
2323
2424namespace __itoa {
2525
......@@ -62,32 +62,41 @@ inline constexpr char __base_16_lut[512] = {
6262 'f', 'd', 'f', 'e', 'f', 'f'};
6363
6464inline constexpr uint32_t __pow10_32[10] = {
65 UINT32_C(0), UINT32_C(10), UINT32_C(100), UINT32_C(1000), UINT32_C(10000),
66 UINT32_C(100000), UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000), UINT32_C(1000000000)};
67
68inline constexpr uint64_t __pow10_64[20] = {UINT64_C(0),
69 UINT64_C(10),
70 UINT64_C(100),
71 UINT64_C(1000),
72 UINT64_C(10000),
73 UINT64_C(100000),
74 UINT64_C(1000000),
75 UINT64_C(10000000),
76 UINT64_C(100000000),
77 UINT64_C(1000000000),
78 UINT64_C(10000000000),
79 UINT64_C(100000000000),
80 UINT64_C(1000000000000),
81 UINT64_C(10000000000000),
82 UINT64_C(100000000000000),
83 UINT64_C(1000000000000000),
84 UINT64_C(10000000000000000),
85 UINT64_C(100000000000000000),
86 UINT64_C(1000000000000000000),
87 UINT64_C(10000000000000000000)};
65 UINT32_C(0),
66 UINT32_C(10),
67 UINT32_C(100),
68 UINT32_C(1000),
69 UINT32_C(10000),
70 UINT32_C(100000),
71 UINT32_C(1000000),
72 UINT32_C(10000000),
73 UINT32_C(100000000),
74 UINT32_C(1000000000)};
75
76inline constexpr uint64_t __pow10_64[20] = {
77 UINT64_C(0),
78 UINT64_C(10),
79 UINT64_C(100),
80 UINT64_C(1000),
81 UINT64_C(10000),
82 UINT64_C(100000),
83 UINT64_C(1000000),
84 UINT64_C(10000000),
85 UINT64_C(100000000),
86 UINT64_C(1000000000),
87 UINT64_C(10000000000),
88 UINT64_C(100000000000),
89 UINT64_C(1000000000000),
90 UINT64_C(10000000000000),
91 UINT64_C(100000000000000),
92 UINT64_C(1000000000000000),
93 UINT64_C(10000000000000000),
94 UINT64_C(100000000000000000),
95 UINT64_C(1000000000000000000),
96 UINT64_C(10000000000000000000)};
8897
8998# ifndef _LIBCPP_HAS_NO_INT128
90inline constexpr int __pow10_128_offset = 0;
99inline constexpr int __pow10_128_offset = 0;
91100inline constexpr __uint128_t __pow10_128[40] = {
92101 UINT64_C(0),
93102 UINT64_C(10),
......@@ -147,7 +156,7 @@ inline constexpr char __digits_base_10[200] = {
147156
148157} // namespace __itoa
149158
150#endif // _LIBCPP_STD_VER > 14
159#endif // _LIBCPP_STD_VER >= 17
151160
152161_LIBCPP_END_NAMESPACE_STD
153162
lib/libcxx/include/__charconv/to_chars.h created+25
......@@ -0,0 +1,25 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___CHARCONV_TO_CHARS
11#define _LIBCPP___CHARCONV_TO_CHARS
12
13#include <__charconv/to_chars_floating_point.h>
14#include <__charconv/to_chars_integral.h>
15#include <__config>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18# pragma GCC system_header
19#endif
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23_LIBCPP_END_NAMESPACE_STD
24
25#endif // _LIBCPP___CHARCONV_TO_CHARS
lib/libcxx/include/__charconv/to_chars_base_10.h+11-9
......@@ -25,7 +25,7 @@ _LIBCPP_PUSH_MACROS
2525
2626_LIBCPP_BEGIN_NAMESPACE_STD
2727
28#if _LIBCPP_STD_VER > 14
28#if _LIBCPP_STD_VER >= 17
2929
3030namespace __itoa {
3131
......@@ -72,7 +72,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __append10(char* __fir
7272 static_cast<uint32_t>(__value % 100000000));
7373}
7474
75_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u32(char* __first, uint32_t __value) noexcept {
75_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char*
76__base_10_u32(char* __first, uint32_t __value) noexcept {
7677 if (__value < 1000000) {
7778 if (__value < 10000) {
7879 if (__value < 100) {
......@@ -107,7 +108,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u32(c
107108 return __itoa::__append10(__first, __value);
108109}
109110
110_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u64(char* __buffer, uint64_t __value) noexcept {
111_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char*
112__base_10_u64(char* __buffer, uint64_t __value) noexcept {
111113 if (__value <= UINT32_MAX)
112114 return __itoa::__base_10_u32(__buffer, static_cast<uint32_t>(__value));
113115
......@@ -130,12 +132,13 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u64(c
130132/// range that can be used. However the range is sufficient for
131133/// \ref __base_10_u128.
132134_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline __uint128_t __pow_10(int __exp) noexcept {
133 _LIBCPP_ASSERT(__exp >= __pow10_128_offset, "Index out of bounds");
135 _LIBCPP_ASSERT_UNCATEGORIZED(__exp >= __pow10_128_offset, "Index out of bounds");
134136 return __pow10_128[__exp - __pow10_128_offset];
135137}
136138
137_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u128(char* __buffer, __uint128_t __value) noexcept {
138 _LIBCPP_ASSERT(
139_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char*
140__base_10_u128(char* __buffer, __uint128_t __value) noexcept {
141 _LIBCPP_ASSERT_UNCATEGORIZED(
139142 __value > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true.");
140143
141144 // Unlike the 64 to 32 bit case the 128 bit case the "upper half" can't be
......@@ -159,8 +162,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u128(
159162 __value %= __itoa::__pow_10(29);
160163 __buffer = __itoa::__append10(__buffer, static_cast<uint64_t>(__value / __itoa::__pow_10(19)));
161164 __value %= __itoa::__pow_10(19);
162 }
163 else {
165 } else {
164166 // step 2
165167 // This version needs to determine the position of the leading non-zero digit.
166168 __buffer = __base_10_u64(__buffer, static_cast<uint64_t>(__value / __itoa::__pow_10(19)));
......@@ -176,7 +178,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u128(
176178# endif
177179} // namespace __itoa
178180
179#endif // _LIBCPP_STD_VER > 14
181#endif // _LIBCPP_STD_VER >= 17
180182
181183_LIBCPP_END_NAMESPACE_STD
182184
lib/libcxx/include/__charconv/to_chars_floating_point.h created+56
......@@ -0,0 +1,56 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___CHARCONV_TO_CHARS_FLOATING_POINT_H
11#define _LIBCPP___CHARCONV_TO_CHARS_FLOATING_POINT_H
12
13#include <__availability>
14#include <__charconv/chars_format.h>
15#include <__charconv/to_chars_result.h>
16#include <__config>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19# pragma GCC system_header
20#endif
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24#if _LIBCPP_STD_VER >= 17
25
26_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
27to_chars(char* __first, char* __last, float __value);
28
29_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
30to_chars(char* __first, char* __last, double __value);
31
32_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
33to_chars(char* __first, char* __last, long double __value);
34
35_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
36to_chars(char* __first, char* __last, float __value, chars_format __fmt);
37
38_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
39to_chars(char* __first, char* __last, double __value, chars_format __fmt);
40
41_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
42to_chars(char* __first, char* __last, long double __value, chars_format __fmt);
43
44_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
45to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision);
46
47_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
48to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision);
49
50_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result
51to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision);
52#endif // _LIBCPP_STD_VER >= 17
53
54_LIBCPP_END_NAMESPACE_STD
55
56#endif // _LIBCPP___CHARCONV_TO_CHARS_FLOATING_POINT_H
lib/libcxx/include/__charconv/to_chars_integral.h created+326
......@@ -0,0 +1,326 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H
11#define _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H
12
13#include <__algorithm/copy_n.h>
14#include <__bit/countl.h>
15#include <__charconv/tables.h>
16#include <__charconv/to_chars_base_10.h>
17#include <__charconv/to_chars_result.h>
18#include <__charconv/traits.h>
19#include <__config>
20#include <__system_error/errc.h>
21#include <__type_traits/enable_if.h>
22#include <__type_traits/integral_constant.h>
23#include <__type_traits/is_same.h>
24#include <__type_traits/make_32_64_or_128_bit.h>
25#include <__type_traits/make_unsigned.h>
26#include <__utility/unreachable.h>
27#include <cstddef>
28#include <cstdint>
29#include <limits>
30
31#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
32# pragma GCC system_header
33#endif
34
35_LIBCPP_PUSH_MACROS
36#include <__undef_macros>
37
38_LIBCPP_BEGIN_NAMESPACE_STD
39
40#if _LIBCPP_STD_VER >= 17
41
42to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
43
44template <typename _Tp>
45inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
46__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type);
47
48template <typename _Tp>
49inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
50__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) {
51 auto __x = std::__to_unsigned_like(__value);
52 if (__value < 0 && __first != __last) {
53 *__first++ = '-';
54 __x = std::__complement(__x);
55 }
56
57 return std::__to_chars_itoa(__first, __last, __x, false_type());
58}
59
60template <typename _Tp>
61inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
62__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) {
63 using __tx = __itoa::__traits<_Tp>;
64 auto __diff = __last - __first;
65
66 if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
67 return {__tx::__convert(__first, __value), errc(0)};
68 else
69 return {__last, errc::value_too_large};
70}
71
72# ifndef _LIBCPP_HAS_NO_INT128
73template <>
74inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
75__to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type) {
76 // When the value fits in 64-bits use the 64-bit code path. This reduces
77 // the number of expensive calculations on 128-bit values.
78 //
79 // NOTE the 128-bit code path requires this optimization.
80 if (__value <= numeric_limits<uint64_t>::max())
81 return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type());
82
83 using __tx = __itoa::__traits<__uint128_t>;
84 auto __diff = __last - __first;
85
86 if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
87 return {__tx::__convert(__first, __value), errc(0)};
88 else
89 return {__last, errc::value_too_large};
90}
91# endif
92
93template <class _Tp>
94inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
95__to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type);
96
97template <typename _Tp>
98inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
99__to_chars_integral(char* __first, char* __last, _Tp __value, int __base, true_type) {
100 auto __x = std::__to_unsigned_like(__value);
101 if (__value < 0 && __first != __last) {
102 *__first++ = '-';
103 __x = std::__complement(__x);
104 }
105
106 return std::__to_chars_integral(__first, __last, __x, __base, false_type());
107}
108
109namespace __itoa {
110
111template <unsigned _Base>
112struct _LIBCPP_HIDDEN __integral;
113
114template <>
115struct _LIBCPP_HIDDEN __integral<2> {
116 template <typename _Tp>
117 _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
118 // If value == 0 still need one digit. If the value != this has no
119 // effect since the code scans for the most significant bit set. (Note
120 // that __libcpp_clz doesn't work for 0.)
121 return numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1);
122 }
123
124 template <typename _Tp>
125 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
126 __to_chars(char* __first, char* __last, _Tp __value) {
127 ptrdiff_t __cap = __last - __first;
128 int __n = __width(__value);
129 if (__n > __cap)
130 return {__last, errc::value_too_large};
131
132 __last = __first + __n;
133 char* __p = __last;
134 const unsigned __divisor = 16;
135 while (__value > __divisor) {
136 unsigned __c = __value % __divisor;
137 __value /= __divisor;
138 __p -= 4;
139 std::copy_n(&__base_2_lut[4 * __c], 4, __p);
140 }
141 do {
142 unsigned __c = __value % 2;
143 __value /= 2;
144 *--__p = "01"[__c];
145 } while (__value != 0);
146 return {__last, errc(0)};
147 }
148};
149
150template <>
151struct _LIBCPP_HIDDEN __integral<8> {
152 template <typename _Tp>
153 _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
154 // If value == 0 still need one digit. If the value != this has no
155 // effect since the code scans for the most significat bit set. (Note
156 // that __libcpp_clz doesn't work for 0.)
157 return ((numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1)) + 2) / 3;
158 }
159
160 template <typename _Tp>
161 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
162 __to_chars(char* __first, char* __last, _Tp __value) {
163 ptrdiff_t __cap = __last - __first;
164 int __n = __width(__value);
165 if (__n > __cap)
166 return {__last, errc::value_too_large};
167
168 __last = __first + __n;
169 char* __p = __last;
170 unsigned __divisor = 64;
171 while (__value > __divisor) {
172 unsigned __c = __value % __divisor;
173 __value /= __divisor;
174 __p -= 2;
175 std::copy_n(&__base_8_lut[2 * __c], 2, __p);
176 }
177 do {
178 unsigned __c = __value % 8;
179 __value /= 8;
180 *--__p = "01234567"[__c];
181 } while (__value != 0);
182 return {__last, errc(0)};
183 }
184};
185
186template <>
187struct _LIBCPP_HIDDEN __integral<16> {
188 template <typename _Tp>
189 _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
190 // If value == 0 still need one digit. If the value != this has no
191 // effect since the code scans for the most significat bit set. (Note
192 // that __libcpp_clz doesn't work for 0.)
193 return (numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1) + 3) / 4;
194 }
195
196 template <typename _Tp>
197 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
198 __to_chars(char* __first, char* __last, _Tp __value) {
199 ptrdiff_t __cap = __last - __first;
200 int __n = __width(__value);
201 if (__n > __cap)
202 return {__last, errc::value_too_large};
203
204 __last = __first + __n;
205 char* __p = __last;
206 unsigned __divisor = 256;
207 while (__value > __divisor) {
208 unsigned __c = __value % __divisor;
209 __value /= __divisor;
210 __p -= 2;
211 std::copy_n(&__base_16_lut[2 * __c], 2, __p);
212 }
213 if (__first != __last)
214 do {
215 unsigned __c = __value % 16;
216 __value /= 16;
217 *--__p = "0123456789abcdef"[__c];
218 } while (__value != 0);
219 return {__last, errc(0)};
220 }
221};
222
223} // namespace __itoa
224
225template <unsigned _Base, typename _Tp, typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0>
226_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) {
227 return __itoa::__integral<_Base>::__width(__value);
228}
229
230template <unsigned _Base, typename _Tp, typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0>
231_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) {
232 return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value));
233}
234
235template <unsigned _Base, typename _Tp, typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0>
236_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
237__to_chars_integral(char* __first, char* __last, _Tp __value) {
238 return __itoa::__integral<_Base>::__to_chars(__first, __last, __value);
239}
240
241template <unsigned _Base, typename _Tp, typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0>
242_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
243__to_chars_integral(char* __first, char* __last, _Tp __value) {
244 return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value));
245}
246
247template <typename _Tp>
248_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value, unsigned __base) {
249 _LIBCPP_ASSERT_UNCATEGORIZED(__value >= 0, "The function requires a non-negative value.");
250
251 unsigned __base_2 = __base * __base;
252 unsigned __base_3 = __base_2 * __base;
253 unsigned __base_4 = __base_2 * __base_2;
254
255 int __r = 0;
256 while (true) {
257 if (__value < __base)
258 return __r + 1;
259 if (__value < __base_2)
260 return __r + 2;
261 if (__value < __base_3)
262 return __r + 3;
263 if (__value < __base_4)
264 return __r + 4;
265
266 __value /= __base_4;
267 __r += 4;
268 }
269
270 __libcpp_unreachable();
271}
272
273template <typename _Tp>
274inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
275__to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type) {
276 if (__base == 10) [[likely]]
277 return std::__to_chars_itoa(__first, __last, __value, false_type());
278
279 switch (__base) {
280 case 2:
281 return std::__to_chars_integral<2>(__first, __last, __value);
282 case 8:
283 return std::__to_chars_integral<8>(__first, __last, __value);
284 case 16:
285 return std::__to_chars_integral<16>(__first, __last, __value);
286 }
287
288 ptrdiff_t __cap = __last - __first;
289 int __n = std::__to_chars_integral_width(__value, __base);
290 if (__n > __cap)
291 return {__last, errc::value_too_large};
292
293 __last = __first + __n;
294 char* __p = __last;
295 do {
296 unsigned __c = __value % __base;
297 __value /= __base;
298 *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
299 } while (__value != 0);
300 return {__last, errc(0)};
301}
302
303template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
304inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
305to_chars(char* __first, char* __last, _Tp __value) {
306 using _Type = __make_32_64_or_128_bit_t<_Tp>;
307 static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars");
308 return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>());
309}
310
311template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
312inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
313to_chars(char* __first, char* __last, _Tp __value, int __base) {
314 _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base && __base <= 36, "base not in [2, 36]");
315
316 using _Type = __make_32_64_or_128_bit_t<_Tp>;
317 return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>());
318}
319
320#endif // _LIBCPP_STD_VER >= 17
321
322_LIBCPP_END_NAMESPACE_STD
323
324_LIBCPP_POP_MACROS
325
326#endif // _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H
lib/libcxx/include/__charconv/to_chars_result.h+8-9
......@@ -11,7 +11,7 @@
1111#define _LIBCPP___CHARCONV_TO_CHARS_RESULT_H
1212
1313#include <__config>
14#include <__errc>
14#include <__system_error/errc.h>
1515
1616#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1717# pragma GCC system_header
......@@ -19,18 +19,17 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 14
22#if _LIBCPP_STD_VER >= 17
2323
24struct _LIBCPP_TYPE_VIS to_chars_result
25{
26 char* ptr;
27 errc ec;
28# if _LIBCPP_STD_VER > 17
29 _LIBCPP_HIDE_FROM_ABI friend bool operator==(const to_chars_result&, const to_chars_result&) = default;
24struct _LIBCPP_EXPORTED_FROM_ABI to_chars_result {
25 char* ptr;
26 errc ec;
27# if _LIBCPP_STD_VER >= 20
28 _LIBCPP_HIDE_FROM_ABI friend bool operator==(const to_chars_result&, const to_chars_result&) = default;
3029# endif
3130};
3231
33#endif // _LIBCPP_STD_VER > 14
32#endif // _LIBCPP_STD_VER >= 17
3433
3534_LIBCPP_END_NAMESPACE_STD
3635
lib/libcxx/include/__charconv/traits.h created+199
......@@ -0,0 +1,199 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___CHARCONV_TRAITS
11#define _LIBCPP___CHARCONV_TRAITS
12
13#include <__bit/countl.h>
14#include <__charconv/tables.h>
15#include <__charconv/to_chars_base_10.h>
16#include <__config>
17#include <__type_traits/enable_if.h>
18#include <__type_traits/is_unsigned.h>
19#include <cstdint>
20#include <limits>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23# pragma GCC system_header
24#endif
25
26_LIBCPP_PUSH_MACROS
27#include <__undef_macros>
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31#if _LIBCPP_STD_VER >= 17
32
33namespace __itoa {
34
35template <typename _Tp, typename = void>
36struct _LIBCPP_HIDDEN __traits_base;
37
38template <typename _Tp>
39struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) <= sizeof(uint32_t)>> {
40 using type = uint32_t;
41
42 /// The width estimation using a log10 algorithm.
43 ///
44 /// The algorithm is based on
45 /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
46 /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
47 /// function requires its input to have at least one bit set the value of
48 /// zero is set to one. This means the first element of the lookup table is
49 /// zero.
50 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
51 auto __t = (32 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
52 return __t - (__v < __itoa::__pow10_32[__t]) + 1;
53 }
54
55 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) {
56 return __itoa::__base_10_u32(__p, __v);
57 }
58
59 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_32)& __pow() {
60 return __itoa::__pow10_32;
61 }
62};
63
64template <typename _Tp>
65struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(uint64_t)>> {
66 using type = uint64_t;
67
68 /// The width estimation using a log10 algorithm.
69 ///
70 /// The algorithm is based on
71 /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
72 /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
73 /// function requires its input to have at least one bit set the value of
74 /// zero is set to one. This means the first element of the lookup table is
75 /// zero.
76 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
77 auto __t = (64 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
78 return __t - (__v < __itoa::__pow10_64[__t]) + 1;
79 }
80
81 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) {
82 return __itoa::__base_10_u64(__p, __v);
83 }
84
85 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_64)& __pow() {
86 return __itoa::__pow10_64;
87 }
88};
89
90# ifndef _LIBCPP_HAS_NO_INT128
91template <typename _Tp>
92struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__uint128_t)> > {
93 using type = __uint128_t;
94
95 /// The width estimation using a log10 algorithm.
96 ///
97 /// The algorithm is based on
98 /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
99 /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
100 /// function requires its input to have at least one bit set the value of
101 /// zero is set to one. This means the first element of the lookup table is
102 /// zero.
103 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
104 _LIBCPP_ASSERT_UNCATEGORIZED(
105 __v > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true.");
106 // There's always a bit set in the upper 64-bits.
107 auto __t = (128 - std::__libcpp_clz(static_cast<uint64_t>(__v >> 64))) * 1233 >> 12;
108 _LIBCPP_ASSERT_UNCATEGORIZED(__t >= __itoa::__pow10_128_offset, "Index out of bounds");
109 // __t is adjusted since the lookup table misses the lower entries.
110 return __t - (__v < __itoa::__pow10_128[__t - __itoa::__pow10_128_offset]) + 1;
111 }
112
113 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) {
114 return __itoa::__base_10_u128(__p, __v);
115 }
116
117 // TODO FMT This pow function should get an index.
118 // By moving this to its own header it can be reused by the pow function in to_chars_base_10.
119 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_128)& __pow() {
120 return __itoa::__pow10_128;
121 }
122};
123# endif
124
125template <typename _Tp>
126inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
127__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r) {
128 auto __c = __a * __b;
129 __r = __c;
130 return __c > numeric_limits<unsigned char>::max();
131}
132
133template <typename _Tp>
134inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
135__mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r) {
136 auto __c = __a * __b;
137 __r = __c;
138 return __c > numeric_limits<unsigned short>::max();
139}
140
141template <typename _Tp>
142inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool __mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) {
143 static_assert(is_unsigned<_Tp>::value, "");
144 return __builtin_mul_overflow(__a, __b, &__r);
145}
146
147template <typename _Tp, typename _Up>
148inline _LIBCPP_HIDE_FROM_ABI bool _LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r) {
149 return __itoa::__mul_overflowed(__a, static_cast<_Tp>(__b), __r);
150}
151
152template <typename _Tp>
153struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp> {
154 static constexpr int digits = numeric_limits<_Tp>::digits10 + 1;
155 using __traits_base<_Tp>::__pow;
156 using typename __traits_base<_Tp>::type;
157
158 // precondition: at least one non-zero character available
159 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char const*
160 __read(char const* __p, char const* __ep, type& __a, type& __b) {
161 type __cprod[digits];
162 int __j = digits - 1;
163 int __i = digits;
164 do {
165 if (*__p < '0' || *__p > '9')
166 break;
167 __cprod[--__i] = *__p++ - '0';
168 } while (__p != __ep && __i != 0);
169
170 __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1, __cprod[__i]);
171 if (__itoa::__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b))
172 --__p;
173 return __p;
174 }
175
176 template <typename _It1, typename _It2, class _Up>
177 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Up
178 __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init) {
179 for (; __first1 < __last1; ++__first1, ++__first2)
180 __init = __init + *__first1 * *__first2;
181 return __init;
182 }
183};
184
185} // namespace __itoa
186
187template <typename _Tp>
188inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Tp __complement(_Tp __x) {
189 static_assert(is_unsigned<_Tp>::value, "cast to unsigned first");
190 return _Tp(~__x + 1);
191}
192
193#endif // _LIBCPP_STD_VER >= 17
194
195_LIBCPP_END_NAMESPACE_STD
196
197_LIBCPP_POP_MACROS
198
199#endif // _LIBCPP___CHARCONV_TRAITS
lib/libcxx/include/__chrono/calendar.h+5-5
......@@ -18,7 +18,7 @@
1818# pragma GCC system_header
1919#endif
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
......@@ -26,12 +26,12 @@ namespace chrono
2626{
2727
2828struct local_t {};
29template<class Duration>
30using local_time = time_point<local_t, Duration>;
29template<class _Duration>
30using local_time = time_point<local_t, _Duration>;
3131using local_seconds = local_time<seconds>;
3232using local_days = local_time<days>;
3333
34struct last_spec { _LIBCPP_HIDE_FROM_ABI explicit last_spec() = default; };
34struct last_spec { explicit last_spec() = default; };
3535inline constexpr last_spec last{};
3636
3737
......@@ -39,6 +39,6 @@ inline constexpr last_spec last{};
3939
4040_LIBCPP_END_NAMESPACE_STD
4141
42#endif // _LIBCPP_STD_VER > 17
42#endif // _LIBCPP_STD_VER >= 20
4343
4444#endif // _LIBCPP___CHRONO_CALENDAR_H
lib/libcxx/include/__chrono/concepts.h created+36
......@@ -0,0 +1,36 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___CHRONO_CONCEPTS_H
11#define _LIBCPP___CHRONO_CONCEPTS_H
12
13#include <__chrono/hh_mm_ss.h>
14#include <__chrono/time_point.h>
15#include <__config>
16#include <__type_traits/is_specialization.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19# pragma GCC system_header
20#endif
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24#if _LIBCPP_STD_VER >= 20
25
26template <class _Tp>
27concept __is_hh_mm_ss = __is_specialization_v<_Tp, chrono::hh_mm_ss>;
28
29template <class _Tp>
30concept __is_time_point = __is_specialization_v<_Tp, chrono::time_point>;
31
32#endif // _LIBCPP_STD_VER >= 20
33
34_LIBCPP_END_NAMESPACE_STD
35
36#endif // _LIBCPP___CHRONO_CONCEPTS_H
lib/libcxx/include/__chrono/convert_to_tm.h+68-9
......@@ -10,8 +10,11 @@
1010#ifndef _LIBCPP___CHRONO_CONVERT_TO_TM_H
1111#define _LIBCPP___CHRONO_CONVERT_TO_TM_H
1212
13#include <__chrono/calendar.h>
14#include <__chrono/concepts.h>
1315#include <__chrono/day.h>
1416#include <__chrono/duration.h>
17#include <__chrono/file_clock.h>
1518#include <__chrono/hh_mm_ss.h>
1619#include <__chrono/month.h>
1720#include <__chrono/month_weekday.h>
......@@ -26,17 +29,23 @@
2629#include <__chrono/year_month_weekday.h>
2730#include <__concepts/same_as.h>
2831#include <__config>
32#include <__format/format_error.h>
2933#include <__memory/addressof.h>
34#include <__type_traits/is_convertible.h>
3035#include <cstdint>
3136#include <ctime>
37#include <limits>
3238
3339#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3440# pragma GCC system_header
3541#endif
3642
43_LIBCPP_PUSH_MACROS
44#include <__undef_macros>
45
3746_LIBCPP_BEGIN_NAMESPACE_STD
3847
39#if _LIBCPP_STD_VER > 17
48#if _LIBCPP_STD_VER >= 20
4049
4150// Conerts a chrono date and weekday to a given _Tm type.
4251//
......@@ -67,6 +76,24 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _Date& __date, chrono::weekday _
6776 return __result;
6877}
6978
79template <class _Tm, class _Duration>
80_LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const chrono::sys_time<_Duration> __tp) {
81 chrono::sys_days __days = chrono::floor<chrono::days>(__tp);
82 chrono::year_month_day __ymd{__days};
83
84 _Tm __result = std::__convert_to_tm<_Tm>(chrono::year_month_day{__ymd}, chrono::weekday{__days});
85
86 uint64_t __sec =
87 chrono::duration_cast<chrono::seconds>(__tp - chrono::time_point_cast<chrono::seconds>(__days)).count();
88 __sec %= 24 * 3600;
89 __result.tm_hour = __sec / 3600;
90 __sec %= 3600;
91 __result.tm_min = __sec / 60;
92 __result.tm_sec = __sec % 60;
93
94 return __result;
95}
96
7097// Convert a chrono (calendar) time point, or dururation to the given _Tm type,
7198// which must have the same properties as std::tm.
7299template <class _Tm, class _ChronoT>
......@@ -76,17 +103,37 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) {
76103 __result.tm_zone = "UTC";
77104# endif
78105
79 if constexpr (chrono::__is_duration<_ChronoT>::value) {
106 if constexpr (__is_time_point<_ChronoT>) {
107 if constexpr (same_as<typename _ChronoT::clock, chrono::system_clock>)
108 return std::__convert_to_tm<_Tm>(__value);
109 else if constexpr (same_as<typename _ChronoT::clock, chrono::file_clock>)
110 return std::__convert_to_tm<_Tm>(_ChronoT::clock::to_sys(__value));
111 else if constexpr (same_as<typename _ChronoT::clock, chrono::local_t>)
112 return std::__convert_to_tm<_Tm>(chrono::sys_time<typename _ChronoT::duration>{__value.time_since_epoch()});
113 else
114 static_assert(sizeof(_ChronoT) == 0, "TODO: Add the missing clock specialization");
115 } else if constexpr (chrono::__is_duration<_ChronoT>::value) {
80116 // [time.format]/6
81117 // ... However, if a flag refers to a "time of day" (e.g. %H, %I, %p,
82118 // etc.), then a specialization of duration is interpreted as the time of
83119 // day elapsed since midnight.
84 uint64_t __sec = chrono::duration_cast<chrono::seconds>(__value).count();
85 __sec %= 24 * 3600;
86 __result.tm_hour = __sec / 3600;
87 __sec %= 3600;
88 __result.tm_min = __sec / 60;
89 __result.tm_sec = __sec % 60;
120
121 // Not all values can be converted to hours, it may run into ratio
122 // conversion errors. In that case the conversion to seconds works.
123 if constexpr (is_convertible_v<_ChronoT, chrono::hours>) {
124 auto __hour = chrono::floor<chrono::hours>(__value);
125 auto __sec = chrono::duration_cast<chrono::seconds>(__value - __hour);
126 __result.tm_hour = __hour.count() % 24;
127 __result.tm_min = __sec.count() / 60;
128 __result.tm_sec = __sec.count() % 60;
129 } else {
130 uint64_t __sec = chrono::duration_cast<chrono::seconds>(__value).count();
131 __sec %= 24 * 3600;
132 __result.tm_hour = __sec / 3600;
133 __sec %= 3600;
134 __result.tm_min = __sec / 60;
135 __result.tm_sec = __sec % 60;
136 }
90137 } else if constexpr (same_as<_ChronoT, chrono::day>)
91138 __result.tm_mday = static_cast<unsigned>(__value);
92139 else if constexpr (same_as<_ChronoT, chrono::month>)
......@@ -114,14 +161,26 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) {
114161 } else if constexpr (same_as<_ChronoT, chrono::year_month_weekday> ||
115162 same_as<_ChronoT, chrono::year_month_weekday_last>) {
116163 return std::__convert_to_tm<_Tm>(chrono::year_month_day{static_cast<chrono::sys_days>(__value)}, __value.weekday());
164 } else if constexpr (__is_hh_mm_ss<_ChronoT>) {
165 __result.tm_sec = __value.seconds().count();
166 __result.tm_min = __value.minutes().count();
167 // In libc++ hours is stored as a long. The type in std::tm is an int. So
168 // the overflow can only occur when hour uses more bits than an int
169 // provides.
170 if constexpr (sizeof(std::chrono::hours::rep) > sizeof(__result.tm_hour))
171 if (__value.hours().count() > std::numeric_limits<decltype(__result.tm_hour)>::max())
172 std::__throw_format_error("Formatting hh_mm_ss, encountered an hour overflow");
173 __result.tm_hour = __value.hours().count();
117174 } else
118175 static_assert(sizeof(_ChronoT) == 0, "Add the missing type specialization");
119176
120177 return __result;
121178}
122179
123#endif //if _LIBCPP_STD_VER > 17
180#endif // if _LIBCPP_STD_VER >= 20
124181
125182_LIBCPP_END_NAMESPACE_STD
126183
184_LIBCPP_POP_MACROS
185
127186#endif // _LIBCPP___CHRONO_CONVERT_TO_TM_H
lib/libcxx/include/__chrono/day.h+3-3
......@@ -18,7 +18,7 @@
1818# pragma GCC system_header
1919#endif
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
......@@ -29,7 +29,7 @@ class day {
2929private:
3030 unsigned char __d_;
3131public:
32 _LIBCPP_HIDE_FROM_ABI day() = default;
32 day() = default;
3333 _LIBCPP_HIDE_FROM_ABI explicit inline constexpr day(unsigned __val) noexcept : __d_(static_cast<unsigned char>(__val)) {}
3434 _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator++() noexcept { ++__d_; return *this; }
3535 _LIBCPP_HIDE_FROM_ABI inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; }
......@@ -79,6 +79,6 @@ day& day::operator-=(const days& __dd) noexcept
7979
8080_LIBCPP_END_NAMESPACE_STD
8181
82#endif // _LIBCPP_STD_VER > 17
82#endif // _LIBCPP_STD_VER >= 20
8383
8484#endif // _LIBCPP___CHRONO_DAY_H
lib/libcxx/include/__chrono/duration.h+31-12
......@@ -10,6 +10,8 @@
1010#ifndef _LIBCPP___CHRONO_DURATION_H
1111#define _LIBCPP___CHRONO_DURATION_H
1212
13#include <__compare/ordering.h>
14#include <__compare/three_way_comparable.h>
1315#include <__config>
1416#include <__type_traits/common_type.h>
1517#include <__type_traits/enable_if.h>
......@@ -130,7 +132,7 @@ duration_cast(const duration<_Rep, _Period>& __fd)
130132template <class _Rep>
131133struct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {};
132134
133#if _LIBCPP_STD_VER > 14
135#if _LIBCPP_STD_VER >= 17
134136template <class _Rep>
135137inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value;
136138#endif
......@@ -144,7 +146,7 @@ public:
144146 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {return numeric_limits<_Rep>::lowest();}
145147};
146148
147#if _LIBCPP_STD_VER > 14
149#if _LIBCPP_STD_VER >= 17
148150template <class _ToDuration, class _Rep, class _Period>
149151inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
150152typename enable_if
......@@ -186,11 +188,11 @@ round(const duration<_Rep, _Period>& __d)
186188{
187189 _ToDuration __lower = chrono::floor<_ToDuration>(__d);
188190 _ToDuration __upper = __lower + _ToDuration{1};
189 auto __lowerDiff = __d - __lower;
190 auto __upperDiff = __upper - __d;
191 if (__lowerDiff < __upperDiff)
191 auto __lower_diff = __d - __lower;
192 auto __upper_diff = __upper - __d;
193 if (__lower_diff < __upper_diff)
192194 return __lower;
193 if (__lowerDiff > __upperDiff)
195 if (__lower_diff > __upper_diff)
194196 return __upper;
195197 return __lower.count() & 1 ? __upper : __lower;
196198}
......@@ -242,11 +244,10 @@ private:
242244 rep __rep_;
243245public:
244246
245 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
246247#ifndef _LIBCPP_CXX03_LANG
247 duration() = default;
248 constexpr duration() = default;
248249#else
249 duration() {}
250 _LIBCPP_HIDE_FROM_ABI duration() {}
250251#endif
251252
252253 template <class _Rep2>
......@@ -307,7 +308,7 @@ typedef duration<long long, milli> milliseconds;
307308typedef duration<long long > seconds;
308309typedef duration< long, ratio< 60> > minutes;
309310typedef duration< long, ratio<3600> > hours;
310#if _LIBCPP_STD_VER > 17
311#if _LIBCPP_STD_VER >= 20
311312typedef duration< int, ratio_multiply<ratio<24>, hours::period>> days;
312313typedef duration< int, ratio_multiply<ratio<7>, days::period>> weeks;
313314typedef duration< int, ratio_multiply<ratio<146097, 400>, days::period>> years;
......@@ -343,6 +344,8 @@ operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period
343344 return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
344345}
345346
347#if _LIBCPP_STD_VER <= 17
348
346349// Duration !=
347350
348351template <class _Rep1, class _Period1, class _Rep2, class _Period2>
......@@ -354,6 +357,8 @@ operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period
354357 return !(__lhs == __rhs);
355358}
356359
360#endif // _LIBCPP_STD_VER <= 17
361
357362// Duration <
358363
359364template <class _LhsDuration, class _RhsDuration>
......@@ -417,6 +422,20 @@ operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period
417422 return !(__lhs < __rhs);
418423}
419424
425#if _LIBCPP_STD_VER >= 20
426
427template<class _Rep1, class _Period1, class _Rep2, class _Period2>
428 requires three_way_comparable<common_type_t<_Rep1, _Rep2>>
429_LIBCPP_HIDE_FROM_ABI
430constexpr auto operator<=>(const duration<_Rep1, _Period1>& __lhs,
431 const duration<_Rep2, _Period2>& __rhs)
432{
433 using _Ct = common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>;
434 return _Ct(__lhs).count() <=> _Ct(__rhs).count();
435}
436
437#endif // _LIBCPP_STD_VER >= 20
438
420439// Duration +
421440
422441template <class _Rep1, class _Period1, class _Rep2, class _Period2>
......@@ -530,7 +549,7 @@ operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2
530549
531550} // namespace chrono
532551
533#if _LIBCPP_STD_VER > 11
552#if _LIBCPP_STD_VER >= 14
534553// Suffixes for duration literals [time.duration.literals]
535554inline namespace literals
536555{
......@@ -609,7 +628,7 @@ namespace chrono { // hoist the literals into namespace std::chrono
609628 using namespace literals::chrono_literals;
610629} // namespace chrono
611630
612#endif // _LIBCPP_STD_VER > 11
631#endif // _LIBCPP_STD_VER >= 14
613632
614633_LIBCPP_END_NAMESPACE_STD
615634
lib/libcxx/include/__chrono/file_clock.h+5-5
......@@ -27,7 +27,7 @@ struct _FilesystemClock;
2727_LIBCPP_END_NAMESPACE_FILESYSTEM
2828#endif // !_LIBCPP_CXX03_LANG
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_BEGIN_NAMESPACE_STD
3333
......@@ -44,7 +44,7 @@ using file_time = time_point<file_clock, _Duration>;
4444
4545_LIBCPP_END_NAMESPACE_STD
4646
47#endif // _LIBCPP_STD_VER > 17
47#endif // _LIBCPP_STD_VER >= 20
4848
4949#ifndef _LIBCPP_CXX03_LANG
5050_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
......@@ -63,9 +63,9 @@ struct _FilesystemClock {
6363 _LIBCPP_EXPORTED_FROM_ABI
6464 static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false;
6565
66 _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept;
66 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_EXPORTED_FROM_ABI static time_point now() noexcept;
6767
68#if _LIBCPP_STD_VER > 17
68#if _LIBCPP_STD_VER >= 20
6969 template <class _Duration>
7070 _LIBCPP_HIDE_FROM_ABI
7171 static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) {
......@@ -77,7 +77,7 @@ struct _FilesystemClock {
7777 static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) {
7878 return chrono::file_time<_Duration>(__t.time_since_epoch());
7979 }
80#endif // _LIBCPP_STD_VER > 17
80#endif // _LIBCPP_STD_VER >= 20
8181};
8282_LIBCPP_END_NAMESPACE_FILESYSTEM
8383#endif // !_LIBCPP_CXX03_LANG
lib/libcxx/include/__chrono/formatter.h+228-114
......@@ -11,9 +11,11 @@
1111#define _LIBCPP___CHRONO_FORMATTER_H
1212
1313#include <__chrono/calendar.h>
14#include <__chrono/concepts.h>
1415#include <__chrono/convert_to_tm.h>
1516#include <__chrono/day.h>
1617#include <__chrono/duration.h>
18#include <__chrono/file_clock.h>
1719#include <__chrono/hh_mm_ss.h>
1820#include <__chrono/month.h>
1921#include <__chrono/month_weekday.h>
......@@ -21,6 +23,7 @@
2123#include <__chrono/ostream.h>
2224#include <__chrono/parser_std_format_spec.h>
2325#include <__chrono/statically_widen.h>
26#include <__chrono/system_clock.h>
2427#include <__chrono/time_point.h>
2528#include <__chrono/weekday.h>
2629#include <__chrono/year.h>
......@@ -35,13 +38,12 @@
3538#include <__format/format_functions.h>
3639#include <__format/format_parse_context.h>
3740#include <__format/formatter.h>
38#include <__format/formatter_output.h>
3941#include <__format/parser_std_format_spec.h>
42#include <__format/write_escaped.h>
4043#include <__memory/addressof.h>
4144#include <cmath>
4245#include <ctime>
4346#include <sstream>
44#include <string>
4547#include <string_view>
4648
4749#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -50,7 +52,7 @@
5052
5153_LIBCPP_BEGIN_NAMESPACE_STD
5254
53#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
55#if _LIBCPP_STD_VER >= 20
5456
5557namespace __formatter {
5658
......@@ -75,13 +77,15 @@ namespace __formatter {
7577// For tiny ratios it's not possible to convert a duration to a hh_mm_ss. This
7678// fails compile-time due to the limited precision of the ratio (64-bit is too
7779// small). Therefore a duration uses its own conversion.
78template <class _CharT, class _Tp>
79 requires(chrono::__is_duration<_Tp>::value)
80_LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(const _Tp& __value, basic_stringstream<_CharT>& __sstr) {
80template <class _CharT, class _Rep, class _Period>
81_LIBCPP_HIDE_FROM_ABI void
82__format_sub_seconds(const chrono::duration<_Rep, _Period>& __value, basic_stringstream<_CharT>& __sstr) {
8183 __sstr << std::use_facet<numpunct<_CharT>>(__sstr.getloc()).decimal_point();
8284
85 using __duration = chrono::duration<_Rep, _Period>;
86
8387 auto __fraction = __value - chrono::duration_cast<chrono::seconds>(__value);
84 if constexpr (chrono::treat_as_floating_point_v<typename _Tp::rep>)
88 if constexpr (chrono::treat_as_floating_point_v<_Rep>)
8589 // When the floating-point value has digits itself they are ignored based
8690 // on the wording in [tab:time.format.spec]
8791 // If the precision of the input cannot be exactly represented with
......@@ -96,19 +100,44 @@ _LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(const _Tp& __value, basic_string
96100 // https://godbolt.org/z/6dsbnW8ba
97101 std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
98102 _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}.0f}"),
99 __fraction.count(),
100 chrono::hh_mm_ss<_Tp>::fractional_width);
103 chrono::duration_cast<typename chrono::hh_mm_ss<__duration>::precision>(__fraction).count(),
104 chrono::hh_mm_ss<__duration>::fractional_width);
105 else
106 std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
107 _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}}"),
108 chrono::duration_cast<typename chrono::hh_mm_ss<__duration>::precision>(__fraction).count(),
109 chrono::hh_mm_ss<__duration>::fractional_width);
110}
111
112template <class _CharT, __is_time_point _Tp>
113_LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(const _Tp& __value, basic_stringstream<_CharT>& __sstr) {
114 __formatter::__format_sub_seconds(__value.time_since_epoch(), __sstr);
115}
116
117template <class _CharT, class _Duration>
118_LIBCPP_HIDE_FROM_ABI void
119__format_sub_seconds(const chrono::hh_mm_ss<_Duration>& __value, basic_stringstream<_CharT>& __sstr) {
120 __sstr << std::use_facet<numpunct<_CharT>>(__sstr.getloc()).decimal_point();
121 if constexpr (chrono::treat_as_floating_point_v<typename _Duration::rep>)
122 std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
123 _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}.0f}"),
124 __value.subseconds().count(),
125 __value.fractional_width);
101126 else
102127 std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
103128 _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}}"),
104 __fraction.count(),
105 chrono::hh_mm_ss<_Tp>::fractional_width);
129 __value.subseconds().count(),
130 __value.fractional_width);
106131}
107132
108133template <class _Tp>
109134consteval bool __use_fraction() {
110 if constexpr (chrono::__is_duration<_Tp>::value)
135 if constexpr (__is_time_point<_Tp>)
136 return chrono::hh_mm_ss<typename _Tp::duration>::fractional_width;
137 else if constexpr (chrono::__is_duration<_Tp>::value)
111138 return chrono::hh_mm_ss<_Tp>::fractional_width;
139 else if constexpr (__is_hh_mm_ss<_Tp>)
140 return _Tp::fractional_width;
112141 else
113142 return false;
114143}
......@@ -169,7 +198,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
169198 if (__year < 1000 || __year > 9999)
170199 __formatter::__format_century(__year, __sstr);
171200 else
172 __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
201 __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
173202 } break;
174203
175204 case _CharT('j'):
......@@ -180,7 +209,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
180209 // an intemediate step.
181210 __sstr << chrono::duration_cast<chrono::days>(chrono::duration_cast<chrono::seconds>(__value)).count();
182211 else
183 __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
212 __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
184213 break;
185214
186215 case _CharT('q'):
......@@ -208,7 +237,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
208237
209238 case _CharT('S'):
210239 case _CharT('T'):
211 __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
240 __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
212241 if constexpr (__use_fraction<_Tp>())
213242 __formatter::__format_sub_seconds(__value, __sstr);
214243 break;
......@@ -240,20 +269,19 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
240269 //
241270 // TODO FMT evaluate the comment above.
242271
243# if defined(__GLIBC__) || defined(_AIX)
272# if defined(__GLIBC__) || defined(_AIX) || defined(_WIN32)
244273 case _CharT('y'):
245274 // Glibc fails for negative values, AIX for positive values too.
246275 __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), (std::abs(__t.tm_year + 1900)) % 100);
247276 break;
248# endif // defined(__GLIBC__) || defined(_AIX)
277# endif // defined(__GLIBC__) || defined(_AIX) || defined(_WIN32)
249278
250 case _CharT('Y'): {
251 int __year = __t.tm_year + 1900;
252 if (__year < 1000)
253 __formatter::__format_year(__year, __sstr);
254 else
255 __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
256 } break;
279 case _CharT('Y'):
280 // Depending on the platform's libc the range of supported years is
281 // limited. Intead of of testing all conditions use the internal
282 // implementation unconditionally.
283 __formatter::__format_year(__t.tm_year + 1900, __sstr);
284 break;
257285
258286 case _CharT('F'): {
259287 int __year = __t.tm_year + 1900;
......@@ -261,9 +289,14 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
261289 __formatter::__format_year(__year, __sstr);
262290 __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday);
263291 } else
264 __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
292 __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
265293 } break;
266294
295 case _CharT('Z'):
296 // TODO FMT Add proper timezone support.
297 __sstr << _LIBCPP_STATICALLY_WIDEN(_CharT, "UTC");
298 break;
299
267300 case _CharT('O'):
268301 if constexpr (__use_fraction<_Tp>()) {
269302 // Handle OS using the normal representation for the non-fractional
......@@ -271,7 +304,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
271304 // fractional part should be formatted.
272305 if (*(__it + 1) == 'S') {
273306 ++__it;
274 __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
307 __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
275308 __formatter::__format_sub_seconds(__value, __sstr);
276309 break;
277310 }
......@@ -281,7 +314,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
281314 ++__it;
282315 [[fallthrough]];
283316 default:
284 __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
317 __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
285318 break;
286319 }
287320 } else {
......@@ -292,7 +325,9 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
292325
293326template <class _Tp>
294327_LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) {
295 if constexpr (same_as<_Tp, chrono::day>)
328 if constexpr (__is_time_point<_Tp>)
329 return true;
330 else if constexpr (same_as<_Tp, chrono::day>)
296331 return true;
297332 else if constexpr (same_as<_Tp, chrono::month>)
298333 return __value.ok();
......@@ -322,13 +357,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) {
322357 return __value.weekday().ok();
323358 else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
324359 return __value.weekday().ok();
360 else if constexpr (__is_hh_mm_ss<_Tp>)
361 return true;
325362 else
326363 static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
327364}
328365
329366template <class _Tp>
330367_LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) {
331 if constexpr (same_as<_Tp, chrono::day>)
368 if constexpr (__is_time_point<_Tp>)
369 return true;
370 else if constexpr (same_as<_Tp, chrono::day>)
332371 return true;
333372 else if constexpr (same_as<_Tp, chrono::month>)
334373 return __value.ok();
......@@ -358,13 +397,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) {
358397 return __value.weekday().ok();
359398 else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
360399 return __value.weekday().ok();
400 else if constexpr (__is_hh_mm_ss<_Tp>)
401 return true;
361402 else
362403 static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
363404}
364405
365406template <class _Tp>
366407_LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) {
367 if constexpr (same_as<_Tp, chrono::day>)
408 if constexpr (__is_time_point<_Tp>)
409 return true;
410 else if constexpr (same_as<_Tp, chrono::day>)
368411 return true;
369412 else if constexpr (same_as<_Tp, chrono::month>)
370413 return __value.ok();
......@@ -394,13 +437,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) {
394437 return __value.ok();
395438 else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
396439 return __value.ok();
440 else if constexpr (__is_hh_mm_ss<_Tp>)
441 return true;
397442 else
398443 static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
399444}
400445
401446template <class _Tp>
402447_LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) {
403 if constexpr (same_as<_Tp, chrono::day>)
448 if constexpr (__is_time_point<_Tp>)
449 return true;
450 else if constexpr (same_as<_Tp, chrono::day>)
404451 return true;
405452 else if constexpr (same_as<_Tp, chrono::month>)
406453 return __value.ok();
......@@ -430,16 +477,18 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) {
430477 return __value.month().ok();
431478 else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
432479 return __value.month().ok();
480 else if constexpr (__is_hh_mm_ss<_Tp>)
481 return true;
433482 else
434483 static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
435484}
436485
437template <class _CharT, class _Tp>
486template <class _CharT, class _Tp, class _FormatContext>
438487_LIBCPP_HIDE_FROM_ABI auto
439488__format_chrono(const _Tp& __value,
440 auto& __ctx,
489 _FormatContext& __ctx,
441490 __format_spec::__parsed_specifications<_CharT> __specs,
442 basic_string_view<_CharT> __chrono_specs) -> decltype(__ctx.out()) {
491 basic_string_view<_CharT> __chrono_specs) {
443492 basic_stringstream<_CharT> __sstr;
444493 // [time.format]/2
445494 // 2.1 - the "C" locale if the L option is not present in chrono-format-spec, otherwise
......@@ -464,42 +513,63 @@ __format_chrono(const _Tp& __value,
464513 } else {
465514 // Test __weekday_name_ before __weekday_ to give a better error.
466515 if (__specs.__chrono_.__weekday_name_ && !__formatter::__weekday_name_ok(__value))
467 std::__throw_format_error("formatting a weekday name needs a valid weekday");
516 std::__throw_format_error("Formatting a weekday name needs a valid weekday");
468517
469518 if (__specs.__chrono_.__weekday_ && !__formatter::__weekday_ok(__value))
470 std::__throw_format_error("formatting a weekday needs a valid weekday");
519 std::__throw_format_error("Formatting a weekday needs a valid weekday");
471520
472521 if (__specs.__chrono_.__day_of_year_ && !__formatter::__date_ok(__value))
473 std::__throw_format_error("formatting a day of year needs a valid date");
522 std::__throw_format_error("Formatting a day of year needs a valid date");
474523
475524 if (__specs.__chrono_.__week_of_year_ && !__formatter::__date_ok(__value))
476 std::__throw_format_error("formatting a week of year needs a valid date");
525 std::__throw_format_error("Formatting a week of year needs a valid date");
477526
478527 if (__specs.__chrono_.__month_name_ && !__formatter::__month_name_ok(__value))
479 std::__throw_format_error("formatting a month name from an invalid month number");
528 std::__throw_format_error("Formatting a month name from an invalid month number");
529
530 if constexpr (__is_hh_mm_ss<_Tp>) {
531 // Note this is a pedantic intepretation of the Standard. A hh_mm_ss
532 // is no longer a time_of_day and can store an arbitrary number of
533 // hours. A number of hours in a 12 or 24 hour clock can't represent
534 // 24 hours or more. The functions std::chrono::make12 and
535 // std::chrono::make24 reaffirm this view point.
536 //
537 // Interestingly this will be the only output stream function that
538 // throws.
539 //
540 // TODO FMT The wording probably needs to be adapted to
541 // - The displayed hours is hh_mm_ss.hours() % 24
542 // - It should probably allow %j in the same fashion as duration.
543 // - The stream formatter should change its output when hours >= 24
544 // - Write it as not valid,
545 // - or write the number of days.
546 if (__specs.__chrono_.__hour_ && __value.hours().count() > 23)
547 std::__throw_format_error("Formatting a hour needs a valid value");
548
549 if (__value.is_negative())
550 __sstr << _CharT('-');
551 }
480552
481553 __formatter::__format_chrono_using_chrono_specs(__value, __sstr, __chrono_specs);
482554 }
483555 }
484556
485 // TODO FMT Use the stringstream's view after P0408R7 has been implemented.
486 basic_string<_CharT> __str = __sstr.str();
487 return __formatter::__write_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs);
557 return __formatter::__write_string(__sstr.view(), __ctx.out(), __specs);
488558}
489559
490560} // namespace __formatter
491561
492562template <__fmt_char_type _CharT>
493struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_chrono {
563struct _LIBCPP_TEMPLATE_VIS __formatter_chrono {
494564public:
495 _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(
496 basic_format_parse_context<_CharT>& __parse_ctx, __format_spec::__fields __fields, __format_spec::__flags __flags)
497 -> decltype(__parse_ctx.begin()) {
498 return __parser_.__parse(__parse_ctx, __fields, __flags);
565 template <class _ParseContext>
566 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator
567 __parse(_ParseContext& __ctx, __format_spec::__fields __fields, __format_spec::__flags __flags) {
568 return __parser_.__parse(__ctx, __fields, __flags);
499569 }
500570
501 template <class _Tp>
502 _LIBCPP_HIDE_FROM_ABI auto format(const _Tp& __value, auto& __ctx) const -> decltype(__ctx.out()) const {
571 template <class _Tp, class _FormatContext>
572 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _Tp& __value, _FormatContext& __ctx) const {
503573 return __formatter::__format_chrono(
504574 __value, __ctx, __parser_.__parser_.__get_parsed_chrono_specifications(__ctx), __parser_.__chrono_specs_);
505575 }
......@@ -507,13 +577,47 @@ public:
507577 __format_spec::__parser_chrono<_CharT> __parser_;
508578};
509579
580template <class _Duration, __fmt_char_type _CharT>
581struct _LIBCPP_TEMPLATE_VIS formatter<chrono::sys_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
582public:
583 using _Base = __formatter_chrono<_CharT>;
584
585 template <class _ParseContext>
586 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
587 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__clock);
588 }
589};
590
591template <class _Duration, __fmt_char_type _CharT>
592struct _LIBCPP_TEMPLATE_VIS formatter<chrono::file_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
593public:
594 using _Base = __formatter_chrono<_CharT>;
595
596 template <class _ParseContext>
597 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
598 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__clock);
599 }
600};
601
602template <class _Duration, __fmt_char_type _CharT>
603struct _LIBCPP_TEMPLATE_VIS formatter<chrono::local_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
604public:
605 using _Base = __formatter_chrono<_CharT>;
606
607 template <class _ParseContext>
608 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
609 // The flags are not __clock since there is no associated time-zone.
610 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date_time);
611 }
612};
613
510614template <class _Rep, class _Period, __fmt_char_type _CharT>
511615struct formatter<chrono::duration<_Rep, _Period>, _CharT> : public __formatter_chrono<_CharT> {
512616public:
513617 using _Base = __formatter_chrono<_CharT>;
514618
515 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
516 -> decltype(__parse_ctx.begin()) {
619 template <class _ParseContext>
620 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
517621 // [time.format]/1
518622 // Giving a precision specification in the chrono-format-spec is valid only
519623 // for std::chrono::duration types where the representation type Rep is a
......@@ -523,193 +627,203 @@ public:
523627 //
524628 // Note this doesn't refer to chrono::treat_as_floating_point_v<_Rep>.
525629 if constexpr (std::floating_point<_Rep>)
526 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono_fractional, __format_spec::__flags::__duration);
630 return _Base::__parse(__ctx, __format_spec::__fields_chrono_fractional, __format_spec::__flags::__duration);
527631 else
528 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__duration);
632 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__duration);
529633 }
530634};
531635
532636template <__fmt_char_type _CharT>
533struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::day, _CharT>
637struct _LIBCPP_TEMPLATE_VIS formatter<chrono::day, _CharT>
534638 : public __formatter_chrono<_CharT> {
535639public:
536640 using _Base = __formatter_chrono<_CharT>;
537641
538 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
539 -> decltype(__parse_ctx.begin()) {
540 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__day);
642 template <class _ParseContext>
643 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
644 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__day);
541645 }
542646};
543647
544648template <__fmt_char_type _CharT>
545struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month, _CharT>
649struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month, _CharT>
546650 : public __formatter_chrono<_CharT> {
547651public:
548652 using _Base = __formatter_chrono<_CharT>;
549653
550 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
551 -> decltype(__parse_ctx.begin()) {
552 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month);
654 template <class _ParseContext>
655 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
656 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month);
553657 }
554658};
555659
556660template <__fmt_char_type _CharT>
557struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year, _CharT>
661struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year, _CharT>
558662 : public __formatter_chrono<_CharT> {
559663public:
560664 using _Base = __formatter_chrono<_CharT>;
561665
562 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
563 -> decltype(__parse_ctx.begin()) {
564 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year);
666 template <class _ParseContext>
667 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
668 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year);
565669 }
566670};
567671
568672template <__fmt_char_type _CharT>
569struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekday, _CharT>
673struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday, _CharT>
570674 : public __formatter_chrono<_CharT> {
571675public:
572676 using _Base = __formatter_chrono<_CharT>;
573677
574 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
575 -> decltype(__parse_ctx.begin()) {
576 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
678 template <class _ParseContext>
679 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
680 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
577681 }
578682};
579683
580684template <__fmt_char_type _CharT>
581struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekday_indexed, _CharT>
685struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday_indexed, _CharT>
582686 : public __formatter_chrono<_CharT> {
583687public:
584688 using _Base = __formatter_chrono<_CharT>;
585689
586 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
587 -> decltype(__parse_ctx.begin()) {
588 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
690 template <class _ParseContext>
691 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
692 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
589693 }
590694};
591695
592696template <__fmt_char_type _CharT>
593struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekday_last, _CharT>
697struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday_last, _CharT>
594698 : public __formatter_chrono<_CharT> {
595699public:
596700 using _Base = __formatter_chrono<_CharT>;
597701
598 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
599 -> decltype(__parse_ctx.begin()) {
600 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
702 template <class _ParseContext>
703 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
704 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
601705 }
602706};
603707
604708template <__fmt_char_type _CharT>
605struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_day, _CharT>
709struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_day, _CharT>
606710 : public __formatter_chrono<_CharT> {
607711public:
608712 using _Base = __formatter_chrono<_CharT>;
609713
610 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
611 -> decltype(__parse_ctx.begin()) {
612 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_day);
714 template <class _ParseContext>
715 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
716 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_day);
613717 }
614718};
615719
616720template <__fmt_char_type _CharT>
617struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_day_last, _CharT>
721struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_day_last, _CharT>
618722 : public __formatter_chrono<_CharT> {
619723public:
620724 using _Base = __formatter_chrono<_CharT>;
621725
622 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
623 -> decltype(__parse_ctx.begin()) {
624 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month);
726 template <class _ParseContext>
727 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
728 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month);
625729 }
626730};
627731
628732template <__fmt_char_type _CharT>
629struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_weekday, _CharT>
733struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_weekday, _CharT>
630734 : public __formatter_chrono<_CharT> {
631735public:
632736 using _Base = __formatter_chrono<_CharT>;
633737
634 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
635 -> decltype(__parse_ctx.begin()) {
636 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
738 template <class _ParseContext>
739 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
740 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
637741 }
638742};
639743
640744template <__fmt_char_type _CharT>
641struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_weekday_last, _CharT>
745struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_weekday_last, _CharT>
642746 : public __formatter_chrono<_CharT> {
643747public:
644748 using _Base = __formatter_chrono<_CharT>;
645749
646 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
647 -> decltype(__parse_ctx.begin()) {
648 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
750 template <class _ParseContext>
751 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
752 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
649753 }
650754};
651755
652756template <__fmt_char_type _CharT>
653struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month, _CharT>
757struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month, _CharT>
654758 : public __formatter_chrono<_CharT> {
655759public:
656760 using _Base = __formatter_chrono<_CharT>;
657761
658 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
659 -> decltype(__parse_ctx.begin()) {
660 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year_month);
762 template <class _ParseContext>
763 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
764 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year_month);
661765 }
662766};
663767
664768template <__fmt_char_type _CharT>
665struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_day, _CharT>
769struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_day, _CharT>
666770 : public __formatter_chrono<_CharT> {
667771public:
668772 using _Base = __formatter_chrono<_CharT>;
669773
670 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
671 -> decltype(__parse_ctx.begin()) {
672 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
774 template <class _ParseContext>
775 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
776 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
673777 }
674778};
675779
676780template <__fmt_char_type _CharT>
677struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_day_last, _CharT>
781struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_day_last, _CharT>
678782 : public __formatter_chrono<_CharT> {
679783public:
680784 using _Base = __formatter_chrono<_CharT>;
681785
682 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
683 -> decltype(__parse_ctx.begin()) {
684 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
786 template <class _ParseContext>
787 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
788 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
685789 }
686790};
687791
688792template <__fmt_char_type _CharT>
689struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_weekday, _CharT>
793struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_weekday, _CharT>
690794 : public __formatter_chrono<_CharT> {
691795public:
692796 using _Base = __formatter_chrono<_CharT>;
693797
694 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
695 -> decltype(__parse_ctx.begin()) {
696 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
798 template <class _ParseContext>
799 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
800 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
697801 }
698802};
699803
700804template <__fmt_char_type _CharT>
701struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_weekday_last, _CharT>
805struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_weekday_last, _CharT>
702806 : public __formatter_chrono<_CharT> {
703807public:
704808 using _Base = __formatter_chrono<_CharT>;
705809
706 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
707 -> decltype(__parse_ctx.begin()) {
708 return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
810 template <class _ParseContext>
811 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
812 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
709813 }
710814};
711815
712#endif // if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
816template <class _Duration, __fmt_char_type _CharT>
817struct formatter<chrono::hh_mm_ss<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
818public:
819 using _Base = __formatter_chrono<_CharT>;
820
821 template <class _ParseContext>
822 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
823 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__time);
824 }
825};
826#endif // if _LIBCPP_STD_VER >= 20
713827
714828_LIBCPP_END_NAMESPACE_STD
715829
lib/libcxx/include/__chrono/hh_mm_ss.h+4-3
......@@ -13,14 +13,14 @@
1313#include <__chrono/duration.h>
1414#include <__chrono/time_point.h>
1515#include <__config>
16#include <__type_traits/common_type.h>
1617#include <ratio>
17#include <type_traits>
1818
1919#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2020# pragma GCC system_header
2121#endif
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
......@@ -85,6 +85,7 @@ private:
8585 chrono::seconds __s_;
8686 precision __f_;
8787};
88_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(hh_mm_ss);
8889
8990_LIBCPP_HIDE_FROM_ABI constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); }
9091_LIBCPP_HIDE_FROM_ABI constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); }
......@@ -107,6 +108,6 @@ _LIBCPP_HIDE_FROM_ABI constexpr hours make24(const hours& __h, bool __is_pm) noe
107108
108109_LIBCPP_END_NAMESPACE_STD
109110
110#endif // _LIBCPP_STD_VER > 17
111#endif // _LIBCPP_STD_VER >= 20
111112
112113#endif // _LIBCPP___CHRONO_HH_MM_SS_H
lib/libcxx/include/__chrono/literals.h+2-2
......@@ -18,7 +18,7 @@
1818# pragma GCC system_header
1919#endif
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
......@@ -44,6 +44,6 @@ namespace chrono { // hoist the literals into namespace std::chrono
4444
4545_LIBCPP_END_NAMESPACE_STD
4646
47#endif // _LIBCPP_STD_VER > 17
47#endif // _LIBCPP_STD_VER >= 20
4848
4949#endif // _LIBCPP___CHRONO_LITERALS_H
lib/libcxx/include/__chrono/month.h+5-5
......@@ -18,7 +18,7 @@
1818# pragma GCC system_header
1919#endif
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
......@@ -29,11 +29,11 @@ class month {
2929private:
3030 unsigned char __m_;
3131public:
32 _LIBCPP_HIDE_FROM_ABI month() = default;
32 month() = default;
3333 _LIBCPP_HIDE_FROM_ABI explicit inline constexpr month(unsigned __val) noexcept : __m_(static_cast<unsigned char>(__val)) {}
34 _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator++() noexcept { ++__m_; return *this; }
34 _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator++() noexcept { *this += months{1}; return *this; }
3535 _LIBCPP_HIDE_FROM_ABI inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; }
36 _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator--() noexcept { --__m_; return *this; }
36 _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator--() noexcept { *this -= months{1}; return *this; }
3737 _LIBCPP_HIDE_FROM_ABI inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; }
3838 _LIBCPP_HIDE_FROM_ABI constexpr month& operator+=(const months& __m1) noexcept;
3939 _LIBCPP_HIDE_FROM_ABI constexpr month& operator-=(const months& __m1) noexcept;
......@@ -98,6 +98,6 @@ inline constexpr month December{12};
9898
9999_LIBCPP_END_NAMESPACE_STD
100100
101#endif // _LIBCPP_STD_VER > 17
101#endif // _LIBCPP_STD_VER >= 20
102102
103103#endif // _LIBCPP___CHRONO_MONTH_H
lib/libcxx/include/__chrono/month_weekday.h+2-11
......@@ -18,7 +18,7 @@
1818# pragma GCC system_header
1919#endif
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
......@@ -41,10 +41,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
4141bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
4242{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
4343
44_LIBCPP_HIDE_FROM_ABI inline constexpr
45bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
46{ return !(__lhs == __rhs); }
47
4844_LIBCPP_HIDE_FROM_ABI inline constexpr
4945month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept
5046{ return month_weekday{__lhs, __rhs}; }
......@@ -77,11 +73,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
7773bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
7874{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
7975
80_LIBCPP_HIDE_FROM_ABI inline constexpr
81bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
82{ return !(__lhs == __rhs); }
83
84
8576_LIBCPP_HIDE_FROM_ABI inline constexpr
8677month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept
8778{ return month_weekday_last{__lhs, __rhs}; }
......@@ -101,6 +92,6 @@ month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept
10192
10293_LIBCPP_END_NAMESPACE_STD
10394
104#endif // _LIBCPP_STD_VER > 17
95#endif // _LIBCPP_STD_VER >= 20
10596
10697#endif // _LIBCPP___CHRONO_MONTH_WEEKDAY_H
lib/libcxx/include/__chrono/monthday.h+3-3
......@@ -20,7 +20,7 @@
2020# pragma GCC system_header
2121#endif
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
......@@ -32,7 +32,7 @@ private:
3232 chrono::month __m_;
3333 chrono::day __d_;
3434public:
35 _LIBCPP_HIDE_FROM_ABI month_day() = default;
35 month_day() = default;
3636 _LIBCPP_HIDE_FROM_ABI constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept
3737 : __m_{__mval}, __d_{__dval} {}
3838 _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; }
......@@ -124,6 +124,6 @@ month_day_last operator/(last_spec, int __rhs) noexcept
124124
125125_LIBCPP_END_NAMESPACE_STD
126126
127#endif // _LIBCPP_STD_VER > 17
127#endif // _LIBCPP_STD_VER >= 20
128128
129129#endif // _LIBCPP___CHRONO_MONTHDAY_H
lib/libcxx/include/__chrono/ostream.h+54-28
......@@ -10,12 +10,16 @@
1010#ifndef _LIBCPP___CHRONO_OSTREAM_H
1111#define _LIBCPP___CHRONO_OSTREAM_H
1212
13#include <__chrono/calendar.h>
1314#include <__chrono/day.h>
1415#include <__chrono/duration.h>
16#include <__chrono/file_clock.h>
17#include <__chrono/hh_mm_ss.h>
1518#include <__chrono/month.h>
1619#include <__chrono/month_weekday.h>
1720#include <__chrono/monthday.h>
1821#include <__chrono/statically_widen.h>
22#include <__chrono/system_clock.h>
1923#include <__chrono/weekday.h>
2024#include <__chrono/year.h>
2125#include <__chrono/year_month.h>
......@@ -33,10 +37,28 @@
3337
3438_LIBCPP_BEGIN_NAMESPACE_STD
3539
36#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
40#if _LIBCPP_STD_VER >= 20
3741
3842namespace chrono {
3943
44template <class _CharT, class _Traits, class _Duration>
45_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
46operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_time<_Duration> __tp) {
47 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp);
48}
49
50template <class _CharT, class _Traits, class _Duration>
51_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
52operator<<(basic_ostream<_CharT, _Traits>& __os, const file_time<_Duration> __tp) {
53 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp);
54}
55
56template <class _CharT, class _Traits, class _Duration>
57_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
58operator<<(basic_ostream<_CharT, _Traits>& __os, const local_time<_Duration> __tp) {
59 return __os << sys_time<_Duration>{__tp.time_since_epoch()};
60}
61
4062// Depending on the type the return is a const _CharT* or a basic_string<_CharT>
4163template <class _CharT, class _Period>
4264_LIBCPP_HIDE_FROM_ABI auto __units_suffix() {
......@@ -92,7 +114,7 @@ _LIBCPP_HIDE_FROM_ABI auto __units_suffix() {
92114}
93115
94116template <class _CharT, class _Traits, class _Rep, class _Period>
95_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
117_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
96118operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>& __d) {
97119 basic_ostringstream<_CharT, _Traits> __s;
98120 __s.flags(__os.flags());
......@@ -103,21 +125,19 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>&
103125}
104126
105127template <class _CharT, class _Traits>
106_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
107operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d) {
108 return __os
109 << (__d.ok()
110 ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%d}"), __d)
111 // Note this error differs from the wording of the Standard. The
112 // Standard wording doesn't work well on AIX or Windows. There
113 // the formatted day seems to be either modulo 100 or completely
114 // omitted. Judging by the wording this is valid.
115 // TODO FMT Write a paper of file an LWG issue.
116 : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02} is not a valid day"), static_cast<unsigned>(__d)));
128_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d) {
129 return __os << (__d.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%d}"), __d)
130 // Note this error differs from the wording of the Standard. The
131 // Standard wording doesn't work well on AIX or Windows. There
132 // the formatted day seems to be either modulo 100 or completely
133 // omitted. Judging by the wording this is valid.
134 // TODO FMT Write a paper of file an LWG issue.
135 : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02} is not a valid day"),
136 static_cast<unsigned>(__d)));
117137}
118138
119139template <class _CharT, class _Traits>
120_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
140_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
121141operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m) {
122142 return __os << (__m.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%b}"), __m)
123143 : std::format(__os.getloc(),
......@@ -126,14 +146,14 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m) {
126146}
127147
128148template <class _CharT, class _Traits>
129_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
149_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
130150operator<<(basic_ostream<_CharT, _Traits>& __os, const year& __y) {
131151 return __os << (__y.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y}"), __y)
132152 : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y} is not a valid year"), __y));
133153}
134154
135155template <class _CharT, class _Traits>
136_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
156_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
137157operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) {
138158 return __os << (__wd.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%a}"), __wd)
139159 : std::format(__os.getloc(), // TODO FMT Standard mandated locale isn't used.
......@@ -142,7 +162,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) {
142162}
143163
144164template <class _CharT, class _Traits>
145_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
165_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
146166operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) {
147167 auto __i = __wdi.index();
148168 return __os << (__i >= 1 && __i <= 5
......@@ -154,13 +174,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) {
154174}
155175
156176template <class _CharT, class _Traits>
157_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
177_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
158178operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_last& __wdl) {
159179 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[last]"), __wdl.weekday());
160180}
161181
162182template <class _CharT, class _Traits>
163_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
183_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
164184operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) {
165185 // TODO FMT The Standard allows 30th of February to be printed.
166186 // It would be nice to show an error message instead.
......@@ -168,47 +188,47 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) {
168188}
169189
170190template <class _CharT, class _Traits>
171_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
191_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
172192operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day_last& __mdl) {
173193 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/last"), __mdl.month());
174194}
175195
176196template <class _CharT, class _Traits>
177_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
197_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
178198operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday& __mwd) {
179199 return __os << std::format(
180200 __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwd.month(), __mwd.weekday_indexed());
181201}
182202
183203template <class _CharT, class _Traits>
184_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
204_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
185205operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday_last& __mwdl) {
186206 return __os << std::format(
187207 __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwdl.month(), __mwdl.weekday_last());
188208}
189209
190210template <class _CharT, class _Traits>
191_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
211_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
192212operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month& __ym) {
193213 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ym.year(), __ym.month());
194214}
195215
196216template <class _CharT, class _Traits>
197_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
217_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
198218operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day& __ymd) {
199219 return __os << (__ymd.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F}"), __ymd)
200220 : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F} is not a valid date"), __ymd));
201221}
202222
203223template <class _CharT, class _Traits>
204_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
224_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
205225operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day_last& __ymdl) {
206226 return __os << std::format(
207227 __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ymdl.year(), __ymdl.month_day_last());
208228}
209229
210230template <class _CharT, class _Traits>
211_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
231_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
212232operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymwd) {
213233 return __os << std::format(
214234 __os.getloc(),
......@@ -219,7 +239,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymw
219239}
220240
221241template <class _CharT, class _Traits>
222_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
242_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
223243operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last& __ymwdl) {
224244 return __os << std::format(
225245 __os.getloc(),
......@@ -229,9 +249,15 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last&
229249 __ymwdl.weekday_last());
230250}
231251
252template <class _CharT, class _Traits, class _Duration>
253_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
254operator<<(basic_ostream<_CharT, _Traits>& __os, const hh_mm_ss<_Duration> __hms) {
255 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%T}"), __hms);
256}
257
232258} // namespace chrono
233259
234#endif //if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
260#endif // if _LIBCPP_STD_VER >= 20
235261
236262_LIBCPP_END_NAMESPACE_STD
237263
lib/libcxx/include/__chrono/parser_std_format_spec.h+27-20
......@@ -24,7 +24,7 @@
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
27#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
27#if _LIBCPP_STD_VER >= 20
2828
2929namespace __format_spec {
3030
......@@ -137,17 +137,19 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __validate_time_zone(__flags __flags) {
137137
138138template <class _CharT>
139139class _LIBCPP_TEMPLATE_VIS __parser_chrono {
140 using _ConstIterator = typename basic_format_parse_context<_CharT>::const_iterator;
141
140142public:
141 _LIBCPP_HIDE_FROM_ABI constexpr auto
142 __parse(basic_format_parse_context<_CharT>& __parse_ctx, __fields __fields, __flags __flags)
143 -> decltype(__parse_ctx.begin()) {
144 const _CharT* __begin = __parser_.__parse(__parse_ctx, __fields);
145 const _CharT* __end = __parse_ctx.end();
143 template <class _ParseContext>
144 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator
145 __parse(_ParseContext& __ctx, __fields __fields, __flags __flags) {
146 _ConstIterator __begin = __parser_.__parse(__ctx, __fields);
147 _ConstIterator __end = __ctx.end();
146148 if (__begin == __end)
147149 return __begin;
148150
149 const _CharT* __last = __parse_chrono_specs(__begin, __end, __flags);
150 __chrono_specs_ = basic_string_view<_CharT>{__begin, __last};
151 _ConstIterator __last = __parse_chrono_specs(__begin, __end, __flags);
152 __chrono_specs_ = basic_string_view<_CharT>{__begin, __last};
151153
152154 return __last;
153155 }
......@@ -156,19 +158,20 @@ public:
156158 basic_string_view<_CharT> __chrono_specs_;
157159
158160private:
159 _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
160 __parse_chrono_specs(const _CharT* __begin, const _CharT* __end, __flags __flags) {
161 _LIBCPP_ASSERT(__begin != __end,
162 "When called with an empty input the function will cause "
163 "undefined behavior by evaluating data not in the input");
161 _LIBCPP_HIDE_FROM_ABI constexpr _ConstIterator
162 __parse_chrono_specs(_ConstIterator __begin, _ConstIterator __end, __flags __flags) {
163 _LIBCPP_ASSERT_UNCATEGORIZED(
164 __begin != __end,
165 "When called with an empty input the function will cause "
166 "undefined behavior by evaluating data not in the input");
164167
165168 if (*__begin != _CharT('%') && *__begin != _CharT('}'))
166 std::__throw_format_error("Expected '%' or '}' in the chrono format-string");
169 std::__throw_format_error("The format specifier expects a '%' or a '}'");
167170
168171 do {
169172 switch (*__begin) {
170173 case _CharT('{'):
171 std::__throw_format_error("The chrono-specs contains a '{'");
174 std::__throw_format_error("The chrono specifiers contain a '{'");
172175
173176 case _CharT('}'):
174177 return __begin;
......@@ -190,10 +193,10 @@ private:
190193 /// \pre *__begin == '%'
191194 /// \post __begin points at the end parsed conversion-spec
192195 _LIBCPP_HIDE_FROM_ABI constexpr void
193 __parse_conversion_spec(const _CharT*& __begin, const _CharT* __end, __flags __flags) {
196 __parse_conversion_spec(_ConstIterator& __begin, _ConstIterator __end, __flags __flags) {
194197 ++__begin;
195198 if (__begin == __end)
196 std::__throw_format_error("End of input while parsing the modifier chrono conversion-spec");
199 std::__throw_format_error("End of input while parsing a conversion specifier");
197200
198201 switch (*__begin) {
199202 case _CharT('n'):
......@@ -212,6 +215,7 @@ private:
212215 case _CharT('p'): // TODO FMT does the formater require an hour or a time?
213216 case _CharT('H'):
214217 case _CharT('I'):
218 __parser_.__hour_ = true;
215219 __validate_hour(__flags);
216220 break;
217221
......@@ -219,6 +223,7 @@ private:
219223 case _CharT('R'):
220224 case _CharT('T'):
221225 case _CharT('X'):
226 __parser_.__hour_ = true;
222227 __format_spec::__validate_time(__flags);
223228 break;
224229
......@@ -304,13 +309,14 @@ private:
304309 /// \pre *__begin == 'E'
305310 /// \post __begin is incremented by one.
306311 _LIBCPP_HIDE_FROM_ABI constexpr void
307 __parse_modifier_E(const _CharT*& __begin, const _CharT* __end, __flags __flags) {
312 __parse_modifier_E(_ConstIterator& __begin, _ConstIterator __end, __flags __flags) {
308313 ++__begin;
309314 if (__begin == __end)
310315 std::__throw_format_error("End of input while parsing the modifier E");
311316
312317 switch (*__begin) {
313318 case _CharT('X'):
319 __parser_.__hour_ = true;
314320 __format_spec::__validate_time(__flags);
315321 break;
316322
......@@ -343,7 +349,7 @@ private:
343349 /// \pre *__begin == 'O'
344350 /// \post __begin is incremented by one.
345351 _LIBCPP_HIDE_FROM_ABI constexpr void
346 __parse_modifier_O(const _CharT*& __begin, const _CharT* __end, __flags __flags) {
352 __parse_modifier_O(_ConstIterator& __begin, _ConstIterator __end, __flags __flags) {
347353 ++__begin;
348354 if (__begin == __end)
349355 std::__throw_format_error("End of input while parsing the modifier O");
......@@ -359,6 +365,7 @@ private:
359365
360366 case _CharT('I'):
361367 case _CharT('H'):
368 __parser_.__hour_ = true;
362369 __format_spec::__validate_hour(__flags);
363370 break;
364371
......@@ -403,7 +410,7 @@ private:
403410
404411} // namespace __format_spec
405412
406#endif //_LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
413#endif //_LIBCPP_STD_VER >= 20
407414
408415_LIBCPP_END_NAMESPACE_STD
409416
lib/libcxx/include/__chrono/statically_widen.h+3-3
......@@ -22,7 +22,7 @@
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
2828template <__fmt_char_type _CharT>
......@@ -33,7 +33,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __statically_widen(const char* __s
3333 return __wstr;
3434}
3535# define _LIBCPP_STATICALLY_WIDEN(_CharT, __str) ::std::__statically_widen<_CharT>(__str, L##__str)
36# else // _LIBCPP_HAS_NO_WIDE_CHARACTERS
36# else // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3737
3838// Without this indirection the unit test test/libcxx/modules_include.sh.cpp
3939// fails for the CI build "No wide characters". This seems like a bug.
......@@ -45,7 +45,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __statically_widen(const char* __s
4545# define _LIBCPP_STATICALLY_WIDEN(_CharT, __str) ::std::__statically_widen<_CharT>(__str)
4646# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4747
48#endif //_LIBCPP_STD_VER > 17
48#endif //_LIBCPP_STD_VER >= 20
4949
5050_LIBCPP_END_NAMESPACE_STD
5151
lib/libcxx/include/__chrono/steady_clock.h+1-1
......@@ -24,7 +24,7 @@ namespace chrono
2424{
2525
2626#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
27class _LIBCPP_TYPE_VIS steady_clock
27class _LIBCPP_EXPORTED_FROM_ABI steady_clock
2828{
2929public:
3030 typedef nanoseconds duration;
lib/libcxx/include/__chrono/system_clock.h+2-2
......@@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2424namespace chrono
2525{
2626
27class _LIBCPP_TYPE_VIS system_clock
27class _LIBCPP_EXPORTED_FROM_ABI system_clock
2828{
2929public:
3030 typedef microseconds duration;
......@@ -38,7 +38,7 @@ public:
3838 static time_point from_time_t(time_t __t) _NOEXCEPT;
3939};
4040
41#if _LIBCPP_STD_VER > 17
41#if _LIBCPP_STD_VER >= 20
4242
4343template <class _Duration>
4444using sys_time = time_point<system_clock, _Duration>;
lib/libcxx/include/__chrono/time_point.h+18-2
......@@ -11,6 +11,8 @@
1111#define _LIBCPP___CHRONO_TIME_POINT_H
1212
1313#include <__chrono/duration.h>
14#include <__compare/ordering.h>
15#include <__compare/three_way_comparable.h>
1416#include <__config>
1517#include <__type_traits/common_type.h>
1618#include <__type_traits/enable_if.h>
......@@ -90,7 +92,7 @@ time_point_cast(const time_point<_Clock, _Duration>& __t)
9092 return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
9193}
9294
93#if _LIBCPP_STD_VER > 14
95#if _LIBCPP_STD_VER >= 17
9496template <class _ToDuration, class _Clock, class _Duration>
9597inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
9698typename enable_if
......@@ -138,7 +140,7 @@ abs(duration<_Rep, _Period> __d)
138140{
139141 return __d >= __d.zero() ? +__d : -__d;
140142}
141#endif // _LIBCPP_STD_VER > 14
143#endif // _LIBCPP_STD_VER >= 17
142144
143145// time_point ==
144146
......@@ -150,6 +152,8 @@ operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock,
150152 return __lhs.time_since_epoch() == __rhs.time_since_epoch();
151153}
152154
155#if _LIBCPP_STD_VER <= 17
156
153157// time_point !=
154158
155159template <class _Clock, class _Duration1, class _Duration2>
......@@ -160,6 +164,8 @@ operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock,
160164 return !(__lhs == __rhs);
161165}
162166
167#endif // _LIBCPP_STD_VER <= 17
168
163169// time_point <
164170
165171template <class _Clock, class _Duration1, class _Duration2>
......@@ -200,6 +206,16 @@ operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock,
200206 return !(__lhs < __rhs);
201207}
202208
209#if _LIBCPP_STD_VER >= 20
210
211template <class _Clock, class _Duration1, three_way_comparable_with<_Duration1> _Duration2>
212_LIBCPP_HIDE_FROM_ABI constexpr auto
213operator<=>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
214 return __lhs.time_since_epoch() <=> __rhs.time_since_epoch();
215}
216
217#endif // _LIBCPP_STD_VER >= 20
218
203219// time_point operator+(time_point x, duration y);
204220
205221template <class _Clock, class _Duration1, class _Rep2, class _Period2>
lib/libcxx/include/__chrono/weekday.h+4-17
......@@ -20,7 +20,7 @@
2020# pragma GCC system_header
2121#endif
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
......@@ -35,7 +35,7 @@ private:
3535 unsigned char __wd_;
3636 _LIBCPP_HIDE_FROM_ABI static constexpr unsigned char __weekday_from_days(int __days) noexcept;
3737public:
38 _LIBCPP_HIDE_FROM_ABI weekday() = default;
38 weekday() = default;
3939 _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(unsigned __val) noexcept : __wd_(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {}
4040 _LIBCPP_HIDE_FROM_ABI inline constexpr weekday(const sys_days& __sysd) noexcept
4141 : __wd_(__weekday_from_days(__sysd.time_since_epoch().count())) {}
......@@ -69,10 +69,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
6969bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept
7070{ return __lhs.c_encoding() == __rhs.c_encoding(); }
7171
72_LIBCPP_HIDE_FROM_ABI inline constexpr
73bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept
74{ return !(__lhs == __rhs); }
75
7672_LIBCPP_HIDE_FROM_ABI inline constexpr
7773bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept
7874{ return __lhs.c_encoding() < __rhs.c_encoding(); }
......@@ -126,7 +122,7 @@ private:
126122 chrono::weekday __wd_;
127123 unsigned char __idx_;
128124public:
129 _LIBCPP_HIDE_FROM_ABI weekday_indexed() = default;
125 weekday_indexed() = default;
130126 _LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept
131127 : __wd_{__wdval}, __idx_(__idxval) {}
132128 _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wd_; }
......@@ -138,11 +134,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
138134bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
139135{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); }
140136
141_LIBCPP_HIDE_FROM_ABI inline constexpr
142bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
143{ return !(__lhs == __rhs); }
144
145
146137class weekday_last {
147138private:
148139 chrono::weekday __wd_;
......@@ -157,10 +148,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
157148bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
158149{ return __lhs.weekday() == __rhs.weekday(); }
159150
160_LIBCPP_HIDE_FROM_ABI inline constexpr
161bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
162{ return !(__lhs == __rhs); }
163
164151_LIBCPP_HIDE_FROM_ABI inline constexpr
165152weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; }
166153
......@@ -180,6 +167,6 @@ inline constexpr weekday Saturday{6};
180167
181168_LIBCPP_END_NAMESPACE_STD
182169
183#endif // _LIBCPP_STD_VER > 17
170#endif // _LIBCPP_STD_VER >= 20
184171
185172#endif // _LIBCPP___CHRONO_WEEKDAY_H
lib/libcxx/include/__chrono/year.h+3-3
......@@ -22,7 +22,7 @@
2222_LIBCPP_PUSH_MACROS
2323#include <__undef_macros>
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727_LIBCPP_BEGIN_NAMESPACE_STD
2828
......@@ -33,7 +33,7 @@ class year {
3333private:
3434 short __y_;
3535public:
36 _LIBCPP_HIDE_FROM_ABI year() = default;
36 year() = default;
3737 _LIBCPP_HIDE_FROM_ABI explicit inline constexpr year(int __val) noexcept : __y_(static_cast<short>(__val)) {}
3838
3939 _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator++() noexcept { ++__y_; return *this; }
......@@ -95,7 +95,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept {
9595
9696_LIBCPP_END_NAMESPACE_STD
9797
98#endif // _LIBCPP_STD_VER > 17
98#endif // _LIBCPP_STD_VER >= 20
9999
100100_LIBCPP_POP_MACROS
101101
lib/libcxx/include/__chrono/year_month.h+3-3
......@@ -20,7 +20,7 @@
2020# pragma GCC system_header
2121#endif
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
......@@ -31,7 +31,7 @@ class year_month {
3131 chrono::year __y_;
3232 chrono::month __m_;
3333public:
34 _LIBCPP_HIDE_FROM_ABI year_month() = default;
34 year_month() = default;
3535 _LIBCPP_HIDE_FROM_ABI constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept
3636 : __y_{__yval}, __m_{__mval} {}
3737 _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; }
......@@ -96,6 +96,6 @@ year_month operator-(const year_month& __lhs, const years& __rhs) noexcept
9696
9797_LIBCPP_END_NAMESPACE_STD
9898
99#endif // _LIBCPP_STD_VER > 17
99#endif // _LIBCPP_STD_VER >= 20
100100
101101#endif // _LIBCPP___CHRONO_YEAR_MONTH_H
lib/libcxx/include/__chrono/year_month_day.h+3-3
......@@ -27,7 +27,7 @@
2727# pragma GCC system_header
2828#endif
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_BEGIN_NAMESPACE_STD
3333
......@@ -42,7 +42,7 @@ private:
4242 chrono::month __m_;
4343 chrono::day __d_;
4444public:
45 _LIBCPP_HIDE_FROM_ABI year_month_day() = default;
45 year_month_day() = default;
4646 _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day(
4747 const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept
4848 : __y_{__yval}, __m_{__mval}, __d_{__dval} {}
......@@ -302,6 +302,6 @@ bool year_month_day::ok() const noexcept
302302
303303_LIBCPP_END_NAMESPACE_STD
304304
305#endif // _LIBCPP_STD_VER > 17
305#endif // _LIBCPP_STD_VER >= 20
306306
307307#endif // _LIBCPP___CHRONO_YEAR_MONTH_DAY_H
lib/libcxx/include/__chrono/year_month_weekday.h+3-12
......@@ -27,7 +27,7 @@
2727# pragma GCC system_header
2828#endif
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_BEGIN_NAMESPACE_STD
3333
......@@ -39,7 +39,7 @@ class year_month_weekday {
3939 chrono::month __m_;
4040 chrono::weekday_indexed __wdi_;
4141public:
42 _LIBCPP_HIDE_FROM_ABI year_month_weekday() = default;
42 year_month_weekday() = default;
4343 _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval,
4444 const chrono::weekday_indexed& __wdival) noexcept
4545 : __y_{__yval}, __m_{__mval}, __wdi_{__wdival} {}
......@@ -98,10 +98,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
9898bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
9999{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
100100
101_LIBCPP_HIDE_FROM_ABI inline constexpr
102bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
103{ return !(__lhs == __rhs); }
104
105101_LIBCPP_HIDE_FROM_ABI inline constexpr
106102year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept
107103{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; }
......@@ -191,11 +187,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
191187bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
192188{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
193189
194_LIBCPP_HIDE_FROM_ABI inline constexpr
195bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
196{ return !(__lhs == __rhs); }
197
198
199190_LIBCPP_HIDE_FROM_ABI inline constexpr
200191year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept
201192{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; }
......@@ -250,6 +241,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekd
250241
251242_LIBCPP_END_NAMESPACE_STD
252243
253#endif // _LIBCPP_STD_VER > 17
244#endif // _LIBCPP_STD_VER >= 20
254245
255246#endif // _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H
lib/libcxx/include/__compare/common_comparison_category.h+7-7
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525namespace __comp_detail {
2626
......@@ -65,14 +65,14 @@ _LIBCPP_HIDE_FROM_ABI
6565constexpr auto __get_comp_type() {
6666 using _CCC = _ClassifyCompCategory;
6767 constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...};
68 constexpr _CCC _Cat = __comp_detail::__compute_comp_type(__type_kinds);
69 if constexpr (_Cat == _None)
68 constexpr _CCC __cat = __comp_detail::__compute_comp_type(__type_kinds);
69 if constexpr (__cat == _None)
7070 return void();
71 else if constexpr (_Cat == _PartialOrd)
71 else if constexpr (__cat == _PartialOrd)
7272 return partial_ordering::equivalent;
73 else if constexpr (_Cat == _WeakOrd)
73 else if constexpr (__cat == _WeakOrd)
7474 return weak_ordering::equivalent;
75 else if constexpr (_Cat == _StrongOrd)
75 else if constexpr (__cat == _StrongOrd)
7676 return strong_ordering::equivalent;
7777 else
7878 static_assert(_False, "unhandled case");
......@@ -88,7 +88,7 @@ struct _LIBCPP_TEMPLATE_VIS common_comparison_category {
8888template<class... _Ts>
8989using common_comparison_category_t = typename common_comparison_category<_Ts...>::type;
9090
91#endif // _LIBCPP_STD_VER > 17
91#endif // _LIBCPP_STD_VER >= 20
9292
9393_LIBCPP_END_NAMESPACE_STD
9494
lib/libcxx/include/__compare/compare_partial_order_fallback.h+2-2
......@@ -23,7 +23,7 @@
2323
2424_LIBCPP_BEGIN_NAMESPACE_STD
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828// [cmp.alg]
2929namespace __compare_partial_order_fallback {
......@@ -67,7 +67,7 @@ inline namespace __cpo {
6767 inline constexpr auto compare_partial_order_fallback = __compare_partial_order_fallback::__fn{};
6868} // namespace __cpo
6969
70#endif // _LIBCPP_STD_VER > 17
70#endif // _LIBCPP_STD_VER >= 20
7171
7272_LIBCPP_END_NAMESPACE_STD
7373
lib/libcxx/include/__compare/compare_strong_order_fallback.h+2-2
......@@ -23,7 +23,7 @@
2323
2424_LIBCPP_BEGIN_NAMESPACE_STD
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828// [cmp.alg]
2929namespace __compare_strong_order_fallback {
......@@ -64,7 +64,7 @@ inline namespace __cpo {
6464 inline constexpr auto compare_strong_order_fallback = __compare_strong_order_fallback::__fn{};
6565} // namespace __cpo
6666
67#endif // _LIBCPP_STD_VER > 17
67#endif // _LIBCPP_STD_VER >= 20
6868
6969_LIBCPP_END_NAMESPACE_STD
7070
lib/libcxx/include/__compare/compare_three_way.h+2-2
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525struct _LIBCPP_TEMPLATE_VIS compare_three_way
2626{
......@@ -34,7 +34,7 @@ struct _LIBCPP_TEMPLATE_VIS compare_three_way
3434 using is_transparent = void;
3535};
3636
37#endif // _LIBCPP_STD_VER > 17
37#endif // _LIBCPP_STD_VER >= 20
3838
3939_LIBCPP_END_NAMESPACE_STD
4040
lib/libcxx/include/__compare/compare_three_way_result.h+2-2
......@@ -19,7 +19,7 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 17
22#if _LIBCPP_STD_VER >= 20
2323
2424template<class, class, class>
2525struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result { };
......@@ -37,7 +37,7 @@ struct _LIBCPP_TEMPLATE_VIS compare_three_way_result : __compare_three_way_resul
3737template<class _Tp, class _Up = _Tp>
3838using compare_three_way_result_t = typename compare_three_way_result<_Tp, _Up>::type;
3939
40#endif // _LIBCPP_STD_VER > 17
40#endif // _LIBCPP_STD_VER >= 20
4141
4242_LIBCPP_END_NAMESPACE_STD
4343
lib/libcxx/include/__compare/compare_weak_order_fallback.h+2-2
......@@ -23,7 +23,7 @@
2323
2424_LIBCPP_BEGIN_NAMESPACE_STD
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828// [cmp.alg]
2929namespace __compare_weak_order_fallback {
......@@ -64,7 +64,7 @@ inline namespace __cpo {
6464 inline constexpr auto compare_weak_order_fallback = __compare_weak_order_fallback::__fn{};
6565} // namespace __cpo
6666
67#endif // _LIBCPP_STD_VER > 17
67#endif // _LIBCPP_STD_VER >= 20
6868
6969_LIBCPP_END_NAMESPACE_STD
7070
lib/libcxx/include/__compare/is_eq.h+2-2
......@@ -18,7 +18,7 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; }
2424_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; }
......@@ -27,7 +27,7 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexce
2727_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; }
2828_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; }
2929
30#endif // _LIBCPP_STD_VER > 17
30#endif // _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_END_NAMESPACE_STD
3333
lib/libcxx/include/__compare/ordering.h+3-3
......@@ -19,7 +19,7 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 17
22#if _LIBCPP_STD_VER >= 20
2323
2424// exposition only
2525enum class _LIBCPP_ENUM_VIS _OrdResult : signed char {
......@@ -40,7 +40,7 @@ template<class _Tp, class... _Args>
4040inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...);
4141
4242struct _CmpUnspecifiedParam {
43 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEVAL
43 _LIBCPP_HIDE_FROM_ABI constexpr
4444 _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
4545
4646 template<class _Tp, class = enable_if_t<!__one_of_v<_Tp, int, partial_ordering, weak_ordering, strong_ordering>>>
......@@ -319,7 +319,7 @@ inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater)
319319template <class _Tp>
320320concept __comparison_category = __one_of_v<_Tp, partial_ordering, weak_ordering, strong_ordering>;
321321
322#endif // _LIBCPP_STD_VER > 17
322#endif // _LIBCPP_STD_VER >= 20
323323
324324_LIBCPP_END_NAMESPACE_STD
325325
lib/libcxx/include/__compare/partial_order.h+2-2
......@@ -24,7 +24,7 @@
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929// [cmp.alg]
3030namespace __partial_order {
......@@ -67,7 +67,7 @@ inline namespace __cpo {
6767 inline constexpr auto partial_order = __partial_order::__fn{};
6868} // namespace __cpo
6969
70#endif // _LIBCPP_STD_VER > 17
70#endif // _LIBCPP_STD_VER >= 20
7171
7272_LIBCPP_END_NAMESPACE_STD
7373
lib/libcxx/include/__compare/strong_order.h+2-2
......@@ -30,7 +30,7 @@ _LIBCPP_PUSH_MACROS
3030
3131_LIBCPP_BEGIN_NAMESPACE_STD
3232
33#if _LIBCPP_STD_VER > 17
33#if _LIBCPP_STD_VER >= 20
3434
3535// [cmp.alg]
3636namespace __strong_order {
......@@ -130,7 +130,7 @@ inline namespace __cpo {
130130 inline constexpr auto strong_order = __strong_order::__fn{};
131131} // namespace __cpo
132132
133#endif // _LIBCPP_STD_VER > 17
133#endif // _LIBCPP_STD_VER >= 20
134134
135135_LIBCPP_END_NAMESPACE_STD
136136
lib/libcxx/include/__compare/synth_three_way.h+23-17
......@@ -21,30 +21,36 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24#if _LIBCPP_STD_VER > 17
24#if _LIBCPP_STD_VER >= 20
2525
2626// [expos.only.func]
2727
28_LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way =
29 []<class _Tp, class _Up>(const _Tp& __t, const _Up& __u)
30 requires requires {
31 { __t < __u } -> __boolean_testable;
32 { __u < __t } -> __boolean_testable;
33 }
34 {
35 if constexpr (three_way_comparable_with<_Tp, _Up>) {
36 return __t <=> __u;
37 } else {
38 if (__t < __u) return weak_ordering::less;
39 if (__u < __t) return weak_ordering::greater;
40 return weak_ordering::equivalent;
41 }
42 };
28// TODO MODULES restore the lamba to match the Standard.
29// See https://github.com/llvm/llvm-project/issues/57222
30//_LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way =
31// []<class _Tp, class _Up>(const _Tp& __t, const _Up& __u)
32template <class _Tp, class _Up>
33_LIBCPP_HIDE_FROM_ABI constexpr auto __synth_three_way(const _Tp& __t, const _Up& __u)
34 requires requires {
35 { __t < __u } -> __boolean_testable;
36 { __u < __t } -> __boolean_testable;
37 }
38{
39 if constexpr (three_way_comparable_with<_Tp, _Up>) {
40 return __t <=> __u;
41 } else {
42 if (__t < __u)
43 return weak_ordering::less;
44 if (__u < __t)
45 return weak_ordering::greater;
46 return weak_ordering::equivalent;
47 }
48}
4349
4450template <class _Tp, class _Up = _Tp>
4551using __synth_three_way_result = decltype(std::__synth_three_way(std::declval<_Tp&>(), std::declval<_Up&>()));
4652
47#endif // _LIBCPP_STD_VER > 17
53#endif // _LIBCPP_STD_VER >= 20
4854
4955_LIBCPP_END_NAMESPACE_STD
5056
lib/libcxx/include/__compare/three_way_comparable.h+2-2
......@@ -25,7 +25,7 @@
2525
2626_LIBCPP_BEGIN_NAMESPACE_STD
2727
28#if _LIBCPP_STD_VER > 17
28#if _LIBCPP_STD_VER >= 20
2929
3030template<class _Tp, class _Cat>
3131concept __compares_as =
......@@ -52,7 +52,7 @@ concept three_way_comparable_with =
5252 { __u <=> __t } -> __compares_as<_Cat>;
5353 };
5454
55#endif // _LIBCPP_STD_VER > 17
55#endif // _LIBCPP_STD_VER >= 20
5656
5757_LIBCPP_END_NAMESPACE_STD
5858
lib/libcxx/include/__compare/weak_order.h+2-2
......@@ -24,7 +24,7 @@
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929// [cmp.alg]
3030namespace __weak_order {
......@@ -95,7 +95,7 @@ inline namespace __cpo {
9595 inline constexpr auto weak_order = __weak_order::__fn{};
9696} // namespace __cpo
9797
98#endif // _LIBCPP_STD_VER > 17
98#endif // _LIBCPP_STD_VER >= 20
9999
100100_LIBCPP_END_NAMESPACE_STD
101101
lib/libcxx/include/__concepts/arithmetic.h+6-6
......@@ -22,20 +22,20 @@
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727// [concepts.arithmetic], arithmetic concepts
2828
29template<class _Tp>
29template <class _Tp>
3030concept integral = is_integral_v<_Tp>;
3131
32template<class _Tp>
32template <class _Tp>
3333concept signed_integral = integral<_Tp> && is_signed_v<_Tp>;
3434
35template<class _Tp>
35template <class _Tp>
3636concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>;
3737
38template<class _Tp>
38template <class _Tp>
3939concept floating_point = is_floating_point_v<_Tp>;
4040
4141// Concept helpers for the internal type traits for the fundamental types.
......@@ -45,7 +45,7 @@ concept __libcpp_unsigned_integer = __libcpp_is_unsigned_integer<_Tp>::value;
4545template <class _Tp>
4646concept __libcpp_signed_integer = __libcpp_is_signed_integer<_Tp>::value;
4747
48#endif // _LIBCPP_STD_VER > 17
48#endif // _LIBCPP_STD_VER >= 20
4949
5050_LIBCPP_END_NAMESPACE_STD
5151
lib/libcxx/include/__concepts/assignable.h+8-8
......@@ -22,19 +22,19 @@
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727// [concept.assignable]
2828
29template<class _Lhs, class _Rhs>
29template <class _Lhs, class _Rhs>
3030concept assignable_from =
31 is_lvalue_reference_v<_Lhs> &&
32 common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> &&
33 requires (_Lhs __lhs, _Rhs&& __rhs) {
34 { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>;
35 };
31 is_lvalue_reference_v<_Lhs> &&
32 common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> &&
33 requires(_Lhs __lhs, _Rhs&& __rhs) {
34 { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>;
35 };
3636
37#endif // _LIBCPP_STD_VER > 17
37#endif // _LIBCPP_STD_VER >= 20
3838
3939_LIBCPP_END_NAMESPACE_STD
4040
lib/libcxx/include/__concepts/boolean_testable.h+4-4
......@@ -19,19 +19,19 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 17
22#if _LIBCPP_STD_VER >= 20
2323
2424// [concepts.booleantestable]
2525
26template<class _Tp>
26template <class _Tp>
2727concept __boolean_testable_impl = convertible_to<_Tp, bool>;
2828
29template<class _Tp>
29template <class _Tp>
3030concept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) {
3131 { !_VSTD::forward<_Tp>(__t) } -> __boolean_testable_impl;
3232};
3333
34#endif // _LIBCPP_STD_VER > 17
34#endif // _LIBCPP_STD_VER >= 20
3535
3636_LIBCPP_END_NAMESPACE_STD
3737
lib/libcxx/include/__concepts/class_or_enum.h+4-4
......@@ -21,19 +21,19 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24#if _LIBCPP_STD_VER > 17
24#if _LIBCPP_STD_VER >= 20
2525
2626// Whether a type is a class type or enumeration type according to the Core wording.
2727
28template<class _Tp>
28template <class _Tp>
2929concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>;
3030
3131// Work around Clang bug https://llvm.org/PR52970
3232// TODO: remove this workaround once libc++ no longer has to support Clang 13 (it was fixed in Clang 14).
33template<class _Tp>
33template <class _Tp>
3434concept __workaround_52970 = is_class_v<__remove_cvref_t<_Tp>> || is_union_v<__remove_cvref_t<_Tp>>;
3535
36#endif // _LIBCPP_STD_VER > 17
36#endif // _LIBCPP_STD_VER >= 20
3737
3838_LIBCPP_END_NAMESPACE_STD
3939
lib/libcxx/include/__concepts/common_reference_with.h+5-6
......@@ -20,17 +20,16 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525// [concept.commonref]
2626
27template<class _Tp, class _Up>
27template <class _Tp, class _Up>
2828concept common_reference_with =
29 same_as<common_reference_t<_Tp, _Up>, common_reference_t<_Up, _Tp>> &&
30 convertible_to<_Tp, common_reference_t<_Tp, _Up>> &&
31 convertible_to<_Up, common_reference_t<_Tp, _Up>>;
29 same_as<common_reference_t<_Tp, _Up>, common_reference_t<_Up, _Tp>> &&
30 convertible_to<_Tp, common_reference_t<_Tp, _Up>> && convertible_to<_Up, common_reference_t<_Tp, _Up>>;
3231
33#endif // _LIBCPP_STD_VER > 17
32#endif // _LIBCPP_STD_VER >= 20
3433
3534_LIBCPP_END_NAMESPACE_STD
3635
lib/libcxx/include/__concepts/common_with.h+19-17
......@@ -23,27 +23,29 @@
2323
2424_LIBCPP_BEGIN_NAMESPACE_STD
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828// [concept.common]
2929
30template<class _Tp, class _Up>
30// clang-format off
31template <class _Tp, class _Up>
3132concept common_with =
32 same_as<common_type_t<_Tp, _Up>, common_type_t<_Up, _Tp>> &&
33 requires {
34 static_cast<common_type_t<_Tp, _Up>>(std::declval<_Tp>());
35 static_cast<common_type_t<_Tp, _Up>>(std::declval<_Up>());
36 } &&
37 common_reference_with<
38 add_lvalue_reference_t<const _Tp>,
39 add_lvalue_reference_t<const _Up>> &&
40 common_reference_with<
41 add_lvalue_reference_t<common_type_t<_Tp, _Up>>,
42 common_reference_t<
43 add_lvalue_reference_t<const _Tp>,
44 add_lvalue_reference_t<const _Up>>>;
45
46#endif // _LIBCPP_STD_VER > 17
33 same_as<common_type_t<_Tp, _Up>, common_type_t<_Up, _Tp>> &&
34 requires {
35 static_cast<common_type_t<_Tp, _Up>>(std::declval<_Tp>());
36 static_cast<common_type_t<_Tp, _Up>>(std::declval<_Up>());
37 } &&
38 common_reference_with<
39 add_lvalue_reference_t<const _Tp>,
40 add_lvalue_reference_t<const _Up>> &&
41 common_reference_with<
42 add_lvalue_reference_t<common_type_t<_Tp, _Up>>,
43 common_reference_t<
44 add_lvalue_reference_t<const _Tp>,
45 add_lvalue_reference_t<const _Up>>>;
46// clang-format on
47
48#endif // _LIBCPP_STD_VER >= 20
4749
4850_LIBCPP_END_NAMESPACE_STD
4951
lib/libcxx/include/__concepts/constructible.h+16-17
......@@ -20,36 +20,35 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525// [concept.constructible]
26template<class _Tp, class... _Args>
27concept constructible_from =
28 destructible<_Tp> && is_constructible_v<_Tp, _Args...>;
26template <class _Tp, class... _Args>
27concept constructible_from = destructible<_Tp> && is_constructible_v<_Tp, _Args...>;
2928
3029// [concept.default.init]
3130
32template<class _Tp>
31template <class _Tp>
3332concept __default_initializable = requires { ::new _Tp; };
3433
35template<class _Tp>
36concept default_initializable = constructible_from<_Tp> &&
37 requires { _Tp{}; } && __default_initializable<_Tp>;
34template <class _Tp>
35concept default_initializable = constructible_from<_Tp> && requires { _Tp{}; } && __default_initializable<_Tp>;
3836
3937// [concept.moveconstructible]
40template<class _Tp>
41concept move_constructible =
42 constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>;
38template <class _Tp>
39concept move_constructible = constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>;
4340
4441// [concept.copyconstructible]
45template<class _Tp>
42// clang-format off
43template <class _Tp>
4644concept copy_constructible =
47 move_constructible<_Tp> &&
48 constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> &&
49 constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp> &&
50 constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>;
45 move_constructible<_Tp> &&
46 constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> &&
47 constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp> &&
48 constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>;
49// clang-format on
5150
52#endif // _LIBCPP_STD_VER > 17
51#endif // _LIBCPP_STD_VER >= 20
5352
5453_LIBCPP_END_NAMESPACE_STD
5554
lib/libcxx/include/__concepts/convertible_to.h+4-8
......@@ -19,18 +19,14 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 17
22#if _LIBCPP_STD_VER >= 20
2323
2424// [concept.convertible]
2525
26template<class _From, class _To>
27concept convertible_to =
28 is_convertible_v<_From, _To> &&
29 requires {
30 static_cast<_To>(std::declval<_From>());
31 };
26template <class _From, class _To>
27concept convertible_to = is_convertible_v<_From, _To> && requires { static_cast<_To>(std::declval<_From>()); };
3228
33#endif // _LIBCPP_STD_VER > 17
29#endif // _LIBCPP_STD_VER >= 20
3430
3531_LIBCPP_END_NAMESPACE_STD
3632
lib/libcxx/include/__concepts/copyable.h+11-9
......@@ -20,19 +20,21 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525// [concepts.object]
2626
27template<class _Tp>
27// clang-format off
28template <class _Tp>
2829concept copyable =
29 copy_constructible<_Tp> &&
30 movable<_Tp> &&
31 assignable_from<_Tp&, _Tp&> &&
32 assignable_from<_Tp&, const _Tp&> &&
33 assignable_from<_Tp&, const _Tp>;
34
35#endif // _LIBCPP_STD_VER > 17
30 copy_constructible<_Tp> &&
31 movable<_Tp> &&
32 assignable_from<_Tp&, _Tp&> &&
33 assignable_from<_Tp&, const _Tp&> &&
34 assignable_from<_Tp&, const _Tp>;
35// clang-format on
36
37#endif // _LIBCPP_STD_VER >= 20
3638
3739_LIBCPP_END_NAMESPACE_STD
3840
lib/libcxx/include/__concepts/derived_from.h+4-6
......@@ -19,16 +19,14 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 17
22#if _LIBCPP_STD_VER >= 20
2323
2424// [concept.derived]
2525
26template<class _Dp, class _Bp>
27concept derived_from =
28 is_base_of_v<_Bp, _Dp> &&
29 is_convertible_v<const volatile _Dp*, const volatile _Bp*>;
26template <class _Dp, class _Bp>
27concept derived_from = is_base_of_v<_Bp, _Dp> && is_convertible_v<const volatile _Dp*, const volatile _Bp*>;
3028
31#endif // _LIBCPP_STD_VER > 17
29#endif // _LIBCPP_STD_VER >= 20
3230
3331_LIBCPP_END_NAMESPACE_STD
3432
lib/libcxx/include/__concepts/destructible.h+3-3
......@@ -18,14 +18,14 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323// [concept.destructible]
2424
25template<class _Tp>
25template <class _Tp>
2626concept destructible = is_nothrow_destructible_v<_Tp>;
2727
28#endif // _LIBCPP_STD_VER > 17
28#endif // _LIBCPP_STD_VER >= 20
2929
3030_LIBCPP_END_NAMESPACE_STD
3131
lib/libcxx/include/__concepts/different_from.h+3-3
......@@ -19,12 +19,12 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 17
22#if _LIBCPP_STD_VER >= 20
2323
24template<class _Tp, class _Up>
24template <class _Tp, class _Up>
2525concept __different_from = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
2626
27#endif // _LIBCPP_STD_VER > 17
27#endif // _LIBCPP_STD_VER >= 20
2828
2929_LIBCPP_END_NAMESPACE_STD
3030
lib/libcxx/include/__concepts/equality_comparable.h+22-20
......@@ -21,33 +21,35 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24#if _LIBCPP_STD_VER > 17
24#if _LIBCPP_STD_VER >= 20
2525
2626// [concept.equalitycomparable]
2727
28template<class _Tp, class _Up>
28template <class _Tp, class _Up>
2929concept __weakly_equality_comparable_with =
30 requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
31 { __t == __u } -> __boolean_testable;
32 { __t != __u } -> __boolean_testable;
33 { __u == __t } -> __boolean_testable;
34 { __u != __t } -> __boolean_testable;
35 };
36
37template<class _Tp>
30 requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
31 { __t == __u } -> __boolean_testable;
32 { __t != __u } -> __boolean_testable;
33 { __u == __t } -> __boolean_testable;
34 { __u != __t } -> __boolean_testable;
35 };
36
37template <class _Tp>
3838concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>;
3939
40template<class _Tp, class _Up>
40// clang-format off
41template <class _Tp, class _Up>
4142concept equality_comparable_with =
42 equality_comparable<_Tp> && equality_comparable<_Up> &&
43 common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> &&
44 equality_comparable<
45 common_reference_t<
46 __make_const_lvalue_ref<_Tp>,
47 __make_const_lvalue_ref<_Up>>> &&
48 __weakly_equality_comparable_with<_Tp, _Up>;
49
50#endif // _LIBCPP_STD_VER > 17
43 equality_comparable<_Tp> && equality_comparable<_Up> &&
44 common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> &&
45 equality_comparable<
46 common_reference_t<
47 __make_const_lvalue_ref<_Tp>,
48 __make_const_lvalue_ref<_Up>>> &&
49 __weakly_equality_comparable_with<_Tp, _Up>;
50// clang-format on
51
52#endif // _LIBCPP_STD_VER >= 20
5153
5254_LIBCPP_END_NAMESPACE_STD
5355
lib/libcxx/include/__concepts/invocable.h+4-4
......@@ -19,21 +19,21 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 17
22#if _LIBCPP_STD_VER >= 20
2323
2424// [concept.invocable]
2525
26template<class _Fn, class... _Args>
26template <class _Fn, class... _Args>
2727concept invocable = requires(_Fn&& __fn, _Args&&... __args) {
2828 _VSTD::invoke(_VSTD::forward<_Fn>(__fn), _VSTD::forward<_Args>(__args)...); // not required to be equality preserving
2929};
3030
3131// [concept.regular.invocable]
3232
33template<class _Fn, class... _Args>
33template <class _Fn, class... _Args>
3434concept regular_invocable = invocable<_Fn, _Args...>;
3535
36#endif // _LIBCPP_STD_VER > 17
36#endif // _LIBCPP_STD_VER >= 20
3737
3838_LIBCPP_END_NAMESPACE_STD
3939
lib/libcxx/include/__concepts/movable.h+4-8
......@@ -21,18 +21,14 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24#if _LIBCPP_STD_VER > 17
24#if _LIBCPP_STD_VER >= 20
2525
2626// [concepts.object]
2727
28template<class _Tp>
29concept movable =
30 is_object_v<_Tp> &&
31 move_constructible<_Tp> &&
32 assignable_from<_Tp&, _Tp> &&
33 swappable<_Tp>;
28template <class _Tp>
29concept movable = is_object_v<_Tp> && move_constructible<_Tp> && assignable_from<_Tp&, _Tp> && swappable<_Tp>;
3430
35#endif // _LIBCPP_STD_VER > 17
31#endif // _LIBCPP_STD_VER >= 20
3632
3733_LIBCPP_END_NAMESPACE_STD
3834
lib/libcxx/include/__concepts/predicate.h+4-5
......@@ -20,15 +20,14 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525// [concept.predicate]
2626
27template<class _Fn, class... _Args>
28concept predicate =
29 regular_invocable<_Fn, _Args...> && __boolean_testable<invoke_result_t<_Fn, _Args...>>;
27template <class _Fn, class... _Args>
28concept predicate = regular_invocable<_Fn, _Args...> && __boolean_testable<invoke_result_t<_Fn, _Args...>>;
3029
31#endif // _LIBCPP_STD_VER > 17
30#endif // _LIBCPP_STD_VER >= 20
3231
3332_LIBCPP_END_NAMESPACE_STD
3433
lib/libcxx/include/__concepts/regular.h+3-3
......@@ -19,14 +19,14 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 17
22#if _LIBCPP_STD_VER >= 20
2323
2424// [concept.object]
2525
26template<class _Tp>
26template <class _Tp>
2727concept regular = semiregular<_Tp> && equality_comparable<_Tp>;
2828
29#endif // _LIBCPP_STD_VER > 17
29#endif // _LIBCPP_STD_VER >= 20
3030
3131_LIBCPP_END_NAMESPACE_STD
3232
lib/libcxx/include/__concepts/relation.h+6-7
......@@ -18,26 +18,25 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323// [concept.relation]
2424
25template<class _Rp, class _Tp, class _Up>
25template <class _Rp, class _Tp, class _Up>
2626concept relation =
27 predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> &&
28 predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>;
27 predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> && predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>;
2928
3029// [concept.equiv]
3130
32template<class _Rp, class _Tp, class _Up>
31template <class _Rp, class _Tp, class _Up>
3332concept equivalence_relation = relation<_Rp, _Tp, _Up>;
3433
3534// [concept.strictweakorder]
3635
37template<class _Rp, class _Tp, class _Up>
36template <class _Rp, class _Tp, class _Up>
3837concept strict_weak_order = relation<_Rp, _Tp, _Up>;
3938
40#endif // _LIBCPP_STD_VER > 17
39#endif // _LIBCPP_STD_VER >= 20
4140
4241_LIBCPP_END_NAMESPACE_STD
4342
lib/libcxx/include/__concepts/same_as.h+4-4
......@@ -18,17 +18,17 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323// [concept.same]
2424
25template<class _Tp, class _Up>
25template <class _Tp, class _Up>
2626concept __same_as_impl = _IsSame<_Tp, _Up>::value;
2727
28template<class _Tp, class _Up>
28template <class _Tp, class _Up>
2929concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>;
3030
31#endif // _LIBCPP_STD_VER > 17
31#endif // _LIBCPP_STD_VER >= 20
3232
3333_LIBCPP_END_NAMESPACE_STD
3434
lib/libcxx/include/__concepts/semiregular.h+3-3
......@@ -19,14 +19,14 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 17
22#if _LIBCPP_STD_VER >= 20
2323
2424// [concept.object]
2525
26template<class _Tp>
26template <class _Tp>
2727concept semiregular = copyable<_Tp> && default_initializable<_Tp>;
2828
29#endif // _LIBCPP_STD_VER > 17
29#endif // _LIBCPP_STD_VER >= 20
3030
3131_LIBCPP_END_NAMESPACE_STD
3232
lib/libcxx/include/__concepts/swappable.h+63-61
......@@ -28,94 +28,96 @@
2828# pragma GCC system_header
2929#endif
3030
31_LIBCPP_PUSH_MACROS
32#include <__undef_macros>
33
3134_LIBCPP_BEGIN_NAMESPACE_STD
3235
33#if _LIBCPP_STD_VER > 17
36#if _LIBCPP_STD_VER >= 20
3437
3538// [concept.swappable]
3639
3740namespace ranges {
3841namespace __swap {
3942
40 template<class _Tp>
41 void swap(_Tp&, _Tp&) = delete;
43template <class _Tp>
44void swap(_Tp&, _Tp&) = delete;
4245
43 template<class _Tp, class _Up>
44 concept __unqualified_swappable_with =
46// clang-format off
47template <class _Tp, class _Up>
48concept __unqualified_swappable_with =
4549 (__class_or_enum<remove_cvref_t<_Tp>> || __class_or_enum<remove_cvref_t<_Up>>) &&
4650 requires(_Tp&& __t, _Up&& __u) {
47 swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
51 swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
4852 };
53// clang-format on
4954
50 struct __fn;
55struct __fn;
5156
52 template<class _Tp, class _Up, size_t _Size>
53 concept __swappable_arrays =
54 !__unqualified_swappable_with<_Tp(&)[_Size], _Up(&)[_Size]> &&
57// clang-format off
58template <class _Tp, class _Up, size_t _Size>
59concept __swappable_arrays =
60 !__unqualified_swappable_with<_Tp (&)[_Size], _Up (&)[_Size]> &&
5561 extent_v<_Tp> == extent_v<_Up> &&
56 requires(_Tp(& __t)[_Size], _Up(& __u)[_Size], const __fn& __swap) {
57 __swap(__t[0], __u[0]);
62 requires(_Tp (&__t)[_Size], _Up (&__u)[_Size], const __fn& __swap) {
63 __swap(__t[0], __u[0]);
5864 };
59
60 template<class _Tp>
61 concept __exchangeable =
62 !__unqualified_swappable_with<_Tp&, _Tp&> &&
63 move_constructible<_Tp> &&
64 assignable_from<_Tp&, _Tp>;
65
66 struct __fn {
67 // 2.1 `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and...
68 // *The name `swap` is used here unqualified.
69 template<class _Tp, class _Up>
70 requires __unqualified_swappable_with<_Tp, _Up>
71 constexpr void operator()(_Tp&& __t, _Up&& __u) const
72 noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))
73 {
74 swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
75 }
76
77 // 2.2 Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and...
78 template<class _Tp, class _Up, size_t _Size>
79 requires __swappable_arrays<_Tp, _Up, _Size>
80 constexpr void operator()(_Tp(& __t)[_Size], _Up(& __u)[_Size]) const
81 noexcept(noexcept((*this)(*__t, *__u)))
82 {
83 // TODO(cjdb): replace with `ranges::swap_ranges`.
84 for (size_t __i = 0; __i < _Size; ++__i) {
85 (*this)(__t[__i], __u[__i]);
86 }
65// clang-format on
66
67template <class _Tp>
68concept __exchangeable =
69 !__unqualified_swappable_with<_Tp&, _Tp&> && move_constructible<_Tp> && assignable_from<_Tp&, _Tp>;
70
71struct __fn {
72 // 2.1 `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and...
73 // *The name `swap` is used here unqualified.
74 template <class _Tp, class _Up>
75 requires __unqualified_swappable_with<_Tp, _Up>
76 _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp&& __t, _Up&& __u) const
77 noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) {
78 swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
79 }
80
81 // 2.2 Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and...
82 template <class _Tp, class _Up, size_t _Size>
83 requires __swappable_arrays<_Tp, _Up, _Size>
84 _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp (&__t)[_Size], _Up (&__u)[_Size]) const
85 noexcept(noexcept((*this)(*__t, *__u))) {
86 // TODO(cjdb): replace with `ranges::swap_ranges`.
87 for (size_t __i = 0; __i < _Size; ++__i) {
88 (*this)(__t[__i], __u[__i]);
8789 }
88
89 // 2.3 Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models...
90 template<__exchangeable _Tp>
91 constexpr void operator()(_Tp& __x, _Tp& __y) const
92 noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>)
93 {
94 __y = _VSTD::exchange(__x, _VSTD::move(__y));
95 }
96 };
90 }
91
92 // 2.3 Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models...
93 template <__exchangeable _Tp>
94 _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp& __x, _Tp& __y) const
95 noexcept(is_nothrow_move_constructible_v<_Tp>&& is_nothrow_move_assignable_v<_Tp>) {
96 __y = _VSTD::exchange(__x, _VSTD::move(__y));
97 }
98};
9799} // namespace __swap
98100
99101inline namespace __cpo {
100 inline constexpr auto swap = __swap::__fn{};
102inline constexpr auto swap = __swap::__fn{};
101103} // namespace __cpo
102104} // namespace ranges
103105
104template<class _Tp>
106template <class _Tp>
105107concept swappable = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); };
106108
107template<class _Tp, class _Up>
108concept swappable_with =
109 common_reference_with<_Tp, _Up> &&
110 requires(_Tp&& __t, _Up&& __u) {
111 ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t));
112 ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u));
113 ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
114 ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t));
115 };
109template <class _Tp, class _Up>
110concept swappable_with = common_reference_with<_Tp, _Up> && requires(_Tp&& __t, _Up&& __u) {
111 ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t));
112 ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u));
113 ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
114 ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t));
115};
116116
117#endif // _LIBCPP_STD_VER > 17
117#endif // _LIBCPP_STD_VER >= 20
118118
119119_LIBCPP_END_NAMESPACE_STD
120120
121_LIBCPP_POP_MACROS
122
121123#endif // _LIBCPP___CONCEPTS_SWAPPABLE_H
lib/libcxx/include/__concepts/totally_ordered.h+26-25
......@@ -21,37 +21,38 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24#if _LIBCPP_STD_VER > 17
24#if _LIBCPP_STD_VER >= 20
2525
2626// [concept.totallyordered]
2727
28template<class _Tp, class _Up>
29concept __partially_ordered_with =
30 requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
31 { __t < __u } -> __boolean_testable;
32 { __t > __u } -> __boolean_testable;
33 { __t <= __u } -> __boolean_testable;
34 { __t >= __u } -> __boolean_testable;
35 { __u < __t } -> __boolean_testable;
36 { __u > __t } -> __boolean_testable;
37 { __u <= __t } -> __boolean_testable;
38 { __u >= __t } -> __boolean_testable;
39 };
40
41template<class _Tp>
28template <class _Tp, class _Up>
29concept __partially_ordered_with = requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
30 { __t < __u } -> __boolean_testable;
31 { __t > __u } -> __boolean_testable;
32 { __t <= __u } -> __boolean_testable;
33 { __t >= __u } -> __boolean_testable;
34 { __u < __t } -> __boolean_testable;
35 { __u > __t } -> __boolean_testable;
36 { __u <= __t } -> __boolean_testable;
37 { __u >= __t } -> __boolean_testable;
38};
39
40template <class _Tp>
4241concept totally_ordered = equality_comparable<_Tp> && __partially_ordered_with<_Tp, _Tp>;
4342
44template<class _Tp, class _Up>
43// clang-format off
44template <class _Tp, class _Up>
4545concept totally_ordered_with =
46 totally_ordered<_Tp> && totally_ordered<_Up> &&
47 equality_comparable_with<_Tp, _Up> &&
48 totally_ordered<
49 common_reference_t<
50 __make_const_lvalue_ref<_Tp>,
51 __make_const_lvalue_ref<_Up>>> &&
52 __partially_ordered_with<_Tp, _Up>;
53
54#endif // _LIBCPP_STD_VER > 17
46 totally_ordered<_Tp> && totally_ordered<_Up> &&
47 equality_comparable_with<_Tp, _Up> &&
48 totally_ordered<
49 common_reference_t<
50 __make_const_lvalue_ref<_Tp>,
51 __make_const_lvalue_ref<_Up>>> &&
52 __partially_ordered_with<_Tp, _Up>;
53// clang-format on
54
55#endif // _LIBCPP_STD_VER >= 20
5556
5657_LIBCPP_END_NAMESPACE_STD
5758
lib/libcxx/include/__condition_variable/condition_variable.h created+245
......@@ -0,0 +1,245 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___CONDITION_VARIABLE_CONDITION_VARIABLE_H
10#define _LIBCPP___CONDITION_VARIABLE_CONDITION_VARIABLE_H
11
12#include <__chrono/steady_clock.h>
13#include <__chrono/system_clock.h>
14#include <__chrono/time_point.h>
15#include <__config>
16#include <__mutex/mutex.h>
17#include <__mutex/unique_lock.h>
18#include <__system_error/system_error.h>
19#include <__threading_support>
20#include <__type_traits/enable_if.h>
21#include <__type_traits/is_floating_point.h>
22#include <__utility/move.h>
23#include <limits>
24#include <ratio>
25
26#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27# pragma GCC system_header
28#endif
29
30_LIBCPP_PUSH_MACROS
31#include <__undef_macros>
32
33_LIBCPP_BEGIN_NAMESPACE_STD
34
35#ifndef _LIBCPP_HAS_NO_THREADS
36
37// enum class cv_status
38_LIBCPP_DECLARE_STRONG_ENUM(cv_status){no_timeout, timeout};
39_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status)
40
41class _LIBCPP_EXPORTED_FROM_ABI condition_variable {
42 __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
43
44public:
45 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR condition_variable() _NOEXCEPT = default;
46
47# ifdef _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
48 ~condition_variable() = default;
49# else
50 ~condition_variable();
51# endif
52
53 condition_variable(const condition_variable&) = delete;
54 condition_variable& operator=(const condition_variable&) = delete;
55
56 void notify_one() _NOEXCEPT;
57 void notify_all() _NOEXCEPT;
58
59 void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
60 template <class _Predicate>
61 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS void wait(unique_lock<mutex>& __lk, _Predicate __pred);
62
63 template <class _Clock, class _Duration>
64 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS cv_status
65 wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t);
66
67 template <class _Clock, class _Duration, class _Predicate>
68 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
69 wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t, _Predicate __pred);
70
71 template <class _Rep, class _Period>
72 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS cv_status
73 wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d);
74
75 template <class _Rep, class _Period, class _Predicate>
76 bool _LIBCPP_HIDE_FROM_ABI
77 wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred);
78
79 typedef __libcpp_condvar_t* native_handle_type;
80 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }
81
82private:
83 void
84 __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
85# if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
86 _LIBCPP_HIDE_FROM_ABI void
87 __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::steady_clock, chrono::nanoseconds>) _NOEXCEPT;
88# endif
89 template <class _Clock>
90 _LIBCPP_HIDE_FROM_ABI void
91 __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT;
92};
93#endif // !_LIBCPP_HAS_NO_THREADS
94
95template <class _Rep, class _Period>
96inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<is_floating_point<_Rep>::value, chrono::nanoseconds>
97__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) {
98 using namespace chrono;
99 using __ratio = ratio_divide<_Period, nano>;
100 using __ns_rep = nanoseconds::rep;
101 _Rep __result_float = __d.count() * __ratio::num / __ratio::den;
102
103 _Rep __result_max = numeric_limits<__ns_rep>::max();
104 if (__result_float >= __result_max) {
105 return nanoseconds::max();
106 }
107
108 _Rep __result_min = numeric_limits<__ns_rep>::min();
109 if (__result_float <= __result_min) {
110 return nanoseconds::min();
111 }
112
113 return nanoseconds(static_cast<__ns_rep>(__result_float));
114}
115
116template <class _Rep, class _Period>
117inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<!is_floating_point<_Rep>::value, chrono::nanoseconds>
118__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) {
119 using namespace chrono;
120 if (__d.count() == 0) {
121 return nanoseconds(0);
122 }
123
124 using __ratio = ratio_divide<_Period, nano>;
125 using __ns_rep = nanoseconds::rep;
126 __ns_rep __result_max = numeric_limits<__ns_rep>::max();
127 if (__d.count() > 0 && __d.count() > __result_max / __ratio::num) {
128 return nanoseconds::max();
129 }
130
131 __ns_rep __result_min = numeric_limits<__ns_rep>::min();
132 if (__d.count() < 0 && __d.count() < __result_min / __ratio::num) {
133 return nanoseconds::min();
134 }
135
136 __ns_rep __result = __d.count() * __ratio::num / __ratio::den;
137 if (__result == 0) {
138 return nanoseconds(1);
139 }
140
141 return nanoseconds(__result);
142}
143
144#ifndef _LIBCPP_HAS_NO_THREADS
145template <class _Predicate>
146void condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred) {
147 while (!__pred())
148 wait(__lk);
149}
150
151template <class _Clock, class _Duration>
152cv_status condition_variable::wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t) {
153 using namespace chrono;
154 using __clock_tp_ns = time_point<_Clock, nanoseconds>;
155
156 typename _Clock::time_point __now = _Clock::now();
157 if (__t <= __now)
158 return cv_status::timeout;
159
160 __clock_tp_ns __t_ns = __clock_tp_ns(std::__safe_nanosecond_cast(__t.time_since_epoch()));
161
162 __do_timed_wait(__lk, __t_ns);
163 return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
164}
165
166template <class _Clock, class _Duration, class _Predicate>
167bool condition_variable::wait_until(
168 unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t, _Predicate __pred) {
169 while (!__pred()) {
170 if (wait_until(__lk, __t) == cv_status::timeout)
171 return __pred();
172 }
173 return true;
174}
175
176template <class _Rep, class _Period>
177cv_status condition_variable::wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d) {
178 using namespace chrono;
179 if (__d <= __d.zero())
180 return cv_status::timeout;
181 using __ns_rep = nanoseconds::rep;
182 steady_clock::time_point __c_now = steady_clock::now();
183
184# if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
185 using __clock_tp_ns = time_point<steady_clock, nanoseconds>;
186 __ns_rep __now_count_ns = std::__safe_nanosecond_cast(__c_now.time_since_epoch()).count();
187# else
188 using __clock_tp_ns = time_point<system_clock, nanoseconds>;
189 __ns_rep __now_count_ns = std::__safe_nanosecond_cast(system_clock::now().time_since_epoch()).count();
190# endif
191
192 __ns_rep __d_ns_count = std::__safe_nanosecond_cast(__d).count();
193
194 if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) {
195 __do_timed_wait(__lk, __clock_tp_ns::max());
196 } else {
197 __do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count)));
198 }
199
200 return steady_clock::now() - __c_now < __d ? cv_status::no_timeout : cv_status::timeout;
201}
202
203template <class _Rep, class _Period, class _Predicate>
204inline bool
205condition_variable::wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred) {
206 return wait_until(__lk, chrono::steady_clock::now() + __d, std::move(__pred));
207}
208
209# if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
210inline void condition_variable::__do_timed_wait(
211 unique_lock<mutex>& __lk, chrono::time_point<chrono::steady_clock, chrono::nanoseconds> __tp) _NOEXCEPT {
212 using namespace chrono;
213 if (!__lk.owns_lock())
214 __throw_system_error(EPERM, "condition_variable::timed wait: mutex not locked");
215 nanoseconds __d = __tp.time_since_epoch();
216 timespec __ts;
217 seconds __s = duration_cast<seconds>(__d);
218 using __ts_sec = decltype(__ts.tv_sec);
219 const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max();
220 if (__s.count() < __ts_sec_max) {
221 __ts.tv_sec = static_cast<__ts_sec>(__s.count());
222 __ts.tv_nsec = (__d - __s).count();
223 } else {
224 __ts.tv_sec = __ts_sec_max;
225 __ts.tv_nsec = giga::num - 1;
226 }
227 int __ec = pthread_cond_clockwait(&__cv_, __lk.mutex()->native_handle(), CLOCK_MONOTONIC, &__ts);
228 if (__ec != 0 && __ec != ETIMEDOUT)
229 __throw_system_error(__ec, "condition_variable timed_wait failed");
230}
231# endif // _LIBCPP_HAS_COND_CLOCKWAIT
232
233template <class _Clock>
234inline void condition_variable::__do_timed_wait(unique_lock<mutex>& __lk,
235 chrono::time_point<_Clock, chrono::nanoseconds> __tp) _NOEXCEPT {
236 wait_for(__lk, __tp - _Clock::now());
237}
238
239#endif // _LIBCPP_HAS_NO_THREADS
240
241_LIBCPP_END_NAMESPACE_STD
242
243_LIBCPP_POP_MACROS
244
245#endif // _LIBCPP___CONDITION_VARIABLE_CONDITION_VARIABLE_H
lib/libcxx/include/__config+284-69
......@@ -35,10 +35,12 @@
3535
3636#ifdef __cplusplus
3737
38// The attributes supported by clang are documented at https://clang.llvm.org/docs/AttributeReference.html
39
3840// _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM.
39// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 16.0.1 == 16.00.01), _LIBCPP_VERSION is
41// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is
4042// defined to XXYYZZ.
41# define _LIBCPP_VERSION 160001
43# define _LIBCPP_VERSION 170000
4244
4345# define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
4446# define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)
......@@ -51,6 +53,7 @@
5153# define _LIBCPP_FREESTANDING
5254# endif
5355
56// NOLINTBEGIN(libcpp-cpp-version-check)
5457# ifndef _LIBCPP_STD_VER
5558# if __cplusplus <= 201103L
5659# define _LIBCPP_STD_VER 11
......@@ -60,11 +63,14 @@
6063# define _LIBCPP_STD_VER 17
6164# elif __cplusplus <= 202002L
6265# define _LIBCPP_STD_VER 20
66# elif __cplusplus <= 202302L
67# define _LIBCPP_STD_VER 23
6368# else
6469// Expected release year of the next C++ standard
65# define _LIBCPP_STD_VER 23
70# define _LIBCPP_STD_VER 26
6671# endif
6772# endif // _LIBCPP_STD_VER
73// NOLINTEND(libcpp-cpp-version-check)
6874
6975# if defined(__ELF__)
7076# define _LIBCPP_OBJECT_FORMAT_ELF 1
......@@ -80,6 +86,8 @@
8086// ... add new file formats here ...
8187# endif
8288
89// ABI {
90
8391# if _LIBCPP_ABI_VERSION >= 2
8492// Change short string representation so that string data starts at offset 0,
8593// improving its alignment in some cases.
......@@ -165,6 +173,12 @@
165173# if defined(__FreeBSD__)
166174# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
167175# endif
176// For XCOFF linkers, we have problems if we see a weak hidden version of a symbol
177// in user code (like you get with -fvisibility-inlines-hidden) and then a strong def
178// in the library, so we need to always rely on the library version.
179# if defined(_AIX)
180# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
181# endif
168182# endif
169183
170184# if defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_ABI_VERSION >= 2
......@@ -179,9 +193,151 @@
179193# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
180194# endif
181195
196// Changes the iterator type of select containers (see below) to a bounded iterator that keeps track of whether it's
197// within the bounds of the original container and asserts it on every dereference.
198//
199// ABI impact: changes the iterator type of the relevant containers.
200//
201// Supported containers:
202// - `span`;
203// - `string_view`;
204// - `array`.
205// #define _LIBCPP_ABI_BOUNDED_ITERATORS
206
207// } ABI
208
209// HARDENING {
210
211# ifndef _LIBCPP_ENABLE_ASSERTIONS
212# define _LIBCPP_ENABLE_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS_DEFAULT
213# endif
214# if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1
215# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1"
216# endif
217
218// NOTE: These modes are experimental and are not stable yet in LLVM 17. Please refrain from using them and use the
219// documented libc++ "safe" mode instead.
220//
221// Enables the hardened mode which consists of all checks intended to be used in production. Hardened mode prioritizes
222// security-critical checks that can be done with relatively little overhead in constant time. Mutually exclusive with
223// `_LIBCPP_ENABLE_DEBUG_MODE`.
224//
225// #define _LIBCPP_ENABLE_HARDENED_MODE 1
226
227// Enables the debug mode which contains all the checks from the hardened mode and additionally more expensive checks
228// that may affect the complexity of algorithms. The debug mode is intended to be used for testing, not in production.
229// Mutually exclusive with `_LIBCPP_ENABLE_HARDENED_MODE`.
230//
231// #define _LIBCPP_ENABLE_DEBUG_MODE 1
232
233// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These
234// macros are only for internal use -- users should only pick one of the high-level hardening modes described above.
235//
236// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and
237// a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid:
238// - the sentinel is reachable from the begin iterator;
239// - TODO(hardening): both iterators refer to the same container.
240//
241// - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through
242// the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access
243// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like
244// `optional` and `function` are considered one-element containers for the purposes of this check.
245//
246// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the
247// given ranges do not overlap.
248//
249// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure
250// the containers have compatible allocators.
251//
252// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on
253// user input.
254//
255// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet.
256
257# ifndef _LIBCPP_ENABLE_HARDENED_MODE
258# define _LIBCPP_ENABLE_HARDENED_MODE _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT
259# endif
260# if _LIBCPP_ENABLE_HARDENED_MODE != 0 && _LIBCPP_ENABLE_HARDENED_MODE != 1
261# error "_LIBCPP_ENABLE_HARDENED_MODE must be set to 0 or 1."
262# endif
263
264# ifndef _LIBCPP_ENABLE_DEBUG_MODE
265# define _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT
266# endif
267# if _LIBCPP_ENABLE_DEBUG_MODE != 0 && _LIBCPP_ENABLE_DEBUG_MODE != 1
268# error "_LIBCPP_ENABLE_DEBUG_MODE must be set to 0 or 1."
269# endif
270
271# if _LIBCPP_ENABLE_HARDENED_MODE && _LIBCPP_ENABLE_DEBUG_MODE
272# error "Only one of _LIBCPP_ENABLE_HARDENED_MODE and _LIBCPP_ENABLE_DEBUG_MODE can be enabled."
273# endif
274
275# if _LIBCPP_ENABLE_ASSERTIONS && (_LIBCPP_ENABLE_HARDENED_MODE || _LIBCPP_ENABLE_DEBUG_MODE)
276# error \
277 "_LIBCPP_ENABLE_ASSERTIONS is mutually exclusive with _LIBCPP_ENABLE_HARDENED_MODE and _LIBCPP_ENABLE_DEBUG_MODE."
278# endif
279
280// Hardened mode checks.
281
282// clang-format off
283# if _LIBCPP_ENABLE_HARDENED_MODE
284
285// Enabled checks.
286# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
287# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
288// Disabled checks.
289// Overlapping ranges will make algorithms produce incorrect results but don't directly lead to a security
290// vulnerability.
291# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression)
292# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression)
293# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
294# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression)
295
296// Debug mode checks.
297
298# elif _LIBCPP_ENABLE_DEBUG_MODE
299
300// All checks enabled.
301# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
302# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
303# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message)
304# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message)
305# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSERT(expression, message)
306# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message)
307
308// Safe mode checks.
309
310# elif _LIBCPP_ENABLE_ASSERTIONS
311
312// All checks enabled.
313# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
314# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
315# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message)
316# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message)
317# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSERT(expression, message)
318# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message)
319
320// Disable all checks if hardening is not enabled.
321
322# else
323
324// All checks disabled.
325# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSUME(expression)
326# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSUME(expression)
327# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression)
328# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression)
329# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
330# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression)
331
332# endif // _LIBCPP_ENABLE_HARDENED_MODE
333// clang-format on
334
335// } HARDENING
336
182337# define _LIBCPP_TOSTRING2(x) #x
183338# define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
184339
340// NOLINTNEXTLINE(libcpp-cpp-version-check)
185341# if __cplusplus < 201103L
186342# define _LIBCPP_CXX03_LANG
187343# endif
......@@ -262,7 +418,11 @@
262418// Incomplete features get their own specific disabling flags. This makes it
263419// easier to grep for target specific flags once the feature is complete.
264420# if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY)
265# define _LIBCPP_HAS_NO_INCOMPLETE_FORMAT
421# define _LIBCPP_HAS_NO_INCOMPLETE_PSTL
422# endif
423
424# if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY)
425# define _LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN
266426# endif
267427
268428// Need to detect which libc we're using if we're on Linux.
......@@ -300,8 +460,8 @@
300460# endif // __BYTE_ORDER__
301461
302462# ifdef __FreeBSD__
303# include <sys/endian.h>
304463# include <osreldate.h>
464# include <sys/endian.h>
305465# if _BYTE_ORDER == _LITTLE_ENDIAN
306466# define _LIBCPP_LITTLE_ENDIAN
307467# else // _BYTE_ORDER == _LITTLE_ENDIAN
......@@ -335,15 +495,6 @@
335495# define _LIBCPP_HAS_OPEN_WITH_WCHAR
336496# endif // defined(_WIN32)
337497
338# ifdef __sun__
339# include <sys/isa_defs.h>
340# ifdef _LITTLE_ENDIAN
341# define _LIBCPP_LITTLE_ENDIAN
342# else
343# define _LIBCPP_BIG_ENDIAN
344# endif
345# endif // __sun__
346
347498# if defined(_AIX) && !defined(__64BIT__)
348499// The size of wchar is 2 byte on 32-bit mode on AIX.
349500# define _LIBCPP_SHORT_WCHAR 1
......@@ -388,7 +539,7 @@
388539// When this option is used, the token passed to `std::random_device`'s
389540// constructor *must* be "/dev/urandom" -- anything else is an error.
390541# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
391 defined(__DragonFly__) || defined(__sun__)
542 defined(__DragonFly__)
392543# define _LIBCPP_USING_ARC4_RANDOM
393544# elif defined(__wasi__) || defined(__EMSCRIPTEN__)
394545# define _LIBCPP_USING_GETENTROPY
......@@ -449,15 +600,24 @@ typedef __char32_t char32_t;
449600# endif
450601
451602# if !defined(__cpp_exceptions) || __cpp_exceptions < 199711L
452# define _LIBCPP_NO_EXCEPTIONS
603# define _LIBCPP_HAS_NO_EXCEPTIONS
453604# endif
454605
455606# define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp)
456607
457608# if defined(_LIBCPP_COMPILER_CLANG_BASED)
458609
459# if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && (!defined(__arm__) || __ARM_ARCH_7K__ >= 2)
460# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
610# if defined(__APPLE__)
611# if defined(__i386__) || defined(__x86_64__)
612// use old string layout on x86_64 and i386
613# elif defined(__arm__)
614// use old string layout on arm (which does not include aarch64/arm64), except on watch ABIs
615# if defined(__ARM_ARCH_7K__) && __ARM_ARCH_7K__ >= 2
616# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
617# endif
618# else
619# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
620# endif
461621# endif
462622
463623// Objective-C++ features (opt-in)
......@@ -535,9 +695,6 @@ typedef __char32_t char32_t;
535695# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport)
536696# endif
537697
538# define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS
539# define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS
540# define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS
541698# define _LIBCPP_HIDDEN
542699# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
543700# define _LIBCPP_TEMPLATE_VIS
......@@ -553,11 +710,8 @@ typedef __char32_t char32_t;
553710# endif
554711
555712# define _LIBCPP_HIDDEN _LIBCPP_VISIBILITY("hidden")
556# define _LIBCPP_FUNC_VIS _LIBCPP_VISIBILITY("default")
557# define _LIBCPP_TYPE_VIS _LIBCPP_VISIBILITY("default")
558713# define _LIBCPP_TEMPLATE_DATA_VIS _LIBCPP_VISIBILITY("default")
559714# define _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_VISIBILITY("default")
560# define _LIBCPP_EXCEPTION_ABI _LIBCPP_VISIBILITY("default")
561715# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_VISIBILITY("default")
562716# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
563717
......@@ -666,7 +820,7 @@ typedef __char32_t char32_t;
666820
667821_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
668822
669# if _LIBCPP_STD_VER > 14
823# if _LIBCPP_STD_VER >= 17
670824# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
671825 _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem {
672826# else
......@@ -683,16 +837,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
683837# define _LIBCPP_PREFERRED_OVERLOAD __attribute__((__enable_if__(true, "")))
684838# endif
685839
686# ifndef __SIZEOF_INT128__
840# if !defined(__SIZEOF_INT128__) || defined(_MSC_VER)
687841# define _LIBCPP_HAS_NO_INT128
688842# endif
689843
690# ifndef __cpp_consteval
691# define _LIBCPP_CONSTEVAL _LIBCPP_CONSTEXPR
692# else
693# define _LIBCPP_CONSTEVAL consteval
694# endif
695
696844# if __has_attribute(__malloc__)
697845# define _LIBCPP_NOALIAS __attribute__((__malloc__))
698846# else
......@@ -707,7 +855,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
707855
708856# ifdef _LIBCPP_CXX03_LANG
709857# define _LIBCPP_DECLARE_STRONG_ENUM(x) \
710 struct _LIBCPP_TYPE_VIS x { \
858 struct _LIBCPP_EXPORTED_FROM_ABI x { \
711859 enum __lx
712860// clang-format off
713861# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \
......@@ -723,8 +871,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
723871# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)
724872# endif // _LIBCPP_CXX03_LANG
725873
726# if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || defined(__sun__) || \
727 defined(__NetBSD__)
874# if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || defined(__NetBSD__)
728875# define _LIBCPP_LOCALE__L_EXTENSIONS 1
729876# endif
730877
......@@ -764,7 +911,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
764911# define _LIBCPP_HAS_DEFAULTRUNELOCALE
765912# endif
766913
767# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__)
914# if defined(__APPLE__) || defined(__FreeBSD__)
768915# define _LIBCPP_WCTYPE_IS_MASK
769916# endif
770917
......@@ -777,10 +924,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
777924// Deprecations warnings are always enabled, except when users explicitly opt-out
778925// by defining _LIBCPP_DISABLE_DEPRECATION_WARNINGS.
779926# if !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
780# if __has_attribute(deprecated)
781# define _LIBCPP_DEPRECATED __attribute__((deprecated))
782# define _LIBCPP_DEPRECATED_(m) __attribute__((deprecated(m)))
783# elif _LIBCPP_STD_VER > 11
927# if __has_attribute(__deprecated__)
928# define _LIBCPP_DEPRECATED __attribute__((__deprecated__))
929# define _LIBCPP_DEPRECATED_(m) __attribute__((__deprecated__(m)))
930# elif _LIBCPP_STD_VER >= 14
784931# define _LIBCPP_DEPRECATED [[deprecated]]
785932# define _LIBCPP_DEPRECATED_(m) [[deprecated(m)]]
786933# else
......@@ -798,29 +945,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
798945# define _LIBCPP_DEPRECATED_IN_CXX11
799946# endif
800947
801# if _LIBCPP_STD_VER > 11
948# if _LIBCPP_STD_VER >= 14
802949# define _LIBCPP_DEPRECATED_IN_CXX14 _LIBCPP_DEPRECATED
803950# else
804951# define _LIBCPP_DEPRECATED_IN_CXX14
805952# endif
806953
807# if _LIBCPP_STD_VER > 14
954# if _LIBCPP_STD_VER >= 17
808955# define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
809956# else
810957# define _LIBCPP_DEPRECATED_IN_CXX17
811958# endif
812959
813# if _LIBCPP_STD_VER > 17
960# if _LIBCPP_STD_VER >= 20
814961# define _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_DEPRECATED
815962# else
816963# define _LIBCPP_DEPRECATED_IN_CXX20
817964# endif
818965
819#if _LIBCPP_STD_VER >= 23
820# define _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_DEPRECATED
821#else
822# define _LIBCPP_DEPRECATED_IN_CXX23
823#endif
966# if _LIBCPP_STD_VER >= 23
967# define _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_DEPRECATED
968# else
969# define _LIBCPP_DEPRECATED_IN_CXX23
970# endif
824971
825972# if !defined(_LIBCPP_HAS_NO_CHAR8_T)
826973# define _LIBCPP_DEPRECATED_WITH_CHAR8_T _LIBCPP_DEPRECATED
......@@ -840,37 +987,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
840987# endif
841988
842989# if _LIBCPP_STD_VER <= 11
843# define _LIBCPP_EXPLICIT_AFTER_CXX11
990# define _LIBCPP_EXPLICIT_SINCE_CXX14
991# else
992# define _LIBCPP_EXPLICIT_SINCE_CXX14 explicit
993# endif
994
995# if _LIBCPP_STD_VER >= 23
996# define _LIBCPP_EXPLICIT_SINCE_CXX23 explicit
844997# else
845# define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit
998# define _LIBCPP_EXPLICIT_SINCE_CXX23
846999# endif
8471000
848# if _LIBCPP_STD_VER > 11
1001# if _LIBCPP_STD_VER >= 14
8491002# define _LIBCPP_CONSTEXPR_SINCE_CXX14 constexpr
8501003# else
8511004# define _LIBCPP_CONSTEXPR_SINCE_CXX14
8521005# endif
8531006
854# if _LIBCPP_STD_VER > 14
1007# if _LIBCPP_STD_VER >= 17
8551008# define _LIBCPP_CONSTEXPR_SINCE_CXX17 constexpr
8561009# else
8571010# define _LIBCPP_CONSTEXPR_SINCE_CXX17
8581011# endif
8591012
860# if _LIBCPP_STD_VER > 17
1013# if _LIBCPP_STD_VER >= 20
8611014# define _LIBCPP_CONSTEXPR_SINCE_CXX20 constexpr
8621015# else
8631016# define _LIBCPP_CONSTEXPR_SINCE_CXX20
8641017# endif
8651018
866# if _LIBCPP_STD_VER > 20
1019# if _LIBCPP_STD_VER >= 23
8671020# define _LIBCPP_CONSTEXPR_SINCE_CXX23 constexpr
8681021# else
8691022# define _LIBCPP_CONSTEXPR_SINCE_CXX23
8701023# endif
8711024
8721025# if __has_cpp_attribute(nodiscard)
873# define _LIBCPP_NODISCARD [[nodiscard]]
1026# define _LIBCPP_NODISCARD [[__nodiscard__]]
8741027# else
8751028// We can't use GCC's [[gnu::warn_unused_result]] and
8761029// __attribute__((warn_unused_result)), because GCC does not silence them via
......@@ -886,7 +1039,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
8861039# define _LIBCPP_NODISCARD_EXT
8871040# endif
8881041
889# if _LIBCPP_STD_VER > 17 || !defined(_LIBCPP_DISABLE_NODISCARD_EXT)
1042# if _LIBCPP_STD_VER >= 20 || !defined(_LIBCPP_DISABLE_NODISCARD_EXT)
8901043# define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD
8911044# else
8921045# define _LIBCPP_NODISCARD_AFTER_CXX17
......@@ -899,8 +1052,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
8991052# endif
9001053
9011054# ifndef _LIBCPP_HAS_NO_ASAN
902 extern "C" _LIBCPP_FUNC_VIS void
1055 extern "C" _LIBCPP_EXPORTED_FROM_ABI void
9031056 __sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*);
1057# if _LIBCPP_CLANG_VER >= 1600
1058extern "C" _LIBCPP_EXPORTED_FROM_ABI void __sanitizer_annotate_double_ended_contiguous_container(
1059 const void*, const void*, const void*, const void*, const void*, const void*);
1060extern "C" _LIBCPP_EXPORTED_FROM_ABI int
1061__sanitizer_verify_double_ended_contiguous_container(const void*, const void*, const void*, const void*);
1062# endif
9041063# endif
9051064
9061065// Try to find out if RTTI is disabled.
......@@ -927,7 +1086,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
9271086 defined(__linux__) || \
9281087 defined(__GNU__) || \
9291088 defined(__APPLE__) || \
930 defined(__sun__) || \
9311089 defined(__MVS__) || \
9321090 defined(_AIX) || \
9331091 defined(__EMSCRIPTEN__)
......@@ -1034,6 +1192,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
10341192# define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
10351193# endif
10361194
1195# if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(__no_thread_safety_analysis__)
1196# define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((__no_thread_safety_analysis__))
1197# else
1198# define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
1199# endif
1200
10371201# if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS)
10381202# if defined(__clang__) && __has_attribute(acquire_capability)
10391203// Work around the attribute handling in clang. When both __declspec and
......@@ -1052,7 +1216,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
10521216# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x)
10531217# endif
10541218
1055# if _LIBCPP_STD_VER > 17
1219# if _LIBCPP_STD_VER >= 20
10561220# define _LIBCPP_CONSTINIT constinit
10571221# elif __has_attribute(__require_constant_initialization__)
10581222# define _LIBCPP_CONSTINIT __attribute__((__require_constant_initialization__))
......@@ -1099,6 +1263,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
10991263# define _LIBCPP_PREFERRED_NAME(x)
11001264# endif
11011265
1266# if __has_attribute(__no_sanitize__)
1267# define _LIBCPP_NO_SANITIZE(...) __attribute__((__no_sanitize__(__VA_ARGS__)))
1268# else
1269# define _LIBCPP_NO_SANITIZE(...)
1270# endif
1271
11021272// We often repeat things just for handling wide characters in the library.
11031273// When wide characters are disabled, it can be useful to have a quick way of
11041274// disabling it without having to resort to #if-#endif, which has a larger
......@@ -1132,8 +1302,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
11321302# define _LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
11331303# endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES
11341304
1135# define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")")
1136# define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")")
1305// clang-format off
1306# define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")") _Pragma("push_macro(\"refresh()\")") _Pragma("push_macro(\"move(int, int)\")") _Pragma("push_macro(\"erase()\")")
1307# define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")") _Pragma("pop_macro(\"refresh()\")") _Pragma("pop_macro(\"move(int, int)\")") _Pragma("pop_macro(\"erase()\")")
1308// clang-format on
11371309
11381310# ifndef _LIBCPP_NO_AUTO_LINK
11391311# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY)
......@@ -1189,7 +1361,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
11891361// [[msvc::no_unique_address]], this should be preferred though.
11901362# define _LIBCPP_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
11911363# elif __has_cpp_attribute(no_unique_address)
1192# define _LIBCPP_NO_UNIQUE_ADDRESS [[no_unique_address]]
1364# define _LIBCPP_NO_UNIQUE_ADDRESS [[__no_unique_address__]]
11931365# else
11941366# define _LIBCPP_NO_UNIQUE_ADDRESS /* nothing */
11951367// Note that this can be replaced by #error as soon as clang-cl
......@@ -1252,13 +1424,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
12521424// macro is used to mark them as such, which suppresses the
12531425// '-Wctad-maybe-unsupported' compiler warning when CTAD is used in user code
12541426// with these classes.
1255#if _LIBCPP_STD_VER >= 17
1256# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) \
1257 template <class ..._Tag> \
1258 _ClassName(typename _Tag::__allow_ctad...) -> _ClassName<_Tag...>
1259#else
1260# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "")
1261#endif
1427# if _LIBCPP_STD_VER >= 17
1428# ifdef _LIBCPP_COMPILER_CLANG_BASED
1429# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) \
1430 template <class... _Tag> \
1431 [[maybe_unused]] _ClassName(typename _Tag::__allow_ctad...)->_ClassName<_Tag...>
1432# else
1433# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(ClassName) \
1434 template <class... _Tag> \
1435 ClassName(typename _Tag::__allow_ctad...)->ClassName<_Tag...>
1436# endif
1437# else
1438# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "")
1439# endif
12621440
12631441// TODO(varconst): currently, there are bugs in Clang's intrinsics when handling Objective-C++ `id`, so don't use
12641442// compiler intrinsics in the Objective-C++ mode.
......@@ -1266,6 +1444,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
12661444# define _LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS
12671445# endif
12681446
1447# define _PSTL_PRAGMA(x) _Pragma(#x)
1448
1449// Enable SIMD for compilers that support OpenMP 4.0
1450# if (defined(_OPENMP) && _OPENMP >= 201307)
1451
1452# define _PSTL_UDR_PRESENT
1453# define _PSTL_PRAGMA_SIMD _PSTL_PRAGMA(omp simd)
1454# define _PSTL_PRAGMA_DECLARE_SIMD _PSTL_PRAGMA(omp declare simd)
1455# define _PSTL_PRAGMA_SIMD_REDUCTION(PRM) _PSTL_PRAGMA(omp simd reduction(PRM))
1456# define _PSTL_PRAGMA_SIMD_SCAN(PRM) _PSTL_PRAGMA(omp simd reduction(inscan, PRM))
1457# define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan inclusive(PRM))
1458# define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan exclusive(PRM))
1459
1460// Declaration of reduction functor, where
1461// NAME - the name of the functor
1462// OP - type of the callable object with the reduction operation
1463// omp_in - refers to the local partial result
1464// omp_out - refers to the final value of the combiner operator
1465// omp_priv - refers to the private copy of the initial value
1466// omp_orig - refers to the original variable to be reduced
1467# define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP) \
1468 _PSTL_PRAGMA(omp declare reduction(NAME:OP : omp_out(omp_in)) initializer(omp_priv = omp_orig))
1469
1470# else // (defined(_OPENMP) && _OPENMP >= 201307)
1471
1472# define _PSTL_PRAGMA_SIMD
1473# define _PSTL_PRAGMA_DECLARE_SIMD
1474# define _PSTL_PRAGMA_SIMD_REDUCTION(PRM)
1475# define _PSTL_PRAGMA_SIMD_SCAN(PRM)
1476# define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM)
1477# define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM)
1478# define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP)
1479
1480# endif // (defined(_OPENMP) && _OPENMP >= 201307)
1481
1482# define _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
1483
12691484#endif // __cplusplus
12701485
12711486#endif // _LIBCPP___CONFIG
lib/libcxx/include/__coroutine/coroutine_handle.h+12-14
......@@ -21,7 +21,7 @@
2121# pragma GCC system_header
2222#endif
2323
24#if _LIBCPP_STD_VER > 17
24#if _LIBCPP_STD_VER >= 20
2525
2626_LIBCPP_BEGIN_NAMESPACE_STD
2727
......@@ -33,7 +33,6 @@ template <>
3333struct _LIBCPP_TEMPLATE_VIS coroutine_handle<void> {
3434public:
3535 // [coroutine.handle.con], construct/reset
36 _LIBCPP_HIDE_FROM_ABI
3736 constexpr coroutine_handle() noexcept = default;
3837
3938 _LIBCPP_HIDE_FROM_ABI
......@@ -64,7 +63,7 @@ public:
6463
6564 _LIBCPP_HIDE_FROM_ABI
6665 bool done() const {
67 _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines");
66 _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "done() can be called only on suspended coroutines");
6867 return __builtin_coro_done(__handle_);
6968 }
7069
......@@ -74,19 +73,19 @@ public:
7473
7574 _LIBCPP_HIDE_FROM_ABI
7675 void resume() const {
77 _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines");
78 _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done");
76 _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "resume() can be called only on suspended coroutines");
77 _LIBCPP_ASSERT_UNCATEGORIZED(!done(), "resume() has undefined behavior when the coroutine is done");
7978 __builtin_coro_resume(__handle_);
8079 }
8180
8281 _LIBCPP_HIDE_FROM_ABI
8382 void destroy() const {
84 _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines");
83 _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "destroy() can be called only on suspended coroutines");
8584 __builtin_coro_destroy(__handle_);
8685 }
8786
8887private:
89 bool __is_suspended() const {
88 _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const {
9089 // FIXME actually implement a check for if the coro is suspended.
9190 return __handle_ != nullptr;
9291 }
......@@ -108,7 +107,6 @@ template <class _Promise>
108107struct _LIBCPP_TEMPLATE_VIS coroutine_handle {
109108public:
110109 // [coroutine.handle.con], construct/reset
111 _LIBCPP_HIDE_FROM_ABI
112110 constexpr coroutine_handle() noexcept = default;
113111
114112 _LIBCPP_HIDE_FROM_ABI
......@@ -154,7 +152,7 @@ public:
154152
155153 _LIBCPP_HIDE_FROM_ABI
156154 bool done() const {
157 _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines");
155 _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "done() can be called only on suspended coroutines");
158156 return __builtin_coro_done(__handle_);
159157 }
160158
......@@ -164,14 +162,14 @@ public:
164162
165163 _LIBCPP_HIDE_FROM_ABI
166164 void resume() const {
167 _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines");
168 _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done");
165 _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "resume() can be called only on suspended coroutines");
166 _LIBCPP_ASSERT_UNCATEGORIZED(!done(), "resume() has undefined behavior when the coroutine is done");
169167 __builtin_coro_resume(__handle_);
170168 }
171169
172170 _LIBCPP_HIDE_FROM_ABI
173171 void destroy() const {
174 _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines");
172 _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "destroy() can be called only on suspended coroutines");
175173 __builtin_coro_destroy(__handle_);
176174 }
177175
......@@ -182,7 +180,7 @@ public:
182180 }
183181
184182private:
185 bool __is_suspended() const {
183 _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const {
186184 // FIXME actually implement a check for if the coro is suspended.
187185 return __handle_ != nullptr;
188186 }
......@@ -198,6 +196,6 @@ struct hash<coroutine_handle<_Tp>> {
198196
199197_LIBCPP_END_NAMESPACE_STD
200198
201#endif // __LIBCPP_STD_VER > 17
199#endif // __LIBCPP_STD_VER >= 20
202200
203201#endif // _LIBCPP___COROUTINE_COROUTINE_HANDLE_H
lib/libcxx/include/__coroutine/coroutine_traits.h+2-2
......@@ -16,7 +16,7 @@
1616# pragma GCC system_header
1717#endif
1818
19#if _LIBCPP_STD_VER > 17
19#if _LIBCPP_STD_VER >= 20
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
......@@ -48,6 +48,6 @@ struct coroutine_traits
4848
4949_LIBCPP_END_NAMESPACE_STD
5050
51#endif // __LIBCPP_STD_VER > 17
51#endif // __LIBCPP_STD_VER >= 20
5252
5353#endif // _LIBCPP___COROUTINE_COROUTINE_TRAITS_H
lib/libcxx/include/__coroutine/noop_coroutine_handle.h+2-2
......@@ -16,7 +16,7 @@
1616# pragma GCC system_header
1717#endif
1818
19#if _LIBCPP_STD_VER > 17
19#if _LIBCPP_STD_VER >= 20
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
......@@ -107,6 +107,6 @@ noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle()
107107
108108_LIBCPP_END_NAMESPACE_STD
109109
110#endif // __LIBCPP_STD_VER > 17
110#endif // __LIBCPP_STD_VER >= 20
111111
112112#endif // _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H
lib/libcxx/include/__coroutine/trivial_awaitables.h+2-2
......@@ -16,7 +16,7 @@
1616# pragma GCC system_header
1717#endif
1818
19#if _LIBCPP_STD_VER > 17
19#if _LIBCPP_STD_VER >= 20
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
......@@ -41,6 +41,6 @@ struct suspend_always {
4141
4242_LIBCPP_END_NAMESPACE_STD
4343
44#endif // __LIBCPP_STD_VER > 17
44#endif // __LIBCPP_STD_VER >= 20
4545
4646#endif // __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H
lib/libcxx/include/__debug deleted-266
......@@ -1,266 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___DEBUG
11#define _LIBCPP___DEBUG
12
13#include <__assert>
14#include <__config>
15#include <__type_traits/is_constant_evaluated.h>
16#include <cstddef>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19# pragma GCC system_header
20#endif
21
22#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY)
23# define _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY
24#endif
25
26#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING)
27# define _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
28#endif
29
30#ifdef _LIBCPP_ENABLE_DEBUG_MODE
31# define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(::std::__libcpp_is_constant_evaluated() || (x), m)
32#else
33# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0)
34#endif
35
36#if defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY)
37
38_LIBCPP_BEGIN_NAMESPACE_STD
39
40struct _LIBCPP_TYPE_VIS __c_node;
41
42struct _LIBCPP_TYPE_VIS __i_node
43{
44 void* __i_;
45 __i_node* __next_;
46 __c_node* __c_;
47
48 __i_node(const __i_node&) = delete;
49 __i_node& operator=(const __i_node&) = delete;
50
51 _LIBCPP_INLINE_VISIBILITY
52 __i_node(void* __i, __i_node* __next, __c_node* __c)
53 : __i_(__i), __next_(__next), __c_(__c) {}
54 ~__i_node();
55};
56
57struct _LIBCPP_TYPE_VIS __c_node
58{
59 void* __c_;
60 __c_node* __next_;
61 __i_node** beg_;
62 __i_node** end_;
63 __i_node** cap_;
64
65 __c_node(const __c_node&) = delete;
66 __c_node& operator=(const __c_node&) = delete;
67
68 _LIBCPP_INLINE_VISIBILITY
69 explicit __c_node(void* __c, __c_node* __next)
70 : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {}
71 virtual ~__c_node();
72
73 virtual bool __dereferenceable(const void*) const = 0;
74 virtual bool __decrementable(const void*) const = 0;
75 virtual bool __addable(const void*, ptrdiff_t) const = 0;
76 virtual bool __subscriptable(const void*, ptrdiff_t) const = 0;
77
78 void __add(__i_node* __i);
79 _LIBCPP_HIDDEN void __remove(__i_node* __i);
80};
81
82template <class _Cont>
83struct _C_node
84 : public __c_node
85{
86 explicit _C_node(void* __c, __c_node* __n)
87 : __c_node(__c, __n) {}
88
89 bool __dereferenceable(const void*) const override;
90 bool __decrementable(const void*) const override;
91 bool __addable(const void*, ptrdiff_t) const override;
92 bool __subscriptable(const void*, ptrdiff_t) const override;
93};
94
95template <class _Cont>
96inline bool
97_C_node<_Cont>::__dereferenceable(const void* __i) const
98{
99 typedef typename _Cont::const_iterator iterator;
100 const iterator* __j = static_cast<const iterator*>(__i);
101 _Cont* _Cp = static_cast<_Cont*>(__c_);
102 return _Cp->__dereferenceable(__j);
103}
104
105template <class _Cont>
106inline bool
107_C_node<_Cont>::__decrementable(const void* __i) const
108{
109 typedef typename _Cont::const_iterator iterator;
110 const iterator* __j = static_cast<const iterator*>(__i);
111 _Cont* _Cp = static_cast<_Cont*>(__c_);
112 return _Cp->__decrementable(__j);
113}
114
115template <class _Cont>
116inline bool
117_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const
118{
119 typedef typename _Cont::const_iterator iterator;
120 const iterator* __j = static_cast<const iterator*>(__i);
121 _Cont* _Cp = static_cast<_Cont*>(__c_);
122 return _Cp->__addable(__j, __n);
123}
124
125template <class _Cont>
126inline bool
127_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const
128{
129 typedef typename _Cont::const_iterator iterator;
130 const iterator* __j = static_cast<const iterator*>(__i);
131 _Cont* _Cp = static_cast<_Cont*>(__c_);
132 return _Cp->__subscriptable(__j, __n);
133}
134
135class _LIBCPP_TYPE_VIS __libcpp_db
136{
137 __c_node** __cbeg_;
138 __c_node** __cend_;
139 size_t __csz_;
140 __i_node** __ibeg_;
141 __i_node** __iend_;
142 size_t __isz_;
143
144 explicit __libcpp_db();
145public:
146 __libcpp_db(const __libcpp_db&) = delete;
147 __libcpp_db& operator=(const __libcpp_db&) = delete;
148
149 ~__libcpp_db();
150
151 class __db_c_iterator;
152 class __db_c_const_iterator;
153 class __db_i_iterator;
154 class __db_i_const_iterator;
155
156 __db_c_const_iterator __c_end() const;
157 __db_i_const_iterator __i_end() const;
158
159 typedef __c_node*(_InsertConstruct)(void*, void*, __c_node*);
160
161 template <class _Cont>
162 _LIBCPP_INLINE_VISIBILITY static __c_node* __create_C_node(void *__mem, void *__c, __c_node *__next) {
163 return ::new (__mem) _C_node<_Cont>(__c, __next);
164 }
165
166 template <class _Cont>
167 _LIBCPP_INLINE_VISIBILITY
168 void __insert_c(_Cont* __c)
169 {
170 __insert_c(static_cast<void*>(__c), &__create_C_node<_Cont>);
171 }
172
173 void __insert_i(void* __i);
174 void __insert_c(void* __c, _InsertConstruct* __fn);
175 void __erase_c(void* __c);
176
177 void __insert_ic(void* __i, const void* __c);
178 void __iterator_copy(void* __i, const void* __i0);
179 void __erase_i(void* __i);
180
181 void* __find_c_from_i(void* __i) const;
182 void __invalidate_all(void* __c);
183 __c_node* __find_c_and_lock(void* __c) const;
184 __c_node* __find_c(void* __c) const;
185 void unlock() const;
186
187 void swap(void* __c1, void* __c2);
188
189
190 bool __dereferenceable(const void* __i) const;
191 bool __decrementable(const void* __i) const;
192 bool __addable(const void* __i, ptrdiff_t __n) const;
193 bool __subscriptable(const void* __i, ptrdiff_t __n) const;
194 bool __less_than_comparable(const void* __i, const void* __j) const;
195private:
196 _LIBCPP_HIDDEN
197 __i_node* __insert_iterator(void* __i);
198 _LIBCPP_HIDDEN
199 __i_node* __find_iterator(const void* __i) const;
200
201 friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db();
202};
203
204_LIBCPP_FUNC_VIS __libcpp_db* __get_db();
205_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db();
206
207_LIBCPP_END_NAMESPACE_STD
208
209#endif // defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY)
210
211_LIBCPP_BEGIN_NAMESPACE_STD
212
213template <class _Tp>
214_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_c(_Tp* __c) {
215#ifdef _LIBCPP_ENABLE_DEBUG_MODE
216 if (!__libcpp_is_constant_evaluated())
217 __get_db()->__insert_c(__c);
218#else
219 (void)(__c);
220#endif
221}
222
223template <class _Tp>
224_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_i(_Tp* __i) {
225#ifdef _LIBCPP_ENABLE_DEBUG_MODE
226 if (!__libcpp_is_constant_evaluated())
227 __get_db()->__insert_i(__i);
228#else
229 (void)(__i);
230#endif
231}
232
233template <class _Tp>
234_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_erase_c(_Tp* __c) {
235#ifdef _LIBCPP_ENABLE_DEBUG_MODE
236 if (!__libcpp_is_constant_evaluated())
237 __get_db()->__erase_c(__c);
238#else
239 (void)(__c);
240#endif
241}
242
243template <class _Tp>
244_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_swap(_Tp* __lhs, _Tp* __rhs) {
245#ifdef _LIBCPP_ENABLE_DEBUG_MODE
246 if (!__libcpp_is_constant_evaluated())
247 __get_db()->swap(__lhs, __rhs);
248#else
249 (void)(__lhs);
250 (void)(__rhs);
251#endif
252}
253
254template <class _Tp>
255_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_invalidate_all(_Tp* __c) {
256#ifdef _LIBCPP_ENABLE_DEBUG_MODE
257 if (!__libcpp_is_constant_evaluated())
258 __get_db()->__invalidate_all(__c);
259#else
260 (void)(__c);
261#endif
262}
263
264_LIBCPP_END_NAMESPACE_STD
265
266#endif // _LIBCPP___DEBUG
lib/libcxx/include/__debug_utils/strict_weak_ordering_check.h created+77
......@@ -0,0 +1,77 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK
10#define _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK
11
12#include <__config>
13
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/is_sorted.h>
16#include <__assert>
17#include <__iterator/iterator_traits.h>
18#include <__type_traits/is_constant_evaluated.h>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21# pragma GCC system_header
22#endif
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _RandomAccessIterator, class _Comp>
27_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
28__check_strict_weak_ordering_sorted(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
29#ifdef _LIBCPP_DEBUG_STRICT_WEAK_ORDERING_CHECK
30 using __diff_t = __iter_diff_t<_RandomAccessIterator>;
31 using _Comp_ref = __comp_ref_type<_Comp>;
32 if (!__libcpp_is_constant_evaluated()) {
33 // Check if the range is actually sorted.
34 _LIBCPP_ASSERT_UNCATEGORIZED(
35 (std::is_sorted<_RandomAccessIterator, _Comp_ref>(__first, __last, _Comp_ref(__comp))),
36 "The range is not sorted after the sort, your comparator is not a valid strict-weak ordering");
37 // Limit the number of elements we need to check.
38 __diff_t __size = __last - __first > __diff_t(100) ? __diff_t(100) : __last - __first;
39 __diff_t __p = 0;
40 while (__p < __size) {
41 __diff_t __q = __p + __diff_t(1);
42 // Find first element that is greater than *(__first+__p).
43 while (__q < __size && !__comp(*(__first + __p), *(__first + __q))) {
44 ++__q;
45 }
46 // Check that the elements from __p to __q are equal between each other.
47 for (__diff_t __b = __p; __b < __q; ++__b) {
48 for (__diff_t __a = __p; __a <= __b; ++__a) {
49 _LIBCPP_ASSERT_UNCATEGORIZED(
50 !__comp(*(__first + __a), *(__first + __b)), "Your comparator is not a valid strict-weak ordering");
51 _LIBCPP_ASSERT_UNCATEGORIZED(
52 !__comp(*(__first + __b), *(__first + __a)), "Your comparator is not a valid strict-weak ordering");
53 }
54 }
55 // Check that elements between __p and __q are less than between __q and __size.
56 for (__diff_t __a = __p; __a < __q; ++__a) {
57 for (__diff_t __b = __q; __b < __size; ++__b) {
58 _LIBCPP_ASSERT_UNCATEGORIZED(
59 __comp(*(__first + __a), *(__first + __b)), "Your comparator is not a valid strict-weak ordering");
60 _LIBCPP_ASSERT_UNCATEGORIZED(
61 !__comp(*(__first + __b), *(__first + __a)), "Your comparator is not a valid strict-weak ordering");
62 }
63 }
64 // Skip these equal elements.
65 __p = __q;
66 }
67 }
68#else
69 (void)__first;
70 (void)__last;
71 (void)__comp;
72#endif
73}
74
75_LIBCPP_END_NAMESPACE_STD
76
77#endif // _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK
lib/libcxx/include/__errc deleted-217
......@@ -1,217 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ERRC
11#define _LIBCPP___ERRC
12
13/*
14 system_error synopsis
15
16namespace std
17{
18
19enum class errc
20{
21 address_family_not_supported, // EAFNOSUPPORT
22 address_in_use, // EADDRINUSE
23 address_not_available, // EADDRNOTAVAIL
24 already_connected, // EISCONN
25 argument_list_too_long, // E2BIG
26 argument_out_of_domain, // EDOM
27 bad_address, // EFAULT
28 bad_file_descriptor, // EBADF
29 bad_message, // EBADMSG
30 broken_pipe, // EPIPE
31 connection_aborted, // ECONNABORTED
32 connection_already_in_progress, // EALREADY
33 connection_refused, // ECONNREFUSED
34 connection_reset, // ECONNRESET
35 cross_device_link, // EXDEV
36 destination_address_required, // EDESTADDRREQ
37 device_or_resource_busy, // EBUSY
38 directory_not_empty, // ENOTEMPTY
39 executable_format_error, // ENOEXEC
40 file_exists, // EEXIST
41 file_too_large, // EFBIG
42 filename_too_long, // ENAMETOOLONG
43 function_not_supported, // ENOSYS
44 host_unreachable, // EHOSTUNREACH
45 identifier_removed, // EIDRM
46 illegal_byte_sequence, // EILSEQ
47 inappropriate_io_control_operation, // ENOTTY
48 interrupted, // EINTR
49 invalid_argument, // EINVAL
50 invalid_seek, // ESPIPE
51 io_error, // EIO
52 is_a_directory, // EISDIR
53 message_size, // EMSGSIZE
54 network_down, // ENETDOWN
55 network_reset, // ENETRESET
56 network_unreachable, // ENETUNREACH
57 no_buffer_space, // ENOBUFS
58 no_child_process, // ECHILD
59 no_link, // ENOLINK
60 no_lock_available, // ENOLCK
61 no_message_available, // ENODATA
62 no_message, // ENOMSG
63 no_protocol_option, // ENOPROTOOPT
64 no_space_on_device, // ENOSPC
65 no_stream_resources, // ENOSR
66 no_such_device_or_address, // ENXIO
67 no_such_device, // ENODEV
68 no_such_file_or_directory, // ENOENT
69 no_such_process, // ESRCH
70 not_a_directory, // ENOTDIR
71 not_a_socket, // ENOTSOCK
72 not_a_stream, // ENOSTR
73 not_connected, // ENOTCONN
74 not_enough_memory, // ENOMEM
75 not_supported, // ENOTSUP
76 operation_canceled, // ECANCELED
77 operation_in_progress, // EINPROGRESS
78 operation_not_permitted, // EPERM
79 operation_not_supported, // EOPNOTSUPP
80 operation_would_block, // EWOULDBLOCK
81 owner_dead, // EOWNERDEAD
82 permission_denied, // EACCES
83 protocol_error, // EPROTO
84 protocol_not_supported, // EPROTONOSUPPORT
85 read_only_file_system, // EROFS
86 resource_deadlock_would_occur, // EDEADLK
87 resource_unavailable_try_again, // EAGAIN
88 result_out_of_range, // ERANGE
89 state_not_recoverable, // ENOTRECOVERABLE
90 stream_timeout, // ETIME
91 text_file_busy, // ETXTBSY
92 timed_out, // ETIMEDOUT
93 too_many_files_open_in_system, // ENFILE
94 too_many_files_open, // EMFILE
95 too_many_links, // EMLINK
96 too_many_symbolic_link_levels, // ELOOP
97 value_too_large, // EOVERFLOW
98 wrong_protocol_type // EPROTOTYPE
99};
100
101*/
102
103#include <__config>
104#include <cerrno>
105
106#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
107# pragma GCC system_header
108#endif
109
110_LIBCPP_BEGIN_NAMESPACE_STD
111
112// Some error codes are not present on all platforms, so we provide equivalents
113// for them:
114
115//enum class errc
116_LIBCPP_DECLARE_STRONG_ENUM(errc)
117{
118 address_family_not_supported = EAFNOSUPPORT,
119 address_in_use = EADDRINUSE,
120 address_not_available = EADDRNOTAVAIL,
121 already_connected = EISCONN,
122 argument_list_too_long = E2BIG,
123 argument_out_of_domain = EDOM,
124 bad_address = EFAULT,
125 bad_file_descriptor = EBADF,
126 bad_message = EBADMSG,
127 broken_pipe = EPIPE,
128 connection_aborted = ECONNABORTED,
129 connection_already_in_progress = EALREADY,
130 connection_refused = ECONNREFUSED,
131 connection_reset = ECONNRESET,
132 cross_device_link = EXDEV,
133 destination_address_required = EDESTADDRREQ,
134 device_or_resource_busy = EBUSY,
135 directory_not_empty = ENOTEMPTY,
136 executable_format_error = ENOEXEC,
137 file_exists = EEXIST,
138 file_too_large = EFBIG,
139 filename_too_long = ENAMETOOLONG,
140 function_not_supported = ENOSYS,
141 host_unreachable = EHOSTUNREACH,
142 identifier_removed = EIDRM,
143 illegal_byte_sequence = EILSEQ,
144 inappropriate_io_control_operation = ENOTTY,
145 interrupted = EINTR,
146 invalid_argument = EINVAL,
147 invalid_seek = ESPIPE,
148 io_error = EIO,
149 is_a_directory = EISDIR,
150 message_size = EMSGSIZE,
151 network_down = ENETDOWN,
152 network_reset = ENETRESET,
153 network_unreachable = ENETUNREACH,
154 no_buffer_space = ENOBUFS,
155 no_child_process = ECHILD,
156 no_link = ENOLINK,
157 no_lock_available = ENOLCK,
158#ifdef ENODATA
159 no_message_available = ENODATA,
160#else
161 no_message_available = ENOMSG,
162#endif
163 no_message = ENOMSG,
164 no_protocol_option = ENOPROTOOPT,
165 no_space_on_device = ENOSPC,
166#ifdef ENOSR
167 no_stream_resources = ENOSR,
168#else
169 no_stream_resources = ENOMEM,
170#endif
171 no_such_device_or_address = ENXIO,
172 no_such_device = ENODEV,
173 no_such_file_or_directory = ENOENT,
174 no_such_process = ESRCH,
175 not_a_directory = ENOTDIR,
176 not_a_socket = ENOTSOCK,
177#ifdef ENOSTR
178 not_a_stream = ENOSTR,
179#else
180 not_a_stream = EINVAL,
181#endif
182 not_connected = ENOTCONN,
183 not_enough_memory = ENOMEM,
184 not_supported = ENOTSUP,
185 operation_canceled = ECANCELED,
186 operation_in_progress = EINPROGRESS,
187 operation_not_permitted = EPERM,
188 operation_not_supported = EOPNOTSUPP,
189 operation_would_block = EWOULDBLOCK,
190 owner_dead = EOWNERDEAD,
191 permission_denied = EACCES,
192 protocol_error = EPROTO,
193 protocol_not_supported = EPROTONOSUPPORT,
194 read_only_file_system = EROFS,
195 resource_deadlock_would_occur = EDEADLK,
196 resource_unavailable_try_again = EAGAIN,
197 result_out_of_range = ERANGE,
198 state_not_recoverable = ENOTRECOVERABLE,
199#ifdef ETIME
200 stream_timeout = ETIME,
201#else
202 stream_timeout = ETIMEDOUT,
203#endif
204 text_file_busy = ETXTBSY,
205 timed_out = ETIMEDOUT,
206 too_many_files_open_in_system = ENFILE,
207 too_many_files_open = EMFILE,
208 too_many_links = EMLINK,
209 too_many_symbolic_link_levels = ELOOP,
210 value_too_large = EOVERFLOW,
211 wrong_protocol_type = EPROTOTYPE
212};
213_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc)
214
215_LIBCPP_END_NAMESPACE_STD
216
217#endif // _LIBCPP___ERRC
lib/libcxx/include/__exception/exception.h created+91
......@@ -0,0 +1,91 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___EXCEPTION_EXCEPTION_H
10#define _LIBCPP___EXCEPTION_EXCEPTION_H
11
12#include <__config>
13
14// <vcruntime_exception.h> defines its own std::exception and std::bad_exception types,
15// which we use in order to be ABI-compatible with other STLs on Windows.
16#if defined(_LIBCPP_ABI_VCRUNTIME)
17# include <vcruntime_exception.h>
18#endif
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21# pragma GCC system_header
22#endif
23
24namespace std { // purposefully not using versioning namespace
25
26#if defined(_LIBCPP_ABI_VCRUNTIME) && (!defined(_HAS_EXCEPTIONS) || _HAS_EXCEPTIONS != 0)
27// The std::exception class was already included above, but we're explicit about this condition here for clarity.
28
29#elif defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0
30// However, <vcruntime_exception.h> does not define std::exception and std::bad_exception
31// when _HAS_EXCEPTIONS == 0.
32//
33// Since libc++ still wants to provide the std::exception hierarchy even when _HAS_EXCEPTIONS == 0
34// (after all those are simply types like any other), we define an ABI-compatible version
35// of the VCRuntime std::exception and std::bad_exception types in that mode.
36
37struct __std_exception_data {
38 char const* _What;
39 bool _DoFree;
40};
41
42class exception { // base of all library exceptions
43public:
44 exception() _NOEXCEPT : __data_() {}
45
46 explicit exception(char const* __message) _NOEXCEPT : __data_() {
47 __data_._What = __message;
48 __data_._DoFree = true;
49 }
50
51 exception(exception const&) _NOEXCEPT {}
52
53 exception& operator=(exception const&) _NOEXCEPT { return *this; }
54
55 virtual ~exception() _NOEXCEPT {}
56
57 virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; }
58
59private:
60 __std_exception_data __data_;
61};
62
63class bad_exception : public exception {
64public:
65 bad_exception() _NOEXCEPT : exception("bad exception") {}
66};
67
68#else // !defined(_LIBCPP_ABI_VCRUNTIME)
69// On all other platforms, we define our own std::exception and std::bad_exception types
70// regardless of whether exceptions are turned on as a language feature.
71
72class _LIBCPP_EXPORTED_FROM_ABI exception {
73public:
74 _LIBCPP_HIDE_FROM_ABI exception() _NOEXCEPT {}
75 _LIBCPP_HIDE_FROM_ABI exception(const exception&) _NOEXCEPT = default;
76
77 virtual ~exception() _NOEXCEPT;
78 virtual const char* what() const _NOEXCEPT;
79};
80
81class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception {
82public:
83 _LIBCPP_HIDE_FROM_ABI bad_exception() _NOEXCEPT {}
84 ~bad_exception() _NOEXCEPT override;
85 const char* what() const _NOEXCEPT override;
86};
87#endif // !_LIBCPP_ABI_VCRUNTIME
88
89} // namespace std
90
91#endif // _LIBCPP___EXCEPTION_EXCEPTION_H
lib/libcxx/include/__exception/exception_ptr.h created+109
......@@ -0,0 +1,109 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
10#define _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
11
12#include <__config>
13#include <__exception/operations.h>
14#include <__memory/addressof.h>
15#include <cstddef>
16#include <cstdlib>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19# pragma GCC system_header
20#endif
21
22namespace std { // purposefully not using versioning namespace
23
24#ifndef _LIBCPP_ABI_MICROSOFT
25
26class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
27 void* __ptr_;
28
29public:
30 _LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {}
31 _LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
32
33 exception_ptr(const exception_ptr&) _NOEXCEPT;
34 exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
35 ~exception_ptr() _NOEXCEPT;
36
37 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_ != nullptr; }
38
39 friend _LIBCPP_HIDE_FROM_ABI bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {
40 return __x.__ptr_ == __y.__ptr_;
41 }
42
43 friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {
44 return !(__x == __y);
45 }
46
47 friend _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
48 friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
49};
50
51template <class _Ep>
52_LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
53# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
54 try {
55 throw __e;
56 } catch (...) {
57 return current_exception();
58 }
59# else
60 ((void)__e);
61 std::abort();
62# endif
63}
64
65#else // _LIBCPP_ABI_MICROSOFT
66
67class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
68 _LIBCPP_DIAGNOSTIC_PUSH
69 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field")
70 void* __ptr1_;
71 void* __ptr2_;
72 _LIBCPP_DIAGNOSTIC_POP
73
74public:
75 exception_ptr() _NOEXCEPT;
76 exception_ptr(nullptr_t) _NOEXCEPT;
77 exception_ptr(const exception_ptr& __other) _NOEXCEPT;
78 exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT;
79 exception_ptr& operator=(nullptr_t) _NOEXCEPT;
80 ~exception_ptr() _NOEXCEPT;
81 explicit operator bool() const _NOEXCEPT;
82};
83
84_LIBCPP_EXPORTED_FROM_ABI bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT;
85
86inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {
87 return !(__x == __y);
88}
89
90_LIBCPP_EXPORTED_FROM_ABI void swap(exception_ptr&, exception_ptr&) _NOEXCEPT;
91
92_LIBCPP_EXPORTED_FROM_ABI exception_ptr __copy_exception_ptr(void* __except, const void* __ptr);
93_LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
94_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
95
96// This is a built-in template function which automagically extracts the required
97// information.
98template <class _E>
99void* __GetExceptionInfo(_E);
100
101template <class _Ep>
102_LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
103 return __copy_exception_ptr(std::addressof(__e), __GetExceptionInfo(__e));
104}
105
106#endif // _LIBCPP_ABI_MICROSOFT
107} // namespace std
108
109#endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
lib/libcxx/include/__exception/nested_exception.h created+101
......@@ -0,0 +1,101 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H
10#define _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H
11
12#include <__config>
13#include <__exception/exception_ptr.h>
14#include <__memory/addressof.h>
15#include <__type_traits/decay.h>
16#include <__type_traits/is_base_of.h>
17#include <__type_traits/is_class.h>
18#include <__type_traits/is_convertible.h>
19#include <__type_traits/is_copy_constructible.h>
20#include <__type_traits/is_final.h>
21#include <__type_traits/is_polymorphic.h>
22#include <__utility/forward.h>
23#include <cstddef>
24
25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26# pragma GCC system_header
27#endif
28
29namespace std { // purposefully not using versioning namespace
30
31class _LIBCPP_EXPORTED_FROM_ABI nested_exception {
32 exception_ptr __ptr_;
33
34public:
35 nested_exception() _NOEXCEPT;
36 // nested_exception(const nested_exception&) noexcept = default;
37 // nested_exception& operator=(const nested_exception&) noexcept = default;
38 virtual ~nested_exception() _NOEXCEPT;
39
40 // access functions
41 _LIBCPP_NORETURN void rethrow_nested() const;
42 _LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; }
43};
44
45template <class _Tp>
46struct __nested : public _Tp, public nested_exception {
47 _LIBCPP_HIDE_FROM_ABI explicit __nested(const _Tp& __t) : _Tp(__t) {}
48};
49
50#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
51template <class _Tp, class _Up, bool>
52struct __throw_with_nested;
53
54template <class _Tp, class _Up>
55struct __throw_with_nested<_Tp, _Up, true> {
56 _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void __do_throw(_Tp&& __t) {
57 throw __nested<_Up>(std::forward<_Tp>(__t));
58 }
59};
60
61template <class _Tp, class _Up>
62struct __throw_with_nested<_Tp, _Up, false> {
63 _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void __do_throw(_Tp&& __t) { throw std::forward<_Tp>(__t); }
64};
65#endif
66
67template <class _Tp>
68_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void throw_with_nested(_Tp&& __t) {
69#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
70 using _Up = __decay_t<_Tp>;
71 static_assert(is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible");
72 __throw_with_nested<_Tp,
73 _Up,
74 is_class<_Up>::value && !is_base_of<nested_exception, _Up>::value &&
75 !__libcpp_is_final<_Up>::value>::__do_throw(std::forward<_Tp>(__t));
76#else
77 ((void)__t);
78 // FIXME: Make this abort
79#endif
80}
81
82template <class _From, class _To>
83struct __can_dynamic_cast
84 : _BoolConstant< is_polymorphic<_From>::value &&
85 (!is_base_of<_To, _From>::value || is_convertible<const _From*, const _To*>::value)> {};
86
87template <class _Ep>
88inline _LIBCPP_HIDE_FROM_ABI void
89rethrow_if_nested(const _Ep& __e, __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value>* = 0) {
90 const nested_exception* __nep = dynamic_cast<const nested_exception*>(std::addressof(__e));
91 if (__nep)
92 __nep->rethrow_nested();
93}
94
95template <class _Ep>
96inline _LIBCPP_HIDE_FROM_ABI void
97rethrow_if_nested(const _Ep&, __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value>* = 0) {}
98
99} // namespace std
100
101#endif // _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H
lib/libcxx/include/__exception/operations.h created+42
......@@ -0,0 +1,42 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___EXCEPTION_OPERATIONS_H
10#define _LIBCPP___EXCEPTION_OPERATIONS_H
11
12#include <__availability>
13#include <__config>
14#include <cstddef>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20namespace std { // purposefully not using versioning namespace
21#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) || \
22 defined(_LIBCPP_BUILDING_LIBRARY)
23using unexpected_handler = void (*)();
24_LIBCPP_EXPORTED_FROM_ABI unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
25_LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT;
26_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void unexpected();
27#endif
28
29using terminate_handler = void (*)();
30_LIBCPP_EXPORTED_FROM_ABI terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
31_LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT;
32
33_LIBCPP_EXPORTED_FROM_ABI bool uncaught_exception() _NOEXCEPT;
34_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_exceptions() _NOEXCEPT;
35
36class _LIBCPP_EXPORTED_FROM_ABI exception_ptr;
37
38_LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
39_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
40} // namespace std
41
42#endif // _LIBCPP___EXCEPTION_OPERATIONS_H
lib/libcxx/include/__exception/terminate.h created+22
......@@ -0,0 +1,22 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___EXCEPTION_TERMINATE_H
10#define _LIBCPP___EXCEPTION_TERMINATE_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15# pragma GCC system_header
16#endif
17
18namespace std { // purposefully not using versioning namespace
19_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void terminate() _NOEXCEPT;
20} // namespace std
21
22#endif // _LIBCPP___EXCEPTION_TERMINATE_H
lib/libcxx/include/__expected/bad_expected_access.h+8-4
......@@ -10,14 +10,16 @@
1010#define _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H
1111
1212#include <__config>
13#include <__exception/exception.h>
1314#include <__utility/move.h>
1415
15#include <exception>
16
1716#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1817# pragma GCC system_header
1918#endif
2019
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
2123#if _LIBCPP_STD_VER >= 23
2224
2325_LIBCPP_BEGIN_NAMESPACE_STD
......@@ -33,14 +35,14 @@ protected:
3335 _LIBCPP_HIDE_FROM_ABI bad_expected_access(bad_expected_access&&) = default;
3436 _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(const bad_expected_access&) = default;
3537 _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(bad_expected_access&&) = default;
36 ~bad_expected_access() override = default;
38 _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_expected_access() override = default;
3739
3840public:
3941 // The way this has been designed (by using a class template below) means that we'll already
4042 // have a profusion of these vtables in TUs, and the dynamic linker will already have a bunch
4143 // of work to do. So it is not worth hiding the <void> specialization in the dylib, given that
4244 // it adds deployment target restrictions.
43 const char* what() const noexcept override { return "bad access to std::expected"; }
45 _LIBCPP_HIDE_FROM_ABI_VIRTUAL const char* what() const noexcept override { return "bad access to std::expected"; }
4446};
4547
4648template <class _Err>
......@@ -61,4 +63,6 @@ _LIBCPP_END_NAMESPACE_STD
6163
6264#endif // _LIBCPP_STD_VER >= 23
6365
66_LIBCPP_POP_MACROS
67
6468#endif // _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H
lib/libcxx/include/__expected/expected.h+626-40
......@@ -14,10 +14,12 @@
1414#include <__expected/bad_expected_access.h>
1515#include <__expected/unexpect.h>
1616#include <__expected/unexpected.h>
17#include <__functional/invoke.h>
1718#include <__memory/addressof.h>
1819#include <__memory/construct_at.h>
1920#include <__type_traits/conjunction.h>
2021#include <__type_traits/disjunction.h>
22#include <__type_traits/integral_constant.h>
2123#include <__type_traits/is_assignable.h>
2224#include <__type_traits/is_constructible.h>
2325#include <__type_traits/is_convertible.h>
......@@ -44,36 +46,48 @@
4446#include <__type_traits/negation.h>
4547#include <__type_traits/remove_cv.h>
4648#include <__type_traits/remove_cvref.h>
49#include <__utility/as_const.h>
4750#include <__utility/exception_guard.h>
4851#include <__utility/forward.h>
4952#include <__utility/in_place.h>
5053#include <__utility/move.h>
5154#include <__utility/swap.h>
52#include <cstdlib> // for std::abort
55#include <__verbose_abort>
5356#include <initializer_list>
5457
5558#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5659# pragma GCC system_header
5760#endif
5861
62_LIBCPP_PUSH_MACROS
63#include <__undef_macros>
64
5965#if _LIBCPP_STD_VER >= 23
6066
6167_LIBCPP_BEGIN_NAMESPACE_STD
6268
63namespace __expected {
69template <class _Tp, class _Err>
70class expected;
71
72template <class _Tp>
73struct __is_std_expected : false_type {};
74
75template <class _Tp, class _Err>
76struct __is_std_expected<expected<_Tp, _Err>> : true_type {};
77
78struct __expected_construct_in_place_from_invoke_tag {};
79struct __expected_construct_unexpected_from_invoke_tag {};
6480
6581template <class _Err, class _Arg>
6682_LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) {
67# ifndef _LIBCPP_NO_EXCEPTIONS
83# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
6884 throw bad_expected_access<_Err>(std::forward<_Arg>(__arg));
6985# else
7086 (void)__arg;
71 std::abort();
87 _LIBCPP_VERBOSE_ABORT("bad_expected_access was thrown in -fno-exceptions mode");
7288# endif
7389}
7490
75} // namespace __expected
76
7791template <class _Tp, class _Err>
7892class expected {
7993 static_assert(
......@@ -166,6 +180,15 @@ private:
166180 _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
167181 _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>> >;
168182
183 template <class _Func, class... _Args>
184 _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
185 std::__expected_construct_in_place_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
186 : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(true) {}
187
188 template <class _Func, class... _Args>
189 _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
190 std::__expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
191 : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(false) {}
169192
170193public:
171194 template <class _Up, class _OtherErr>
......@@ -503,32 +526,32 @@ public:
503526
504527 // [expected.object.obs], observers
505528 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept {
506 _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value");
529 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator-> requires the expected to contain a value");
507530 return std::addressof(__union_.__val_);
508531 }
509532
510533 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept {
511 _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value");
534 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator-> requires the expected to contain a value");
512535 return std::addressof(__union_.__val_);
513536 }
514537
515538 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept {
516 _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
539 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
517540 return __union_.__val_;
518541 }
519542
520543 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept {
521 _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
544 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
522545 return __union_.__val_;
523546 }
524547
525548 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept {
526 _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
549 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
527550 return std::move(__union_.__val_);
528551 }
529552
530553 _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept {
531 _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
554 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
532555 return std::move(__union_.__val_);
533556 }
534557
......@@ -537,50 +560,56 @@ public:
537560 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; }
538561
539562 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& {
563 static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
540564 if (!__has_val_) {
541 __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
565 std::__throw_bad_expected_access<_Err>(std::as_const(error()));
542566 }
543567 return __union_.__val_;
544568 }
545569
546570 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & {
571 static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
547572 if (!__has_val_) {
548 __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
573 std::__throw_bad_expected_access<_Err>(std::as_const(error()));
549574 }
550575 return __union_.__val_;
551576 }
552577
553578 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& {
579 static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>,
580 "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
554581 if (!__has_val_) {
555 __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
582 std::__throw_bad_expected_access<_Err>(std::move(error()));
556583 }
557584 return std::move(__union_.__val_);
558585 }
559586
560587 _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && {
588 static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>,
589 "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
561590 if (!__has_val_) {
562 __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
591 std::__throw_bad_expected_access<_Err>(std::move(error()));
563592 }
564593 return std::move(__union_.__val_);
565594 }
566595
567596 _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
568 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
597 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
569598 return __union_.__unex_;
570599 }
571600
572601 _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
573 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
602 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
574603 return __union_.__unex_;
575604 }
576605
577606 _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
578 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
607 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
579608 return std::move(__union_.__unex_);
580609 }
581610
582611 _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
583 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
612 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
584613 return std::move(__union_.__unex_);
585614 }
586615
......@@ -598,6 +627,245 @@ public:
598627 return __has_val_ ? std::move(__union_.__val_) : static_cast<_Tp>(std::forward<_Up>(__v));
599628 }
600629
630 template <class _Up = _Err>
631 _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
632 static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
633 static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
634 if (has_value())
635 return std::forward<_Up>(__error);
636 return error();
637 }
638
639 template <class _Up = _Err>
640 _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
641 static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible");
642 static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
643 if (has_value())
644 return std::forward<_Up>(__error);
645 return std::move(error());
646 }
647
648 // [expected.void.monadic], monadic
649 template <class _Func>
650 requires is_constructible_v<_Err, _Err&>
651 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
652 using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&>>;
653 static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected");
654 static_assert(is_same_v<typename _Up::error_type, _Err>,
655 "The result of f(value()) must have the same error_type as this expected");
656 if (has_value()) {
657 return std::invoke(std::forward<_Func>(__f), value());
658 }
659 return _Up(unexpect, error());
660 }
661
662 template <class _Func>
663 requires is_constructible_v<_Err, const _Err&>
664 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
665 using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&>>;
666 static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected");
667 static_assert(is_same_v<typename _Up::error_type, _Err>,
668 "The result of f(value()) must have the same error_type as this expected");
669 if (has_value()) {
670 return std::invoke(std::forward<_Func>(__f), value());
671 }
672 return _Up(unexpect, error());
673 }
674
675 template <class _Func>
676 requires is_constructible_v<_Err, _Err&&>
677 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
678 using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&&>>;
679 static_assert(
680 __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected");
681 static_assert(is_same_v<typename _Up::error_type, _Err>,
682 "The result of f(std::move(value())) must have the same error_type as this expected");
683 if (has_value()) {
684 return std::invoke(std::forward<_Func>(__f), std::move(value()));
685 }
686 return _Up(unexpect, std::move(error()));
687 }
688
689 template <class _Func>
690 requires is_constructible_v<_Err, const _Err&&>
691 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
692 using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>;
693 static_assert(
694 __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected");
695 static_assert(is_same_v<typename _Up::error_type, _Err>,
696 "The result of f(std::move(value())) must have the same error_type as this expected");
697 if (has_value()) {
698 return std::invoke(std::forward<_Func>(__f), std::move(value()));
699 }
700 return _Up(unexpect, std::move(error()));
701 }
702
703 template <class _Func>
704 requires is_constructible_v<_Tp, _Tp&>
705 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
706 using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>;
707 static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
708 static_assert(is_same_v<typename _Gp::value_type, _Tp>,
709 "The result of f(error()) must have the same value_type as this expected");
710 if (has_value()) {
711 return _Gp(in_place, value());
712 }
713 return std::invoke(std::forward<_Func>(__f), error());
714 }
715
716 template <class _Func>
717 requires is_constructible_v<_Tp, const _Tp&>
718 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
719 using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>;
720 static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
721 static_assert(is_same_v<typename _Gp::value_type, _Tp>,
722 "The result of f(error()) must have the same value_type as this expected");
723 if (has_value()) {
724 return _Gp(in_place, value());
725 }
726 return std::invoke(std::forward<_Func>(__f), error());
727 }
728
729 template <class _Func>
730 requires is_constructible_v<_Tp, _Tp&&>
731 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
732 using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>;
733 static_assert(
734 __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
735 static_assert(is_same_v<typename _Gp::value_type, _Tp>,
736 "The result of f(std::move(error())) must have the same value_type as this expected");
737 if (has_value()) {
738 return _Gp(in_place, std::move(value()));
739 }
740 return std::invoke(std::forward<_Func>(__f), std::move(error()));
741 }
742
743 template <class _Func>
744 requires is_constructible_v<_Tp, const _Tp&&>
745 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
746 using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>;
747 static_assert(
748 __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
749 static_assert(is_same_v<typename _Gp::value_type, _Tp>,
750 "The result of f(std::move(error())) must have the same value_type as this expected");
751 if (has_value()) {
752 return _Gp(in_place, std::move(value()));
753 }
754 return std::invoke(std::forward<_Func>(__f), std::move(error()));
755 }
756
757 template <class _Func>
758 requires is_constructible_v<_Err, _Err&>
759 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
760 using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&>>;
761 if (!has_value()) {
762 return expected<_Up, _Err>(unexpect, error());
763 }
764 if constexpr (!is_void_v<_Up>) {
765 return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), value());
766 } else {
767 std::invoke(std::forward<_Func>(__f), value());
768 return expected<_Up, _Err>();
769 }
770 }
771
772 template <class _Func>
773 requires is_constructible_v<_Err, const _Err&>
774 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
775 using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&>>;
776 if (!has_value()) {
777 return expected<_Up, _Err>(unexpect, error());
778 }
779 if constexpr (!is_void_v<_Up>) {
780 return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), value());
781 } else {
782 std::invoke(std::forward<_Func>(__f), value());
783 return expected<_Up, _Err>();
784 }
785 }
786
787 template <class _Func>
788 requires is_constructible_v<_Err, _Err&&>
789 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
790 using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&&>>;
791 if (!has_value()) {
792 return expected<_Up, _Err>(unexpect, std::move(error()));
793 }
794 if constexpr (!is_void_v<_Up>) {
795 return expected<_Up, _Err>(
796 __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
797 } else {
798 std::invoke(std::forward<_Func>(__f), std::move(value()));
799 return expected<_Up, _Err>();
800 }
801 }
802
803 template <class _Func>
804 requires is_constructible_v<_Err, const _Err&&>
805 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
806 using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&&>>;
807 if (!has_value()) {
808 return expected<_Up, _Err>(unexpect, std::move(error()));
809 }
810 if constexpr (!is_void_v<_Up>) {
811 return expected<_Up, _Err>(
812 __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
813 } else {
814 std::invoke(std::forward<_Func>(__f), std::move(value()));
815 return expected<_Up, _Err>();
816 }
817 }
818
819 template <class _Func>
820 requires is_constructible_v<_Tp, _Tp&>
821 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
822 using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>;
823 static_assert(__valid_std_unexpected<_Gp>::value,
824 "The result of f(error()) must be a valid template argument for unexpected");
825 if (has_value()) {
826 return expected<_Tp, _Gp>(in_place, value());
827 }
828 return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
829 }
830
831 template <class _Func>
832 requires is_constructible_v<_Tp, const _Tp&>
833 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
834 using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>;
835 static_assert(__valid_std_unexpected<_Gp>::value,
836 "The result of f(error()) must be a valid template argument for unexpected");
837 if (has_value()) {
838 return expected<_Tp, _Gp>(in_place, value());
839 }
840 return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
841 }
842
843 template <class _Func>
844 requires is_constructible_v<_Tp, _Tp&&>
845 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
846 using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>;
847 static_assert(__valid_std_unexpected<_Gp>::value,
848 "The result of f(std::move(error())) must be a valid template argument for unexpected");
849 if (has_value()) {
850 return expected<_Tp, _Gp>(in_place, std::move(value()));
851 }
852 return expected<_Tp, _Gp>(
853 __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
854 }
855
856 template <class _Func>
857 requires is_constructible_v<_Tp, const _Tp&&>
858 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
859 using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>;
860 static_assert(__valid_std_unexpected<_Gp>::value,
861 "The result of f(std::move(error())) must be a valid template argument for unexpected");
862 if (has_value()) {
863 return expected<_Tp, _Gp>(in_place, std::move(value()));
864 }
865 return expected<_Tp, _Gp>(
866 __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
867 }
868
601869 // [expected.object.eq], equality operators
602870 template <class _T2, class _E2>
603871 requires(!is_void_v<_T2>)
......@@ -625,24 +893,66 @@ public:
625893
626894private:
627895 struct __empty_t {};
628 // use named union because [[no_unique_address]] cannot be applied to an unnamed union
629 _LIBCPP_NO_UNIQUE_ADDRESS union __union_t {
896
897 template <class _ValueType, class _ErrorType>
898 union __union_t {
899 _LIBCPP_HIDE_FROM_ABI constexpr __union_t() {}
900
901 template <class _Func, class... _Args>
902 _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
903 std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args)
904 : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
905
906 template <class _Func, class... _Args>
907 _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
908 std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
909 : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
910
911 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
912 requires(is_trivially_destructible_v<_ValueType> && is_trivially_destructible_v<_ErrorType>)
913 = default;
914
915 // the expected's destructor handles this
916 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {}
917
918 _ValueType __val_;
919 _ErrorType __unex_;
920 };
921
922 // use named union because [[no_unique_address]] cannot be applied to an unnamed union,
923 // also guaranteed elision into a potentially-overlapping subobject is unsettled (and
924 // it's not clear that it's implementable, given that the function is allowed to clobber
925 // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107.
926 template <class _ValueType, class _ErrorType>
927 requires(is_trivially_move_constructible_v<_ValueType> && is_trivially_move_constructible_v<_ErrorType>)
928 union __union_t<_ValueType, _ErrorType> {
630929 _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
631930
931 template <class _Func, class... _Args>
932 _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
933 std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args)
934 : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
935
936 template <class _Func, class... _Args>
937 _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
938 std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
939 : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
940
632941 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
633 requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)
942 requires(is_trivially_destructible_v<_ValueType> && is_trivially_destructible_v<_ErrorType>)
634943 = default;
635944
636945 // the expected's destructor handles this
637946 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
638 requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
947 requires(!is_trivially_destructible_v<_ValueType> || !is_trivially_destructible_v<_ErrorType>)
639948 {}
640949
641950 _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_;
642 _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
643 _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
644 } __union_;
951 _LIBCPP_NO_UNIQUE_ADDRESS _ValueType __val_;
952 _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_;
953 };
645954
955 _LIBCPP_NO_UNIQUE_ADDRESS __union_t<_Tp, _Err> __union_;
646956 bool __has_val_;
647957};
648958
......@@ -762,6 +1072,19 @@ public:
7621072 std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...);
7631073 }
7641074
1075private:
1076 template <class _Func>
1077 _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(__expected_construct_in_place_from_invoke_tag, _Func&& __f)
1078 : __has_val_(true) {
1079 std::invoke(std::forward<_Func>(__f));
1080 }
1081
1082 template <class _Func, class... _Args>
1083 _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
1084 __expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
1085 : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(false) {}
1086
1087public:
7651088 // [expected.void.dtor], destructor
7661089
7671090 _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
......@@ -894,41 +1217,270 @@ public:
8941217 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; }
8951218
8961219 _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept {
897 _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
1220 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
8981221 }
8991222
9001223 _LIBCPP_HIDE_FROM_ABI constexpr void value() const& {
9011224 if (!__has_val_) {
902 __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
1225 std::__throw_bad_expected_access<_Err>(__union_.__unex_);
9031226 }
9041227 }
9051228
9061229 _LIBCPP_HIDE_FROM_ABI constexpr void value() && {
9071230 if (!__has_val_) {
908 __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
1231 std::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
9091232 }
9101233 }
9111234
9121235 _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
913 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
1236 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
9141237 return __union_.__unex_;
9151238 }
9161239
9171240 _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
918 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
1241 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
9191242 return __union_.__unex_;
9201243 }
9211244
9221245 _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
923 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
1246 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
9241247 return std::move(__union_.__unex_);
9251248 }
9261249
9271250 _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
928 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
1251 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
9291252 return std::move(__union_.__unex_);
9301253 }
9311254
1255 template <class _Up = _Err>
1256 _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
1257 static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
1258 static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
1259 if (has_value()) {
1260 return std::forward<_Up>(__error);
1261 }
1262 return error();
1263 }
1264
1265 template <class _Up = _Err>
1266 _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
1267 static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible");
1268 static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
1269 if (has_value()) {
1270 return std::forward<_Up>(__error);
1271 }
1272 return std::move(error());
1273 }
1274
1275 // [expected.void.monadic], monadic
1276 template <class _Func>
1277 requires is_constructible_v<_Err, _Err&>
1278 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
1279 using _Up = remove_cvref_t<invoke_result_t<_Func>>;
1280 static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
1281 static_assert(
1282 is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
1283 if (has_value()) {
1284 return std::invoke(std::forward<_Func>(__f));
1285 }
1286 return _Up(unexpect, error());
1287 }
1288
1289 template <class _Func>
1290 requires is_constructible_v<_Err, const _Err&>
1291 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
1292 using _Up = remove_cvref_t<invoke_result_t<_Func>>;
1293 static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
1294 static_assert(
1295 is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
1296 if (has_value()) {
1297 return std::invoke(std::forward<_Func>(__f));
1298 }
1299 return _Up(unexpect, error());
1300 }
1301
1302 template <class _Func>
1303 requires is_constructible_v<_Err, _Err&&>
1304 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
1305 using _Up = remove_cvref_t<invoke_result_t<_Func>>;
1306 static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
1307 static_assert(
1308 is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
1309 if (has_value()) {
1310 return std::invoke(std::forward<_Func>(__f));
1311 }
1312 return _Up(unexpect, std::move(error()));
1313 }
1314
1315 template <class _Func>
1316 requires is_constructible_v<_Err, const _Err&&>
1317 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
1318 using _Up = remove_cvref_t<invoke_result_t<_Func>>;
1319 static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
1320 static_assert(
1321 is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
1322 if (has_value()) {
1323 return std::invoke(std::forward<_Func>(__f));
1324 }
1325 return _Up(unexpect, std::move(error()));
1326 }
1327
1328 template <class _Func>
1329 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
1330 using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>;
1331 static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
1332 static_assert(is_same_v<typename _Gp::value_type, _Tp>,
1333 "The result of f(error()) must have the same value_type as this expected");
1334 if (has_value()) {
1335 return _Gp();
1336 }
1337 return std::invoke(std::forward<_Func>(__f), error());
1338 }
1339
1340 template <class _Func>
1341 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
1342 using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>;
1343 static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
1344 static_assert(is_same_v<typename _Gp::value_type, _Tp>,
1345 "The result of f(error()) must have the same value_type as this expected");
1346 if (has_value()) {
1347 return _Gp();
1348 }
1349 return std::invoke(std::forward<_Func>(__f), error());
1350 }
1351
1352 template <class _Func>
1353 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
1354 using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>;
1355 static_assert(__is_std_expected<_Gp>::value,
1356 "The result of f(std::move(error())) must be a specialization of std::expected");
1357 static_assert(is_same_v<typename _Gp::value_type, _Tp>,
1358 "The result of f(std::move(error())) must have the same value_type as this expected");
1359 if (has_value()) {
1360 return _Gp();
1361 }
1362 return std::invoke(std::forward<_Func>(__f), std::move(error()));
1363 }
1364
1365 template <class _Func>
1366 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
1367 using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>;
1368 static_assert(__is_std_expected<_Gp>::value,
1369 "The result of f(std::move(error())) must be a specialization of std::expected");
1370 static_assert(is_same_v<typename _Gp::value_type, _Tp>,
1371 "The result of f(std::move(error())) must have the same value_type as this expected");
1372 if (has_value()) {
1373 return _Gp();
1374 }
1375 return std::invoke(std::forward<_Func>(__f), std::move(error()));
1376 }
1377
1378 template <class _Func>
1379 requires is_constructible_v<_Err, _Err&>
1380 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
1381 using _Up = remove_cv_t<invoke_result_t<_Func>>;
1382 if (!has_value()) {
1383 return expected<_Up, _Err>(unexpect, error());
1384 }
1385 if constexpr (!is_void_v<_Up>) {
1386 return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
1387 } else {
1388 std::invoke(std::forward<_Func>(__f));
1389 return expected<_Up, _Err>();
1390 }
1391 }
1392
1393 template <class _Func>
1394 requires is_constructible_v<_Err, const _Err&>
1395 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
1396 using _Up = remove_cv_t<invoke_result_t<_Func>>;
1397 if (!has_value()) {
1398 return expected<_Up, _Err>(unexpect, error());
1399 }
1400 if constexpr (!is_void_v<_Up>) {
1401 return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
1402 } else {
1403 std::invoke(std::forward<_Func>(__f));
1404 return expected<_Up, _Err>();
1405 }
1406 }
1407
1408 template <class _Func>
1409 requires is_constructible_v<_Err, _Err&&>
1410 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
1411 using _Up = remove_cv_t<invoke_result_t<_Func>>;
1412 if (!has_value()) {
1413 return expected<_Up, _Err>(unexpect, std::move(error()));
1414 }
1415 if constexpr (!is_void_v<_Up>) {
1416 return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
1417 } else {
1418 std::invoke(std::forward<_Func>(__f));
1419 return expected<_Up, _Err>();
1420 }
1421 }
1422
1423 template <class _Func>
1424 requires is_constructible_v<_Err, const _Err&&>
1425 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
1426 using _Up = remove_cv_t<invoke_result_t<_Func>>;
1427 if (!has_value()) {
1428 return expected<_Up, _Err>(unexpect, std::move(error()));
1429 }
1430 if constexpr (!is_void_v<_Up>) {
1431 return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
1432 } else {
1433 std::invoke(std::forward<_Func>(__f));
1434 return expected<_Up, _Err>();
1435 }
1436 }
1437
1438 template <class _Func>
1439 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
1440 using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>;
1441 static_assert(__valid_std_unexpected<_Gp>::value,
1442 "The result of f(error()) must be a valid template argument for unexpected");
1443 if (has_value()) {
1444 return expected<_Tp, _Gp>();
1445 }
1446 return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
1447 }
1448
1449 template <class _Func>
1450 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
1451 using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>;
1452 static_assert(__valid_std_unexpected<_Gp>::value,
1453 "The result of f(error()) must be a valid template argument for unexpected");
1454 if (has_value()) {
1455 return expected<_Tp, _Gp>();
1456 }
1457 return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
1458 }
1459
1460 template <class _Func>
1461 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
1462 using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>;
1463 static_assert(__valid_std_unexpected<_Gp>::value,
1464 "The result of f(std::move(error())) must be a valid template argument for unexpected");
1465 if (has_value()) {
1466 return expected<_Tp, _Gp>();
1467 }
1468 return expected<_Tp, _Gp>(
1469 __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
1470 }
1471
1472 template <class _Func>
1473 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
1474 using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>;
1475 static_assert(__valid_std_unexpected<_Gp>::value,
1476 "The result of f(std::move(error())) must be a valid template argument for unexpected");
1477 if (has_value()) {
1478 return expected<_Tp, _Gp>();
1479 }
1480 return expected<_Tp, _Gp>(
1481 __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
1482 }
1483
9321484 // [expected.void.eq], equality operators
9331485 template <class _T2, class _E2>
9341486 requires is_void_v<_T2>
......@@ -947,23 +1499,55 @@ public:
9471499
9481500private:
9491501 struct __empty_t {};
950 // use named union because [[no_unique_address]] cannot be applied to an unnamed union
951 _LIBCPP_NO_UNIQUE_ADDRESS union __union_t {
1502
1503 template <class _ErrorType>
1504 union __union_t {
9521505 _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
9531506
1507 template <class _Func, class... _Args>
1508 _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
1509 __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
1510 : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
1511
9541512 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
955 requires(is_trivially_destructible_v<_Err>)
1513 requires(is_trivially_destructible_v<_ErrorType>)
9561514 = default;
9571515
9581516 // the expected's destructor handles this
1517 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {}
1518
1519 __empty_t __empty_;
1520 _ErrorType __unex_;
1521 };
1522
1523 // use named union because [[no_unique_address]] cannot be applied to an unnamed union,
1524 // also guaranteed elision into a potentially-overlapping subobject is unsettled (and
1525 // it's not clear that it's implementable, given that the function is allowed to clobber
1526 // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107.
1527 template <class _ErrorType>
1528 requires is_trivially_move_constructible_v<_ErrorType>
1529 union __union_t<_ErrorType> {
1530 _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
1531
1532 template <class _Func, class... _Args>
1533 _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
1534 __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
1535 : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
1536
9591537 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
960 requires(!is_trivially_destructible_v<_Err>)
1538 requires(is_trivially_destructible_v<_ErrorType>)
1539 = default;
1540
1541 // the expected's destructor handles this
1542 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
1543 requires(!is_trivially_destructible_v<_ErrorType>)
9611544 {}
9621545
9631546 _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_;
964 _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
965 } __union_;
1547 _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_;
1548 };
9661549
1550 _LIBCPP_NO_UNIQUE_ADDRESS __union_t<_Err> __union_;
9671551 bool __has_val_;
9681552};
9691553
......@@ -971,4 +1555,6 @@ _LIBCPP_END_NAMESPACE_STD
9711555
9721556#endif // _LIBCPP_STD_VER >= 23
9731557
1558_LIBCPP_POP_MACROS
1559
9741560#endif // _LIBCPP___EXPECTED_EXPECTED_H
lib/libcxx/include/__expected/unexpect.h+1-1
......@@ -20,7 +20,7 @@
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
2222struct unexpect_t {
23 _LIBCPP_HIDE_FROM_ABI explicit unexpect_t() = default;
23 explicit unexpect_t() = default;
2424};
2525
2626inline constexpr unexpect_t unexpect{};
lib/libcxx/include/__expected/unexpected.h+5
......@@ -31,6 +31,9 @@
3131# pragma GCC system_header
3232#endif
3333
34_LIBCPP_PUSH_MACROS
35#include <__undef_macros>
36
3437#if _LIBCPP_STD_VER >= 23
3538
3639_LIBCPP_BEGIN_NAMESPACE_STD
......@@ -119,4 +122,6 @@ _LIBCPP_END_NAMESPACE_STD
119122
120123#endif // _LIBCPP_STD_VER >= 23
121124
125_LIBCPP_POP_MACROS
126
122127#endif // _LIBCPP___EXPECTED_UNEXPECTED_H
lib/libcxx/include/__filesystem/copy_options.h-4
......@@ -21,8 +21,6 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2323
24_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
25
2624enum class _LIBCPP_ENUM_VIS copy_options : unsigned short {
2725 none = 0,
2826 skip_existing = 1,
......@@ -75,8 +73,6 @@ inline copy_options& operator^=(copy_options& __lhs, copy_options __rhs) {
7573 return __lhs = __lhs ^ __rhs;
7674}
7775
78_LIBCPP_AVAILABILITY_FILESYSTEM_POP
79
8076_LIBCPP_END_NAMESPACE_FILESYSTEM
8177
8278#endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/directory_entry.h+17-18
......@@ -12,8 +12,8 @@
1212
1313#include <__availability>
1414#include <__chrono/time_point.h>
15#include <__compare/ordering.h>
1516#include <__config>
16#include <__errc>
1717#include <__filesystem/file_status.h>
1818#include <__filesystem/file_time_type.h>
1919#include <__filesystem/file_type.h>
......@@ -21,11 +21,12 @@
2121#include <__filesystem/operations.h>
2222#include <__filesystem/path.h>
2323#include <__filesystem/perms.h>
24#include <__system_error/errc.h>
25#include <__system_error/error_code.h>
26#include <__utility/move.h>
2427#include <__utility/unreachable.h>
2528#include <cstdint>
26#include <cstdlib>
2729#include <iosfwd>
28#include <system_error>
2930
3031#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3132# pragma GCC system_header
......@@ -34,21 +35,20 @@
3435_LIBCPP_PUSH_MACROS
3536#include <__undef_macros>
3637
37#ifndef _LIBCPP_CXX03_LANG
38#if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
3839
3940_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
4041
41_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
42
42_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
4343
4444class directory_entry {
4545 typedef _VSTD_FS::path _Path;
4646
4747public:
4848 // constructors and destructors
49 directory_entry() noexcept = default;
50 directory_entry(directory_entry const&) = default;
51 directory_entry(directory_entry&&) noexcept = default;
49 _LIBCPP_HIDE_FROM_ABI directory_entry() noexcept = default;
50 _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry const&) = default;
51 _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry&&) noexcept = default;
5252
5353 _LIBCPP_INLINE_VISIBILITY
5454 explicit directory_entry(_Path const& __p) : __p_(__p) {
......@@ -61,10 +61,10 @@ public:
6161 __refresh(&__ec);
6262 }
6363
64 ~directory_entry() {}
64 _LIBCPP_HIDE_FROM_ABI ~directory_entry() {}
6565
66 directory_entry& operator=(directory_entry const&) = default;
67 directory_entry& operator=(directory_entry&&) noexcept = default;
66 _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry const&) = default;
67 _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry&&) noexcept = default;
6868
6969 _LIBCPP_INLINE_VISIBILITY
7070 void assign(_Path const& __p) {
......@@ -321,8 +321,7 @@ private:
321321 __data_ = __dt;
322322 }
323323
324 _LIBCPP_FUNC_VIS
325 error_code __do_refresh() noexcept;
324 _LIBCPP_EXPORTED_FROM_ABI error_code __do_refresh() noexcept;
326325
327326 _LIBCPP_INLINE_VISIBILITY
328327 static bool __is_dne_error(error_code const& __ec) {
......@@ -510,17 +509,17 @@ public:
510509private:
511510 friend class directory_iterator;
512511 friend class recursive_directory_iterator;
513 explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
514 __dir_element_proxy(__dir_element_proxy&& __o)
512 _LIBCPP_HIDE_FROM_ABI explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
513 _LIBCPP_HIDE_FROM_ABI __dir_element_proxy(__dir_element_proxy&& __o)
515514 : __elem_(_VSTD::move(__o.__elem_)) {}
516515 directory_entry __elem_;
517516};
518517
519_LIBCPP_AVAILABILITY_FILESYSTEM_POP
518_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
520519
521520_LIBCPP_END_NAMESPACE_FILESYSTEM
522521
523#endif // _LIBCPP_CXX03_LANG
522#endif // !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
524523
525524_LIBCPP_POP_MACROS
526525
lib/libcxx/include/__filesystem/directory_iterator.h+21-17
......@@ -16,22 +16,24 @@
1616#include <__filesystem/directory_entry.h>
1717#include <__filesystem/directory_options.h>
1818#include <__filesystem/path.h>
19#include <__iterator/default_sentinel.h>
1920#include <__iterator/iterator_traits.h>
2021#include <__memory/shared_ptr.h>
2122#include <__ranges/enable_borrowed_range.h>
2223#include <__ranges/enable_view.h>
24#include <__system_error/error_code.h>
25#include <__utility/move.h>
2326#include <cstddef>
24#include <system_error>
2527
2628#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2729# pragma GCC system_header
2830#endif
2931
30#ifndef _LIBCPP_CXX03_LANG
32#if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
3133
3234_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
3335
34_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
36_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
3537
3638class _LIBCPP_HIDDEN __dir_stream;
3739class directory_iterator {
......@@ -81,7 +83,7 @@ public:
8183
8284 _LIBCPP_HIDE_FROM_ABI
8385 const directory_entry& operator*() const {
84 _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
86 _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "The end iterator cannot be dereferenced");
8587 return __dereference();
8688 }
8789
......@@ -101,21 +103,23 @@ public:
101103 _LIBCPP_HIDE_FROM_ABI
102104 directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
103105
106# if _LIBCPP_STD_VER >= 20
107
108 _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept { return *this == directory_iterator(); }
109
110# endif
111
104112private:
105113 inline _LIBCPP_HIDE_FROM_ABI friend bool
106114 operator==(const directory_iterator& __lhs,
107115 const directory_iterator& __rhs) noexcept;
108116
109117 // construct the dir_stream
110 _LIBCPP_FUNC_VIS
111 directory_iterator(const path&, error_code*,
112 directory_options = directory_options::none);
118 _LIBCPP_EXPORTED_FROM_ABI directory_iterator(const path&, error_code*, directory_options = directory_options::none);
113119
114 _LIBCPP_FUNC_VIS
115 directory_iterator& __increment(error_code* __ec = nullptr);
120 _LIBCPP_EXPORTED_FROM_ABI directory_iterator& __increment(error_code* __ec = nullptr);
116121
117 _LIBCPP_FUNC_VIS
118 const directory_entry& __dereference() const;
122 _LIBCPP_EXPORTED_FROM_ABI const directory_entry& __dereference() const;
119123
120124private:
121125 shared_ptr<__dir_stream> __imp_;
......@@ -144,22 +148,22 @@ end(directory_iterator) noexcept {
144148 return directory_iterator();
145149}
146150
147_LIBCPP_AVAILABILITY_FILESYSTEM_POP
151_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
148152
149153_LIBCPP_END_NAMESPACE_FILESYSTEM
150154
151#if _LIBCPP_STD_VER > 17
155#if _LIBCPP_STD_VER >= 20
152156
153157template <>
154_LIBCPP_AVAILABILITY_FILESYSTEM
158_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
155159inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::directory_iterator> = true;
156160
157161template <>
158_LIBCPP_AVAILABILITY_FILESYSTEM
162_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
159163inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true;
160164
161#endif // _LIBCPP_STD_VER > 17
165#endif // _LIBCPP_STD_VER >= 20
162166
163#endif // _LIBCPP_CXX03_LANG
167#endif // !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
164168
165169#endif // _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H
lib/libcxx/include/__filesystem/directory_options.h-4
......@@ -21,8 +21,6 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2323
24_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
25
2624enum class _LIBCPP_ENUM_VIS directory_options : unsigned char {
2725 none = 0,
2826 follow_directory_symlink = 1,
......@@ -73,8 +71,6 @@ inline directory_options& operator^=(directory_options& __lhs,
7371 return __lhs = __lhs ^ __rhs;
7472}
7573
76_LIBCPP_AVAILABILITY_FILESYSTEM_POP
77
7874_LIBCPP_END_NAMESPACE_FILESYSTEM
7975
8076#endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/file_status.h+13-9
......@@ -23,9 +23,7 @@
2323
2424_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2525
26_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
27
28class _LIBCPP_TYPE_VIS file_status {
26class _LIBCPP_EXPORTED_FROM_ABI file_status {
2927public:
3028 // constructors
3129 _LIBCPP_INLINE_VISIBILITY
......@@ -35,14 +33,14 @@ public:
3533 : __ft_(__ft),
3634 __prms_(__prms) {}
3735
38 file_status(const file_status&) noexcept = default;
39 file_status(file_status&&) noexcept = default;
36 _LIBCPP_HIDE_FROM_ABI file_status(const file_status&) noexcept = default;
37 _LIBCPP_HIDE_FROM_ABI file_status(file_status&&) noexcept = default;
4038
4139 _LIBCPP_INLINE_VISIBILITY
4240 ~file_status() {}
4341
44 file_status& operator=(const file_status&) noexcept = default;
45 file_status& operator=(file_status&&) noexcept = default;
42 _LIBCPP_HIDE_FROM_ABI file_status& operator=(const file_status&) noexcept = default;
43 _LIBCPP_HIDE_FROM_ABI file_status& operator=(file_status&&) noexcept = default;
4644
4745 // observers
4846 _LIBCPP_INLINE_VISIBILITY
......@@ -58,13 +56,19 @@ public:
5856 _LIBCPP_INLINE_VISIBILITY
5957 void permissions(perms __p) noexcept { __prms_ = __p; }
6058
59# if _LIBCPP_STD_VER >= 20
60
61 _LIBCPP_HIDE_FROM_ABI friend bool operator==(const file_status& __lhs, const file_status& __rhs) noexcept {
62 return __lhs.type() == __rhs.type() && __lhs.permissions() == __rhs.permissions();
63 }
64
65# endif
66
6167private:
6268 file_type __ft_;
6369 perms __prms_;
6470};
6571
66_LIBCPP_AVAILABILITY_FILESYSTEM_POP
67
6872_LIBCPP_END_NAMESPACE_FILESYSTEM
6973
7074#endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/filesystem_error.h+25-38
......@@ -14,11 +14,13 @@
1414#include <__config>
1515#include <__filesystem/path.h>
1616#include <__memory/shared_ptr.h>
17#include <__system_error/error_code.h>
18#include <__system_error/system_error.h>
1719#include <__utility/forward.h>
20#include <__verbose_abort>
1821#include <iosfwd>
1922#include <new>
20#include <system_error>
21#include <type_traits>
23#include <string>
2224
2325#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2426# pragma GCC system_header
......@@ -28,50 +30,38 @@
2830
2931_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
3032
31class _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error {
33class _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_EXPORTED_FROM_ABI filesystem_error : public system_error {
3234public:
33 _LIBCPP_INLINE_VISIBILITY
34 filesystem_error(const string& __what, error_code __ec)
35 : system_error(__ec, __what),
36 __storage_(make_shared<_Storage>(path(), path())) {
35 _LIBCPP_HIDE_FROM_ABI filesystem_error(const string& __what, error_code __ec)
36 : system_error(__ec, __what), __storage_(make_shared<_Storage>(path(), path())) {
3737 __create_what(0);
3838 }
3939
40 _LIBCPP_INLINE_VISIBILITY
41 filesystem_error(const string& __what, const path& __p1, error_code __ec)
42 : system_error(__ec, __what),
43 __storage_(make_shared<_Storage>(__p1, path())) {
40 _LIBCPP_HIDE_FROM_ABI filesystem_error(const string& __what, const path& __p1, error_code __ec)
41 : system_error(__ec, __what), __storage_(make_shared<_Storage>(__p1, path())) {
4442 __create_what(1);
4543 }
4644
47 _LIBCPP_INLINE_VISIBILITY
48 filesystem_error(const string& __what, const path& __p1, const path& __p2,
49 error_code __ec)
50 : system_error(__ec, __what),
51 __storage_(make_shared<_Storage>(__p1, __p2)) {
45 _LIBCPP_HIDE_FROM_ABI filesystem_error(const string& __what, const path& __p1, const path& __p2, error_code __ec)
46 : system_error(__ec, __what), __storage_(make_shared<_Storage>(__p1, __p2)) {
5247 __create_what(2);
5348 }
5449
55 _LIBCPP_INLINE_VISIBILITY
56 const path& path1() const noexcept { return __storage_->__p1_; }
50 _LIBCPP_HIDE_FROM_ABI const path& path1() const noexcept { return __storage_->__p1_; }
5751
58 _LIBCPP_INLINE_VISIBILITY
59 const path& path2() const noexcept { return __storage_->__p2_; }
52 _LIBCPP_HIDE_FROM_ABI const path& path2() const noexcept { return __storage_->__p2_; }
6053
61 filesystem_error(const filesystem_error&) = default;
54 _LIBCPP_HIDE_FROM_ABI filesystem_error(const filesystem_error&) = default;
6255 ~filesystem_error() override; // key function
6356
6457 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
65 const char* what() const noexcept override {
66 return __storage_->__what_.c_str();
67 }
58 const char* what() const noexcept override { return __storage_->__what_.c_str(); }
6859
6960 void __create_what(int __num_paths);
7061
7162private:
7263 struct _LIBCPP_HIDDEN _Storage {
73 _LIBCPP_INLINE_VISIBILITY
74 _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {}
64 _LIBCPP_HIDE_FROM_ABI _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {}
7565
7666 path __p1_;
7767 path __p2_;
......@@ -80,22 +70,19 @@ private:
8070 shared_ptr<_Storage> __storage_;
8171};
8272
83// TODO(ldionne): We need to pop the pragma and push it again after
84// filesystem_error to work around PR41078.
85_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
86
73# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
8774template <class... _Args>
88_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
89#ifndef _LIBCPP_NO_EXCEPTIONS
90void __throw_filesystem_error(_Args&&... __args) {
75_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY void
76__throw_filesystem_error(_Args&&... __args) {
9177 throw filesystem_error(_VSTD::forward<_Args>(__args)...);
9278}
93#else
94void __throw_filesystem_error(_Args&&...) {
95 _VSTD::abort();
79# else
80template <class... _Args>
81_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY void
82__throw_filesystem_error(_Args&&...) {
83 _LIBCPP_VERBOSE_ABORT("filesystem_error was thrown in -fno-exceptions mode");
9684}
97#endif
98_LIBCPP_AVAILABILITY_FILESYSTEM_POP
85# endif
9986
10087_LIBCPP_END_NAMESPACE_FILESYSTEM
10188
lib/libcxx/include/__filesystem/operations.h+36-36
......@@ -21,46 +21,46 @@
2121#include <__filesystem/perm_options.h>
2222#include <__filesystem/perms.h>
2323#include <__filesystem/space_info.h>
24#include <__system_error/error_code.h>
2425#include <cstdint>
25#include <system_error>
2626
2727#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2828# pragma GCC system_header
2929#endif
3030
31#ifndef _LIBCPP_CXX03_LANG
31#if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
3232
3333_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
3434
35_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
36
37_LIBCPP_FUNC_VIS path __absolute(const path&, error_code* __ec = nullptr);
38_LIBCPP_FUNC_VIS path __canonical(const path&, error_code* __ec = nullptr);
39_LIBCPP_FUNC_VIS bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr);
40_LIBCPP_FUNC_VIS void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr);
41_LIBCPP_FUNC_VIS void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr);
42_LIBCPP_FUNC_VIS bool __create_directories(const path&, error_code* = nullptr);
43_LIBCPP_FUNC_VIS void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr);
44_LIBCPP_FUNC_VIS bool __create_directory(const path&, error_code* = nullptr);
45_LIBCPP_FUNC_VIS bool __create_directory(const path&, const path& __attributes, error_code* = nullptr);
46_LIBCPP_FUNC_VIS void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr);
47_LIBCPP_FUNC_VIS void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr);
48_LIBCPP_FUNC_VIS path __current_path(error_code* __ec = nullptr);
49_LIBCPP_FUNC_VIS void __current_path(const path&, error_code* __ec = nullptr);
50_LIBCPP_FUNC_VIS bool __equivalent(const path&, const path&, error_code* __ec = nullptr);
51_LIBCPP_FUNC_VIS file_status __status(const path&, error_code* __ec = nullptr);
52_LIBCPP_FUNC_VIS uintmax_t __file_size(const path&, error_code* __ec = nullptr);
53_LIBCPP_FUNC_VIS uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr);
54_LIBCPP_FUNC_VIS file_status __symlink_status(const path&, error_code* __ec = nullptr);
55_LIBCPP_FUNC_VIS file_time_type __last_write_time(const path&, error_code* __ec = nullptr);
56_LIBCPP_FUNC_VIS void __last_write_time(const path&, file_time_type __new_time, error_code* __ec = nullptr);
57_LIBCPP_FUNC_VIS path __weakly_canonical(path const& __p, error_code* __ec = nullptr);
58_LIBCPP_FUNC_VIS path __read_symlink(const path&, error_code* __ec = nullptr);
59_LIBCPP_FUNC_VIS uintmax_t __remove_all(const path&, error_code* __ec = nullptr);
60_LIBCPP_FUNC_VIS bool __remove(const path&, error_code* __ec = nullptr);
61_LIBCPP_FUNC_VIS void __rename(const path& __from, const path& __to, error_code* __ec = nullptr);
62_LIBCPP_FUNC_VIS void __resize_file(const path&, uintmax_t __size, error_code* = nullptr);
63_LIBCPP_FUNC_VIS path __temp_directory_path(error_code* __ec = nullptr);
35_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
36
37_LIBCPP_EXPORTED_FROM_ABI path __absolute(const path&, error_code* __ec = nullptr);
38_LIBCPP_EXPORTED_FROM_ABI path __canonical(const path&, error_code* __ec = nullptr);
39_LIBCPP_EXPORTED_FROM_ABI bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr);
40_LIBCPP_EXPORTED_FROM_ABI void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr);
41_LIBCPP_EXPORTED_FROM_ABI void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr);
42_LIBCPP_EXPORTED_FROM_ABI bool __create_directories(const path&, error_code* = nullptr);
43_LIBCPP_EXPORTED_FROM_ABI void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr);
44_LIBCPP_EXPORTED_FROM_ABI bool __create_directory(const path&, error_code* = nullptr);
45_LIBCPP_EXPORTED_FROM_ABI bool __create_directory(const path&, const path& __attributes, error_code* = nullptr);
46_LIBCPP_EXPORTED_FROM_ABI void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr);
47_LIBCPP_EXPORTED_FROM_ABI void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr);
48_LIBCPP_EXPORTED_FROM_ABI path __current_path(error_code* __ec = nullptr);
49_LIBCPP_EXPORTED_FROM_ABI void __current_path(const path&, error_code* __ec = nullptr);
50_LIBCPP_EXPORTED_FROM_ABI bool __equivalent(const path&, const path&, error_code* __ec = nullptr);
51_LIBCPP_EXPORTED_FROM_ABI file_status __status(const path&, error_code* __ec = nullptr);
52_LIBCPP_EXPORTED_FROM_ABI uintmax_t __file_size(const path&, error_code* __ec = nullptr);
53_LIBCPP_EXPORTED_FROM_ABI uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr);
54_LIBCPP_EXPORTED_FROM_ABI file_status __symlink_status(const path&, error_code* __ec = nullptr);
55_LIBCPP_EXPORTED_FROM_ABI file_time_type __last_write_time(const path&, error_code* __ec = nullptr);
56_LIBCPP_EXPORTED_FROM_ABI void __last_write_time(const path&, file_time_type __new_time, error_code* __ec = nullptr);
57_LIBCPP_EXPORTED_FROM_ABI path __weakly_canonical(path const& __p, error_code* __ec = nullptr);
58_LIBCPP_EXPORTED_FROM_ABI path __read_symlink(const path&, error_code* __ec = nullptr);
59_LIBCPP_EXPORTED_FROM_ABI uintmax_t __remove_all(const path&, error_code* __ec = nullptr);
60_LIBCPP_EXPORTED_FROM_ABI bool __remove(const path&, error_code* __ec = nullptr);
61_LIBCPP_EXPORTED_FROM_ABI void __rename(const path& __from, const path& __to, error_code* __ec = nullptr);
62_LIBCPP_EXPORTED_FROM_ABI void __resize_file(const path&, uintmax_t __size, error_code* = nullptr);
63_LIBCPP_EXPORTED_FROM_ABI path __temp_directory_path(error_code* __ec = nullptr);
6464
6565inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p) { return __absolute(__p); }
6666inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p, error_code& __ec) { return __absolute(__p, &__ec); }
......@@ -118,7 +118,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p, error_code&
118118inline _LIBCPP_HIDE_FROM_ABI bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; }
119119inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p) { return is_directory(__status(__p)); }
120120inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p, error_code& __ec) noexcept { return is_directory(__status(__p, &__ec)); }
121_LIBCPP_FUNC_VIS bool __fs_is_empty(const path& __p, error_code* __ec = nullptr);
121_LIBCPP_EXPORTED_FROM_ABI bool __fs_is_empty(const path& __p, error_code* __ec = nullptr);
122122inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p) { return __fs_is_empty(__p); }
123123inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p, error_code& __ec) { return __fs_is_empty(__p, &__ec); }
124124inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; }
......@@ -140,7 +140,7 @@ inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p) { r
140140inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p, error_code& __ec) noexcept { return __last_write_time(__p, &__ec); }
141141inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t) { __last_write_time(__p, __t); }
142142inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t, error_code& __ec) noexcept { __last_write_time(__p, __t, &__ec); }
143_LIBCPP_FUNC_VIS void __permissions(const path&, perms, perm_options, error_code* = nullptr);
143_LIBCPP_EXPORTED_FROM_ABI void __permissions(const path&, perms, perm_options, error_code* = nullptr);
144144inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace) { __permissions(__p, __prms, __opts); }
145145inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { __permissions(__p, __prms, perm_options::replace, &__ec); }
146146inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) { __permissions(__p, __prms, __opts, &__ec); }
......@@ -180,7 +180,7 @@ inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to) {
180180inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to, error_code& __ec) noexcept { return __rename(__from, __to, &__ec); }
181181inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns) { return __resize_file(__p, __ns); }
182182inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { return __resize_file(__p, __ns, &__ec); }
183_LIBCPP_FUNC_VIS space_info __space(const path&, error_code* __ec = nullptr);
183_LIBCPP_EXPORTED_FROM_ABI space_info __space(const path&, error_code* __ec = nullptr);
184184inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p) { return __space(__p); }
185185inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p, error_code& __ec) noexcept { return __space(__p, &__ec); }
186186inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p) { return __status(__p); }
......@@ -192,10 +192,10 @@ inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path(error_code& __ec) { return
192192inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p) { return __weakly_canonical(__p); }
193193inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p, error_code& __ec) { return __weakly_canonical(__p, &__ec); }
194194
195_LIBCPP_AVAILABILITY_FILESYSTEM_POP
195_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
196196
197197_LIBCPP_END_NAMESPACE_FILESYSTEM
198198
199#endif // _LIBCPP_CXX03_LANG
199#endif // !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
200200
201201#endif // _LIBCPP___FILESYSTEM_OPERATIONS_H
lib/libcxx/include/__filesystem/path.h+31-17
......@@ -14,12 +14,18 @@
1414#include <__algorithm/replace_copy.h>
1515#include <__availability>
1616#include <__config>
17#include <__functional/hash.h>
18#include <__functional/unary_function.h>
19#include <__fwd/hash.h>
1720#include <__iterator/back_insert_iterator.h>
1821#include <__iterator/iterator_traits.h>
22#include <__type_traits/decay.h>
23#include <__type_traits/is_pointer.h>
24#include <__type_traits/remove_const.h>
25#include <__type_traits/remove_pointer.h>
1926#include <cstddef>
2027#include <string>
2128#include <string_view>
22#include <type_traits>
2329
2430#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
2531# include <iomanip> // for quoted
......@@ -34,7 +40,7 @@
3440
3541_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
3642
37_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
43_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
3844
3945template <class _Tp>
4046struct __can_convert_char {
......@@ -139,7 +145,7 @@ struct __is_pathable_string<
139145 }
140146};
141147
142template <class _Source, class _DS = typename decay<_Source>::type,
148template <class _Source, class _DS = __decay_t<_Source>,
143149 class _UnqualPtrType =
144150 __remove_const_t<__remove_pointer_t<_DS> >,
145151 bool _IsCharPtr = is_pointer<_DS>::value&&
......@@ -168,7 +174,7 @@ struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
168174 static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
169175};
170176
171template <class _Iter, bool _IsIt = __is_cpp17_input_iterator<_Iter>::value,
177template <class _Iter, bool _IsIt = __has_input_iterator_category<_Iter>::value,
172178 class = void>
173179struct __is_pathable_iter : false_type {};
174180
......@@ -217,10 +223,8 @@ typedef char __path_value;
217223#endif
218224
219225#if defined(_LIBCPP_WIN32API)
220_LIBCPP_FUNC_VIS
221size_t __wide_to_char(const wstring&, char*, size_t);
222_LIBCPP_FUNC_VIS
223size_t __char_to_wide(const string&, wchar_t*, size_t);
226_LIBCPP_EXPORTED_FROM_ABI size_t __wide_to_char(const wstring&, char*, size_t);
227_LIBCPP_EXPORTED_FROM_ABI size_t __char_to_wide(const string&, wchar_t*, size_t);
224228#endif
225229
226230template <class _ECharT>
......@@ -303,7 +307,7 @@ struct _PathCVT<__path_value> {
303307
304308 template <class _Iter>
305309 _LIBCPP_HIDE_FROM_ABI
306 static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type
310 static typename enable_if<__has_exactly_input_iterator_category<_Iter>::value>::type
307311 __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
308312 for (; __b != __e; ++__b)
309313 __dest.push_back(*__b);
......@@ -311,7 +315,7 @@ struct _PathCVT<__path_value> {
311315
312316 template <class _Iter>
313317 _LIBCPP_HIDE_FROM_ABI
314 static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
318 static typename enable_if<__has_forward_iterator_category<_Iter>::value>::type
315319 __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
316320 __dest.append(__b, __e);
317321 }
......@@ -348,7 +352,7 @@ struct _PathCVT<char> {
348352
349353 template <class _Iter>
350354 _LIBCPP_HIDE_FROM_ABI
351 static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type
355 static typename enable_if<__has_exactly_input_iterator_category<_Iter>::value>::type
352356 __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
353357 basic_string<char> __tmp(__b, __e);
354358 __append_string(__dest, __tmp);
......@@ -356,7 +360,7 @@ struct _PathCVT<char> {
356360
357361 template <class _Iter>
358362 _LIBCPP_HIDE_FROM_ABI
359 static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
363 static typename enable_if<__has_forward_iterator_category<_Iter>::value>::type
360364 __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
361365 basic_string<char> __tmp(__b, __e);
362366 __append_string(__dest, __tmp);
......@@ -439,7 +443,7 @@ struct _PathExport<char8_t> {
439443#endif /* !_LIBCPP_HAS_NO_CHAR8_T */
440444#endif /* _LIBCPP_WIN32API */
441445
442class _LIBCPP_TYPE_VIS path {
446class _LIBCPP_EXPORTED_FROM_ABI path {
443447 template <class _SourceOrIter, class _Tp = path&>
444448 using _EnableIfPathable =
445449 typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
......@@ -1029,7 +1033,7 @@ public:
10291033 }
10301034
10311035 // iterators
1032 class _LIBCPP_TYPE_VIS iterator;
1036 class _LIBCPP_EXPORTED_FROM_ABI iterator;
10331037 typedef iterator const_iterator;
10341038
10351039 iterator begin() const;
......@@ -1079,13 +1083,23 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(path& __lhs, path& __rhs) noexcept {
10791083 __lhs.swap(__rhs);
10801084}
10811085
1082_LIBCPP_FUNC_VIS
1083size_t hash_value(const path& __p) noexcept;
1086_LIBCPP_EXPORTED_FROM_ABI size_t hash_value(const path& __p) noexcept;
10841087
1085_LIBCPP_AVAILABILITY_FILESYSTEM_POP
1088_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
10861089
10871090_LIBCPP_END_NAMESPACE_FILESYSTEM
10881091
1092_LIBCPP_BEGIN_NAMESPACE_STD
1093
1094template <>
1095struct _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY hash<_VSTD_FS::path> : __unary_function<_VSTD_FS::path, size_t> {
1096 _LIBCPP_HIDE_FROM_ABI size_t operator()(_VSTD_FS::path const& __p) const noexcept {
1097 return _VSTD_FS::hash_value(__p);
1098 }
1099};
1100
1101_LIBCPP_END_NAMESPACE_STD
1102
10891103#endif // _LIBCPP_CXX03_LANG
10901104
10911105#endif // _LIBCPP___FILESYSTEM_PATH_H
lib/libcxx/include/__filesystem/path_iterator.h+14-16
......@@ -27,9 +27,7 @@
2727
2828_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2929
30_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
31
32class _LIBCPP_TYPE_VIS path::iterator {
30class _LIBCPP_EXPORTED_FROM_ABI path::iterator {
3331public:
3432 enum _ParserState : unsigned char {
3533 _Singular,
......@@ -56,10 +54,10 @@ public:
5654 : __stashed_elem_(), __path_ptr_(nullptr), __entry_(),
5755 __state_(_Singular) {}
5856
59 iterator(const iterator&) = default;
60 ~iterator() = default;
57 _LIBCPP_HIDE_FROM_ABI iterator(const iterator&) = default;
58 _LIBCPP_HIDE_FROM_ABI ~iterator() = default;
6159
62 iterator& operator=(const iterator&) = default;
60 _LIBCPP_HIDE_FROM_ABI iterator& operator=(const iterator&) = default;
6361
6462 _LIBCPP_INLINE_VISIBILITY
6563 reference operator*() const { return __stashed_elem_; }
......@@ -69,10 +67,10 @@ public:
6967
7068 _LIBCPP_INLINE_VISIBILITY
7169 iterator& operator++() {
72 _LIBCPP_ASSERT(__state_ != _Singular,
73 "attempting to increment a singular iterator");
74 _LIBCPP_ASSERT(__state_ != _AtEnd,
75 "attempting to increment the end iterator");
70 _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _Singular,
71 "attempting to increment a singular iterator");
72 _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _AtEnd,
73 "attempting to increment the end iterator");
7674 return __increment();
7775 }
7876
......@@ -85,10 +83,10 @@ public:
8583
8684 _LIBCPP_INLINE_VISIBILITY
8785 iterator& operator--() {
88 _LIBCPP_ASSERT(__state_ != _Singular,
89 "attempting to decrement a singular iterator");
90 _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
91 "attempting to decrement the begin iterator");
86 _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _Singular,
87 "attempting to decrement a singular iterator");
88 _LIBCPP_ASSERT_UNCATEGORIZED(__entry_.data() != __path_ptr_->native().data(),
89 "attempting to decrement the begin iterator");
9290 return __decrement();
9391 }
9492
......@@ -114,19 +112,19 @@ private:
114112 _ParserState __state_;
115113};
116114
115_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
117116inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs,
118117 const path::iterator& __rhs) {
119118 return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
120119 __lhs.__entry_.data() == __rhs.__entry_.data();
121120}
122121
122_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
123123inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs,
124124 const path::iterator& __rhs) {
125125 return !(__lhs == __rhs);
126126}
127127
128_LIBCPP_AVAILABILITY_FILESYSTEM_POP
129
130128_LIBCPP_END_NAMESPACE_FILESYSTEM
131129
132130#endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/perm_options.h-4
......@@ -21,8 +21,6 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2323
24_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
25
2624enum class _LIBCPP_ENUM_VIS perm_options : unsigned char {
2725 replace = 1,
2826 add = 2,
......@@ -68,8 +66,6 @@ inline perm_options& operator^=(perm_options& __lhs, perm_options __rhs) {
6866 return __lhs = __lhs ^ __rhs;
6967}
7068
71_LIBCPP_AVAILABILITY_FILESYSTEM_POP
72
7369_LIBCPP_END_NAMESPACE_FILESYSTEM
7470
7571#endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/perms.h-4
......@@ -21,8 +21,6 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2323
24_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
25
2624// On Windows, these permission bits map to one single readonly flag per
2725// file, and the executable bit is always returned as set. When setting
2826// permissions, as long as the write bit is set for either owner, group or
......@@ -86,8 +84,6 @@ inline perms& operator|=(perms& __lhs, perms __rhs) { return __lhs = __lhs | __r
8684_LIBCPP_INLINE_VISIBILITY
8785inline perms& operator^=(perms& __lhs, perms __rhs) { return __lhs = __lhs ^ __rhs; }
8886
89_LIBCPP_AVAILABILITY_FILESYSTEM_POP
90
9187_LIBCPP_END_NAMESPACE_FILESYSTEM
9288
9389#endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/recursive_directory_iterator.h+30-32
......@@ -15,22 +15,24 @@
1515#include <__filesystem/directory_entry.h>
1616#include <__filesystem/directory_options.h>
1717#include <__filesystem/path.h>
18#include <__iterator/default_sentinel.h>
1819#include <__iterator/iterator_traits.h>
1920#include <__memory/shared_ptr.h>
2021#include <__ranges/enable_borrowed_range.h>
2122#include <__ranges/enable_view.h>
23#include <__system_error/error_code.h>
24#include <__utility/move.h>
2225#include <cstddef>
23#include <system_error>
2426
2527#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2628# pragma GCC system_header
2729#endif
2830
29#ifndef _LIBCPP_CXX03_LANG
31#if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
3032
3133_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
3234
33_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
35_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
3436
3537class recursive_directory_iterator {
3638public:
......@@ -59,10 +61,10 @@ public:
5961 recursive_directory_iterator(const path& __p, error_code& __ec)
6062 : recursive_directory_iterator(__p, directory_options::none, &__ec) {}
6163
62 recursive_directory_iterator(const recursive_directory_iterator&) = default;
63 recursive_directory_iterator(recursive_directory_iterator&&) = default;
64 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const recursive_directory_iterator&) = default;
65 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(recursive_directory_iterator&&) = default;
6466
65 recursive_directory_iterator&
67 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator&
6668 operator=(const recursive_directory_iterator&) = default;
6769
6870 _LIBCPP_INLINE_VISIBILITY
......@@ -76,7 +78,7 @@ public:
7678 return *this;
7779 }
7880
79 ~recursive_directory_iterator() = default;
81 _LIBCPP_HIDE_FROM_ABI ~recursive_directory_iterator() = default;
8082
8183 _LIBCPP_INLINE_VISIBILITY
8284 const directory_entry& operator*() const { return __dereference(); }
......@@ -84,7 +86,7 @@ public:
8486 _LIBCPP_INLINE_VISIBILITY
8587 const directory_entry* operator->() const { return &__dereference(); }
8688
87 recursive_directory_iterator& operator++() { return __increment(); }
89 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator++() { return __increment(); }
8890
8991 _LIBCPP_INLINE_VISIBILITY
9092 __dir_element_proxy operator++(int) {
......@@ -98,8 +100,8 @@ public:
98100 return __increment(&__ec);
99101 }
100102
101 _LIBCPP_FUNC_VIS directory_options options() const;
102 _LIBCPP_FUNC_VIS int depth() const;
103 _LIBCPP_EXPORTED_FROM_ABI directory_options options() const;
104 _LIBCPP_EXPORTED_FROM_ABI int depth() const;
103105
104106 _LIBCPP_INLINE_VISIBILITY
105107 void pop() { __pop(); }
......@@ -113,25 +115,21 @@ public:
113115 _LIBCPP_INLINE_VISIBILITY
114116 void disable_recursion_pending() { __rec_ = false; }
115117
116private:
117 _LIBCPP_FUNC_VIS
118 recursive_directory_iterator(const path& __p, directory_options __opt,
119 error_code* __ec);
120
121 _LIBCPP_FUNC_VIS
122 const directory_entry& __dereference() const;
118# if _LIBCPP_STD_VER >= 20
123119
124 _LIBCPP_FUNC_VIS
125 bool __try_recursion(error_code* __ec);
126
127 _LIBCPP_FUNC_VIS
128 void __advance(error_code* __ec = nullptr);
120 _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept {
121 return *this == recursive_directory_iterator();
122 }
129123
130 _LIBCPP_FUNC_VIS
131 recursive_directory_iterator& __increment(error_code* __ec = nullptr);
124# endif
132125
133 _LIBCPP_FUNC_VIS
134 void __pop(error_code* __ec = nullptr);
126private:
127 _LIBCPP_EXPORTED_FROM_ABI recursive_directory_iterator(const path& __p, directory_options __opt, error_code* __ec);
128 _LIBCPP_EXPORTED_FROM_ABI const directory_entry& __dereference() const;
129 _LIBCPP_EXPORTED_FROM_ABI bool __try_recursion(error_code* __ec);
130 _LIBCPP_EXPORTED_FROM_ABI void __advance(error_code* __ec = nullptr);
131 _LIBCPP_EXPORTED_FROM_ABI recursive_directory_iterator& __increment(error_code* __ec = nullptr);
132 _LIBCPP_EXPORTED_FROM_ABI void __pop(error_code* __ec = nullptr);
135133
136134 inline _LIBCPP_INLINE_VISIBILITY friend bool
137135 operator==(const recursive_directory_iterator&,
......@@ -164,22 +162,22 @@ end(recursive_directory_iterator) noexcept {
164162 return recursive_directory_iterator();
165163}
166164
167_LIBCPP_AVAILABILITY_FILESYSTEM_POP
165_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
168166
169167_LIBCPP_END_NAMESPACE_FILESYSTEM
170168
171#if _LIBCPP_STD_VER > 17
169#if _LIBCPP_STD_VER >= 20
172170
173171template <>
174_LIBCPP_AVAILABILITY_FILESYSTEM
172_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
175173inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::recursive_directory_iterator> = true;
176174
177175template <>
178_LIBCPP_AVAILABILITY_FILESYSTEM
176_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
179177inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true;
180178
181#endif // _LIBCPP_STD_VER > 17
179#endif // _LIBCPP_STD_VER >= 20
182180
183#endif // _LIBCPP_CXX03_LANG
181#endif // !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
184182
185183#endif // _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H
lib/libcxx/include/__filesystem/space_info.h+2-6
......@@ -22,20 +22,16 @@
2222
2323_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2424
25_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
26
27struct _LIBCPP_TYPE_VIS space_info {
25struct _LIBCPP_EXPORTED_FROM_ABI space_info {
2826 uintmax_t capacity;
2927 uintmax_t free;
3028 uintmax_t available;
3129
32# if _LIBCPP_STD_VER > 17
30# if _LIBCPP_STD_VER >= 20
3331 friend _LIBCPP_HIDE_FROM_ABI bool operator==(const space_info&, const space_info&) = default;
3432# endif
3533};
3634
37_LIBCPP_AVAILABILITY_FILESYSTEM_POP
38
3935_LIBCPP_END_NAMESPACE_FILESYSTEM
4036
4137#endif // _LIBCPP_CXX03_LANG
lib/libcxx/include/__filesystem/u8path.h+2-3
......@@ -15,7 +15,6 @@
1515#include <__config>
1616#include <__filesystem/path.h>
1717#include <string>
18#include <type_traits>
1918
2019// Only required on Windows for __widen_from_utf8, and included conservatively
2120// because it requires support for localization.
......@@ -31,7 +30,7 @@
3130
3231_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
3332
34_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
33_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
3534
3635template <class _InputIt>
3736_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
......@@ -99,7 +98,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
9998#endif
10099}
101100
102_LIBCPP_AVAILABILITY_FILESYSTEM_POP
101_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
103102
104103_LIBCPP_END_NAMESPACE_FILESYSTEM
105104
lib/libcxx/include/__format/buffer.h+101-23
......@@ -27,11 +27,18 @@
2727#include <__iterator/incrementable_traits.h>
2828#include <__iterator/iterator_traits.h>
2929#include <__iterator/wrap_iter.h>
30#include <__memory/addressof.h>
31#include <__memory/allocate_at_least.h>
32#include <__memory/allocator_traits.h>
33#include <__memory/construct_at.h>
34#include <__memory/ranges_construct_at.h>
35#include <__memory/uninitialized_algorithms.h>
36#include <__type_traits/add_pointer.h>
37#include <__type_traits/conditional.h>
38#include <__utility/exception_guard.h>
3039#include <__utility/move.h>
3140#include <cstddef>
3241#include <string_view>
33#include <type_traits>
34#include <vector>
3542
3643#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3744# pragma GCC system_header
......@@ -42,7 +49,7 @@ _LIBCPP_PUSH_MACROS
4249
4350_LIBCPP_BEGIN_NAMESPACE_STD
4451
45#if _LIBCPP_STD_VER > 17
52#if _LIBCPP_STD_VER >= 20
4653
4754namespace __format {
4855
......@@ -100,7 +107,7 @@ public:
100107 size_t __n = __str.size();
101108
102109 __flush_on_overflow(__n);
103 if (__n <= __capacity_) {
110 if (__n < __capacity_) { // push_back requires the buffer to have room for at least one character (so use <).
104111 _VSTD::copy_n(__str.data(), __n, _VSTD::addressof(__ptr_[__size_]));
105112 __size_ += __n;
106113 return;
......@@ -108,7 +115,7 @@ public:
108115
109116 // The output doesn't fit in the internal buffer.
110117 // Copy the data in "__capacity_" sized chunks.
111 _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
118 _LIBCPP_ASSERT_UNCATEGORIZED(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
112119 const _InCharT* __first = __str.data();
113120 do {
114121 size_t __chunk = _VSTD::min(__n, __capacity_);
......@@ -125,11 +132,11 @@ public:
125132 /// Like @ref __copy it may need to do type conversion.
126133 template <__fmt_char_type _InCharT, class _UnaryOperation>
127134 _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) {
128 _LIBCPP_ASSERT(__first <= __last, "not a valid range");
135 _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "not a valid range");
129136
130137 size_t __n = static_cast<size_t>(__last - __first);
131138 __flush_on_overflow(__n);
132 if (__n <= __capacity_) {
139 if (__n < __capacity_) { // push_back requires the buffer to have room for at least one character (so use <).
133140 _VSTD::transform(__first, __last, _VSTD::addressof(__ptr_[__size_]), _VSTD::move(__operation));
134141 __size_ += __n;
135142 return;
......@@ -137,7 +144,7 @@ public:
137144
138145 // The output doesn't fit in the internal buffer.
139146 // Transform the data in "__capacity_" sized chunks.
140 _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
147 _LIBCPP_ASSERT_UNCATEGORIZED(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
141148 do {
142149 size_t __chunk = _VSTD::min(__n, __capacity_);
143150 _VSTD::transform(__first, __first + __chunk, _VSTD::addressof(__ptr_[__size_]), __operation);
......@@ -151,7 +158,7 @@ public:
151158 /// A \c fill_n wrapper.
152159 _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) {
153160 __flush_on_overflow(__n);
154 if (__n <= __capacity_) {
161 if (__n < __capacity_) { // push_back requires the buffer to have room for at least one character (so use <).
155162 _VSTD::fill_n(_VSTD::addressof(__ptr_[__size_]), __n, __value);
156163 __size_ += __n;
157164 return;
......@@ -159,7 +166,7 @@ public:
159166
160167 // The output doesn't fit in the internal buffer.
161168 // Fill the buffer in "__capacity_" sized chunks.
162 _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
169 _LIBCPP_ASSERT_UNCATEGORIZED(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
163170 do {
164171 size_t __chunk = _VSTD::min(__n, __capacity_);
165172 _VSTD::fill_n(_VSTD::addressof(__ptr_[__size_]), __chunk, __value);
......@@ -246,9 +253,9 @@ class _LIBCPP_TEMPLATE_VIS __direct_storage {};
246253template <class _OutIt, class _CharT>
247254concept __enable_direct_output = __fmt_char_type<_CharT> &&
248255 (same_as<_OutIt, _CharT*>
249#ifndef _LIBCPP_ENABLE_DEBUG_MODE
256 // TODO(hardening): the following check might not apply to hardened iterators and might need to be wrapped in an
257 // `#ifdef`.
250258 || same_as<_OutIt, __wrap_iter<_CharT*>>
251#endif
252259 );
253260
254261/// Write policy for directly writing to the underlying output.
......@@ -510,13 +517,19 @@ public:
510517// context and the format arguments need to be retargeted to the new context.
511518// This retargeting is done by a basic_format_context specialized for the
512519// __iterator of this container.
520//
521// This class uses its own buffer management, since using vector
522// would lead to a circular include with formatter for vector<bool>.
513523template <__fmt_char_type _CharT>
514524class _LIBCPP_TEMPLATE_VIS __retarget_buffer {
525 using _Alloc = allocator<_CharT>;
526
515527public:
516528 using value_type = _CharT;
517529
518530 struct __iterator {
519531 using difference_type = ptrdiff_t;
532 using value_type = _CharT;
520533
521534 _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(__retarget_buffer& __buffer)
522535 : __buffer_(std::addressof(__buffer)) {}
......@@ -535,36 +548,101 @@ public:
535548 __retarget_buffer* __buffer_;
536549 };
537550
538 _LIBCPP_HIDE_FROM_ABI explicit __retarget_buffer(size_t __size_hint) { __buffer_.reserve(__size_hint); }
551 __retarget_buffer(const __retarget_buffer&) = delete;
552 __retarget_buffer& operator=(const __retarget_buffer&) = delete;
553
554 _LIBCPP_HIDE_FROM_ABI explicit __retarget_buffer(size_t __size_hint) {
555 // When the initial size is very small a lot of resizes happen
556 // when elements added. So use a hard-coded minimum size.
557 //
558 // Note a size < 2 will not work
559 // - 0 there is no buffer, while push_back requires 1 empty element.
560 // - 1 multiplied by the grow factor is 1 and thus the buffer never
561 // grows.
562 auto __result = std::__allocate_at_least(__alloc_, std::max(__size_hint, 256 / sizeof(_CharT)));
563 __ptr_ = __result.ptr;
564 __capacity_ = __result.count;
565 }
566
567 _LIBCPP_HIDE_FROM_ABI ~__retarget_buffer() {
568 ranges::destroy_n(__ptr_, __size_);
569 allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __capacity_);
570 }
539571
540572 _LIBCPP_HIDE_FROM_ABI __iterator __make_output_iterator() { return __iterator{*this}; }
541573
542 _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) { __buffer_.push_back(__c); }
574 _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) {
575 std::construct_at(__ptr_ + __size_, __c);
576 ++__size_;
577
578 if (__size_ == __capacity_)
579 __grow_buffer();
580 }
543581
544582 template <__fmt_char_type _InCharT>
545583 _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) {
546 __buffer_.insert(__buffer_.end(), __str.begin(), __str.end());
584 size_t __n = __str.size();
585 if (__size_ + __n >= __capacity_)
586 // Push_back requires the buffer to have room for at least one character.
587 __grow_buffer(__size_ + __n + 1);
588
589 std::uninitialized_copy_n(__str.data(), __n, __ptr_ + __size_);
590 __size_ += __n;
547591 }
548592
549593 template <__fmt_char_type _InCharT, class _UnaryOperation>
550594 _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) {
551 _LIBCPP_ASSERT(__first <= __last, "not a valid range");
552 std::transform(__first, __last, std::back_inserter(__buffer_), std::move(__operation));
595 _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "not a valid range");
596
597 size_t __n = static_cast<size_t>(__last - __first);
598 if (__size_ + __n >= __capacity_)
599 // Push_back requires the buffer to have room for at least one character.
600 __grow_buffer(__size_ + __n + 1);
601
602 std::uninitialized_default_construct_n(__ptr_ + __size_, __n);
603 std::transform(__first, __last, __ptr_ + __size_, std::move(__operation));
604 __size_ += __n;
553605 }
554606
555 _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { __buffer_.insert(__buffer_.end(), __n, __value); }
607 _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) {
608 if (__size_ + __n >= __capacity_)
609 // Push_back requires the buffer to have room for at least one character.
610 __grow_buffer(__size_ + __n + 1);
611
612 std::uninitialized_fill_n(__ptr_ + __size_, __n, __value);
613 __size_ += __n;
614 }
556615
557 _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__buffer_.data(), __buffer_.size()}; }
616 _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__ptr_, __size_}; }
558617
559618private:
560 // Use vector instead of string to avoid adding zeros after every append
561 // operation. The buffer is exposed as a string_view and not as a c-string.
562 vector<_CharT> __buffer_;
619 _LIBCPP_HIDE_FROM_ABI void __grow_buffer() { __grow_buffer(__capacity_ * 1.6); }
620
621 _LIBCPP_HIDE_FROM_ABI void __grow_buffer(size_t __capacity) {
622 _LIBCPP_ASSERT_UNCATEGORIZED(__capacity > __capacity_, "the buffer must grow");
623 auto __result = std::__allocate_at_least(__alloc_, __capacity);
624 auto __guard = std::__make_exception_guard([&] {
625 allocator_traits<_Alloc>::deallocate(__alloc_, __result.ptr, __result.count);
626 });
627 // This shouldn't throw, but just to be safe. Note that at -O1 this
628 // guard is optimized away so there is no runtime overhead.
629 std::uninitialized_move_n(__ptr_, __size_, __result.ptr);
630 __guard.__complete();
631 ranges::destroy_n(__ptr_, __size_);
632 allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __capacity_);
633
634 __ptr_ = __result.ptr;
635 __capacity_ = __result.count;
636 }
637 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
638 _CharT* __ptr_;
639 size_t __capacity_;
640 size_t __size_{0};
563641};
564642
565643} // namespace __format
566644
567#endif //_LIBCPP_STD_VER > 17
645#endif //_LIBCPP_STD_VER >= 20
568646
569647_LIBCPP_END_NAMESPACE_STD
570648
lib/libcxx/include/__format/concepts.h+18-14
......@@ -16,9 +16,9 @@
1616#include <__format/format_fwd.h>
1717#include <__format/format_parse_context.h>
1818#include <__type_traits/is_specialization.h>
19#include <__type_traits/remove_const.h>
1920#include <__utility/pair.h>
2021#include <tuple>
21#include <type_traits>
2222
2323#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2424# pragma GCC system_header
......@@ -26,7 +26,7 @@
2626
2727_LIBCPP_BEGIN_NAMESPACE_STD
2828
29#if _LIBCPP_STD_VER > 17
29#if _LIBCPP_STD_VER >= 20
3030
3131/// The character type specializations of \ref formatter.
3232template <class _CharT>
......@@ -44,19 +44,23 @@ concept __fmt_char_type =
4444template <class _CharT>
4545using __fmt_iter_for = _CharT*;
4646
47template <class _Tp, class _Context, class _Formatter = typename _Context::template formatter_type<remove_const_t<_Tp>>>
48concept __formattable_with =
49 semiregular<_Formatter> &&
50 requires(_Formatter& __f,
51 const _Formatter& __cf,
52 _Tp&& __t,
53 _Context __fc,
54 basic_format_parse_context<typename _Context::char_type> __pc) {
55 { __f.parse(__pc) } -> same_as<typename decltype(__pc)::iterator>;
56 { __cf.format(__t, __fc) } -> same_as<typename _Context::iterator>;
57 };
58
4759template <class _Tp, class _CharT>
4860concept __formattable =
49 (semiregular<formatter<remove_cvref_t<_Tp>, _CharT>>) &&
50 requires(formatter<remove_cvref_t<_Tp>, _CharT> __f,
51 const formatter<remove_cvref_t<_Tp>, _CharT> __cf,
52 _Tp __t,
53 basic_format_context<__fmt_iter_for<_CharT>, _CharT> __fc,
54 basic_format_parse_context<_CharT> __pc) {
55 { __f.parse(__pc) } -> same_as<typename basic_format_parse_context<_CharT>::iterator>;
56 { __cf.format(__t, __fc) } -> same_as<__fmt_iter_for<_CharT>>;
57 };
61 __formattable_with<remove_reference_t<_Tp>, basic_format_context<__fmt_iter_for<_CharT>, _CharT>>;
5862
59# if _LIBCPP_STD_VER > 20
63# if _LIBCPP_STD_VER >= 23
6064template <class _Tp, class _CharT>
6165concept formattable = __formattable<_Tp, _CharT>;
6266
......@@ -69,8 +73,8 @@ template <class _Tp>
6973concept __fmt_pair_like =
7074 __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2);
7175
72# endif //_LIBCPP_STD_VER > 20
73#endif //_LIBCPP_STD_VER > 17
76# endif //_LIBCPP_STD_VER >= 23
77#endif //_LIBCPP_STD_VER >= 20
7478
7579_LIBCPP_END_NAMESPACE_STD
7680
lib/libcxx/include/__format/container_adaptor.h+12-9
......@@ -14,17 +14,19 @@
1414# pragma GCC system_header
1515#endif
1616
17#include <__availability>
1817#include <__config>
1918#include <__format/concepts.h>
2019#include <__format/formatter.h>
2120#include <__format/range_default_formatter.h>
21#include <__ranges/ref_view.h>
22#include <__type_traits/is_const.h>
23#include <__type_traits/maybe_const.h>
2224#include <queue>
2325#include <stack>
2426
2527_LIBCPP_BEGIN_NAMESPACE_STD
2628
27#if _LIBCPP_STD_VER > 20
29#if _LIBCPP_STD_VER >= 23
2830
2931// [container.adaptors.format] only specifies the library should provide the
3032// formatter specializations, not which header should provide them.
......@@ -33,10 +35,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3335// adaptor headers. To use the format functions users already include <format>.
3436
3537template <class _Adaptor, class _CharT>
36struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_container_adaptor {
38struct _LIBCPP_TEMPLATE_VIS __formatter_container_adaptor {
3739private:
38 using __maybe_const_adaptor = __fmt_maybe_const<_Adaptor, _CharT>;
39 formatter<typename _Adaptor::container_type, _CharT> __underlying_;
40 using __maybe_const_container = __fmt_maybe_const<typename _Adaptor::container_type, _CharT>;
41 using __maybe_const_adaptor = __maybe_const<is_const_v<__maybe_const_container>, _Adaptor>;
42 formatter<ranges::ref_view<__maybe_const_container>, _CharT> __underlying_;
4043
4144public:
4245 template <class _ParseContext>
......@@ -52,18 +55,18 @@ public:
5255};
5356
5457template <class _CharT, class _Tp, formattable<_CharT> _Container>
55struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<queue<_Tp, _Container>, _CharT>
58struct _LIBCPP_TEMPLATE_VIS formatter<queue<_Tp, _Container>, _CharT>
5659 : public __formatter_container_adaptor<queue<_Tp, _Container>, _CharT> {};
5760
5861template <class _CharT, class _Tp, class _Container, class _Compare>
59struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<priority_queue<_Tp, _Container, _Compare>, _CharT>
62struct _LIBCPP_TEMPLATE_VIS formatter<priority_queue<_Tp, _Container, _Compare>, _CharT>
6063 : public __formatter_container_adaptor<priority_queue<_Tp, _Container, _Compare>, _CharT> {};
6164
6265template <class _CharT, class _Tp, formattable<_CharT> _Container>
63struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<stack<_Tp, _Container>, _CharT>
66struct _LIBCPP_TEMPLATE_VIS formatter<stack<_Tp, _Container>, _CharT>
6467 : public __formatter_container_adaptor<stack<_Tp, _Container>, _CharT> {};
6568
66#endif //_LIBCPP_STD_VER > 20
69#endif //_LIBCPP_STD_VER >= 23
6770
6871_LIBCPP_END_NAMESPACE_STD
6972
lib/libcxx/include/__format/enable_insertable.h+2-2
......@@ -18,7 +18,7 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323namespace __format {
2424
......@@ -28,7 +28,7 @@ inline constexpr bool __enable_insertable = false;
2828
2929} // namespace __format
3030
31#endif //_LIBCPP_STD_VER > 17
31#endif //_LIBCPP_STD_VER >= 20
3232
3333_LIBCPP_END_NAMESPACE_STD
3434
lib/libcxx/include/__format/escaped_output_table.h+2-2
......@@ -72,7 +72,7 @@
7272
7373_LIBCPP_BEGIN_NAMESPACE_STD
7474
75#if _LIBCPP_STD_VER > 20
75#if _LIBCPP_STD_VER >= 23
7676
7777namespace __escaped_output_table {
7878
......@@ -1031,7 +1031,7 @@ inline constexpr uint32_t __unallocated_region_lower_bound = 0x000323b0;
10311031
10321032} // namespace __escaped_output_table
10331033
1034#endif //_LIBCPP_STD_VER > 20
1034#endif //_LIBCPP_STD_VER >= 23
10351035
10361036_LIBCPP_END_NAMESPACE_STD
10371037
lib/libcxx/include/__format/extended_grapheme_cluster_table.h+2-2
......@@ -73,7 +73,7 @@
7373
7474_LIBCPP_BEGIN_NAMESPACE_STD
7575
76#if _LIBCPP_STD_VER > 17
76#if _LIBCPP_STD_VER >= 20
7777
7878namespace __extended_grapheme_custer_property_boundary {
7979
......@@ -1654,7 +1654,7 @@ inline constexpr uint32_t __entries[1496] = {
16541654
16551655} // namespace __extended_grapheme_custer_property_boundary
16561656
1657#endif //_LIBCPP_STD_VER > 17
1657#endif //_LIBCPP_STD_VER >= 20
16581658
16591659_LIBCPP_END_NAMESPACE_STD
16601660
lib/libcxx/include/__format/format_arg.h+16-20
......@@ -13,15 +13,17 @@
1313#include <__assert>
1414#include <__concepts/arithmetic.h>
1515#include <__config>
16#include <__format/format_error.h>
16#include <__format/concepts.h>
1717#include <__format/format_fwd.h>
1818#include <__format/format_parse_context.h>
1919#include <__functional/invoke.h>
2020#include <__memory/addressof.h>
21#include <__type_traits/conditional.h>
2122#include <__utility/forward.h>
23#include <__utility/move.h>
2224#include <__utility/unreachable.h>
2325#include <__variant/monostate.h>
24#include <string>
26#include <cstdint>
2527#include <string_view>
2628
2729#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -30,7 +32,7 @@
3032
3133_LIBCPP_BEGIN_NAMESPACE_STD
3234
33#if _LIBCPP_STD_VER > 17
35#if _LIBCPP_STD_VER >= 20
3436
3537namespace __format {
3638/// The type stored in @ref basic_format_arg.
......@@ -81,7 +83,7 @@ constexpr bool __use_packed_format_arg_store(size_t __size) { return __size <= _
8183
8284_LIBCPP_HIDE_FROM_ABI
8385constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) {
84 _LIBCPP_ASSERT(__id <= __packed_types_max, "");
86 _LIBCPP_ASSERT_UNCATEGORIZED(__id <= __packed_types_max, "");
8587
8688 if (__id > 0)
8789 __types >>= __id * __packed_arg_t_bits;
......@@ -94,7 +96,7 @@ constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) {
9496// This function is not user obervable, so it can directly use the non-standard
9597// types of the "variant". See __arg_t for more details.
9698template <class _Visitor, class _Context>
97_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto)
99_LIBCPP_HIDE_FROM_ABI decltype(auto)
98100__visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
99101 switch (__arg.__type_) {
100102 case __format::__arg_t::__none:
......@@ -155,18 +157,14 @@ public:
155157 /// Contains the implementation for basic_format_arg::handle.
156158 struct __handle {
157159 template <class _Tp>
158 _LIBCPP_HIDE_FROM_ABI explicit __handle(_Tp&& __v) noexcept
160 _LIBCPP_HIDE_FROM_ABI explicit __handle(_Tp& __v) noexcept
159161 : __ptr_(_VSTD::addressof(__v)),
160162 __format_([](basic_format_parse_context<_CharT>& __parse_ctx, _Context& __ctx, const void* __ptr) {
161 using _Dp = remove_cvref_t<_Tp>;
162 using _Formatter = typename _Context::template formatter_type<_Dp>;
163 constexpr bool __const_formattable =
164 requires { _Formatter().format(std::declval<const _Dp&>(), std::declval<_Context&>()); };
165 using _Qp = conditional_t<__const_formattable, const _Dp, _Dp>;
163 using _Dp = remove_const_t<_Tp>;
164 using _Qp = conditional_t<__formattable_with<const _Dp, _Context>, const _Dp, _Dp>;
165 static_assert(__formattable_with<_Qp, _Context>, "Mandated by [format.arg]/10");
166166
167 static_assert(__const_formattable || !is_const_v<remove_reference_t<_Tp>>, "Mandated by [format.arg]/18");
168
169 _Formatter __f;
167 typename _Context::template formatter_type<_Dp> __f;
170168 __parse_ctx.advance_to(__f.parse(__parse_ctx));
171169 __ctx.advance_to(__f.format(*const_cast<_Qp*>(static_cast<const _Dp*>(__ptr)), __ctx));
172170 }) {}
......@@ -218,13 +216,11 @@ public:
218216 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(basic_string_view<_CharT> __value) noexcept
219217 : __string_view_(__value) {}
220218 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const void* __value) noexcept : __ptr_(__value) {}
221 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle __value) noexcept
222 // TODO FMT Investigate why it doesn't work without the forward.
223 : __handle_(std::forward<__handle>(__value)) {}
219 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle&& __value) noexcept : __handle_(std::move(__value)) {}
224220};
225221
226222template <class _Context>
227class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg {
223class _LIBCPP_TEMPLATE_VIS basic_format_arg {
228224public:
229225 class _LIBCPP_TEMPLATE_VIS handle;
230226
......@@ -276,7 +272,7 @@ private:
276272// This function is user facing, so it must wrap the non-standard types of
277273// the "variant" in a handle to stay conforming. See __arg_t for more details.
278274template <class _Visitor, class _Context>
279_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto)
275_LIBCPP_HIDE_FROM_ABI decltype(auto)
280276visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
281277 switch (__arg.__type_) {
282278# ifndef _LIBCPP_HAS_NO_INT128
......@@ -295,7 +291,7 @@ visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
295291 }
296292}
297293
298#endif //_LIBCPP_STD_VER > 17
294#endif //_LIBCPP_STD_VER >= 20
299295
300296_LIBCPP_END_NAMESPACE_STD
301297
lib/libcxx/include/__format/format_arg_store.h+25-16
......@@ -19,15 +19,15 @@
1919#include <__config>
2020#include <__format/concepts.h>
2121#include <__format/format_arg.h>
22#include <__utility/forward.h>
23#include <cstring>
22#include <__type_traits/conditional.h>
23#include <__type_traits/extent.h>
24#include <__type_traits/remove_const.h>
2425#include <string>
2526#include <string_view>
26#include <type_traits>
2727
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232namespace __format {
3333
......@@ -142,21 +142,31 @@ consteval __arg_t __determine_arg_t() {
142142//
143143// Note this version can't be constrained avoiding ambiguous overloads.
144144// That means it can be instantiated by disabled formatters. To solve this, a
145// constrained version for not formattable formatters is added. That overload
146// is marked as deleted to fail creating a storage type for disabled formatters.
145// constrained version for not formattable formatters is added.
147146template <class _Context, class _Tp>
148147consteval __arg_t __determine_arg_t() {
149148 return __arg_t::__handle;
150149}
151150
151// The overload for not formattable types allows triggering the static
152// assertion below.
152153template <class _Context, class _Tp>
153154 requires(!__formattable<_Tp, typename _Context::char_type>)
154consteval __arg_t __determine_arg_t() = delete;
155consteval __arg_t __determine_arg_t() {
156 return __arg_t::__none;
157}
155158
159// Pseudo constuctor for basic_format_arg
160//
161// Modeled after template<class T> explicit basic_format_arg(T& v) noexcept;
162// [format.arg]/4-6
156163template <class _Context, class _Tp>
157_LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __value) noexcept {
158 constexpr __arg_t __arg = __determine_arg_t<_Context, remove_cvref_t<_Tp>>();
159 static_assert(__arg != __arg_t::__none);
164_LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp& __value) noexcept {
165 using _Dp = remove_const_t<_Tp>;
166 constexpr __arg_t __arg = __determine_arg_t<_Context, _Dp>();
167 static_assert(__arg != __arg_t::__none, "the supplied type is not formattable");
168
169 static_assert(__formattable_with<_Tp, _Context>);
160170
161171 // Not all types can be used to directly initialize the
162172 // __basic_format_arg_value. First handle all types needing adjustment, the
......@@ -175,9 +185,9 @@ _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __val
175185 return basic_format_arg<_Context>{__arg, static_cast<unsigned long long>(__value)};
176186 else if constexpr (__arg == __arg_t::__string_view)
177187 // Using std::size on a character array will add the NUL-terminator to the size.
178 if constexpr (is_array_v<remove_cvref_t<_Tp>>)
188 if constexpr (is_array_v<_Dp>)
179189 return basic_format_arg<_Context>{
180 __arg, basic_string_view<typename _Context::char_type>{__value, extent_v<remove_cvref_t<_Tp>> - 1}};
190 __arg, basic_string_view<typename _Context::char_type>{__value, extent_v<_Dp> - 1}};
181191 else
182192 // When the _Traits or _Allocator are different an implicit conversion will
183193 // fail.
......@@ -186,8 +196,7 @@ _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __val
186196 else if constexpr (__arg == __arg_t::__ptr)
187197 return basic_format_arg<_Context>{__arg, static_cast<const void*>(__value)};
188198 else if constexpr (__arg == __arg_t::__handle)
189 return basic_format_arg<_Context>{
190 __arg, typename __basic_format_arg_value<_Context>::__handle{_VSTD::forward<_Tp>(__value)}};
199 return basic_format_arg<_Context>{__arg, typename __basic_format_arg_value<_Context>::__handle{__value}};
191200 else
192201 return basic_format_arg<_Context>{__arg, __value};
193202}
......@@ -218,7 +227,7 @@ _LIBCPP_HIDE_FROM_ABI void __store_basic_format_arg(basic_format_arg<_Context>*
218227template <class _Context, size_t N>
219228struct __packed_format_arg_store {
220229 __basic_format_arg_value<_Context> __values_[N];
221 uint64_t __types_;
230 uint64_t __types_ = 0;
222231};
223232
224233template <class _Context, size_t N>
......@@ -247,7 +256,7 @@ struct _LIBCPP_TEMPLATE_VIS __format_arg_store {
247256 _Storage __storage;
248257};
249258
250#endif //_LIBCPP_STD_VER > 17
259#endif //_LIBCPP_STD_VER >= 20
251260
252261_LIBCPP_END_NAMESPACE_STD
253262
lib/libcxx/include/__format/format_args.h+7-5
......@@ -24,12 +24,12 @@
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929template <class _Context>
30class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_args {
30class _LIBCPP_TEMPLATE_VIS basic_format_args {
3131public:
32 _LIBCPP_HIDE_FROM_ABI basic_format_args() noexcept = default;
32 basic_format_args() noexcept = default;
3333
3434 template <class... _Args>
3535 _LIBCPP_HIDE_FROM_ABI basic_format_args(const __format_arg_store<_Context, _Args...>& __store) noexcept
......@@ -71,9 +71,11 @@ private:
7171 const basic_format_arg<_Context>* __args_;
7272 };
7373};
74_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_args);
7574
76#endif //_LIBCPP_STD_VER > 17
75template <class _Context, class... _Args>
76basic_format_args(__format_arg_store<_Context, _Args...>) -> basic_format_args<_Context>;
77
78#endif //_LIBCPP_STD_VER >= 20
7779
7880_LIBCPP_END_NAMESPACE_STD
7981
lib/libcxx/include/__format/format_context.h+10-11
......@@ -37,11 +37,11 @@
3737
3838_LIBCPP_BEGIN_NAMESPACE_STD
3939
40#if _LIBCPP_STD_VER > 17
40#if _LIBCPP_STD_VER >= 20
4141
4242template <class _OutIt, class _CharT>
4343requires output_iterator<_OutIt, const _CharT&>
44class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context;
44class _LIBCPP_TEMPLATE_VIS basic_format_context;
4545
4646#ifndef _LIBCPP_HAS_NO_LOCALIZATION
4747/**
......@@ -80,7 +80,6 @@ requires output_iterator<_OutIt, const _CharT&>
8080class
8181 // clang-format off
8282 _LIBCPP_TEMPLATE_VIS
83 _LIBCPP_AVAILABILITY_FORMAT
8483 _LIBCPP_PREFERRED_NAME(format_context)
8584 _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wformat_context))
8685 // clang-format on
......@@ -121,9 +120,9 @@ private:
121120 // TODO FMT Validate whether lazy creation is the best solution.
122121 optional<_VSTD::locale> __loc_;
123122
124 template <class __OutIt, class __CharT>
125 friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT>
126 __format_context_create(__OutIt, basic_format_args<basic_format_context<__OutIt, __CharT>>,
123 template <class _OtherOutIt, class _OtherCharT>
124 friend _LIBCPP_HIDE_FROM_ABI basic_format_context<_OtherOutIt, _OtherCharT>
125 __format_context_create(_OtherOutIt, basic_format_args<basic_format_context<_OtherOutIt, _OtherCharT>>,
127126 optional<_VSTD::locale>&&);
128127
129128 // Note: the Standard doesn't specify the required constructors.
......@@ -134,9 +133,9 @@ private:
134133 : __out_it_(_VSTD::move(__out_it)), __args_(__args),
135134 __loc_(_VSTD::move(__loc)) {}
136135#else
137 template <class __OutIt, class __CharT>
138 friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT>
139 __format_context_create(__OutIt, basic_format_args<basic_format_context<__OutIt, __CharT>>);
136 template <class _OtherOutIt, class _OtherCharT>
137 friend _LIBCPP_HIDE_FROM_ABI basic_format_context<_OtherOutIt, _OtherCharT>
138 __format_context_create(_OtherOutIt, basic_format_args<basic_format_context<_OtherOutIt, _OtherCharT>>);
140139
141140 _LIBCPP_HIDE_FROM_ABI
142141 explicit basic_format_context(_OutIt __out_it,
......@@ -162,7 +161,7 @@ private:
162161// Here the width of an element in input is determined dynamically.
163162// Note when the top-level element has no width the retargeting is not needed.
164163template <class _CharT>
165class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
164class _LIBCPP_TEMPLATE_VIS
166165 basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> {
167166public:
168167 using iterator = typename __format::__retarget_buffer<_CharT>::__iterator;
......@@ -216,7 +215,7 @@ private:
216215};
217216
218217_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_context);
219#endif //_LIBCPP_STD_VER > 17
218#endif //_LIBCPP_STD_VER >= 20
220219
221220_LIBCPP_END_NAMESPACE_STD
222221
lib/libcxx/include/__format/format_error.h+11-15
......@@ -11,7 +11,7 @@
1111#define _LIBCPP___FORMAT_FORMAT_ERROR_H
1212
1313#include <__config>
14#include <cstdlib>
14#include <__verbose_abort>
1515#include <stdexcept>
1616
1717#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -20,35 +20,31 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
25class _LIBCPP_EXCEPTION_ABI format_error : public runtime_error {
25_LIBCPP_DIAGNOSTIC_PUSH
26_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
27class _LIBCPP_EXPORTED_FROM_ABI format_error : public runtime_error {
2628public:
2729 _LIBCPP_HIDE_FROM_ABI explicit format_error(const string& __s)
2830 : runtime_error(__s) {}
2931 _LIBCPP_HIDE_FROM_ABI explicit format_error(const char* __s)
3032 : runtime_error(__s) {}
31 // TODO FMT Remove when format is no longer experimental.
32 // Avoids linker errors when building the Clang-cl Windows DLL which doesn't
33 // support the experimental library.
34# ifndef _LIBCPP_INLINE_FORMAT_ERROR_DTOR
35 ~format_error() noexcept override;
36# else
37 ~format_error() noexcept override {}
38# endif
33 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
34 ~format_error() noexcept override = default;
3935};
36_LIBCPP_DIAGNOSTIC_POP
4037
4138_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void
4239__throw_format_error(const char* __s) {
43#ifndef _LIBCPP_NO_EXCEPTIONS
40#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
4441 throw format_error(__s);
4542#else
46 (void)__s;
47 _VSTD::abort();
43 _LIBCPP_VERBOSE_ABORT("format_error was thrown in -fno-exceptions mode with message \"%s\"", __s);
4844#endif
4945}
5046
51#endif //_LIBCPP_STD_VER > 17
47#endif //_LIBCPP_STD_VER >= 20
5248
5349_LIBCPP_END_NAMESPACE_STD
5450
lib/libcxx/include/__format/format_functions.h+116-117
......@@ -10,16 +10,10 @@
1010#ifndef _LIBCPP___FORMAT_FORMAT_FUNCTIONS
1111#define _LIBCPP___FORMAT_FORMAT_FUNCTIONS
1212
13// TODO FMT This is added to fix Apple back-deployment.
14#include <version>
15#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
16
1713#include <__algorithm/clamp.h>
18#include <__availability>
1914#include <__concepts/convertible_to.h>
2015#include <__concepts/same_as.h>
2116#include <__config>
22#include <__debug>
2317#include <__format/buffer.h>
2418#include <__format/format_arg.h>
2519#include <__format/format_arg_store.h>
......@@ -38,7 +32,9 @@
3832#include <__format/formatter_string.h>
3933#include <__format/parser_std_format_spec.h>
4034#include <__iterator/back_insert_iterator.h>
35#include <__iterator/concepts.h>
4136#include <__iterator/incrementable_traits.h>
37#include <__iterator/iterator_traits.h> // iter_value_t
4238#include <__variant/monostate.h>
4339#include <array>
4440#include <string>
......@@ -54,7 +50,7 @@
5450
5551_LIBCPP_BEGIN_NAMESPACE_STD
5652
57#if _LIBCPP_STD_VER > 17
53#if _LIBCPP_STD_VER >= 20
5854
5955// TODO FMT Evaluate which templates should be external templates. This
6056// improves the efficiency of the header. However since the header is still
......@@ -67,16 +63,17 @@ using wformat_args = basic_format_args<wformat_context>;
6763#endif
6864
6965template <class _Context = format_context, class... _Args>
70_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&&... __args) {
66_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&&... __args) {
7167 return _VSTD::__format_arg_store<_Context, _Args...>(__args...);
7268}
7369
74#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
70# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
7571template <class... _Args>
76_LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...> make_wformat_args(_Args&&... __args) {
72_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...>
73make_wformat_args(_Args&&... __args) {
7774 return _VSTD::__format_arg_store<wformat_context, _Args...>(__args...);
7875}
79#endif
76# endif
8077
8178namespace __format {
8279
......@@ -87,14 +84,16 @@ namespace __format {
8784template <class _CharT>
8885class _LIBCPP_TEMPLATE_VIS __compile_time_handle {
8986public:
90 _LIBCPP_HIDE_FROM_ABI
91 constexpr void __parse(basic_format_parse_context<_CharT>& __parse_ctx) const { __parse_(__parse_ctx); }
87 template <class _ParseContext>
88 _LIBCPP_HIDE_FROM_ABI constexpr void __parse(_ParseContext& __ctx) const {
89 __parse_(__ctx);
90 }
9291
9392 template <class _Tp>
9493 _LIBCPP_HIDE_FROM_ABI constexpr void __enable() {
95 __parse_ = [](basic_format_parse_context<_CharT>& __parse_ctx) {
94 __parse_ = [](basic_format_parse_context<_CharT>& __ctx) {
9695 formatter<_Tp, _CharT> __f;
97 __parse_ctx.advance_to(__f.parse(__parse_ctx));
96 __ctx.advance_to(__f.parse(__ctx));
9897 };
9998 }
10099
......@@ -128,13 +127,13 @@ public:
128127
129128 _LIBCPP_HIDE_FROM_ABI constexpr __arg_t arg(size_t __id) const {
130129 if (__id >= __size_)
131 std::__throw_format_error("Argument index out of bounds");
130 std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
132131 return __args_[__id];
133132 }
134133
135134 _LIBCPP_HIDE_FROM_ABI constexpr const __compile_time_handle<_CharT>& __handle(size_t __id) const {
136135 if (__id >= __size_)
137 std::__throw_format_error("Argument index out of bounds");
136 std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
138137 return __handles_[__id];
139138 }
140139
......@@ -147,41 +146,44 @@ private:
147146 size_t __size_;
148147};
149148
150_LIBCPP_HIDE_FROM_ABI
151constexpr void __compile_time_validate_integral(__arg_t __type) {
152 switch (__type) {
153 case __arg_t::__int:
154 case __arg_t::__long_long:
155 case __arg_t::__i128:
156 case __arg_t::__unsigned:
157 case __arg_t::__unsigned_long_long:
158 case __arg_t::__u128:
159 return;
160
161 default:
162 std::__throw_format_error("Argument isn't an integral type");
163 }
164}
165
149// [format.string.std]/8
150// If { arg-idopt } is used in a width or precision, the value of the
151// corresponding formatting argument is used in its place. If the
152// corresponding formatting argument is not of standard signed or unsigned
153// integer type, or its value is negative for precision or non-positive for
154// width, an exception of type format_error is thrown.
155//
166156// _HasPrecision does the formatter have a precision?
167157template <class _CharT, class _Tp, bool _HasPrecision = false>
168_LIBCPP_HIDE_FROM_ABI constexpr void
169__compile_time_validate_argument(basic_format_parse_context<_CharT>& __parse_ctx,
170 __compile_time_basic_format_context<_CharT>& __ctx) {
158_LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_validate_argument(
159 basic_format_parse_context<_CharT>& __parse_ctx, __compile_time_basic_format_context<_CharT>& __ctx) {
160 auto __validate_type = [](__arg_t __type) {
161 // LWG3720 originally allowed "signed or unsigned integer types", however
162 // the final version explicitly changed it to "*standard* signed or unsigned
163 // integer types". It's trivial to use 128-bit integrals in libc++'s
164 // implementation, but other implementations may not implement it.
165 // (Using a width or precision, that does not fit in 64-bits, sounds very
166 // unlikely in real world code.)
167 switch (__type) {
168 case __arg_t::__int:
169 case __arg_t::__long_long:
170 case __arg_t::__unsigned:
171 case __arg_t::__unsigned_long_long:
172 return;
173
174 default:
175 std::__throw_format_error("Replacement argument isn't a standard signed or unsigned integer type");
176 }
177 };
178
171179 formatter<_Tp, _CharT> __formatter;
172180 __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
173 // [format.string.std]/7
174 // ... If the corresponding formatting argument is not of integral type, or
175 // its value is negative for precision or non-positive for width, an
176 // exception of type format_error is thrown.
177 //
178 // Validate whether the arguments are integrals.
179181 if (__formatter.__parser_.__width_as_arg_)
180 __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__width_));
182 __validate_type(__ctx.arg(__formatter.__parser_.__width_));
181183
182184 if constexpr (_HasPrecision)
183185 if (__formatter.__parser_.__precision_as_arg_)
184 __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__precision_));
186 __validate_type(__ctx.arg(__formatter.__parser_.__precision_));
185187}
186188
187189// This function is not user facing, so it can directly use the non-standard types of the "variant".
......@@ -236,30 +238,34 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_forma
236238 std::__throw_format_error("Invalid argument");
237239}
238240
239template <class _CharT, class _ParseCtx, class _Ctx>
240_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
241__handle_replacement_field(const _CharT* __begin, const _CharT* __end,
241template <contiguous_iterator _Iterator, class _ParseCtx, class _Ctx>
242_LIBCPP_HIDE_FROM_ABI constexpr _Iterator
243__handle_replacement_field(_Iterator __begin, _Iterator __end,
242244 _ParseCtx& __parse_ctx, _Ctx& __ctx) {
245 using _CharT = iter_value_t<_Iterator>;
243246 __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx);
244247
245 bool __parse = *__r.__ptr == _CharT(':');
246 switch (*__r.__ptr) {
248 if (__r.__last == __end)
249 std::__throw_format_error("The argument index should end with a ':' or a '}'");
250
251 bool __parse = *__r.__last == _CharT(':');
252 switch (*__r.__last) {
247253 case _CharT(':'):
248254 // The arg-id has a format-specifier, advance the input to the format-spec.
249 __parse_ctx.advance_to(__r.__ptr + 1);
255 __parse_ctx.advance_to(__r.__last + 1);
250256 break;
251257 case _CharT('}'):
252258 // The arg-id has no format-specifier.
253 __parse_ctx.advance_to(__r.__ptr);
259 __parse_ctx.advance_to(__r.__last);
254260 break;
255261 default:
256 std::__throw_format_error("The replacement field arg-id should terminate at a ':' or '}'");
262 std::__throw_format_error("The argument index should end with a ':' or a '}'");
257263 }
258264
259265 if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) {
260266 __arg_t __type = __ctx.arg(__r.__value);
261267 if (__type == __arg_t::__none)
262 std::__throw_format_error("Argument index out of bounds");
268 std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
263269 else if (__type == __arg_t::__handle)
264270 __ctx.__handle(__r.__value).__parse(__parse_ctx);
265271 else if (__parse)
......@@ -268,7 +274,7 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end,
268274 _VSTD::__visit_format_arg(
269275 [&](auto __arg) {
270276 if constexpr (same_as<decltype(__arg), monostate>)
271 std::__throw_format_error("Argument index out of bounds");
277 std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
272278 else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Ctx>::handle>)
273279 __arg.format(__parse_ctx, __ctx);
274280 else {
......@@ -293,8 +299,8 @@ __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) {
293299 using _CharT = typename _ParseCtx::char_type;
294300 static_assert(same_as<typename _Ctx::char_type, _CharT>);
295301
296 const _CharT* __begin = __parse_ctx.begin();
297 const _CharT* __end = __parse_ctx.end();
302 auto __begin = __parse_ctx.begin();
303 auto __end = __parse_ctx.end();
298304 typename _Ctx::iterator __out_it = __ctx.out();
299305 while (__begin != __end) {
300306 switch (*__begin) {
......@@ -341,7 +347,7 @@ struct _LIBCPP_TEMPLATE_VIS basic_format_string {
341347 _Context{__types_.data(), __handles_.data(), sizeof...(_Args)});
342348 }
343349
344 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT constexpr basic_string_view<_CharT> get() const noexcept {
350 _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<_CharT> get() const noexcept {
345351 return __str_;
346352 }
347353
......@@ -353,20 +359,6 @@ private:
353359 static constexpr array<__format::__arg_t, sizeof...(_Args)> __types_{
354360 __format::__determine_arg_t<_Context, remove_cvref_t<_Args>>()...};
355361
356 // TODO FMT remove this work-around when the AIX ICE has been resolved.
357# if defined(_AIX) && defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1400
358 template <class _Tp>
359 static constexpr __format::__compile_time_handle<_CharT> __get_handle() {
360 __format::__compile_time_handle<_CharT> __handle;
361 if (__format::__determine_arg_t<_Context, _Tp>() == __format::__arg_t::__handle)
362 __handle.template __enable<_Tp>();
363
364 return __handle;
365 }
366
367 static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{
368 __get_handle<_Args>()...};
369# else
370362 static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{[] {
371363 using _Tp = remove_cvref_t<_Args>;
372364 __format::__compile_time_handle<_CharT> __handle;
......@@ -375,7 +367,6 @@ private:
375367
376368 return __handle;
377369 }()...};
378# endif
379370};
380371
381372template <class... _Args>
......@@ -406,21 +397,21 @@ requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
406397// https://reviews.llvm.org/D110499#inline-1180704
407398// TODO FMT Evaluate whether we want to file a Clang bug report regarding this.
408399template <output_iterator<const char&> _OutIt>
409_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
400_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
410401vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) {
411402 return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
412403}
413404
414405#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
415406template <output_iterator<const wchar_t&> _OutIt>
416_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
407_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
417408vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
418409 return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
419410}
420411#endif
421412
422413template <output_iterator<const char&> _OutIt, class... _Args>
423_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
414_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
424415format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) {
425416 return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(),
426417 _VSTD::make_format_args(__args...));
......@@ -428,42 +419,48 @@ format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) {
428419
429420#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
430421template <output_iterator<const wchar_t&> _OutIt, class... _Args>
431_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
422_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
432423format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) {
433424 return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(),
434425 _VSTD::make_wformat_args(__args...));
435426}
436427#endif
437428
438_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
429// TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
430// fires too eagerly, see http://llvm.org/PR61563.
431template <class = void>
432_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string
439433vformat(string_view __fmt, format_args __args) {
440434 string __res;
441435 _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
442436 return __res;
443437}
444438
445#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
446_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
439# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
440// TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
441// fires too eagerly, see http://llvm.org/PR61563.
442template <class = void>
443_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
447444vformat(wstring_view __fmt, wformat_args __args) {
448445 wstring __res;
449446 _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
450447 return __res;
451448}
452#endif
449# endif
453450
454451template <class... _Args>
455_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(format_string<_Args...> __fmt,
456 _Args&&... __args) {
452_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string
453format(format_string<_Args...> __fmt, _Args&&... __args) {
457454 return _VSTD::vformat(__fmt.get(), _VSTD::make_format_args(__args...));
458455}
459456
460#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
457# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
461458template <class... _Args>
462_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
459_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
463460format(wformat_string<_Args...> __fmt, _Args&&... __args) {
464461 return _VSTD::vformat(__fmt.get(), _VSTD::make_wformat_args(__args...));
465462}
466#endif
463# endif
467464
468465template <class _Context, class _OutIt, class _CharT>
469466_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n,
......@@ -476,14 +473,14 @@ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it,
476473}
477474
478475template <output_iterator<const char&> _OutIt, class... _Args>
479_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
476_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
480477format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, format_string<_Args...> __fmt, _Args&&... __args) {
481478 return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_format_args(__args...));
482479}
483480
484481#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
485482template <output_iterator<const wchar_t&> _OutIt, class... _Args>
486_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
483_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
487484format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt,
488485 _Args&&... __args) {
489486 return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_wformat_args(__args...));
......@@ -499,20 +496,20 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt,
499496}
500497
501498template <class... _Args>
502_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
499_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
503500formatted_size(format_string<_Args...> __fmt, _Args&&... __args) {
504501 return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)});
505502}
506503
507#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
504# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
508505template <class... _Args>
509_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
506_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
510507formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) {
511508 return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)});
512509}
513#endif
510# endif
514511
515#ifndef _LIBCPP_HAS_NO_LOCALIZATION
512# ifndef _LIBCPP_HAS_NO_LOCALIZATION
516513
517514template <class _OutIt, class _CharT, class _FormatOutIt>
518515requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
......@@ -533,7 +530,7 @@ requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
533530}
534531
535532template <output_iterator<const char&> _OutIt>
536_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to(
533_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(
537534 _OutIt __out_it, locale __loc, string_view __fmt, format_args __args) {
538535 return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
539536 __args);
......@@ -541,7 +538,7 @@ _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt v
541538
542539#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
543540template <output_iterator<const wchar_t&> _OutIt>
544_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to(
541_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(
545542 _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) {
546543 return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
547544 __args);
......@@ -549,7 +546,7 @@ _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt v
549546#endif
550547
551548template <output_iterator<const char&> _OutIt, class... _Args>
552_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
549_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
553550format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
554551 return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(),
555552 _VSTD::make_format_args(__args...));
......@@ -557,14 +554,17 @@ format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&.
557554
558555#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
559556template <output_iterator<const wchar_t&> _OutIt, class... _Args>
560_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
557_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
561558format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
562559 return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(),
563560 _VSTD::make_wformat_args(__args...));
564561}
565562#endif
566563
567_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
564// TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
565// fires too eagerly, see http://llvm.org/PR61563.
566template <class = void>
567_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string
568568vformat(locale __loc, string_view __fmt, format_args __args) {
569569 string __res;
570570 _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
......@@ -572,32 +572,34 @@ vformat(locale __loc, string_view __fmt, format_args __args) {
572572 return __res;
573573}
574574
575#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
576_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
575# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
576// TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
577// fires too eagerly, see http://llvm.org/PR61563.
578template <class = void>
579_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
577580vformat(locale __loc, wstring_view __fmt, wformat_args __args) {
578581 wstring __res;
579582 _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
580583 __args);
581584 return __res;
582585}
583#endif
586# endif
584587
585588template <class... _Args>
586_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(locale __loc,
587 format_string<_Args...> __fmt,
588 _Args&&... __args) {
589_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string
590format(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
589591 return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(),
590592 _VSTD::make_format_args(__args...));
591593}
592594
593#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
595# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
594596template <class... _Args>
595_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
597_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
596598format(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
597599 return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(),
598600 _VSTD::make_wformat_args(__args...));
599601}
600#endif
602# endif
601603
602604template <class _Context, class _OutIt, class _CharT>
603605_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n,
......@@ -611,7 +613,7 @@ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it,
611613}
612614
613615template <output_iterator<const char&> _OutIt, class... _Args>
614_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
616_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
615617format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format_string<_Args...> __fmt,
616618 _Args&&... __args) {
617619 return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(),
......@@ -620,7 +622,7 @@ format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format
620622
621623#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
622624template <output_iterator<const wchar_t&> _OutIt, class... _Args>
623_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
625_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
624626format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, wformat_string<_Args...> __fmt,
625627 _Args&&... __args) {
626628 return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(),
......@@ -638,26 +640,23 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_
638640}
639641
640642template <class... _Args>
641_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
643_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
642644formatted_size(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
643645 return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)});
644646}
645647
646#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
648# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
647649template <class... _Args>
648_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
650_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
649651formatted_size(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
650652 return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)});
651653}
652#endif
653
654#endif // _LIBCPP_HAS_NO_LOCALIZATION
654# endif
655655
656# endif // _LIBCPP_HAS_NO_LOCALIZATION
656657
657#endif //_LIBCPP_STD_VER > 17
658#endif //_LIBCPP_STD_VER >= 20
658659
659660_LIBCPP_END_NAMESPACE_STD
660661
661#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
662
663662#endif // _LIBCPP___FORMAT_FORMAT_FUNCTIONS
lib/libcxx/include/__format/format_fwd.h+5-5
......@@ -20,19 +20,19 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525template <class _Context>
26class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg;
26class _LIBCPP_TEMPLATE_VIS basic_format_arg;
2727
2828template <class _OutIt, class _CharT>
2929 requires output_iterator<_OutIt, const _CharT&>
30class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context;
30class _LIBCPP_TEMPLATE_VIS basic_format_context;
3131
3232template <class _Tp, class _CharT = char>
33struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter;
33struct _LIBCPP_TEMPLATE_VIS formatter;
3434
35#endif //_LIBCPP_STD_VER > 17
35#endif //_LIBCPP_STD_VER >= 20
3636
3737_LIBCPP_END_NAMESPACE_STD
3838
lib/libcxx/include/__format/format_parse_context.h+16-3
......@@ -12,6 +12,7 @@
1212
1313#include <__config>
1414#include <__format/format_error.h>
15#include <__type_traits/is_constant_evaluated.h>
1516#include <string_view>
1617
1718#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -20,10 +21,10 @@
2021
2122_LIBCPP_BEGIN_NAMESPACE_STD
2223
23#if _LIBCPP_STD_VER > 17
24#if _LIBCPP_STD_VER >= 20
2425
2526template <class _CharT>
26class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_parse_context {
27class _LIBCPP_TEMPLATE_VIS basic_format_parse_context {
2728public:
2829 using char_type = _CharT;
2930 using const_iterator = typename basic_string_view<_CharT>::const_iterator;
......@@ -58,6 +59,18 @@ public:
5859
5960 if (__indexing_ == __unknown)
6061 __indexing_ = __automatic;
62
63 // Throws an exception to make the expression a non core constant
64 // expression as required by:
65 // [format.parse.ctx]/8
66 // Remarks: Let cur-arg-id be the value of next_arg_id_ prior to this
67 // call. Call expressions where cur-arg-id >= num_args_ is true are not
68 // core constant expressions (7.7 [expr.const]).
69 // Note: the Throws clause [format.parse.ctx]/9 doesn't specify the
70 // behavior when id >= num_args_.
71 if (is_constant_evaluated() && __next_arg_id_ >= __num_args_)
72 std::__throw_format_error("Argument index outside the valid range");
73
6174 return __next_arg_id_++;
6275 }
6376 _LIBCPP_HIDE_FROM_ABI constexpr void check_arg_id(size_t __id) {
......@@ -93,7 +106,7 @@ using format_parse_context = basic_format_parse_context<char>;
93106using wformat_parse_context = basic_format_parse_context<wchar_t>;
94107#endif
95108
96#endif //_LIBCPP_STD_VER > 17
109#endif //_LIBCPP_STD_VER >= 20
97110
98111_LIBCPP_END_NAMESPACE_STD
99112
lib/libcxx/include/__format/format_string.h+35-30
......@@ -13,6 +13,8 @@
1313#include <__assert>
1414#include <__config>
1515#include <__format/format_error.h>
16#include <__iterator/concepts.h>
17#include <__iterator/iterator_traits.h> // iter_value_t
1618#include <cstddef>
1719#include <cstdint>
1820
......@@ -22,22 +24,22 @@
2224
2325_LIBCPP_BEGIN_NAMESPACE_STD
2426
25#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2628
2729namespace __format {
2830
29template <class _CharT>
31template <contiguous_iterator _Iterator>
3032struct _LIBCPP_TEMPLATE_VIS __parse_number_result {
31 const _CharT* __ptr;
33 _Iterator __last;
3234 uint32_t __value;
3335};
3436
35template <class _CharT>
36__parse_number_result(const _CharT*, uint32_t) -> __parse_number_result<_CharT>;
37template <contiguous_iterator _Iterator>
38__parse_number_result(_Iterator, uint32_t) -> __parse_number_result<_Iterator>;
3739
38template <class _CharT>
39_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
40__parse_number(const _CharT* __begin, const _CharT* __end);
40template <contiguous_iterator _Iterator>
41_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
42__parse_number(_Iterator __begin, _Iterator __end);
4143
4244/**
4345 * The maximum value of a numeric argument.
......@@ -53,27 +55,28 @@ __parse_number(const _CharT* __begin, const _CharT* __end);
5355inline constexpr uint32_t __number_max = INT32_MAX;
5456
5557namespace __detail {
56template <class _CharT>
57_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
58__parse_zero(const _CharT* __begin, const _CharT*, auto& __parse_ctx) {
58template <contiguous_iterator _Iterator>
59_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
60__parse_zero(_Iterator __begin, _Iterator, auto& __parse_ctx) {
5961 __parse_ctx.check_arg_id(0);
6062 return {++__begin, 0}; // can never be larger than the maximum.
6163}
6264
63template <class _CharT>
64_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
65__parse_automatic(const _CharT* __begin, const _CharT*, auto& __parse_ctx) {
65template <contiguous_iterator _Iterator>
66_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
67__parse_automatic(_Iterator __begin, _Iterator, auto& __parse_ctx) {
6668 size_t __value = __parse_ctx.next_arg_id();
67 _LIBCPP_ASSERT(__value <= __number_max,
68 "Compilers don't support this number of arguments");
69 _LIBCPP_ASSERT_UNCATEGORIZED(
70 __value <= __number_max,
71 "Compilers don't support this number of arguments");
6972
7073 return {__begin, uint32_t(__value)};
7174}
7275
73template <class _CharT>
74_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
75__parse_manual(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
76 __parse_number_result<_CharT> __r = __format::__parse_number(__begin, __end);
76template <contiguous_iterator _Iterator>
77_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
78__parse_manual(_Iterator __begin, _Iterator __end, auto& __parse_ctx) {
79 __parse_number_result<_Iterator> __r = __format::__parse_number(__begin, __end);
7780 __parse_ctx.check_arg_id(__r.__value);
7881 return __r;
7982}
......@@ -86,9 +89,10 @@ __parse_manual(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
8689 * The number is used for the 31-bit values @em width and @em precision. This
8790 * allows a maximum value of 2147483647.
8891 */
89template <class _CharT>
90_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
91__parse_number(const _CharT* __begin, const _CharT* __end_input) {
92template <contiguous_iterator _Iterator>
93_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
94__parse_number(_Iterator __begin, _Iterator __end_input) {
95 using _CharT = iter_value_t<_Iterator>;
9296 static_assert(__format::__number_max == INT32_MAX,
9397 "The algorithm is implemented based on this value.");
9498 /*
......@@ -98,7 +102,7 @@ __parse_number(const _CharT* __begin, const _CharT* __end_input) {
98102 * - Does the value exceed width of an uint32_t? (Switching to uint64_t would
99103 * have the same issue, but with a higher maximum.)
100104 */
101 const _CharT* __end = __end_input - __begin > 9 ? __begin + 9 : __end_input;
105 _Iterator __end = __end_input - __begin > 9 ? __begin + 9 : __end_input;
102106 uint32_t __value = *__begin - _CharT('0');
103107 while (++__begin != __end) {
104108 if (*__begin < _CharT('0') || *__begin > _CharT('9'))
......@@ -120,7 +124,7 @@ __parse_number(const _CharT* __begin, const _CharT* __end_input) {
120124 if (__v > __number_max ||
121125 (__begin != __end_input && *__begin >= _CharT('0') &&
122126 *__begin <= _CharT('9')))
123 std::__throw_format_error("The numeric value of the format-spec is too large");
127 std::__throw_format_error("The numeric value of the format specifier is too large");
124128
125129 __value = __v;
126130 }
......@@ -134,9 +138,10 @@ __parse_number(const _CharT* __begin, const _CharT* __end_input) {
134138 * The parser will return a pointer beyond the last consumed character. This
135139 * should be the closing '}' of the arg-id.
136140 */
137template <class _CharT>
138_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
139__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
141template <contiguous_iterator _Iterator>
142_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
143__parse_arg_id(_Iterator __begin, _Iterator __end, auto& __parse_ctx) {
144 using _CharT = iter_value_t<_Iterator>;
140145 switch (*__begin) {
141146 case _CharT('0'):
142147 return __detail::__parse_zero(__begin, __end, __parse_ctx);
......@@ -149,14 +154,14 @@ __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
149154 return __detail::__parse_automatic(__begin, __end, __parse_ctx);
150155 }
151156 if (*__begin < _CharT('0') || *__begin > _CharT('9'))
152 std::__throw_format_error("The arg-id of the format-spec starts with an invalid character");
157 std::__throw_format_error("The argument index starts with an invalid character");
153158
154159 return __detail::__parse_manual(__begin, __end, __parse_ctx);
155160}
156161
157162} // namespace __format
158163
159#endif //_LIBCPP_STD_VER > 17
164#endif //_LIBCPP_STD_VER >= 20
160165
161166_LIBCPP_END_NAMESPACE_STD
162167
lib/libcxx/include/__format/format_to_n_result.h+2-2
......@@ -19,7 +19,7 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 17
22#if _LIBCPP_STD_VER >= 20
2323
2424template <class _OutIt>
2525struct _LIBCPP_TEMPLATE_VIS format_to_n_result {
......@@ -28,7 +28,7 @@ struct _LIBCPP_TEMPLATE_VIS format_to_n_result {
2828};
2929_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(format_to_n_result);
3030
31#endif //_LIBCPP_STD_VER > 17
31#endif //_LIBCPP_STD_VER >= 20
3232
3333_LIBCPP_END_NAMESPACE_STD
3434
lib/libcxx/include/__format/formatter.h+5-5
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525/// The default formatter template.
2626///
......@@ -32,13 +32,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3232/// - is_copy_assignable<F>, and
3333/// - is_move_assignable<F>.
3434template <class _Tp, class _CharT>
35struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter {
35struct _LIBCPP_TEMPLATE_VIS formatter {
3636 formatter() = delete;
3737 formatter(const formatter&) = delete;
3838 formatter& operator=(const formatter&) = delete;
3939};
4040
41# if _LIBCPP_STD_VER > 20
41# if _LIBCPP_STD_VER >= 23
4242
4343template <class _Tp>
4444_LIBCPP_HIDE_FROM_ABI constexpr void __set_debug_format(_Tp& __formatter) {
......@@ -46,8 +46,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __set_debug_format(_Tp& __formatter) {
4646 __formatter.set_debug_format();
4747}
4848
49# endif // _LIBCPP_STD_VER > 20
50#endif // _LIBCPP_STD_VER > 17
49# endif // _LIBCPP_STD_VER >= 23
50#endif // _LIBCPP_STD_VER >= 20
5151
5252_LIBCPP_END_NAMESPACE_STD
5353
lib/libcxx/include/__format/formatter_bool.h+11-12
......@@ -11,17 +11,15 @@
1111#define _LIBCPP___FORMAT_FORMATTER_BOOL_H
1212
1313#include <__algorithm/copy.h>
14#include <__assert>
1415#include <__availability>
1516#include <__config>
16#include <__debug>
1717#include <__format/concepts.h>
18#include <__format/format_error.h>
1918#include <__format/format_parse_context.h>
2019#include <__format/formatter.h>
2120#include <__format/formatter_integral.h>
2221#include <__format/parser_std_format_spec.h>
2322#include <__utility/unreachable.h>
24#include <string_view>
2523
2624#ifndef _LIBCPP_HAS_NO_LOCALIZATION
2725# include <locale>
......@@ -33,19 +31,20 @@
3331
3432_LIBCPP_BEGIN_NAMESPACE_STD
3533
36#if _LIBCPP_STD_VER > 17
34#if _LIBCPP_STD_VER >= 20
3735
3836template <__fmt_char_type _CharT>
39struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<bool, _CharT> {
37struct _LIBCPP_TEMPLATE_VIS formatter<bool, _CharT> {
4038public:
41 _LIBCPP_HIDE_FROM_ABI constexpr auto
42 parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
43 auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral);
44 __format_spec::__process_parsed_bool(__parser_);
39 template <class _ParseContext>
40 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
41 typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral);
42 __format_spec::__process_parsed_bool(__parser_, "a bool");
4543 return __result;
4644 }
4745
48 _LIBCPP_HIDE_FROM_ABI auto format(bool __value, auto& __ctx) const -> decltype(__ctx.out()) {
46 template <class _FormatContext>
47 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(bool __value, _FormatContext& __ctx) const {
4948 switch (__parser_.__type_) {
5049 case __format_spec::__type::__default:
5150 case __format_spec::__type::__string:
......@@ -63,7 +62,7 @@ public:
6362 static_cast<unsigned>(__value), __ctx, __parser_.__get_parsed_std_specifications(__ctx));
6463
6564 default:
66 _LIBCPP_ASSERT(false, "The parse function should have validated the type");
65 _LIBCPP_ASSERT_UNCATEGORIZED(false, "The parse function should have validated the type");
6766 __libcpp_unreachable();
6867 }
6968 }
......@@ -71,7 +70,7 @@ public:
7170 __format_spec::__parser<_CharT> __parser_;
7271};
7372
74#endif //_LIBCPP_STD_VER > 17
73#endif //_LIBCPP_STD_VER >= 20
7574
7675_LIBCPP_END_NAMESPACE_STD
7776
lib/libcxx/include/__format/formatter_char.h+17-14
......@@ -19,6 +19,7 @@
1919#include <__format/formatter_integral.h>
2020#include <__format/formatter_output.h>
2121#include <__format/parser_std_format_spec.h>
22#include <__format/write_escaped.h>
2223#include <__type_traits/conditional.h>
2324#include <__type_traits/is_signed.h>
2425
......@@ -28,23 +29,24 @@
2829
2930_LIBCPP_BEGIN_NAMESPACE_STD
3031
31#if _LIBCPP_STD_VER > 17
32#if _LIBCPP_STD_VER >= 20
3233
3334template <__fmt_char_type _CharT>
34struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_char {
35struct _LIBCPP_TEMPLATE_VIS __formatter_char {
3536public:
36 _LIBCPP_HIDE_FROM_ABI constexpr auto
37 parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
38 auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral);
39 __format_spec::__process_parsed_char(__parser_);
37 template <class _ParseContext>
38 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
39 typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral);
40 __format_spec::__process_parsed_char(__parser_, "a character");
4041 return __result;
4142 }
4243
43 _LIBCPP_HIDE_FROM_ABI auto format(_CharT __value, auto& __ctx) const -> decltype(__ctx.out()) {
44 template <class _FormatContext>
45 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_CharT __value, _FormatContext& __ctx) const {
4446 if (__parser_.__type_ == __format_spec::__type::__default || __parser_.__type_ == __format_spec::__type::__char)
4547 return __formatter::__format_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
4648
47# if _LIBCPP_STD_VER > 20
49# if _LIBCPP_STD_VER >= 23
4850 if (__parser_.__type_ == __format_spec::__type::__debug)
4951 return __formatter::__format_escaped_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
5052# endif
......@@ -60,13 +62,14 @@ public:
6062 return __formatter::__format_integer(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx));
6163 }
6264
63 _LIBCPP_HIDE_FROM_ABI auto format(char __value, auto& __ctx) const -> decltype(__ctx.out())
65 template <class _FormatContext>
66 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(char __value, _FormatContext& __ctx) const
6467 requires(same_as<_CharT, wchar_t>)
6568 {
6669 return format(static_cast<wchar_t>(__value), __ctx);
6770 }
6871
69# if _LIBCPP_STD_VER > 20
72# if _LIBCPP_STD_VER >= 23
7073 _LIBCPP_HIDE_FROM_ABI constexpr void set_debug_format() { __parser_.__type_ = __format_spec::__type::__debug; }
7174# endif
7275
......@@ -74,19 +77,19 @@ public:
7477};
7578
7679template <>
77struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<char, char> : public __formatter_char<char> {};
80struct _LIBCPP_TEMPLATE_VIS formatter<char, char> : public __formatter_char<char> {};
7881
7982# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
8083template <>
81struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<char, wchar_t> : public __formatter_char<wchar_t> {};
84struct _LIBCPP_TEMPLATE_VIS formatter<char, wchar_t> : public __formatter_char<wchar_t> {};
8285
8386template <>
84struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<wchar_t, wchar_t> : public __formatter_char<wchar_t> {
87struct _LIBCPP_TEMPLATE_VIS formatter<wchar_t, wchar_t> : public __formatter_char<wchar_t> {
8588};
8689
8790# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
8891
89#endif //_LIBCPP_STD_VER > 17
92#endif //_LIBCPP_STD_VER >= 20
9093
9194_LIBCPP_END_NAMESPACE_STD
9295
lib/libcxx/include/__format/formatter_floating_point.h+80-43
......@@ -16,6 +16,9 @@
1616#include <__algorithm/min.h>
1717#include <__algorithm/rotate.h>
1818#include <__algorithm/transform.h>
19#include <__charconv/chars_format.h>
20#include <__charconv/to_chars_floating_point.h>
21#include <__charconv/to_chars_result.h>
1922#include <__concepts/arithmetic.h>
2023#include <__concepts/same_as.h>
2124#include <__config>
......@@ -25,10 +28,14 @@
2528#include <__format/formatter_integral.h>
2629#include <__format/formatter_output.h>
2730#include <__format/parser_std_format_spec.h>
31#include <__iterator/concepts.h>
2832#include <__memory/allocator.h>
33#include <__system_error/errc.h>
34#include <__type_traits/conditional.h>
2935#include <__utility/move.h>
3036#include <__utility/unreachable.h>
31#include <charconv>
37#include <cmath>
38#include <cstddef>
3239
3340#ifndef _LIBCPP_HAS_NO_LOCALIZATION
3441# include <locale>
......@@ -43,28 +50,28 @@ _LIBCPP_PUSH_MACROS
4350
4451_LIBCPP_BEGIN_NAMESPACE_STD
4552
46#if _LIBCPP_STD_VER > 17
53#if _LIBCPP_STD_VER >= 20
4754
4855namespace __formatter {
4956
5057template <floating_point _Tp>
5158_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value) {
5259 to_chars_result __r = _VSTD::to_chars(__first, __last, __value);
53 _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small");
60 _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small");
5461 return __r.ptr;
5562}
5663
5764template <floating_point _Tp>
5865_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt) {
5966 to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt);
60 _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small");
67 _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small");
6168 return __r.ptr;
6269}
6370
6471template <floating_point _Tp>
6572_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt, int __precision) {
6673 to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt, __precision);
67 _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small");
74 _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small");
6875 return __r.ptr;
6976}
7077
......@@ -246,10 +253,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffe
246253 __result.__radix_point = __result.__last;
247254
248255 // clang-format off
249 _LIBCPP_ASSERT((__result.__integral != __result.__last) &&
250 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
251 (__result.__exponent == __result.__last || *__result.__exponent == 'e'),
252 "Post-condition failure.");
256 _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) &&
257 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
258 (__result.__exponent == __result.__last || *__result.__exponent == 'e'),
259 "Post-condition failure.");
253260 // clang-format on
254261
255262 return __result;
......@@ -299,10 +306,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(cons
299306 }
300307
301308 // clang-format off
302 _LIBCPP_ASSERT((__result.__integral != __result.__last) &&
303 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
304 (__result.__exponent != __result.__last && *__result.__exponent == 'p'),
305 "Post-condition failure.");
309 _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) &&
310 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
311 (__result.__exponent != __result.__last && *__result.__exponent == 'p'),
312 "Post-condition failure.");
306313 // clang-format on
307314
308315 return __result;
......@@ -329,7 +336,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const
329336 __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::scientific, __precision);
330337
331338 char* __first = __integral + 1;
332 _LIBCPP_ASSERT(__first != __result.__last, "No exponent present");
339 _LIBCPP_ASSERT_UNCATEGORIZED(__first != __result.__last, "No exponent present");
333340 if (*__first == '.') {
334341 __result.__radix_point = __first;
335342 __result.__exponent = __formatter::__find_exponent(__first + 1, __result.__last);
......@@ -339,10 +346,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const
339346 }
340347
341348 // clang-format off
342 _LIBCPP_ASSERT((__result.__integral != __result.__last) &&
343 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
344 (__result.__exponent != __result.__last && *__result.__exponent == 'e'),
345 "Post-condition failure.");
349 _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) &&
350 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
351 (__result.__exponent != __result.__last && *__result.__exponent == 'e'),
352 "Post-condition failure.");
346353 // clang-format on
347354 return __result;
348355}
......@@ -372,10 +379,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer<
372379 __result.__exponent = __result.__last;
373380
374381 // clang-format off
375 _LIBCPP_ASSERT((__result.__integral != __result.__last) &&
376 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
377 (__result.__exponent == __result.__last),
378 "Post-condition failure.");
382 _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) &&
383 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
384 (__result.__exponent == __result.__last),
385 "Post-condition failure.");
379386 // clang-format on
380387 return __result;
381388}
......@@ -409,10 +416,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_
409416 }
410417
411418 // clang-format off
412 _LIBCPP_ASSERT((__result.__integral != __result.__last) &&
413 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
414 (__result.__exponent == __result.__last || *__result.__exponent == 'e'),
415 "Post-condition failure.");
419 _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) &&
420 (__result.__radix_point == __result.__last || *__result.__radix_point == '.') &&
421 (__result.__exponent == __result.__last || *__result.__exponent == 'e'),
422 "Post-condition failure.");
416423 // clang-format on
417424
418425 return __result;
......@@ -484,7 +491,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer(
484491 return __formatter::__format_buffer_general_upper_case(__buffer, __value, __buffer.__precision(), __first);
485492
486493 default:
487 _LIBCPP_ASSERT(false, "The parser should have validated the type");
494 _LIBCPP_ASSERT_UNCATEGORIZED(false, "The parser should have validated the type");
488495 __libcpp_unreachable();
489496 }
490497}
......@@ -522,7 +529,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(
522529 if (__size < __specs.__width_) {
523530 if (__zero_padding) {
524531 __specs.__alignment_ = __format_spec::__alignment::__right;
525 __specs.__fill_ = _CharT('0');
532 __specs.__fill_.__data[0] = _CharT('0');
526533 }
527534
528535 __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_);
......@@ -602,10 +609,40 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_floating_point_non_finite(
602609 return __formatter::__write(__buffer, __last, _VSTD::move(__out_it), __specs);
603610}
604611
605template <floating_point _Tp, class _CharT>
606_LIBCPP_HIDE_FROM_ABI auto
607__format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs)
608 -> decltype(__ctx.out()) {
612/// Writes additional zero's for the precision before the exponent.
613/// This is used when the precision requested in the format string is larger
614/// than the maximum precision of the floating-point type. These precision
615/// digits are always 0.
616///
617/// \param __exponent The location of the exponent character.
618/// \param __num_trailing_zeros The number of 0's to write before the exponent
619/// character.
620template <class _CharT, class _ParserCharT>
621_LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros(
622 const _CharT* __first,
623 const _CharT* __last,
624 output_iterator<const _CharT&> auto __out_it,
625 __format_spec::__parsed_specifications<_ParserCharT> __specs,
626 size_t __size,
627 const _CharT* __exponent,
628 size_t __num_trailing_zeros) -> decltype(__out_it) {
629 _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range");
630 _LIBCPP_ASSERT_UNCATEGORIZED(__num_trailing_zeros > 0,
631 "The overload not writing trailing zeros should have been used");
632
633 __padding_size_result __padding =
634 __formatter::__padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_);
635 __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
636 __out_it = __formatter::__copy(__first, __exponent, _VSTD::move(__out_it));
637 __out_it = __formatter::__fill(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0'));
638 __out_it = __formatter::__copy(__exponent, __last, _VSTD::move(__out_it));
639 return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
640}
641
642
643template <floating_point _Tp, class _CharT, class _FormatContext>
644_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
645__format_floating_point(_Tp __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) {
609646 bool __negative = _VSTD::signbit(__value);
610647
611648 if (!_VSTD::isfinite(__value)) [[unlikely]]
......@@ -707,7 +744,7 @@ __format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specif
707744 // After the sign is written, zero padding is the same a right alignment
708745 // with '0'.
709746 __specs.__alignment_ = __format_spec::__alignment::__right;
710 __specs.__fill_ = _CharT('0');
747 __specs.__fill_.__data[0] = _CharT('0');
711748 }
712749
713750 if (__num_trailing_zeros)
......@@ -722,15 +759,15 @@ __format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specif
722759template <__fmt_char_type _CharT>
723760struct _LIBCPP_TEMPLATE_VIS __formatter_floating_point {
724761public:
725 _LIBCPP_HIDE_FROM_ABI constexpr auto
726 parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
727 auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_floating_point);
728 __format_spec::__process_parsed_floating_point(__parser_);
762 template <class _ParseContext>
763 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
764 typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_floating_point);
765 __format_spec::__process_parsed_floating_point(__parser_, "a floating-point");
729766 return __result;
730767 }
731768
732 template <floating_point _Tp>
733 _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) const -> decltype(__ctx.out()) {
769 template <floating_point _Tp, class _FormatContext>
770 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_Tp __value, _FormatContext& __ctx) const {
734771 return __formatter::__format_floating_point(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx));
735772 }
736773
......@@ -738,16 +775,16 @@ public:
738775};
739776
740777template <__fmt_char_type _CharT>
741struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<float, _CharT>
778struct _LIBCPP_TEMPLATE_VIS formatter<float, _CharT>
742779 : public __formatter_floating_point<_CharT> {};
743780template <__fmt_char_type _CharT>
744struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<double, _CharT>
781struct _LIBCPP_TEMPLATE_VIS formatter<double, _CharT>
745782 : public __formatter_floating_point<_CharT> {};
746783template <__fmt_char_type _CharT>
747struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long double, _CharT>
784struct _LIBCPP_TEMPLATE_VIS formatter<long double, _CharT>
748785 : public __formatter_floating_point<_CharT> {};
749786
750#endif //_LIBCPP_STD_VER > 17
787#endif //_LIBCPP_STD_VER >= 20
751788
752789_LIBCPP_END_NAMESPACE_STD
753790
lib/libcxx/include/__format/formatter_integer.h+23-23
......@@ -19,8 +19,8 @@
1919#include <__format/formatter_integral.h>
2020#include <__format/formatter_output.h>
2121#include <__format/parser_std_format_spec.h>
22#include <__type_traits/is_void.h>
2223#include <__type_traits/make_32_64_or_128_bit.h>
23#include <type_traits>
2424
2525#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2626# pragma GCC system_header
......@@ -28,28 +28,28 @@
2828
2929 _LIBCPP_BEGIN_NAMESPACE_STD
3030
31#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
3232
3333 template <__fmt_char_type _CharT>
34 struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_integer {
34 struct _LIBCPP_TEMPLATE_VIS __formatter_integer {
3535
3636public:
37 _LIBCPP_HIDE_FROM_ABI constexpr auto
38 parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
39 auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral);
40 __format_spec::__process_parsed_integer(__parser_);
37 template <class _ParseContext>
38 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
39 typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral);
40 __format_spec::__process_parsed_integer(__parser_, "an integer");
4141 return __result;
4242 }
4343
44 template <integral _Tp>
45 _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) const -> decltype(__ctx.out()) {
44 template <integral _Tp, class _FormatContext>
45 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_Tp __value, _FormatContext& __ctx) const {
4646 __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
4747
4848 if (__specs.__std_.__type_ == __format_spec::__type::__char)
4949 return __formatter::__format_char(__value, __ctx.out(), __specs);
5050
5151 using _Type = __make_32_64_or_128_bit_t<_Tp>;
52 static_assert(!is_same<_Type, void>::value, "unsupported integral type used in __formatter_integer::__format");
52 static_assert(!is_void<_Type>::value, "unsupported integral type used in __formatter_integer::__format");
5353
5454 // Reduce the number of instantiation of the integer formatter
5555 return __formatter::__format_integer(static_cast<_Type>(__value), __ctx, __specs);
......@@ -60,47 +60,47 @@ public:
6060
6161// Signed integral types.
6262template <__fmt_char_type _CharT>
63struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<signed char, _CharT>
63struct _LIBCPP_TEMPLATE_VIS formatter<signed char, _CharT>
6464 : public __formatter_integer<_CharT> {};
6565template <__fmt_char_type _CharT>
66struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<short, _CharT> : public __formatter_integer<_CharT> {
66struct _LIBCPP_TEMPLATE_VIS formatter<short, _CharT> : public __formatter_integer<_CharT> {
6767};
6868template <__fmt_char_type _CharT>
69struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<int, _CharT> : public __formatter_integer<_CharT> {};
69struct _LIBCPP_TEMPLATE_VIS formatter<int, _CharT> : public __formatter_integer<_CharT> {};
7070template <__fmt_char_type _CharT>
71struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long, _CharT> : public __formatter_integer<_CharT> {};
71struct _LIBCPP_TEMPLATE_VIS formatter<long, _CharT> : public __formatter_integer<_CharT> {};
7272template <__fmt_char_type _CharT>
73struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long long, _CharT>
73struct _LIBCPP_TEMPLATE_VIS formatter<long long, _CharT>
7474 : public __formatter_integer<_CharT> {};
7575# ifndef _LIBCPP_HAS_NO_INT128
7676template <__fmt_char_type _CharT>
77struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__int128_t, _CharT>
77struct _LIBCPP_TEMPLATE_VIS formatter<__int128_t, _CharT>
7878 : public __formatter_integer<_CharT> {};
7979# endif
8080
8181// Unsigned integral types.
8282template <__fmt_char_type _CharT>
83struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned char, _CharT>
83struct _LIBCPP_TEMPLATE_VIS formatter<unsigned char, _CharT>
8484 : public __formatter_integer<_CharT> {};
8585template <__fmt_char_type _CharT>
86struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned short, _CharT>
86struct _LIBCPP_TEMPLATE_VIS formatter<unsigned short, _CharT>
8787 : public __formatter_integer<_CharT> {};
8888template <__fmt_char_type _CharT>
89struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned, _CharT>
89struct _LIBCPP_TEMPLATE_VIS formatter<unsigned, _CharT>
9090 : public __formatter_integer<_CharT> {};
9191template <__fmt_char_type _CharT>
92struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long, _CharT>
92struct _LIBCPP_TEMPLATE_VIS formatter<unsigned long, _CharT>
9393 : public __formatter_integer<_CharT> {};
9494template <__fmt_char_type _CharT>
95struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long long, _CharT>
95struct _LIBCPP_TEMPLATE_VIS formatter<unsigned long long, _CharT>
9696 : public __formatter_integer<_CharT> {};
9797# ifndef _LIBCPP_HAS_NO_INT128
9898template <__fmt_char_type _CharT>
99struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__uint128_t, _CharT>
99struct _LIBCPP_TEMPLATE_VIS formatter<__uint128_t, _CharT>
100100 : public __formatter_integer<_CharT> {};
101101# endif
102102
103#endif //_LIBCPP_STD_VER > 17
103#endif //_LIBCPP_STD_VER >= 20
104104
105105_LIBCPP_END_NAMESPACE_STD
106106
lib/libcxx/include/__format/formatter_integral.h+96-25
......@@ -10,6 +10,9 @@
1010#ifndef _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H
1111#define _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H
1212
13#include <__charconv/to_chars_integral.h>
14#include <__charconv/to_chars_result.h>
15#include <__charconv/traits.h>
1316#include <__concepts/arithmetic.h>
1417#include <__concepts/same_as.h>
1518#include <__config>
......@@ -17,11 +20,13 @@
1720#include <__format/format_error.h>
1821#include <__format/formatter_output.h>
1922#include <__format/parser_std_format_spec.h>
23#include <__system_error/errc.h>
24#include <__type_traits/make_unsigned.h>
2025#include <__utility/unreachable.h>
2126#include <array>
22#include <charconv>
2327#include <limits>
2428#include <string>
29#include <string_view>
2530
2631#ifndef _LIBCPP_HAS_NO_LOCALIZATION
2732# include <locale>
......@@ -36,7 +41,7 @@ _LIBCPP_PUSH_MACROS
3641
3742_LIBCPP_BEGIN_NAMESPACE_STD
3843
39#if _LIBCPP_STD_VER > 17
44#if _LIBCPP_STD_VER >= 20
4045
4146namespace __formatter {
4247
......@@ -80,9 +85,9 @@ _LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative, _
8085 * regardless whether the @c std::numpunct's type is @c char or @c wchar_t.
8186 */
8287_LIBCPP_HIDE_FROM_ABI inline string __determine_grouping(ptrdiff_t __size, const string& __grouping) {
83 _LIBCPP_ASSERT(!__grouping.empty() && __size > __grouping[0],
84 "The slow grouping formatting is used while there will be no "
85 "separators written");
88 _LIBCPP_ASSERT_UNCATEGORIZED(!__grouping.empty() && __size > __grouping[0],
89 "The slow grouping formatting is used while there will be no "
90 "separators written");
8691 string __r;
8792 auto __end = __grouping.end() - 1;
8893 auto __ptr = __grouping.begin();
......@@ -149,7 +154,7 @@ _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value
149154 // TODO FMT Evaluate code overhead due to not calling the internal function
150155 // directly. (Should be zero overhead.)
151156 to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __base);
152 _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small");
157 _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small");
153158 return __r.ptr;
154159}
155160
......@@ -198,16 +203,82 @@ consteval size_t __buffer_size() noexcept
198203 + 1; // Reserve space for the sign.
199204}
200205
201template <unsigned_integral _Tp, class _CharT>
202_LIBCPP_HIDE_FROM_ABI auto __format_integer(
206template <class _OutIt, class _CharT>
207_LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, const char* __begin, const char* __first,
208 const char* __last, string&& __grouping, _CharT __sep,
209 __format_spec::__parsed_specifications<_CharT> __specs) {
210 int __size = (__first - __begin) + // [sign][prefix]
211 (__last - __first) + // data
212 (__grouping.size() - 1); // number of separator characters
213
214 __padding_size_result __padding = {0, 0};
215 if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) {
216 // Write [sign][prefix].
217 __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it));
218
219 if (__specs.__width_ > __size) {
220 // Write zero padding.
221 __padding.__before_ = __specs.__width_ - __size;
222 __out_it = __formatter::__fill(_VSTD::move(__out_it), __specs.__width_ - __size, _CharT('0'));
223 }
224 } else {
225 if (__specs.__width_ > __size) {
226 // Determine padding and write padding.
227 __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_);
228
229 __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
230 }
231 // Write [sign][prefix].
232 __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it));
233 }
234
235 auto __r = __grouping.rbegin();
236 auto __e = __grouping.rend() - 1;
237 _LIBCPP_ASSERT_UNCATEGORIZED(__r != __e, "The slow grouping formatting is used while "
238 "there will be no separators written.");
239 // The output is divided in small groups of numbers to write:
240 // - A group before the first separator.
241 // - A separator and a group, repeated for the number of separators.
242 // - A group after the last separator.
243 // This loop achieves that process by testing the termination condition
244 // midway in the loop.
245 //
246 // TODO FMT This loop evaluates the loop invariant `__parser.__type !=
247 // _Flags::_Type::__hexadecimal_upper_case` for every iteration. (This test
248 // happens in the __write call.) Benchmark whether making two loops and
249 // hoisting the invariant is worth the effort.
250 while (true) {
251 if (__specs.__std_.__type_ == __format_spec::__type::__hexadecimal_upper_case) {
252 __last = __first + *__r;
253 __out_it = __formatter::__transform(__first, __last, _VSTD::move(__out_it), __hex_to_upper);
254 __first = __last;
255 } else {
256 __out_it = __formatter::__copy(__first, *__r, _VSTD::move(__out_it));
257 __first += *__r;
258 }
259
260 if (__r == __e)
261 break;
262
263 ++__r;
264 *__out_it++ = __sep;
265 }
266
267 return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
268}
269
270
271
272template <unsigned_integral _Tp, class _CharT, class _FormatContext>
273_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_integer(
203274 _Tp __value,
204 auto& __ctx,
275 _FormatContext& __ctx,
205276 __format_spec::__parsed_specifications<_CharT> __specs,
206277 bool __negative,
207278 char* __begin,
208279 char* __end,
209280 const char* __prefix,
210 int __base) -> decltype(__ctx.out()) {
281 int __base) {
211282 char* __first = __formatter::__insert_sign(__begin, __negative, __specs.__std_.__sign_);
212283 if (__specs.__std_.__alternate_form_ && __prefix)
213284 while (*__prefix)
......@@ -246,7 +317,7 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer(
246317 // - Write data right aligned with '0' as fill character.
247318 __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it));
248319 __specs.__alignment_ = __format_spec::__alignment::__right;
249 __specs.__fill_ = _CharT('0');
320 __specs.__fill_.__data[0] = _CharT('0');
250321 int32_t __size = __first - __begin;
251322
252323 __specs.__width_ -= _VSTD::min(__size, __specs.__width_);
......@@ -258,10 +329,12 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer(
258329 return __formatter::__write_transformed(__first, __last, __ctx.out(), __specs, __formatter::__hex_to_upper);
259330}
260331
261template <unsigned_integral _Tp, class _CharT>
262_LIBCPP_HIDE_FROM_ABI auto __format_integer(
263 _Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs, bool __negative = false)
264 -> decltype(__ctx.out()) {
332template <unsigned_integral _Tp, class _CharT, class _FormatContext>
333_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
334__format_integer(_Tp __value,
335 _FormatContext& __ctx,
336 __format_spec::__parsed_specifications<_CharT> __specs,
337 bool __negative = false) {
265338 switch (__specs.__std_.__type_) {
266339 case __format_spec::__type::__binary_lower_case: {
267340 array<char, __formatter::__buffer_size<decltype(__value), 2>()> __array;
......@@ -292,15 +365,14 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer(
292365 return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0X", 16);
293366 }
294367 default:
295 _LIBCPP_ASSERT(false, "The parse function should have validated the type");
368 _LIBCPP_ASSERT_UNCATEGORIZED(false, "The parse function should have validated the type");
296369 __libcpp_unreachable();
297370 }
298371}
299372
300template <signed_integral _Tp, class _CharT>
301_LIBCPP_HIDE_FROM_ABI auto
302__format_integer(_Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs)
303 -> decltype(__ctx.out()) {
373template <signed_integral _Tp, class _CharT, class _FormatContext>
374_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
375__format_integer(_Tp __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) {
304376 // Depending on the std-format-spec string the sign and the value
305377 // might not be outputted together:
306378 // - alternate form may insert a prefix string.
......@@ -336,10 +408,9 @@ struct _LIBCPP_TEMPLATE_VIS __bool_strings<wchar_t> {
336408};
337409# endif
338410
339template <class _CharT>
340_LIBCPP_HIDE_FROM_ABI auto
341__format_bool(bool __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs)
342 -> decltype(__ctx.out()) {
411template <class _CharT, class _FormatContext>
412_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
413__format_bool(bool __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) {
343414# ifndef _LIBCPP_HAS_NO_LOCALIZATION
344415 if (__specs.__std_.__locale_specific_form_) {
345416 const auto& __np = std::use_facet<numpunct<_CharT>>(__ctx.locale());
......@@ -354,7 +425,7 @@ __format_bool(bool __value, auto& __ctx, __format_spec::__parsed_specifications<
354425
355426} // namespace __formatter
356427
357#endif //_LIBCPP_STD_VER > 17
428#endif //_LIBCPP_STD_VER >= 20
358429
359430_LIBCPP_END_NAMESPACE_STD
360431
lib/libcxx/include/__format/formatter_output.h+58-308
......@@ -13,22 +13,21 @@
1313#include <__algorithm/ranges_copy.h>
1414#include <__algorithm/ranges_fill_n.h>
1515#include <__algorithm/ranges_transform.h>
16#include <__chrono/statically_widen.h>
16#include <__bit/countl.h>
1717#include <__concepts/same_as.h>
1818#include <__config>
1919#include <__format/buffer.h>
2020#include <__format/concepts.h>
21#include <__format/escaped_output_table.h>
2221#include <__format/formatter.h>
2322#include <__format/parser_std_format_spec.h>
2423#include <__format/unicode.h>
2524#include <__iterator/back_insert_iterator.h>
26#include <__type_traits/make_unsigned.h>
25#include <__iterator/concepts.h>
26#include <__iterator/iterator_traits.h> // iter_value_t
27#include <__memory/addressof.h>
2728#include <__utility/move.h>
2829#include <__utility/unreachable.h>
29#include <charconv>
3030#include <cstddef>
31#include <string>
3231#include <string_view>
3332
3433#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -37,7 +36,7 @@
3736
3837_LIBCPP_BEGIN_NAMESPACE_STD
3938
40#if _LIBCPP_STD_VER > 17
39#if _LIBCPP_STD_VER >= 20
4140
4241namespace __formatter {
4342
......@@ -59,15 +58,15 @@ _LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char __c) {
5958 return __c;
6059}
6160
62struct _LIBCPP_TYPE_VIS __padding_size_result {
61struct _LIBCPP_EXPORTED_FROM_ABI __padding_size_result {
6362 size_t __before_;
6463 size_t __after_;
6564};
6665
6766_LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result
6867__padding_size(size_t __size, size_t __width, __format_spec::__alignment __align) {
69 _LIBCPP_ASSERT(__width > __size, "don't call this function when no padding is required");
70 _LIBCPP_ASSERT(
68 _LIBCPP_ASSERT_UNCATEGORIZED(__width > __size, "don't call this function when no padding is required");
69 _LIBCPP_ASSERT_UNCATEGORIZED(
7170 __align != __format_spec::__alignment::__zero_padding, "the caller should have handled the zero-padding");
7271
7372 size_t __fill = __width - __size;
......@@ -161,69 +160,45 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, _CharT __value)
161160 }
162161}
163162
164template <class _OutIt, class _CharT>
165_LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, const char* __begin, const char* __first,
166 const char* __last, string&& __grouping, _CharT __sep,
167 __format_spec::__parsed_specifications<_CharT> __specs) {
168 int __size = (__first - __begin) + // [sign][prefix]
169 (__last - __first) + // data
170 (__grouping.size() - 1); // number of separator characters
171
172 __padding_size_result __padding = {0, 0};
173 if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) {
174 // Write [sign][prefix].
175 __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it));
176
177 if (__specs.__width_ > __size) {
178 // Write zero padding.
179 __padding.__before_ = __specs.__width_ - __size;
180 __out_it = __formatter::__fill(_VSTD::move(__out_it), __specs.__width_ - __size, _CharT('0'));
181 }
182 } else {
183 if (__specs.__width_ > __size) {
184 // Determine padding and write padding.
185 __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_);
186
187 __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
188 }
189 // Write [sign][prefix].
190 __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it));
191 }
163# ifndef _LIBCPP_HAS_NO_UNICODE
164template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
165 requires(same_as<_CharT, char>)
166_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
167 std::size_t __bytes = std::countl_one(static_cast<unsigned char>(__value.__data[0]));
168 if (__bytes == 0)
169 return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
170
171 for (size_t __i = 0; __i < __n; ++__i)
172 __out_it = __formatter::__copy(
173 std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + __bytes, std::move(__out_it));
174 return __out_it;
175}
192176
193 auto __r = __grouping.rbegin();
194 auto __e = __grouping.rend() - 1;
195 _LIBCPP_ASSERT(__r != __e, "The slow grouping formatting is used while "
196 "there will be no separators written.");
197 // The output is divided in small groups of numbers to write:
198 // - A group before the first separator.
199 // - A separator and a group, repeated for the number of separators.
200 // - A group after the last separator.
201 // This loop achieves that process by testing the termination condition
202 // midway in the loop.
203 //
204 // TODO FMT This loop evaluates the loop invariant `__parser.__type !=
205 // _Flags::_Type::__hexadecimal_upper_case` for every iteration. (This test
206 // happens in the __write call.) Benchmark whether making two loops and
207 // hoisting the invariant is worth the effort.
208 while (true) {
209 if (__specs.__std_.__type_ == __format_spec::__type::__hexadecimal_upper_case) {
210 __last = __first + *__r;
211 __out_it = __formatter::__transform(__first, __last, _VSTD::move(__out_it), __hex_to_upper);
212 __first = __last;
213 } else {
214 __out_it = __formatter::__copy(__first, *__r, _VSTD::move(__out_it));
215 __first += *__r;
216 }
217
218 if (__r == __e)
219 break;
220
221 ++__r;
222 *__out_it++ = __sep;
223 }
177# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
178template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
179 requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2)
180_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
181 if (!__unicode::__is_high_surrogate(__value.__data[0]))
182 return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
183
184 for (size_t __i = 0; __i < __n; ++__i)
185 __out_it = __formatter::__copy(
186 std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + 2, std::move(__out_it));
187 return __out_it;
188}
224189
225 return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
190template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
191 requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4)
192_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
193 return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
226194}
195# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
196# else // _LIBCPP_HAS_NO_UNICODE
197template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
198_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
199 return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
200}
201# endif // _LIBCPP_HAS_NO_UNICODE
227202
228203/// Writes the input to the output with the required padding.
229204///
......@@ -261,27 +236,27 @@ __write(basic_string_view<_CharT> __str,
261236 return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
262237}
263238
264template <class _CharT, class _ParserCharT>
239template <contiguous_iterator _Iterator, class _ParserCharT>
265240_LIBCPP_HIDE_FROM_ABI auto
266__write(const _CharT* __first,
267 const _CharT* __last,
268 output_iterator<const _CharT&> auto __out_it,
241__write(_Iterator __first,
242 _Iterator __last,
243 output_iterator<const iter_value_t<_Iterator>&> auto __out_it,
269244 __format_spec::__parsed_specifications<_ParserCharT> __specs,
270245 ptrdiff_t __size) -> decltype(__out_it) {
271 _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
246 _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range");
272247 return __formatter::__write(basic_string_view{__first, __last}, _VSTD::move(__out_it), __specs, __size);
273248}
274249
275250/// \overload
276251///
277252/// Calls the function above where \a __size = \a __last - \a __first.
278template <class _CharT, class _ParserCharT>
253template <contiguous_iterator _Iterator, class _ParserCharT>
279254_LIBCPP_HIDE_FROM_ABI auto
280__write(const _CharT* __first,
281 const _CharT* __last,
282 output_iterator<const _CharT&> auto __out_it,
255__write(_Iterator __first,
256 _Iterator __last,
257 output_iterator<const iter_value_t<_Iterator>&> auto __out_it,
283258 __format_spec::__parsed_specifications<_ParserCharT> __specs) -> decltype(__out_it) {
284 _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
259 _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range");
285260 return __formatter::__write(__first, __last, _VSTD::move(__out_it), __specs, __last - __first);
286261}
287262
......@@ -290,7 +265,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _Cha
290265 output_iterator<const _CharT&> auto __out_it,
291266 __format_spec::__parsed_specifications<_ParserCharT> __specs,
292267 _UnaryOperation __op) -> decltype(__out_it) {
293 _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
268 _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range");
294269
295270 ptrdiff_t __size = __last - __first;
296271 if (__size >= __specs.__width_)
......@@ -302,35 +277,6 @@ _LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _Cha
302277 return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
303278}
304279
305/// Writes additional zero's for the precision before the exponent.
306/// This is used when the precision requested in the format string is larger
307/// than the maximum precision of the floating-point type. These precision
308/// digits are always 0.
309///
310/// \param __exponent The location of the exponent character.
311/// \param __num_trailing_zeros The number of 0's to write before the exponent
312/// character.
313template <class _CharT, class _ParserCharT>
314_LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros(
315 const _CharT* __first,
316 const _CharT* __last,
317 output_iterator<const _CharT&> auto __out_it,
318 __format_spec::__parsed_specifications<_ParserCharT> __specs,
319 size_t __size,
320 const _CharT* __exponent,
321 size_t __num_trailing_zeros) -> decltype(__out_it) {
322 _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
323 _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used");
324
325 __padding_size_result __padding =
326 __formatter::__padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_);
327 __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
328 __out_it = __formatter::__copy(__first, __exponent, _VSTD::move(__out_it));
329 __out_it = __formatter::__fill(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0'));
330 __out_it = __formatter::__copy(__exponent, __last, _VSTD::move(__out_it));
331 return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
332}
333
334280/// Writes a string using format's width estimation algorithm.
335281///
336282/// \pre !__specs.__has_precision()
......@@ -342,7 +288,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write_string_no_precision(
342288 basic_string_view<_CharT> __str,
343289 output_iterator<const _CharT&> auto __out_it,
344290 __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
345 _LIBCPP_ASSERT(!__specs.__has_precision(), "use __write_string");
291 _LIBCPP_ASSERT_UNCATEGORIZED(!__specs.__has_precision(), "use __write_string");
346292
347293 // No padding -> copy the string
348294 if (!__specs.__has_width())
......@@ -359,211 +305,15 @@ _LIBCPP_HIDE_FROM_ABI auto __write_string_no_precision(
359305
360306template <class _CharT>
361307_LIBCPP_HIDE_FROM_ABI int __truncate(basic_string_view<_CharT>& __str, int __precision) {
362 __format_spec::__column_width_result<_CharT> __result =
308 __format_spec::__column_width_result __result =
363309 __format_spec::__estimate_column_width(__str, __precision, __format_spec::__column_width_rounding::__down);
364310 __str = basic_string_view<_CharT>{__str.begin(), __result.__last_};
365311 return __result.__width_;
366312}
367313
368/// Writes a string using format's width estimation algorithm.
369///
370/// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the
371/// input is ASCII.
372template <class _CharT>
373_LIBCPP_HIDE_FROM_ABI auto __write_string(
374 basic_string_view<_CharT> __str,
375 output_iterator<const _CharT&> auto __out_it,
376 __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
377 if (!__specs.__has_precision())
378 return __formatter::__write_string_no_precision(__str, _VSTD::move(__out_it), __specs);
379
380 int __size = __formatter::__truncate(__str, __specs.__precision_);
381
382 return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size);
383}
384
385# if _LIBCPP_STD_VER > 20
386
387struct __nul_terminator {};
388
389template <class _CharT>
390_LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __cstr, __nul_terminator) {
391 return *__cstr == _CharT('\0');
392}
393
394template <class _CharT>
395_LIBCPP_HIDE_FROM_ABI void
396__write_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value, const _CharT* __prefix) {
397 back_insert_iterator __out_it{__str};
398 std::ranges::copy(__prefix, __nul_terminator{}, __out_it);
399
400 char __buffer[8];
401 to_chars_result __r = std::to_chars(std::begin(__buffer), std::end(__buffer), __value, 16);
402 _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small");
403 std::ranges::copy(std::begin(__buffer), __r.ptr, __out_it);
404
405 __str += _CharT('}');
406}
407
408// [format.string.escaped]/2.2.1.2
409// ...
410// then the sequence \u{hex-digit-sequence} is appended to E, where
411// hex-digit-sequence is the shortest hexadecimal representation of C using
412// lower-case hexadecimal digits.
413template <class _CharT>
414_LIBCPP_HIDE_FROM_ABI void __write_well_formed_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value) {
415 __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\u{"));
416}
417
418// [format.string.escaped]/2.2.3
419// Otherwise (X is a sequence of ill-formed code units), each code unit U is
420// appended to E in order as the sequence \x{hex-digit-sequence}, where
421// hex-digit-sequence is the shortest hexadecimal representation of U using
422// lower-case hexadecimal digits.
423template <class _CharT>
424_LIBCPP_HIDE_FROM_ABI void __write_escape_ill_formed_code_unit(basic_string<_CharT>& __str, char32_t __value) {
425 __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\x{"));
426}
427
428template <class _CharT>
429[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool __is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value) {
430# ifdef _LIBCPP_HAS_NO_UNICODE
431 // For ASCII assume everything above 127 is printable.
432 if (__value > 127)
433 return false;
434# endif
435
436 if (!__escaped_output_table::__needs_escape(__value))
437 return false;
438
439 __formatter::__write_well_formed_escaped_code_unit(__str, __value);
440 return true;
441}
442
443template <class _CharT>
444[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr char32_t __to_char32(_CharT __value) {
445 return static_cast<make_unsigned_t<_CharT>>(__value);
446}
447
448enum class _LIBCPP_ENUM_VIS __escape_quotation_mark { __apostrophe, __double_quote };
449
450// [format.string.escaped]/2
451template <class _CharT>
452[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
453__is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value, __escape_quotation_mark __mark) {
454 // 2.2.1.1 - Mapped character in [tab:format.escape.sequences]
455 switch (__value) {
456 case _CharT('\t'):
457 __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\t");
458 return true;
459 case _CharT('\n'):
460 __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\n");
461 return true;
462 case _CharT('\r'):
463 __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\r");
464 return true;
465 case _CharT('\''):
466 if (__mark == __escape_quotation_mark::__apostrophe)
467 __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\')");
468 else
469 __str += __value;
470 return true;
471 case _CharT('"'):
472 if (__mark == __escape_quotation_mark::__double_quote)
473 __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\")");
474 else
475 __str += __value;
476 return true;
477 case _CharT('\\'):
478 __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\\)");
479 return true;
480
481 // 2.2.1.2 - Space
482 case _CharT(' '):
483 __str += __value;
484 return true;
485 }
486
487 // 2.2.2
488 // Otherwise, if X is a shift sequence, the effect on E and further
489 // decoding of S is unspecified.
490 // For now shift sequences are ignored and treated as Unicode. Other parts
491 // of the format library do the same. It's unknown how ostream treats them.
492 // TODO FMT determine what to do with shift sequences.
493
494 // 2.2.1.2.1 and 2.2.1.2.2 - Escape
495 return __formatter::__is_escaped_sequence_written(__str, __formatter::__to_char32(__value));
496}
497
498template <class _CharT>
499_LIBCPP_HIDE_FROM_ABI void
500__escape(basic_string<_CharT>& __str, basic_string_view<_CharT> __values, __escape_quotation_mark __mark) {
501 __unicode::__code_point_view<_CharT> __view{__values.begin(), __values.end()};
502
503 while (!__view.__at_end()) {
504 const _CharT* __first = __view.__position();
505 typename __unicode::__consume_p2286_result __result = __view.__consume_p2286();
506 if (__result.__ill_formed_size == 0) {
507 if (!__formatter::__is_escaped_sequence_written(__str, __result.__value, __mark))
508 // 2.2.1.3 - Add the character
509 ranges::copy(__first, __view.__position(), std::back_insert_iterator(__str));
510
511 } else {
512 // 2.2.3 sequence of ill-formed code units
513 // The number of code-units in __result.__value depends on the character type being used.
514 if constexpr (sizeof(_CharT) == 1) {
515 _LIBCPP_ASSERT(__result.__ill_formed_size == 1 || __result.__ill_formed_size == 4,
516 "illegal number of invalid code units.");
517 if (__result.__ill_formed_size == 1) // ill-formed, one code unit
518 __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value & 0xff);
519 else { // out of valid range, four code units
520 // The code point was properly encoded, decode the value.
521 __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value >> 18 | 0xf0);
522 __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value >> 12 & 0x3f) | 0x80);
523 __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value >> 6 & 0x3f) | 0x80);
524 __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value & 0x3f) | 0x80);
525 }
526 } else if constexpr (sizeof(_CharT) == 2) {
527 _LIBCPP_ASSERT(__result.__ill_formed_size == 1, "for UTF-16 at most one invalid code unit");
528 __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value & 0xffff);
529 } else {
530 static_assert(sizeof(_CharT) == 4, "unsupported character width");
531 _LIBCPP_ASSERT(__result.__ill_formed_size == 1, "for UTF-32 one code unit is one code point");
532 __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value);
533 }
534 }
535 }
536}
537
538template <class _CharT>
539_LIBCPP_HIDE_FROM_ABI auto
540__format_escaped_char(_CharT __value,
541 output_iterator<const _CharT&> auto __out_it,
542 __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
543 basic_string<_CharT> __str;
544 __str += _CharT('\'');
545 __formatter::__escape(__str, basic_string_view{std::addressof(__value), 1}, __escape_quotation_mark::__apostrophe);
546 __str += _CharT('\'');
547 return __formatter::__write(__str.data(), __str.data() + __str.size(), _VSTD::move(__out_it), __specs, __str.size());
548}
549
550template <class _CharT>
551_LIBCPP_HIDE_FROM_ABI auto
552__format_escaped_string(basic_string_view<_CharT> __values,
553 output_iterator<const _CharT&> auto __out_it,
554 __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
555 basic_string<_CharT> __str;
556 __str += _CharT('"');
557 __formatter::__escape(__str, __values, __escape_quotation_mark::__double_quote);
558 __str += _CharT('"');
559 return __formatter::__write_string(basic_string_view{__str}, _VSTD::move(__out_it), __specs);
560}
561
562# endif // _LIBCPP_STD_VER > 20
563
564314} // namespace __formatter
565315
566#endif //_LIBCPP_STD_VER > 17
316#endif //_LIBCPP_STD_VER >= 20
567317
568318_LIBCPP_END_NAMESPACE_STD
569319
lib/libcxx/include/__format/formatter_pointer.h+16-13
......@@ -27,24 +27,27 @@
2727
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232template <__fmt_char_type _CharT>
3333struct _LIBCPP_TEMPLATE_VIS __formatter_pointer {
3434public:
35 constexpr __formatter_pointer() { __parser_.__alignment_ = __format_spec::__alignment::__right; }
36
37 _LIBCPP_HIDE_FROM_ABI constexpr auto
38 parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
39 auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_pointer);
40 __format_spec::__process_display_type_pointer(__parser_.__type_);
35 template <class _ParseContext>
36 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
37 typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_pointer);
38 __format_spec::__process_display_type_pointer(__parser_.__type_, "a pointer");
4139 return __result;
4240 }
4341
44 _LIBCPP_HIDE_FROM_ABI auto format(const void* __ptr, auto& __ctx) const -> decltype(__ctx.out()) {
42 template <class _FormatContext>
43 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const void* __ptr, _FormatContext& __ctx) const {
4544 __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
4645 __specs.__std_.__alternate_form_ = true;
47 __specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case;
46 __specs.__std_.__type_ =
47 __specs.__std_.__type_ == __format_spec::__type::__pointer_upper_case
48 ? __format_spec::__type::__hexadecimal_upper_case
49 : __format_spec::__type::__hexadecimal_lower_case;
50
4851 return __formatter::__format_integer(reinterpret_cast<uintptr_t>(__ptr), __ctx, __specs);
4952 }
5053
......@@ -57,16 +60,16 @@ public:
5760// - template<> struct formatter<void*, charT>;
5861// - template<> struct formatter<const void*, charT>;
5962template <__fmt_char_type _CharT>
60struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<nullptr_t, _CharT>
63struct _LIBCPP_TEMPLATE_VIS formatter<nullptr_t, _CharT>
6164 : public __formatter_pointer<_CharT> {};
6265template <__fmt_char_type _CharT>
63struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<void*, _CharT> : public __formatter_pointer<_CharT> {
66struct _LIBCPP_TEMPLATE_VIS formatter<void*, _CharT> : public __formatter_pointer<_CharT> {
6467};
6568template <__fmt_char_type _CharT>
66struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const void*, _CharT>
69struct _LIBCPP_TEMPLATE_VIS formatter<const void*, _CharT>
6770 : public __formatter_pointer<_CharT> {};
6871
69#endif //_LIBCPP_STD_VER > 17
72#endif //_LIBCPP_STD_VER >= 20
7073
7174_LIBCPP_END_NAMESPACE_STD
7275
lib/libcxx/include/__format/formatter_string.h+32-35
......@@ -17,7 +17,7 @@
1717#include <__format/formatter.h>
1818#include <__format/formatter_output.h>
1919#include <__format/parser_std_format_spec.h>
20#include <__utility/move.h>
20#include <__format/write_escaped.h>
2121#include <string>
2222#include <string_view>
2323
......@@ -27,20 +27,22 @@
2727
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131
3232template <__fmt_char_type _CharT>
3333struct _LIBCPP_TEMPLATE_VIS __formatter_string {
3434public:
35 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
36 -> decltype(__parse_ctx.begin()) {
37 auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_string);
35 template <class _ParseContext>
36 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
37 typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_string);
3838 __format_spec::__process_display_type_string(__parser_.__type_);
3939 return __result;
4040 }
4141
42 _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT> __str, auto& __ctx) const -> decltype(__ctx.out()) {
43# if _LIBCPP_STD_VER > 20
42 template <class _FormatContext>
43 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
44 format(basic_string_view<_CharT> __str, _FormatContext& __ctx) const {
45# if _LIBCPP_STD_VER >= 23
4446 if (__parser_.__type_ == __format_spec::__type::__debug)
4547 return __formatter::__format_escaped_string(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
4648# endif
......@@ -48,7 +50,7 @@ public:
4850 return __formatter::__write_string(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
4951 }
5052
51# if _LIBCPP_STD_VER > 20
53# if _LIBCPP_STD_VER >= 23
5254 _LIBCPP_HIDE_FROM_ABI constexpr void set_debug_format() { __parser_.__type_ = __format_spec::__type::__debug; }
5355# endif
5456
......@@ -57,16 +59,17 @@ public:
5759
5860// Formatter const char*.
5961template <__fmt_char_type _CharT>
60struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT*, _CharT>
62struct _LIBCPP_TEMPLATE_VIS formatter<const _CharT*, _CharT>
6163 : public __formatter_string<_CharT> {
6264 using _Base = __formatter_string<_CharT>;
6365
64 _LIBCPP_HIDE_FROM_ABI auto format(const _CharT* __str, auto& __ctx) const -> decltype(__ctx.out()) {
65 _LIBCPP_ASSERT(__str, "The basic_format_arg constructor should have "
66 "prevented an invalid pointer.");
66 template <class _FormatContext>
67 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _CharT* __str, _FormatContext& __ctx) const {
68 _LIBCPP_ASSERT_UNCATEGORIZED(__str, "The basic_format_arg constructor should have "
69 "prevented an invalid pointer.");
6770
6871 __format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx);
69# if _LIBCPP_STD_VER > 20
72# if _LIBCPP_STD_VER >= 23
7073 if (_Base::__parser_.__type_ == __format_spec::__type::__debug)
7174 return __formatter::__format_escaped_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs);
7275# endif
......@@ -95,45 +98,38 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT*,
9598
9699// Formatter char*.
97100template <__fmt_char_type _CharT>
98struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT*, _CharT>
101struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT>
99102 : public formatter<const _CharT*, _CharT> {
100103 using _Base = formatter<const _CharT*, _CharT>;
101104
102 _LIBCPP_HIDE_FROM_ABI auto format(_CharT* __str, auto& __ctx) const -> decltype(__ctx.out()) {
105 template <class _FormatContext>
106 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_CharT* __str, _FormatContext& __ctx) const {
103107 return _Base::format(__str, __ctx);
104108 }
105109};
106110
107111// Formatter char[].
108112template <__fmt_char_type _CharT, size_t _Size>
109struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT[_Size], _CharT>
113struct _LIBCPP_TEMPLATE_VIS formatter<_CharT[_Size], _CharT>
110114 : public __formatter_string<_CharT> {
111115 using _Base = __formatter_string<_CharT>;
112116
113 _LIBCPP_HIDE_FROM_ABI auto format(_CharT __str[_Size], auto& __ctx) const -> decltype(__ctx.out()) {
114 return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx);
115 }
116};
117
118// Formatter const char[].
119template <__fmt_char_type _CharT, size_t _Size>
120struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT[_Size], _CharT>
121 : public __formatter_string<_CharT> {
122 using _Base = __formatter_string<_CharT>;
123
124 _LIBCPP_HIDE_FROM_ABI auto format(const _CharT __str[_Size], auto& __ctx) const -> decltype(__ctx.out()) {
117 template <class _FormatContext>
118 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
119 format(const _CharT (&__str)[_Size], _FormatContext& __ctx) const {
125120 return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx);
126121 }
127122};
128123
129124// Formatter std::string.
130125template <__fmt_char_type _CharT, class _Traits, class _Allocator>
131struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT>
126struct _LIBCPP_TEMPLATE_VIS formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT>
132127 : public __formatter_string<_CharT> {
133128 using _Base = __formatter_string<_CharT>;
134129
135 _LIBCPP_HIDE_FROM_ABI auto format(const basic_string<_CharT, _Traits, _Allocator>& __str, auto& __ctx) const
136 -> decltype(__ctx.out()) {
130 template <class _FormatContext>
131 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
132 format(const basic_string<_CharT, _Traits, _Allocator>& __str, _FormatContext& __ctx) const {
137133 // Drop _Traits and _Allocator to have one std::basic_string formatter.
138134 return _Base::format(basic_string_view<_CharT>(__str.data(), __str.size()), __ctx);
139135 }
......@@ -141,18 +137,19 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string<_
141137
142138// Formatter std::string_view.
143139template <__fmt_char_type _CharT, class _Traits>
144struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string_view<_CharT, _Traits>, _CharT>
140struct _LIBCPP_TEMPLATE_VIS formatter<basic_string_view<_CharT, _Traits>, _CharT>
145141 : public __formatter_string<_CharT> {
146142 using _Base = __formatter_string<_CharT>;
147143
148 _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT, _Traits> __str, auto& __ctx) const
149 -> decltype(__ctx.out()) {
144 template <class _FormatContext>
145 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
146 format(basic_string_view<_CharT, _Traits> __str, _FormatContext& __ctx) const {
150147 // Drop _Traits to have one std::basic_string_view formatter.
151148 return _Base::format(basic_string_view<_CharT>(__str.data(), __str.size()), __ctx);
152149 }
153150};
154151
155#endif //_LIBCPP_STD_VER > 17
152#endif //_LIBCPP_STD_VER >= 20
156153
157154_LIBCPP_END_NAMESPACE_STD
158155
lib/libcxx/include/__format/formatter_tuple.h+47-75
......@@ -11,18 +11,16 @@
1111#define _LIBCPP___FORMAT_FORMATTER_TUPLE_H
1212
1313#include <__algorithm/ranges_copy.h>
14#include <__availability>
1514#include <__chrono/statically_widen.h>
1615#include <__config>
16#include <__format/buffer.h>
1717#include <__format/concepts.h>
18#include <__format/format_args.h>
1918#include <__format/format_context.h>
2019#include <__format/format_error.h>
2120#include <__format/format_parse_context.h>
2221#include <__format/formatter.h>
2322#include <__format/formatter_output.h>
2423#include <__format/parser_std_format_spec.h>
25#include <__iterator/back_insert_iterator.h>
2624#include <__type_traits/remove_cvref.h>
2725#include <__utility/integer_sequence.h>
2826#include <__utility/pair.h>
......@@ -35,49 +33,52 @@
3533
3634_LIBCPP_BEGIN_NAMESPACE_STD
3735
38#if _LIBCPP_STD_VER > 20
36#if _LIBCPP_STD_VER >= 23
3937
4038template <__fmt_char_type _CharT, class _Tuple, formattable<_CharT>... _Args>
41struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_tuple {
42 _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
39struct _LIBCPP_TEMPLATE_VIS __formatter_tuple {
40 _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept {
4341 __separator_ = __separator;
4442 }
4543 _LIBCPP_HIDE_FROM_ABI constexpr void
46 set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
44 set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept {
4745 __opening_bracket_ = __opening_bracket;
4846 __closing_bracket_ = __closing_bracket;
4947 }
5048
5149 template <class _ParseContext>
52 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) {
53 const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_tuple);
50 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
51 auto __begin = __parser_.__parse(__ctx, __format_spec::__fields_tuple);
5452
55 // [format.tuple]/7
56 // ... For each element e in underlying_, if e.set_debug_format()
57 // is a valid expression, calls e.set_debug_format().
58 // TODO FMT this can be removed when P2733 is accepted.
59 std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> {
60 std::__set_debug_format(std::get<_Index>(__underlying_));
61 });
62
63 const _CharT* __end = __parse_ctx.end();
64 if (__begin == __end)
65 return __begin;
66
67 if (*__begin == _CharT('m')) {
53 auto __end = __ctx.end();
54 // Note 'n' is part of the type here
55 if (__parser_.__clear_brackets_)
56 set_brackets({}, {});
57 else if (__begin != __end && *__begin == _CharT('m')) {
6858 if constexpr (sizeof...(_Args) == 2) {
6959 set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": "));
7060 set_brackets({}, {});
7161 ++__begin;
7262 } else
73 std::__throw_format_error("The format specifier m requires a pair or a two-element tuple");
74 } else if (*__begin == _CharT('n')) {
75 set_brackets({}, {});
76 ++__begin;
63 std::__throw_format_error("Type m requires a pair or a tuple with two elements");
7764 }
7865
7966 if (__begin != __end && *__begin != _CharT('}'))
80 std::__throw_format_error("The format-spec should consume the input or end with a '}'");
67 std::__throw_format_error("The format specifier should consume the input or end with a '}'");
68
69 __ctx.advance_to(__begin);
70
71 // [format.tuple]/7
72 // ... For each element e in underlying_, if e.set_debug_format()
73 // is a valid expression, calls e.set_debug_format().
74 std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> {
75 auto& __formatter = std::get<_Index>(__underlying_);
76 __formatter.parse(__ctx);
77 // Unlike the range_formatter we don't guard against evil parsers. Since
78 // this format-spec never has a format-spec for the underlying type
79 // adding the test would give additional overhead.
80 std::__set_debug_format(__formatter);
81 });
8182
8283 return __begin;
8384 }
......@@ -91,26 +92,25 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_tuple {
9192 if (!__specs.__has_width())
9293 return __format_tuple(__tuple, __ctx);
9394
94 basic_string<_CharT> __str;
95
96 // Since the output is written to a different iterator a new context is
97 // created. Since the underlying formatter uses the default formatting it
98 // doesn't need a locale or the formatting arguments. So creating a new
99 // context works.
100 //
101 // This solution works for this formatter, but it will not work for the
102 // range_formatter. In that patch a generic solution is work in progress.
103 // Once that is finished it can be used here. (The range_formatter will use
104 // these features so it's easier to add it there and then port it.)
105 //
106 // TODO FMT Use formatting wrapping used in the range_formatter.
107 basic_format_context __c = std::__format_context_create(
108 back_insert_iterator{__str},
109 basic_format_args<basic_format_context<back_insert_iterator<basic_string<_CharT>>, _CharT>>{});
95 // The size of the buffer needed is:
96 // - open bracket characters
97 // - close bracket character
98 // - n elements where every element may have a different size
99 // - (n -1) separators
100 // The size of the element is hard to predict, knowing the type helps but
101 // it depends on the format-spec. As an initial estimate we guess 6
102 // characters.
103 // Typically both brackets are 1 character and the separator is 2
104 // characters. Which means there will be
105 // (n - 1) * 2 + 1 + 1 = n * 2 character
106 // So estimate 8 times the range size as buffer.
107 __format::__retarget_buffer<_CharT> __buffer{8 * tuple_size_v<_Tuple>};
108 basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> __c{
109 __buffer.__make_output_iterator(), __ctx};
110110
111111 __format_tuple(__tuple, __c);
112112
113 return __formatter::__write_string_no_precision(basic_string_view{__str}, __ctx.out(), __specs);
113 return __formatter::__write_string_no_precision(basic_string_view{__buffer.__view()}, __ctx.out(), __specs);
114114 }
115115
116116 template <class _FormatContext>
......@@ -120,35 +120,7 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_tuple {
120120 std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> {
121121 if constexpr (_Index)
122122 __ctx.advance_to(std::ranges::copy(__separator_, __ctx.out()).out);
123
124 // During review Victor suggested to make the exposition only
125 // __underlying_ member a local variable. Currently the Standard
126 // requires nested debug-enabled formatter specializations not to
127 // output escaped output. P2733 fixes that bug, once accepted the
128 // code below can be used.
129 // (Note when a paper allows parsing a tuple-underlying-spec the
130 // exposition only member needs to be a class member. Earlier
131 // revisions of P2286 proposed that, but this was not pursued,
132 // due to time constrains and complexity of the matter.)
133 // TODO FMT This can be updated after P2733 is accepted.
134# if 0
135 // P2286 uses an exposition only member in the formatter
136 // tuple<formatter<remove_cvref_t<_Args>, _CharT>...> __underlying_;
137 // This was used in earlier versions of the paper since
138 // __underlying_.parse(...) was called. This is no longer the case
139 // so we can reduce the scope of the formatter.
140 //
141 // It does require the underlying's parse effect to be moved here too.
142 using _Arg = tuple_element<_Index, decltype(__tuple)>;
143 formatter<remove_cvref_t<_Args>, _CharT> __underlying;
144
145 // [format.tuple]/7
146 // ... For each element e in underlying_, if e.set_debug_format()
147 // is a valid expression, calls e.set_debug_format().
148 std::__set_debug_format(__underlying);
149# else
150123 __ctx.advance_to(std::get<_Index>(__underlying_).format(std::get<_Index>(__tuple), __ctx));
151# endif
152124 });
153125
154126 return std::ranges::copy(__closing_bracket_, __ctx.out()).out;
......@@ -164,14 +136,14 @@ private:
164136};
165137
166138template <__fmt_char_type _CharT, formattable<_CharT>... _Args>
167struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<pair<_Args...>, _CharT>
139struct _LIBCPP_TEMPLATE_VIS formatter<pair<_Args...>, _CharT>
168140 : public __formatter_tuple<_CharT, pair<_Args...>, _Args...> {};
169141
170142template <__fmt_char_type _CharT, formattable<_CharT>... _Args>
171struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<tuple<_Args...>, _CharT>
143struct _LIBCPP_TEMPLATE_VIS formatter<tuple<_Args...>, _CharT>
172144 : public __formatter_tuple<_CharT, tuple<_Args...>, _Args...> {};
173145
174#endif //_LIBCPP_STD_VER > 20
146#endif //_LIBCPP_STD_VER >= 23
175147
176148_LIBCPP_END_NAMESPACE_STD
177149
lib/libcxx/include/__format/parser_std_format_spec.h+415-194
......@@ -16,23 +16,28 @@
1616/// This header has some support for the chrono-format-spec since it doesn't
1717/// affect the std-format-spec.
1818
19#include <__algorithm/find_if.h>
19#include <__algorithm/copy_n.h>
2020#include <__algorithm/min.h>
2121#include <__assert>
2222#include <__concepts/arithmetic.h>
2323#include <__concepts/same_as.h>
2424#include <__config>
25#include <__debug>
2625#include <__format/format_arg.h>
2726#include <__format/format_error.h>
2827#include <__format/format_parse_context.h>
2928#include <__format/format_string.h>
3029#include <__format/unicode.h>
30#include <__format/width_estimation_table.h>
31#include <__iterator/concepts.h>
32#include <__iterator/iterator_traits.h> // iter_value_t
33#include <__memory/addressof.h>
34#include <__type_traits/common_type.h>
35#include <__type_traits/is_constant_evaluated.h>
36#include <__type_traits/is_trivially_copyable.h>
3137#include <__variant/monostate.h>
32#include <bit>
3338#include <cstdint>
39#include <string>
3440#include <string_view>
35#include <type_traits>
3641
3742#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3843# pragma GCC system_header
......@@ -43,24 +48,36 @@ _LIBCPP_PUSH_MACROS
4348
4449_LIBCPP_BEGIN_NAMESPACE_STD
4550
46#if _LIBCPP_STD_VER > 17
51#if _LIBCPP_STD_VER >= 20
4752
4853namespace __format_spec {
4954
50template <class _CharT>
51_LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result< _CharT>
52__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
55_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void
56__throw_invalid_option_format_error(const char* __id, const char* __option) {
57 std::__throw_format_error(
58 (string("The format specifier for ") + __id + " does not allow the " + __option + " option").c_str());
59}
60
61_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void __throw_invalid_type_format_error(const char* __id) {
62 std::__throw_format_error(
63 (string("The type option contains an invalid value for ") + __id + " formatting argument").c_str());
64}
65
66template <contiguous_iterator _Iterator, class _ParseContext>
67_LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result<_Iterator>
68__parse_arg_id(_Iterator __begin, _Iterator __end, _ParseContext& __ctx) {
69 using _CharT = iter_value_t<_Iterator>;
5370 // This function is a wrapper to call the real parser. But it does the
5471 // validation for the pre-conditions and post-conditions.
5572 if (__begin == __end)
56 std::__throw_format_error("End of input while parsing format-spec arg-id");
73 std::__throw_format_error("End of input while parsing an argument index");
5774
58 __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx);
75 __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __ctx);
5976
60 if (__r.__ptr == __end || *__r.__ptr != _CharT('}'))
61 std::__throw_format_error("Invalid arg-id");
77 if (__r.__last == __end || *__r.__last != _CharT('}'))
78 std::__throw_format_error("The argument index is invalid");
6279
63 ++__r.__ptr;
80 ++__r.__last;
6481 return __r;
6582}
6683
......@@ -78,22 +95,33 @@ __substitute_arg_id(basic_format_arg<_Context> __format_arg) {
7895 return _VSTD::__visit_format_arg(
7996 [](auto __arg) -> uint32_t {
8097 using _Type = decltype(__arg);
81 if constexpr (integral<_Type>) {
98 if constexpr (same_as<_Type, monostate>)
99 std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
100
101 // [format.string.std]/8
102 // If { arg-idopt } is used in a width or precision, the value of the
103 // corresponding formatting argument is used in its place. If the
104 // corresponding formatting argument is not of standard signed or unsigned
105 // integer type, or its value is negative for precision or non-positive for
106 // width, an exception of type format_error is thrown.
107 //
108 // When an integral is used in a format function, it is stored as one of
109 // the types checked below. Other integral types are promoted. For example,
110 // a signed char is stored as an int.
111 if constexpr (same_as<_Type, int> || same_as<_Type, unsigned int> || //
112 same_as<_Type, long long> || same_as<_Type, unsigned long long>) {
82113 if constexpr (signed_integral<_Type>) {
83114 if (__arg < 0)
84 std::__throw_format_error("A format-spec arg-id replacement shouldn't have a negative value");
115 std::__throw_format_error("An argument index may not have a negative value");
85116 }
86117
87118 using _CT = common_type_t<_Type, decltype(__format::__number_max)>;
88 if (static_cast<_CT>(__arg) >
89 static_cast<_CT>(__format::__number_max))
90 std::__throw_format_error("A format-spec arg-id replacement exceeds the maximum supported value");
119 if (static_cast<_CT>(__arg) > static_cast<_CT>(__format::__number_max))
120 std::__throw_format_error("The value of the argument index exceeds its maximum value");
91121
92122 return __arg;
93 } else if constexpr (same_as<_Type, monostate>)
94 std::__throw_format_error("Argument index out of bounds");
95 else
96 std::__throw_format_error("A format-spec arg-id replacement argument isn't an integral type");
123 } else
124 std::__throw_format_error("Replacement argument isn't a standard signed or unsigned integer type");
97125 },
98126 __format_arg);
99127}
......@@ -104,42 +132,48 @@ __substitute_arg_id(basic_format_arg<_Context> __format_arg) {
104132/// explicitly.
105133// TODO FMT Use an ABI tag for this struct.
106134struct __fields {
107 uint8_t __sign_ : 1 {false};
108 uint8_t __alternate_form_ : 1 {false};
109 uint8_t __zero_padding_ : 1 {false};
110 uint8_t __precision_ : 1 {false};
111 uint8_t __locale_specific_form_ : 1 {false};
112 uint8_t __type_ : 1 {false};
135 uint16_t __sign_ : 1 {false};
136 uint16_t __alternate_form_ : 1 {false};
137 uint16_t __zero_padding_ : 1 {false};
138 uint16_t __precision_ : 1 {false};
139 uint16_t __locale_specific_form_ : 1 {false};
140 uint16_t __type_ : 1 {false};
113141 // Determines the valid values for fill.
114142 //
115143 // Originally the fill could be any character except { and }. Range-based
116144 // formatters use the colon to mark the beginning of the
117145 // underlying-format-spec. To avoid parsing ambiguities these formatter
118146 // specializations prohibit the use of the colon as a fill character.
119 uint8_t __allow_colon_in_fill_ : 1 {false};
147 uint16_t __use_range_fill_ : 1 {false};
148 uint16_t __clear_brackets_ : 1 {false};
149 uint16_t __consume_all_ : 1 {false};
120150};
121151
122152// By not placing this constant in the formatter class it's not duplicated for
123153// char and wchar_t.
154inline constexpr __fields __fields_bool{.__locale_specific_form_ = true, .__type_ = true, .__consume_all_ = true};
124155inline constexpr __fields __fields_integral{
125156 .__sign_ = true,
126157 .__alternate_form_ = true,
127158 .__zero_padding_ = true,
128159 .__locale_specific_form_ = true,
129 .__type_ = true};
160 .__type_ = true,
161 .__consume_all_ = true};
130162inline constexpr __fields __fields_floating_point{
131163 .__sign_ = true,
132164 .__alternate_form_ = true,
133165 .__zero_padding_ = true,
134166 .__precision_ = true,
135167 .__locale_specific_form_ = true,
136 .__type_ = true};
137inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true};
138inline constexpr __fields __fields_pointer{.__type_ = true};
139
140# if _LIBCPP_STD_VER > 20
141inline constexpr __fields __fields_tuple{.__type_ = false, .__allow_colon_in_fill_ = true};
142inline constexpr __fields __fields_range{.__type_ = false, .__allow_colon_in_fill_ = true};
168 .__type_ = true,
169 .__consume_all_ = true};
170inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true, .__consume_all_ = true};
171inline constexpr __fields __fields_pointer{.__zero_padding_ = true, .__type_ = true, .__consume_all_ = true};
172
173# if _LIBCPP_STD_VER >= 23
174inline constexpr __fields __fields_tuple{.__use_range_fill_ = true, .__clear_brackets_ = true};
175inline constexpr __fields __fields_range{.__use_range_fill_ = true, .__clear_brackets_ = true};
176inline constexpr __fields __fields_fill_align_width{};
143177# endif
144178
145179enum class _LIBCPP_ENUM_VIS __alignment : uint8_t {
......@@ -164,7 +198,7 @@ enum class _LIBCPP_ENUM_VIS __sign : uint8_t {
164198};
165199
166200enum class _LIBCPP_ENUM_VIS __type : uint8_t {
167 __default,
201 __default = 0,
168202 __string,
169203 __binary_lower_case,
170204 __binary_upper_case,
......@@ -172,7 +206,8 @@ enum class _LIBCPP_ENUM_VIS __type : uint8_t {
172206 __decimal,
173207 __hexadecimal_lower_case,
174208 __hexadecimal_upper_case,
175 __pointer,
209 __pointer_lower_case,
210 __pointer_upper_case,
176211 __char,
177212 __hexfloat_lower_case,
178213 __hexfloat_upper_case,
......@@ -185,6 +220,25 @@ enum class _LIBCPP_ENUM_VIS __type : uint8_t {
185220 __debug
186221};
187222
223_LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __create_type_mask(__type __t) {
224 uint32_t __shift = static_cast<uint32_t>(__t);
225 if (__shift == 0)
226 return 1;
227
228 if (__shift > 31)
229 std::__throw_format_error("The type does not fit in the mask");
230
231 return 1 << __shift;
232}
233
234inline constexpr uint32_t __type_mask_integer =
235 __create_type_mask(__type::__binary_lower_case) | //
236 __create_type_mask(__type::__binary_upper_case) | //
237 __create_type_mask(__type::__decimal) | //
238 __create_type_mask(__type::__octal) | //
239 __create_type_mask(__type::__hexadecimal_lower_case) | //
240 __create_type_mask(__type::__hexadecimal_upper_case);
241
188242struct __std {
189243 __alignment __alignment_ : 3;
190244 __sign __sign_ : 2;
......@@ -196,6 +250,7 @@ struct __std {
196250struct __chrono {
197251 __alignment __alignment_ : 3;
198252 bool __locale_specific_form_ : 1;
253 bool __hour_ : 1;
199254 bool __weekday_name_ : 1;
200255 bool __weekday_ : 1;
201256 bool __day_of_year_ : 1;
......@@ -203,6 +258,25 @@ struct __chrono {
203258 bool __month_name_ : 1;
204259};
205260
261// The fill UCS scalar value.
262//
263// This is always an array, with 1, 2, or 4 elements.
264// The size of the data structure is always 32-bits.
265template <class _CharT>
266struct __code_point;
267
268template <>
269struct __code_point<char> {
270 char __data[4] = {' '};
271};
272
273# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
274template <>
275struct __code_point<wchar_t> {
276 wchar_t __data[4 / sizeof(wchar_t)] = {L' '};
277};
278# endif
279
206280/// Contains the parsed formatting specifications.
207281///
208282/// This contains information for both the std-format-spec and the
......@@ -238,7 +312,7 @@ struct __parsed_specifications {
238312 /// replaced with the value of that arg-id.
239313 int32_t __precision_;
240314
241 _CharT __fill_;
315 __code_point<_CharT> __fill_;
242316
243317 _LIBCPP_HIDE_FROM_ABI constexpr bool __has_width() const { return __width_ > 0; }
244318
......@@ -265,48 +339,161 @@ static_assert(is_trivially_copyable_v<__parsed_specifications<wchar_t>>);
265339template <class _CharT>
266340class _LIBCPP_TEMPLATE_VIS __parser {
267341public:
268 _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(basic_format_parse_context<_CharT>& __parse_ctx, __fields __fields)
269 -> decltype(__parse_ctx.begin()) {
270
271 const _CharT* __begin = __parse_ctx.begin();
272 const _CharT* __end = __parse_ctx.end();
342 // Parses the format specification.
343 //
344 // Depending on whether the parsing is done compile-time or run-time
345 // the method slightly differs.
346 // - Only parses a field when it is in the __fields. Accepting all
347 // fields and then validating the valid ones has a performance impact.
348 // This is faster but gives slighly worse error messages.
349 // - At compile-time when a field is not accepted the parser will still
350 // parse it and give an error when it's present. This gives a more
351 // accurate error.
352 // The idea is that most times the format instead of the vformat
353 // functions are used. In that case the error will be detected during
354 // compilation and there is no need to pay for the run-time overhead.
355 template <class _ParseContext>
356 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator __parse(_ParseContext& __ctx, __fields __fields) {
357 auto __begin = __ctx.begin();
358 auto __end = __ctx.end();
273359 if (__begin == __end)
274360 return __begin;
275361
276 if (__parse_fill_align(__begin, __end, __fields.__allow_colon_in_fill_) && __begin == __end)
362 if (__parse_fill_align(__begin, __end, __fields.__use_range_fill_) && __begin == __end)
277363 return __begin;
278364
279 if (__fields.__sign_ && __parse_sign(__begin) && __begin == __end)
280 return __begin;
365 if (__fields.__sign_) {
366 if (__parse_sign(__begin) && __begin == __end)
367 return __begin;
368 } else if (std::is_constant_evaluated() && __parse_sign(__begin)) {
369 std::__throw_format_error("The format specification does not allow the sign option");
370 }
281371
282 if (__fields.__alternate_form_ && __parse_alternate_form(__begin) && __begin == __end)
283 return __begin;
372 if (__fields.__alternate_form_) {
373 if (__parse_alternate_form(__begin) && __begin == __end)
374 return __begin;
375 } else if (std::is_constant_evaluated() && __parse_alternate_form(__begin)) {
376 std::__throw_format_error("The format specifier does not allow the alternate form option");
377 }
284378
285 if (__fields.__zero_padding_ && __parse_zero_padding(__begin) && __begin == __end)
286 return __begin;
379 if (__fields.__zero_padding_) {
380 if (__parse_zero_padding(__begin) && __begin == __end)
381 return __begin;
382 } else if (std::is_constant_evaluated() && __parse_zero_padding(__begin)) {
383 std::__throw_format_error("The format specifier does not allow the zero-padding option");
384 }
287385
288 if (__parse_width(__begin, __end, __parse_ctx) && __begin == __end)
386 if (__parse_width(__begin, __end, __ctx) && __begin == __end)
289387 return __begin;
290388
291 if (__fields.__precision_ && __parse_precision(__begin, __end, __parse_ctx) && __begin == __end)
292 return __begin;
389 if (__fields.__precision_) {
390 if (__parse_precision(__begin, __end, __ctx) && __begin == __end)
391 return __begin;
392 } else if (std::is_constant_evaluated() && __parse_precision(__begin, __end, __ctx)) {
393 std::__throw_format_error("The format specifier does not allow the precision option");
394 }
293395
294 if (__fields.__locale_specific_form_ && __parse_locale_specific_form(__begin) && __begin == __end)
295 return __begin;
396 if (__fields.__locale_specific_form_) {
397 if (__parse_locale_specific_form(__begin) && __begin == __end)
398 return __begin;
399 } else if (std::is_constant_evaluated() && __parse_locale_specific_form(__begin)) {
400 std::__throw_format_error("The format specifier does not allow the locale-specific form option");
401 }
402
403 if (__fields.__clear_brackets_) {
404 if (__parse_clear_brackets(__begin) && __begin == __end)
405 return __begin;
406 } else if (std::is_constant_evaluated() && __parse_clear_brackets(__begin)) {
407 std::__throw_format_error("The format specifier does not allow the n option");
408 }
296409
297 if (__fields.__type_) {
410 if (__fields.__type_)
298411 __parse_type(__begin);
299412
300 // When __type_ is false the calling parser is expected to do additional
301 // parsing. In that case that parser should do the end of format string
302 // validation.
303 if (__begin != __end && *__begin != _CharT('}'))
304 std::__throw_format_error("The format-spec should consume the input or end with a '}'");
305 }
413 if (!__fields.__consume_all_)
414 return __begin;
415
416 if (__begin != __end && *__begin != _CharT('}'))
417 std::__throw_format_error("The format specifier should consume the input or end with a '}'");
306418
307419 return __begin;
308420 }
309421
422 // Validates the selected the parsed data.
423 //
424 // The valid fields in the parser may depend on the display type
425 // selected. But the type is the last optional field, so by the time
426 // it's known an option can't be used, it already has been parsed.
427 // This does the validation again.
428 //
429 // For example an integral may have a sign, zero-padding, or alternate
430 // form when the type option is not 'c'. So the generic approach is:
431 //
432 // typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral);
433 // if (__parser.__type_ == __format_spec::__type::__char) {
434 // __parser.__validate((__format_spec::__fields_bool, "an integer");
435 // ... // more char adjustments
436 // } else {
437 // ... // validate an integral type.
438 // }
439 //
440 // For some types all valid options need a second validation run, like
441 // boolean types.
442 //
443 // Depending on whether the validation is done at compile-time or
444 // run-time the error differs
445 // - run-time the exception is thrown and contains the type of field
446 // being validated.
447 // - at compile-time the line with `std::__throw_format_error` is shown
448 // in the output. In that case it's important for the error to be on one
449 // line.
450 // Note future versions of C++ may allow better compile-time error
451 // reporting.
452 _LIBCPP_HIDE_FROM_ABI constexpr void
453 __validate(__fields __fields, const char* __id, uint32_t __type_mask = -1) const {
454 if (!__fields.__sign_ && __sign_ != __sign::__default) {
455 if (std::is_constant_evaluated())
456 std::__throw_format_error("The format specifier does not allow the sign option");
457 else
458 __format_spec::__throw_invalid_option_format_error(__id, "sign");
459 }
460
461 if (!__fields.__alternate_form_ && __alternate_form_) {
462 if (std::is_constant_evaluated())
463 std::__throw_format_error("The format specifier does not allow the alternate form option");
464 else
465 __format_spec::__throw_invalid_option_format_error(__id, "alternate form");
466 }
467
468 if (!__fields.__zero_padding_ && __alignment_ == __alignment::__zero_padding) {
469 if (std::is_constant_evaluated())
470 std::__throw_format_error("The format specifier does not allow the zero-padding option");
471 else
472 __format_spec::__throw_invalid_option_format_error(__id, "zero-padding");
473 }
474
475 if (!__fields.__precision_ && __precision_ != -1) { // Works both when the precision has a value or an arg-id.
476 if (std::is_constant_evaluated())
477 std::__throw_format_error("The format specifier does not allow the precision option");
478 else
479 __format_spec::__throw_invalid_option_format_error(__id, "precision");
480 }
481
482 if (!__fields.__locale_specific_form_ && __locale_specific_form_) {
483 if (std::is_constant_evaluated())
484 std::__throw_format_error("The format specifier does not allow the locale-specific form option");
485 else
486 __format_spec::__throw_invalid_option_format_error(__id, "locale-specific form");
487 }
488
489 if ((__create_type_mask(__type_) & __type_mask) == 0) {
490 if (std::is_constant_evaluated())
491 std::__throw_format_error("The format specifier uses an invalid value for the type option");
492 else
493 __format_spec::__throw_invalid_type_format_error(__id);
494 }
495 }
496
310497 /// \returns the `__parsed_specifications` with the resolved dynamic sizes..
311498 _LIBCPP_HIDE_FROM_ABI
312499 __parsed_specifications<_CharT> __get_parsed_std_specifications(auto& __ctx) const {
......@@ -326,6 +513,7 @@ public:
326513 .__chrono_ =
327514 __chrono{.__alignment_ = __alignment_,
328515 .__locale_specific_form_ = __locale_specific_form_,
516 .__hour_ = __hour_,
329517 .__weekday_name_ = __weekday_name_,
330518 .__weekday_ = __weekday_,
331519 .__day_of_year_ = __day_of_year_,
......@@ -340,11 +528,13 @@ public:
340528 __sign __sign_ : 2 {__sign::__default};
341529 bool __alternate_form_ : 1 {false};
342530 bool __locale_specific_form_ : 1 {false};
343 bool __reserved_0_ : 1 {false};
531 bool __clear_brackets_ : 1 {false};
344532 __type __type_{__type::__default};
345533
346534 // These flags are only used for formatting chrono. Since the struct has
347535 // padding space left it's added to this structure.
536 bool __hour_ : 1 {false};
537
348538 bool __weekday_name_ : 1 {false};
349539 bool __weekday_ : 1 {false};
350540
......@@ -353,8 +543,8 @@ public:
353543
354544 bool __month_name_ : 1 {false};
355545
356 uint8_t __reserved_1_ : 3 {0};
357 uint8_t __reserved_2_ : 6 {0};
546 uint8_t __reserved_0_ : 2 {0};
547 uint8_t __reserved_1_ : 6 {0};
358548 // These two flags are only used internally and not part of the
359549 // __parsed_specifications. Therefore put them at the end.
360550 bool __width_as_arg_ : 1 {false};
......@@ -366,11 +556,7 @@ public:
366556 /// The requested precision, either the value or the arg-id.
367557 int32_t __precision_{-1};
368558
369 // LWG 3576 will probably change this to always accept a Unicode code point
370 // To avoid changing the size with that change align the field so when it
371 // becomes 32-bit its alignment will remain the same. That also means the
372 // size will remain the same. (D2572 addresses the solution for LWG 3576.)
373 _CharT __fill_{_CharT(' ')};
559 __code_point<_CharT> __fill_{};
374560
375561private:
376562 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alignment(_CharT __c) {
......@@ -390,19 +576,90 @@ private:
390576 return false;
391577 }
392578
579 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_fill_character(_CharT __fill, bool __use_range_fill) {
580 // The forbidden fill characters all code points formed from a single code unit, thus the
581 // check can be omitted when more code units are used.
582 if (__use_range_fill && (__fill == _CharT('{') || __fill == _CharT('}') || __fill == _CharT(':')))
583 std::__throw_format_error("The fill option contains an invalid value");
584 else if (__fill == _CharT('{') || __fill == _CharT('}'))
585 std::__throw_format_error("The fill option contains an invalid value");
586 }
587
588# ifndef _LIBCPP_HAS_NO_UNICODE
589 // range-fill and tuple-fill are identical
590 template <contiguous_iterator _Iterator>
591 requires same_as<_CharT, char>
592# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
593 || (same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2)
594# endif
595 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) {
596 _LIBCPP_ASSERT_UNCATEGORIZED(__begin != __end,
597 "when called with an empty input the function will cause "
598 "undefined behavior by evaluating data not in the input");
599 __unicode::__code_point_view<_CharT> __view{__begin, __end};
600 __unicode::__consume_result __consumed = __view.__consume();
601 if (__consumed.__status != __unicode::__consume_result::__ok)
602 std::__throw_format_error("The format specifier contains malformed Unicode characters");
603
604 if (__view.__position() < __end && __parse_alignment(*__view.__position())) {
605 ptrdiff_t __code_units = __view.__position() - __begin;
606 if (__code_units == 1)
607 // The forbidden fill characters all are code points encoded
608 // in one code unit, thus the check can be omitted when more
609 // code units are used.
610 __validate_fill_character(*__begin, __use_range_fill);
611
612 std::copy_n(__begin, __code_units, std::addressof(__fill_.__data[0]));
613 __begin += __code_units + 1;
614 return true;
615 }
616
617 if (!__parse_alignment(*__begin))
618 return false;
619
620 ++__begin;
621 return true;
622 }
623
624# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
625 template <contiguous_iterator _Iterator>
626 requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4)
627 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) {
628 _LIBCPP_ASSERT_UNCATEGORIZED(__begin != __end,
629 "when called with an empty input the function will cause "
630 "undefined behavior by evaluating data not in the input");
631 if (__begin + 1 != __end && __parse_alignment(*(__begin + 1))) {
632 if (!__unicode::__is_scalar_value(*__begin))
633 std::__throw_format_error("The fill option contains an invalid value");
634
635 __validate_fill_character(*__begin, __use_range_fill);
636
637 __fill_.__data[0] = *__begin;
638 __begin += 2;
639 return true;
640 }
641
642 if (!__parse_alignment(*__begin))
643 return false;
644
645 ++__begin;
646 return true;
647 }
648
649# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
650
651# else // _LIBCPP_HAS_NO_UNICODE
393652 // range-fill and tuple-fill are identical
394 _LIBCPP_HIDE_FROM_ABI constexpr bool
395 __parse_fill_align(const _CharT*& __begin, const _CharT* __end, bool __use_range_fill) {
396 _LIBCPP_ASSERT(__begin != __end, "when called with an empty input the function will cause "
397 "undefined behavior by evaluating data not in the input");
653 template <contiguous_iterator _Iterator>
654 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) {
655 _LIBCPP_ASSERT_UNCATEGORIZED(__begin != __end,
656 "when called with an empty input the function will cause "
657 "undefined behavior by evaluating data not in the input");
398658 if (__begin + 1 != __end) {
399659 if (__parse_alignment(*(__begin + 1))) {
400 if (__use_range_fill && (*__begin == _CharT('{') || *__begin == _CharT('}') || *__begin == _CharT(':')))
401 std::__throw_format_error("The format-spec range-fill field contains an invalid character");
402 else if (*__begin == _CharT('{') || *__begin == _CharT('}'))
403 std::__throw_format_error("The format-spec fill field contains an invalid character");
660 __validate_fill_character(*__begin, __use_range_fill);
404661
405 __fill_ = *__begin;
662 __fill_.__data[0] = *__begin;
406663 __begin += 2;
407664 return true;
408665 }
......@@ -415,7 +672,10 @@ private:
415672 return true;
416673 }
417674
418 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(const _CharT*& __begin) {
675# endif // _LIBCPP_HAS_NO_UNICODE
676
677 template <contiguous_iterator _Iterator>
678 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(_Iterator& __begin) {
419679 switch (*__begin) {
420680 case _CharT('-'):
421681 __sign_ = __sign::__minus;
......@@ -433,7 +693,8 @@ private:
433693 return true;
434694 }
435695
436 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alternate_form(const _CharT*& __begin) {
696 template <contiguous_iterator _Iterator>
697 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alternate_form(_Iterator& __begin) {
437698 if (*__begin != _CharT('#'))
438699 return false;
439700
......@@ -442,7 +703,8 @@ private:
442703 return true;
443704 }
444705
445 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_zero_padding(const _CharT*& __begin) {
706 template <contiguous_iterator _Iterator>
707 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_zero_padding(_Iterator& __begin) {
446708 if (*__begin != _CharT('0'))
447709 return false;
448710
......@@ -452,15 +714,16 @@ private:
452714 return true;
453715 }
454716
455 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(const _CharT*& __begin, const _CharT* __end, auto& __parse_ctx) {
717 template <contiguous_iterator _Iterator>
718 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(_Iterator& __begin, _Iterator __end, auto& __ctx) {
456719 if (*__begin == _CharT('0'))
457 std::__throw_format_error("A format-spec width field shouldn't have a leading zero");
720 std::__throw_format_error("The width option should not have a leading zero");
458721
459722 if (*__begin == _CharT('{')) {
460 __format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx);
723 __format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __ctx);
461724 __width_as_arg_ = true;
462725 __width_ = __r.__value;
463 __begin = __r.__ptr;
726 __begin = __r.__last;
464727 return true;
465728 }
466729
......@@ -469,40 +732,41 @@ private:
469732
470733 __format::__parse_number_result __r = __format::__parse_number(__begin, __end);
471734 __width_ = __r.__value;
472 _LIBCPP_ASSERT(__width_ != 0, "A zero value isn't allowed and should be impossible, "
473 "due to validations in this function");
474 __begin = __r.__ptr;
735 _LIBCPP_ASSERT_UNCATEGORIZED(__width_ != 0, "A zero value isn't allowed and should be impossible, "
736 "due to validations in this function");
737 __begin = __r.__last;
475738 return true;
476739 }
477740
478 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_precision(const _CharT*& __begin, const _CharT* __end,
479 auto& __parse_ctx) {
741 template <contiguous_iterator _Iterator>
742 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_precision(_Iterator& __begin, _Iterator __end, auto& __ctx) {
480743 if (*__begin != _CharT('.'))
481744 return false;
482745
483746 ++__begin;
484747 if (__begin == __end)
485 std::__throw_format_error("End of input while parsing format-spec precision");
748 std::__throw_format_error("End of input while parsing format specifier precision");
486749
487750 if (*__begin == _CharT('{')) {
488 __format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx);
751 __format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __ctx);
489752 __precision_as_arg_ = true;
490753 __precision_ = __arg_id.__value;
491 __begin = __arg_id.__ptr;
754 __begin = __arg_id.__last;
492755 return true;
493756 }
494757
495758 if (*__begin < _CharT('0') || *__begin > _CharT('9'))
496 std::__throw_format_error("The format-spec precision field doesn't contain a value or arg-id");
759 std::__throw_format_error("The precision option does not contain a value or an argument index");
497760
498761 __format::__parse_number_result __r = __format::__parse_number(__begin, __end);
499762 __precision_ = __r.__value;
500763 __precision_as_arg_ = false;
501 __begin = __r.__ptr;
764 __begin = __r.__last;
502765 return true;
503766 }
504767
505 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_locale_specific_form(const _CharT*& __begin) {
768 template <contiguous_iterator _Iterator>
769 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_locale_specific_form(_Iterator& __begin) {
506770 if (*__begin != _CharT('L'))
507771 return false;
508772
......@@ -511,7 +775,18 @@ private:
511775 return true;
512776 }
513777
514 _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin) {
778 template <contiguous_iterator _Iterator>
779 _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_clear_brackets(_Iterator& __begin) {
780 if (*__begin != _CharT('n'))
781 return false;
782
783 __clear_brackets_ = true;
784 ++__begin;
785 return true;
786 }
787
788 template <contiguous_iterator _Iterator>
789 _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(_Iterator& __begin) {
515790 // Determines the type. It does not validate whether the selected type is
516791 // valid. Most formatters have optional fields that are only allowed for
517792 // certain types. These parsers need to do validation after the type has
......@@ -561,7 +836,10 @@ private:
561836 __type_ = __type::__octal;
562837 break;
563838 case 'p':
564 __type_ = __type::__pointer;
839 __type_ = __type::__pointer_lower_case;
840 break;
841 case 'P':
842 __type_ = __type::__pointer_upper_case;
565843 break;
566844 case 's':
567845 __type_ = __type::__string;
......@@ -569,7 +847,7 @@ private:
569847 case 'x':
570848 __type_ = __type::__hexadecimal_lower_case;
571849 break;
572# if _LIBCPP_STD_VER > 20
850# if _LIBCPP_STD_VER >= 23
573851 case '?':
574852 __type_ = __type::__debug;
575853 break;
......@@ -611,36 +889,28 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_string(__format_spec
611889 break;
612890
613891 default:
614 std::__throw_format_error("The format-spec type has a type not supported for a string argument");
892 std::__throw_format_error("The type option contains an invalid value for a string formatting argument");
615893 }
616894}
617895
618896template <class _CharT>
619_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_bool_string(__parser<_CharT>& __parser) {
620 if (__parser.__sign_ != __sign::__default)
621 std::__throw_format_error("A sign field isn't allowed in this format-spec");
622
623 if (__parser.__alternate_form_)
624 std::__throw_format_error("An alternate form field isn't allowed in this format-spec");
625
626 if (__parser.__alignment_ == __alignment::__zero_padding)
627 std::__throw_format_error("A zero-padding field isn't allowed in this format-spec");
628
897_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_bool_string(__parser<_CharT>& __parser, const char* __id) {
898 __parser.__validate(__format_spec::__fields_bool, __id);
629899 if (__parser.__alignment_ == __alignment::__default)
630900 __parser.__alignment_ = __alignment::__left;
631901}
632902
633903template <class _CharT>
634_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_char(__parser<_CharT>& __parser) {
635 __format_spec::__process_display_type_bool_string(__parser);
904_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_char(__parser<_CharT>& __parser, const char* __id) {
905 __format_spec::__process_display_type_bool_string(__parser, __id);
636906}
637907
638908template <class _CharT>
639_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __parser) {
909_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __parser, const char* __id) {
640910 switch (__parser.__type_) {
641911 case __format_spec::__type::__default:
642912 case __format_spec::__type::__string:
643 __format_spec::__process_display_type_bool_string(__parser);
913 __format_spec::__process_display_type_bool_string(__parser, __id);
644914 break;
645915
646916 case __format_spec::__type::__binary_lower_case:
......@@ -652,17 +922,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __p
652922 break;
653923
654924 default:
655 std::__throw_format_error("The format-spec type has a type not supported for a bool argument");
925 __format_spec::__throw_invalid_type_format_error(__id);
656926 }
657927}
658928
659929template <class _CharT>
660_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __parser) {
930_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __parser, const char* __id) {
661931 switch (__parser.__type_) {
662932 case __format_spec::__type::__default:
663933 case __format_spec::__type::__char:
664934 case __format_spec::__type::__debug:
665 __format_spec::__process_display_type_char(__parser);
935 __format_spec::__process_display_type_char(__parser, __id);
666936 break;
667937
668938 case __format_spec::__type::__binary_lower_case:
......@@ -674,12 +944,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __p
674944 break;
675945
676946 default:
677 std::__throw_format_error("The format-spec type has a type not supported for a char argument");
947 __format_spec::__throw_invalid_type_format_error(__id);
678948 }
679949}
680950
681951template <class _CharT>
682_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& __parser) {
952_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& __parser, const char* __id) {
683953 switch (__parser.__type_) {
684954 case __format_spec::__type::__default:
685955 case __format_spec::__type::__binary_lower_case:
......@@ -691,16 +961,16 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>&
691961 break;
692962
693963 case __format_spec::__type::__char:
694 __format_spec::__process_display_type_char(__parser);
964 __format_spec::__process_display_type_char(__parser, __id);
695965 break;
696966
697967 default:
698 std::__throw_format_error("The format-spec type has a type not supported for an integer argument");
968 __format_spec::__throw_invalid_type_format_error(__id);
699969 }
700970}
701971
702972template <class _CharT>
703_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_CharT>& __parser) {
973_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_CharT>& __parser, const char* __id) {
704974 switch (__parser.__type_) {
705975 case __format_spec::__type::__default:
706976 case __format_spec::__type::__hexfloat_lower_case:
......@@ -719,33 +989,34 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_C
719989 break;
720990
721991 default:
722 std::__throw_format_error("The format-spec type has a type not supported for a floating-point argument");
992 __format_spec::__throw_invalid_type_format_error(__id);
723993 }
724994}
725995
726_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_pointer(__format_spec::__type __type) {
996_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_pointer(__format_spec::__type __type, const char* __id) {
727997 switch (__type) {
728998 case __format_spec::__type::__default:
729 case __format_spec::__type::__pointer:
999 case __format_spec::__type::__pointer_lower_case:
1000 case __format_spec::__type::__pointer_upper_case:
7301001 break;
7311002
7321003 default:
733 std::__throw_format_error("The format-spec type has a type not supported for a pointer argument");
1004 __format_spec::__throw_invalid_type_format_error(__id);
7341005 }
7351006}
7361007
737template <class _CharT>
1008template <contiguous_iterator _Iterator>
7381009struct __column_width_result {
7391010 /// The number of output columns.
7401011 size_t __width_;
7411012 /// One beyond the last code unit used in the estimation.
7421013 ///
7431014 /// This limits the original output to fit in the wanted number of columns.
744 const _CharT* __last_;
1015 _Iterator __last_;
7451016};
7461017
747template <class _CharT>
748__column_width_result(size_t, const _CharT*) -> __column_width_result<_CharT>;
1018template <contiguous_iterator _Iterator>
1019__column_width_result(size_t, _Iterator) -> __column_width_result<_Iterator>;
7491020
7501021/// Since a column width can be two it's possible that the requested column
7511022/// width can't be achieved. Depending on the intended usage the policy can be
......@@ -761,66 +1032,16 @@ enum class __column_width_rounding { __down, __up };
7611032# ifndef _LIBCPP_HAS_NO_UNICODE
7621033
7631034namespace __detail {
764
765/// Converts a code point to the column width.
766///
767/// The estimations are conforming to [format.string.general]/11
768///
769/// This version expects a value less than 0x1'0000, which is a 3-byte UTF-8
770/// character.
771_LIBCPP_HIDE_FROM_ABI constexpr int __column_width_3(uint32_t __c) noexcept {
772 _LIBCPP_ASSERT(__c < 0x10000, "Use __column_width_4 or __column_width for larger values");
773
774 // clang-format off
775 return 1 + (__c >= 0x1100 && (__c <= 0x115f ||
776 (__c >= 0x2329 && (__c <= 0x232a ||
777 (__c >= 0x2e80 && (__c <= 0x303e ||
778 (__c >= 0x3040 && (__c <= 0xa4cf ||
779 (__c >= 0xac00 && (__c <= 0xd7a3 ||
780 (__c >= 0xf900 && (__c <= 0xfaff ||
781 (__c >= 0xfe10 && (__c <= 0xfe19 ||
782 (__c >= 0xfe30 && (__c <= 0xfe6f ||
783 (__c >= 0xff00 && (__c <= 0xff60 ||
784 (__c >= 0xffe0 && (__c <= 0xffe6
785 ))))))))))))))))))));
786 // clang-format on
787}
788
789/// @overload
790///
791/// This version expects a value greater than or equal to 0x1'0000, which is a
792/// 4-byte UTF-8 character.
793_LIBCPP_HIDE_FROM_ABI constexpr int __column_width_4(uint32_t __c) noexcept {
794 _LIBCPP_ASSERT(__c >= 0x10000, "Use __column_width_3 or __column_width for smaller values");
795
796 // clang-format off
797 return 1 + (__c >= 0x1'f300 && (__c <= 0x1'f64f ||
798 (__c >= 0x1'f900 && (__c <= 0x1'f9ff ||
799 (__c >= 0x2'0000 && (__c <= 0x2'fffd ||
800 (__c >= 0x3'0000 && (__c <= 0x3'fffd
801 ))))))));
802 // clang-format on
803}
804
805/// @overload
806///
807/// The general case, accepting all values.
808_LIBCPP_HIDE_FROM_ABI constexpr int __column_width(uint32_t __c) noexcept {
809 if (__c < 0x10000)
810 return __detail::__column_width_3(__c);
811
812 return __detail::__column_width_4(__c);
813}
814
815template <class _CharT>
816_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width_grapheme_clustering(
817 const _CharT* __first, const _CharT* __last, size_t __maximum, __column_width_rounding __rounding) noexcept {
1035template <contiguous_iterator _Iterator>
1036_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_Iterator> __estimate_column_width_grapheme_clustering(
1037 _Iterator __first, _Iterator __last, size_t __maximum, __column_width_rounding __rounding) noexcept {
1038 using _CharT = iter_value_t<_Iterator>;
8181039 __unicode::__extended_grapheme_cluster_view<_CharT> __view{__first, __last};
8191040
820 __column_width_result<_CharT> __result{0, __first};
1041 __column_width_result<_Iterator> __result{0, __first};
8211042 while (__result.__last_ != __last && __result.__width_ <= __maximum) {
8221043 typename __unicode::__extended_grapheme_cluster_view<_CharT>::__cluster __cluster = __view.__consume();
823 int __width = __detail::__column_width(__cluster.__code_point_);
1044 int __width = __width_estimation_table::__estimated_width(__cluster.__code_point_);
8241045
8251046 // When the next entry would exceed the maximum width the previous width
8261047 // might be returned. For example when a width of 100 is requested the
......@@ -884,8 +1105,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __is_ascii(char32_t __c) { return __c < 0x8
8841105/// \param __rounding Selects the rounding method.
8851106/// \c __down result.__width_ <= __maximum
8861107/// \c __up result.__width_ <= __maximum + 1
887template <class _CharT>
888_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width(
1108template <class _CharT, class _Iterator = typename basic_string_view<_CharT>::const_iterator>
1109_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_Iterator> __estimate_column_width(
8891110 basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding __rounding) noexcept {
8901111 // The width estimation is done in two steps:
8911112 // - Quickly process for the ASCII part. ASCII has the following properties
......@@ -904,7 +1125,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_
9041125 // need to scan one code unit beyond the requested precision. When this code
9051126 // unit is non-ASCII we omit the current code unit and let the Grapheme
9061127 // clustering algorithm do its work.
907 const _CharT* __it = __str.begin();
1128 auto __it = __str.begin();
9081129 if (__format_spec::__is_ascii(*__it)) {
9091130 do {
9101131 --__maximum;
......@@ -932,7 +1153,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_
9321153}
9331154# else // !defined(_LIBCPP_HAS_NO_UNICODE)
9341155template <class _CharT>
935_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT>
1156_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<typename basic_string_view<_CharT>::const_iterator>
9361157__estimate_column_width(basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding) noexcept {
9371158 // When Unicode isn't supported assume ASCII and every code unit is one code
9381159 // point. In ASCII the estimated column width is always one. Thus there's no
......@@ -945,7 +1166,7 @@ __estimate_column_width(basic_string_view<_CharT> __str, size_t __maximum, __col
9451166
9461167} // namespace __format_spec
9471168
948#endif //_LIBCPP_STD_VER > 17
1169#endif //_LIBCPP_STD_VER >= 20
9491170
9501171_LIBCPP_END_NAMESPACE_STD
9511172
lib/libcxx/include/__format/range_default_formatter.h+52-33
......@@ -14,22 +14,25 @@
1414# pragma GCC system_header
1515#endif
1616
17#include <__availability>
17#include <__algorithm/ranges_copy.h>
1818#include <__chrono/statically_widen.h>
1919#include <__concepts/same_as.h>
2020#include <__config>
2121#include <__format/concepts.h>
2222#include <__format/formatter.h>
2323#include <__format/range_formatter.h>
24#include <__iterator/back_insert_iterator.h>
2425#include <__ranges/concepts.h>
26#include <__ranges/data.h>
27#include <__ranges/size.h>
28#include <__type_traits/conditional.h>
2529#include <__type_traits/remove_cvref.h>
2630#include <__utility/pair.h>
2731#include <string_view>
28#include <tuple>
2932
3033_LIBCPP_BEGIN_NAMESPACE_STD
3134
32#if _LIBCPP_STD_VER > 20
35#if _LIBCPP_STD_VER >= 23
3336
3437template <class _Rp, class _CharT>
3538concept __const_formattable_range =
......@@ -83,40 +86,23 @@ inline constexpr range_format format_kind<_Rp> = [] {
8386 return range_format::sequence;
8487}();
8588
86// This is a non-standard work-around to fix instantiation of
87// formatter<const _CharT[N], _CharT>
88// const _CharT[N] satisfies the ranges::input_range concept.
89// remove_cvref_t<const _CharT[N]> is _CharT[N] so it does not satisfy the
90// requirement of the above specialization. Instead it will instantiate the
91// primary template, which is ill-formed.
92//
93// An alternative solution is to remove the offending formatter.
94//
95// https://godbolt.org/z/bqjhhaexx
96//
97// The removal is proposed in LWG3833, but use the work-around until the issue
98// has been adopted.
99// TODO FMT Implement LWG3833.
100template <class _CharT, size_t N>
101inline constexpr range_format format_kind<const _CharT[N]> = range_format::disabled;
102
10389template <range_format _Kp, ranges::input_range _Rp, class _CharT>
104struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter;
90struct _LIBCPP_TEMPLATE_VIS __range_default_formatter;
10591
10692// Required specializations
10793
10894template <ranges::input_range _Rp, class _CharT>
109struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::sequence, _Rp, _CharT> {
95struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::sequence, _Rp, _CharT> {
11096private:
11197 using __maybe_const_r = __fmt_maybe_const<_Rp, _CharT>;
11298 range_formatter<remove_cvref_t<ranges::range_reference_t<__maybe_const_r>>, _CharT> __underlying_;
11399
114100public:
115 _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
101 _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept {
116102 __underlying_.set_separator(__separator);
117103 }
118104 _LIBCPP_HIDE_FROM_ABI constexpr void
119 set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
105 set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept {
120106 __underlying_.set_brackets(__opening_bracket, __closing_bracket);
121107 }
122108
......@@ -125,14 +111,15 @@ public:
125111 return __underlying_.parse(__ctx);
126112 }
127113
128 template <class FormatContext>
129 _LIBCPP_HIDE_FROM_ABI typename FormatContext::iterator format(__maybe_const_r& __range, FormatContext& __ctx) const {
114 template <class _FormatContext>
115 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
116 format(__maybe_const_r& __range, _FormatContext& __ctx) const {
130117 return __underlying_.format(__range, __ctx);
131118 }
132119};
133120
134121template <ranges::input_range _Rp, class _CharT>
135struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::map, _Rp, _CharT> {
122struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::map, _Rp, _CharT> {
136123private:
137124 using __maybe_const_map = __fmt_maybe_const<_Rp, _CharT>;
138125 using __element_type = remove_cvref_t<ranges::range_reference_t<__maybe_const_map>>;
......@@ -160,7 +147,7 @@ public:
160147};
161148
162149template <ranges::input_range _Rp, class _CharT>
163struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::set, _Rp, _CharT> {
150struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::set, _Rp, _CharT> {
164151private:
165152 using __maybe_const_set = __fmt_maybe_const<_Rp, _CharT>;
166153 using __element_type = remove_cvref_t<ranges::range_reference_t<__maybe_const_set>>;
......@@ -185,16 +172,48 @@ public:
185172
186173template <range_format _Kp, ranges::input_range _Rp, class _CharT>
187174 requires(_Kp == range_format::string || _Kp == range_format::debug_string)
188struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<_Kp, _Rp, _CharT> {
189 __range_default_formatter() = delete; // TODO FMT Implement
175struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<_Kp, _Rp, _CharT> {
176private:
177 // This deviates from the Standard, there the exposition only type is
178 // formatter<basic_string<charT>, charT> underlying_;
179 // Using a string_view allows the format function to avoid a copy of the
180 // input range when it is a contigious range.
181 formatter<basic_string_view<_CharT>, _CharT> __underlying_;
182
183public:
184 template <class _ParseContext>
185 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
186 typename _ParseContext::iterator __i = __underlying_.parse(__ctx);
187 if constexpr (_Kp == range_format::debug_string)
188 __underlying_.set_debug_format();
189 return __i;
190 }
191
192 template <class _FormatContext>
193 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
194 format(conditional_t<ranges::input_range<const _Rp>, const _Rp&, _Rp&> __range, _FormatContext& __ctx) const {
195 // When the range is contiguous use a basic_string_view instead to avoid a
196 // copy of the underlying data. The basic_string_view formatter
197 // specialization is the "basic" string formatter in libc++.
198 if constexpr (ranges::contiguous_range<_Rp> && std::ranges::sized_range<_Rp>)
199 return __underlying_.format(basic_string_view<_CharT>{ranges::data(__range), ranges::size(__range)}, __ctx);
200 else {
201 // P2106's from_range has not been implemented yet. Instead use a simple
202 // copy operation.
203 // TODO FMT use basic_string's "from_range" constructor.
204 // return __underlying_.format(basic_string<_CharT>{from_range, __range}, __ctx);
205 basic_string<_CharT> __str;
206 std::ranges::copy(__range, back_insert_iterator{__str});
207 return __underlying_.format(static_cast<basic_string_view<_CharT>>(__str), __ctx);
208 }
209 }
190210};
191211
192212template <ranges::input_range _Rp, class _CharT>
193213 requires(format_kind<_Rp> != range_format::disabled && formattable<ranges::range_reference_t<_Rp>, _CharT>)
194struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Rp, _CharT>
195 : __range_default_formatter<format_kind<_Rp>, _Rp, _CharT> {};
214struct _LIBCPP_TEMPLATE_VIS formatter<_Rp, _CharT> : __range_default_formatter<format_kind<_Rp>, _Rp, _CharT> {};
196215
197#endif //_LIBCPP_STD_VER > 20
216#endif //_LIBCPP_STD_VER >= 23
198217
199218_LIBCPP_END_NAMESPACE_STD
200219
lib/libcxx/include/__format/range_formatter.h+62-47
......@@ -15,13 +15,11 @@
1515#endif
1616
1717#include <__algorithm/ranges_copy.h>
18#include <__availability>
1918#include <__chrono/statically_widen.h>
2019#include <__concepts/same_as.h>
2120#include <__config>
2221#include <__format/buffer.h>
2322#include <__format/concepts.h>
24#include <__format/format_args.h>
2523#include <__format/format_context.h>
2624#include <__format/format_error.h>
2725#include <__format/formatter.h>
......@@ -36,54 +34,73 @@
3634
3735_LIBCPP_BEGIN_NAMESPACE_STD
3836
39#if _LIBCPP_STD_VER > 20
37#if _LIBCPP_STD_VER >= 23
4038
4139template <class _Tp, class _CharT = char>
4240 requires same_as<remove_cvref_t<_Tp>, _Tp> && formattable<_Tp, _CharT>
43struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter {
44 _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
41struct _LIBCPP_TEMPLATE_VIS range_formatter {
42 _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept {
4543 __separator_ = __separator;
4644 }
4745 _LIBCPP_HIDE_FROM_ABI constexpr void
48 set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
46 set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept {
4947 __opening_bracket_ = __opening_bracket;
5048 __closing_bracket_ = __closing_bracket;
5149 }
5250
53 _LIBCPP_HIDE_FROM_ABI constexpr formatter<_Tp, _CharT>& underlying() { return __underlying_; }
54 _LIBCPP_HIDE_FROM_ABI constexpr const formatter<_Tp, _CharT>& underlying() const { return __underlying_; }
51 _LIBCPP_HIDE_FROM_ABI constexpr formatter<_Tp, _CharT>& underlying() noexcept { return __underlying_; }
52 _LIBCPP_HIDE_FROM_ABI constexpr const formatter<_Tp, _CharT>& underlying() const noexcept { return __underlying_; }
5553
5654 template <class _ParseContext>
57 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) {
58 const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_range);
59 const _CharT* __end = __parse_ctx.end();
60 if (__begin == __end)
61 return __begin;
55 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
56 auto __begin = __parser_.__parse(__ctx, __format_spec::__fields_range);
57 auto __end = __ctx.end();
58 // Note the cases where __begin == __end in this code only happens when the
59 // replacement-field has no terminating }, or when the parse is manually
60 // called with a format-spec. The former is an error and the latter means
61 // using a formatter without the format functions or print.
62 if (__begin == __end) [[unlikely]]
63 return __parse_empty_range_underlying_spec(__ctx, __begin);
6264
6365 // The n field overrides a possible m type, therefore delay applying the
6466 // effect of n until the type has been procesed.
65 bool __clear_brackets = (*__begin == _CharT('n'));
66 if (__clear_brackets) {
67 ++__begin;
68 if (__begin == __end) {
69 // Since there is no more data, clear the brackets before returning.
70 set_brackets({}, {});
71 return __begin;
72 }
73 }
74
7567 __parse_type(__begin, __end);
76 if (__clear_brackets)
68 if (__parser_.__clear_brackets_)
7769 set_brackets({}, {});
78 if (__begin == __end)
79 return __begin;
70 if (__begin == __end) [[unlikely]]
71 return __parse_empty_range_underlying_spec(__ctx, __begin);
8072
8173 bool __has_range_underlying_spec = *__begin == _CharT(':');
74 if (__has_range_underlying_spec) {
75 // range-underlying-spec:
76 // : format-spec
77 ++__begin;
78 } else if (__begin != __end && *__begin != _CharT('}'))
79 // When there is no underlaying range the current parse should have
80 // consumed the format-spec. If not, the not consumed input will be
81 // processed by the underlying. For example {:-} for a range in invalid,
82 // the sign field is not present. Without this check the underlying_ will
83 // get -} as input which my be valid.
84 std::__throw_format_error("The format specifier should consume the input or end with a '}'");
85
86 __ctx.advance_to(__begin);
87 __begin = __underlying_.parse(__ctx);
88
89 // This test should not be required if __has_range_underlying_spec is false.
90 // However this test makes sure the underlying formatter left the parser in
91 // a valid state. (Note this is not a full protection against evil parsers.
92 // For example
93 // } this is test for the next argument {}
94 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
95 // could consume more than it should.
96 if (__begin != __end && *__begin != _CharT('}'))
97 std::__throw_format_error("The format specifier should consume the input or end with a '}'");
98
8299 if (__parser_.__type_ != __format_spec::__type::__default) {
83100 // [format.range.formatter]/6
84101 // If the range-type is s or ?s, then there shall be no n option and no
85102 // range-underlying-spec.
86 if (__clear_brackets) {
103 if (__parser_.__clear_brackets_) {
87104 if (__parser_.__type_ == __format_spec::__type::__string)
88105 std::__throw_format_error("The n option and type s can't be used together");
89106 std::__throw_format_error("The n option and type ?s can't be used together");
......@@ -96,20 +113,6 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter {
96113 } else if (!__has_range_underlying_spec)
97114 std::__set_debug_format(__underlying_);
98115
99 if (__has_range_underlying_spec) {
100 // range-underlying-spec:
101 // : format-spec
102 ++__begin;
103 if (__begin == __end)
104 return __begin;
105
106 __parse_ctx.advance_to(__begin);
107 __begin = __underlying_.parse(__parse_ctx);
108 }
109
110 if (__begin != __end && *__begin != _CharT('}'))
111 std::__throw_format_error("The format-spec should consume the input or end with a '}'");
112
113116 return __begin;
114117 }
115118
......@@ -211,7 +214,8 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter {
211214 __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left};
212215
213216private:
214 _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin, const _CharT* __end) {
217 template <contiguous_iterator _Iterator>
218 _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(_Iterator& __begin, _Iterator __end) {
215219 switch (*__begin) {
216220 case _CharT('m'):
217221 if constexpr (__fmt_pair_like<_Tp>) {
......@@ -219,7 +223,7 @@ private:
219223 set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ", "));
220224 ++__begin;
221225 } else
222 std::__throw_format_error("The range-format-spec type m requires two elements for a pair or tuple");
226 std::__throw_format_error("Type m requires a pair or a tuple with two elements");
223227 break;
224228
225229 case _CharT('s'):
......@@ -227,28 +231,39 @@ private:
227231 __parser_.__type_ = __format_spec::__type::__string;
228232 ++__begin;
229233 } else
230 std::__throw_format_error("The range-format-spec type s requires formatting a character type");
234 std::__throw_format_error("Type s requires character type as formatting argument");
231235 break;
232236
233237 case _CharT('?'):
234238 ++__begin;
235239 if (__begin == __end || *__begin != _CharT('s'))
236 std::__throw_format_error("The format-spec should consume the input or end with a '}'");
240 std::__throw_format_error("The format specifier should consume the input or end with a '}'");
237241 if constexpr (same_as<_Tp, _CharT>) {
238242 __parser_.__type_ = __format_spec::__type::__debug;
239243 ++__begin;
240244 } else
241 std::__throw_format_error("The range-format-spec type ?s requires formatting a character type");
245 std::__throw_format_error("Type ?s requires character type as formatting argument");
242246 }
243247 }
244248
249 template <class _ParseContext>
250 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator
251 __parse_empty_range_underlying_spec(_ParseContext& __ctx, typename _ParseContext::iterator __begin) {
252 __ctx.advance_to(__begin);
253 [[maybe_unused]] typename _ParseContext::iterator __result = __underlying_.parse(__ctx);
254 _LIBCPP_ASSERT_UNCATEGORIZED(
255 __result == __begin,
256 "the underlying's parse function should not advance the input beyond the end of the input");
257 return __begin;
258 }
259
245260 formatter<_Tp, _CharT> __underlying_;
246261 basic_string_view<_CharT> __separator_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ", ");
247262 basic_string_view<_CharT> __opening_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "[");
248263 basic_string_view<_CharT> __closing_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "]");
249264};
250265
251#endif //_LIBCPP_STD_VER > 20
266#endif //_LIBCPP_STD_VER >= 23
252267
253268_LIBCPP_END_NAMESPACE_STD
254269
lib/libcxx/include/__format/unicode.h+186-194
......@@ -11,11 +11,13 @@
1111#define _LIBCPP___FORMAT_UNICODE_H
1212
1313#include <__assert>
14#include <__bit/countl.h>
15#include <__concepts/same_as.h>
1416#include <__config>
1517#include <__format/extended_grapheme_cluster_table.h>
16#include <__type_traits/make_unsigned.h>
17#include <__utility/unreachable.h>
18#include <bit>
18#include <__iterator/concepts.h>
19#include <__iterator/readable_traits.h> // iter_value_t
20#include <string_view>
1921
2022#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2123# pragma GCC system_header
......@@ -23,27 +25,32 @@
2325
2426_LIBCPP_BEGIN_NAMESPACE_STD
2527
26#if _LIBCPP_STD_VER > 17
28#if _LIBCPP_STD_VER >= 20
2729
2830namespace __unicode {
2931
30# if _LIBCPP_STD_VER > 20
31
32/// The result of consuming a code point using P2286' semantics
33///
34/// TODO FMT Combine __consume and __consume_p2286 in one function.
35struct __consume_p2286_result {
36 // A size of 0 means well formed. This to differenciate between
37 // a valid code point and a code unit that's invalid like 0b11111xxx.
38 int __ill_formed_size;
39
40 // If well formed the consumed code point.
41 // Otherwise the ill-formed code units as unsigned 8-bit values. They are
42 // stored in reverse order, to make it easier to extract the values.
43 char32_t __value;
32// Helper struct for the result of a consume operation.
33//
34// The status value for a correct code point is 0. This allows a valid value to
35// be used without masking.
36// When the decoding fails it know the number of code units affected. For the
37// current use-cases that value is not needed, therefore it is not stored.
38// The escape routine needs the number of code units for both a valid and
39// invalid character and keeps track of it itself. Doing it in this result
40// unconditionally would give some overhead when the value is unneeded.
41struct __consume_result {
42 // When __status == __ok it contains the decoded code point.
43 // Else it contains the replacement character U+FFFD
44 char32_t __code_point : 31;
45
46 enum : char32_t {
47 // Consumed a well-formed code point.
48 __ok = 0,
49 // Encountered invalid UTF-8
50 __error = 1
51 } __status : 1 {__ok};
4452};
45
46# endif // _LIBCPP_STD_VER > 20
53static_assert(sizeof(__consume_result) == sizeof(char32_t));
4754
4855# ifndef _LIBCPP_HAS_NO_UNICODE
4956
......@@ -62,9 +69,41 @@ struct __consume_p2286_result {
6269
6370inline constexpr char32_t __replacement_character = U'\ufffd';
6471
65_LIBCPP_HIDE_FROM_ABI constexpr bool __is_continuation(const char* __char, int __count) {
72// The error of a consume operation.
73//
74// This sets the code point to the replacement character. This code point does
75// not participate in the grapheme clustering, so grapheme clustering code can
76// ignore the error status and always use the code point.
77inline constexpr __consume_result __consume_result_error{__replacement_character, __consume_result::__error};
78
79[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool __is_high_surrogate(char32_t __value) {
80 return __value >= 0xd800 && __value <= 0xdbff;
81}
82
83[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool __is_low_surrogate(char32_t __value) {
84 return __value >= 0xdc00 && __value <= 0xdfff;
85}
86
87// https://www.unicode.org/glossary/#surrogate_code_point
88[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool __is_surrogate(char32_t __value) {
89 return __value >= 0xd800 && __value <= 0xdfff;
90}
91
92// https://www.unicode.org/glossary/#code_point
93[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool __is_code_point(char32_t __value) {
94 return __value <= 0x10ffff;
95}
96
97// https://www.unicode.org/glossary/#unicode_scalar_value
98[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool __is_scalar_value(char32_t __value) {
99 return __unicode::__is_code_point(__value) && !__unicode::__is_surrogate(__value);
100}
101
102template <contiguous_iterator _Iterator>
103 requires same_as<iter_value_t<_Iterator>, char>
104_LIBCPP_HIDE_FROM_ABI constexpr bool __is_continuation(_Iterator __char, int __count) {
66105 do {
67 if ((*__char & 0b1000'0000) != 0b1000'0000)
106 if ((*__char & 0b1100'0000) != 0b1000'0000)
68107 return false;
69108 --__count;
70109 ++__char;
......@@ -82,133 +121,116 @@ class __code_point_view;
82121/// UTF-8 specialization.
83122template <>
84123class __code_point_view<char> {
124 using _Iterator = basic_string_view<char>::const_iterator;
125
85126public:
86 _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const char* __first, const char* __last)
127 _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
87128 : __first_(__first), __last_(__last) {}
88129
89130 _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; }
90 _LIBCPP_HIDE_FROM_ABI constexpr const char* __position() const noexcept { return __first_; }
131 _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; }
91132
92 _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept {
93 _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
133 // https://www.unicode.org/versions/latest/ch03.pdf#G7404
134 // Based on Table 3-7, Well-Formed UTF-8 Byte Sequences
135 //
136 // Code Points First Byte Second Byte Third Byte Fourth Byte Remarks
137 // U+0000..U+007F 00..7F U+0000..U+007F 1 code unit range
138 // C0..C1 80..BF invalid overlong encoding
139 // U+0080..U+07FF C2..DF 80..BF U+0080..U+07FF 2 code unit range
140 // E0 80..9F 80..BF invalid overlong encoding
141 // U+0800..U+0FFF E0 A0..BF 80..BF U+0800..U+FFFF 3 code unit range
142 // U+1000..U+CFFF E1..EC 80..BF 80..BF
143 // U+D000..U+D7FF ED 80..9F 80..BF
144 // U+D800..U+DFFF ED A0..BF 80..BF invalid encoding of surrogate code point
145 // U+E000..U+FFFF EE..EF 80..BF 80..BF
146 // F0 80..8F 80..BF 80..BF invalid overlong encoding
147 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF U+10000..U+10FFFF 4 code unit range
148 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
149 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
150 // F4 90..BF 80..BF 80..BF U+110000.. invalid code point range
151 //
152 // Unlike other parsers, these invalid entries are tested after decoding.
153 // - The parser always needs to consume these code units
154 // - The code is optimized for well-formed UTF-8
155 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept {
156 _LIBCPP_ASSERT_UNCATEGORIZED(__first_ != __last_, "can't move beyond the end of input");
94157
95158 // Based on the number of leading 1 bits the number of code units in the
96159 // code point can be determined. See
97160 // https://en.wikipedia.org/wiki/UTF-8#Encoding
98 switch (_VSTD::countl_one(static_cast<unsigned char>(*__first_))) {
161 switch (std::countl_one(static_cast<unsigned char>(*__first_))) {
99162 case 0:
100 return *__first_++;
163 return {static_cast<unsigned char>(*__first_++)};
101164
102 case 2:
165 case 2: {
103166 if (__last_ - __first_ < 2 || !__unicode::__is_continuation(__first_ + 1, 1)) [[unlikely]]
104167 break;
105 else {
106 char32_t __value = static_cast<unsigned char>(*__first_++) & 0x1f;
107 __value <<= 6;
108 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
109 return __value;
110 }
111168
112 case 3:
113 if (__last_ - __first_ < 3 || !__unicode::__is_continuation(__first_ + 1, 2)) [[unlikely]]
114 break;
115 else {
116 char32_t __value = static_cast<unsigned char>(*__first_++) & 0x0f;
117 __value <<= 6;
118 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
119 __value <<= 6;
120 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
121 return __value;
122 }
169 char32_t __value = static_cast<unsigned char>(*__first_++) & 0x1f;
170 __value <<= 6;
171 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
123172
124 case 4:
125 if (__last_ - __first_ < 4 || !__unicode::__is_continuation(__first_ + 1, 3)) [[unlikely]]
126 break;
127 else {
128 char32_t __value = static_cast<unsigned char>(*__first_++) & 0x07;
129 __value <<= 6;
130 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
131 __value <<= 6;
132 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
133 __value <<= 6;
134 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
135 return __value;
136 }
137 }
138 // An invalid number of leading ones can be garbage or a code unit in the
139 // middle of a code point. By consuming one code unit the parser may get
140 // "in sync" after a few code units.
141 ++__first_;
142 return __replacement_character;
143 }
144
145# if _LIBCPP_STD_VER > 20
146 _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept {
147 _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
173 // These values should be encoded in 1 UTF-8 code unit.
174 if (__value < 0x0080) [[unlikely]]
175 return __consume_result_error;
148176
149 // Based on the number of leading 1 bits the number of code units in the
150 // code point can be determined. See
151 // https://en.wikipedia.org/wiki/UTF-8#Encoding
152 switch (std::countl_one(static_cast<unsigned char>(*__first_))) {
153 case 0:
154 return {0, static_cast<unsigned char>(*__first_++)};
177 return {__value};
178 }
155179
156 case 2:
157 if (__last_ - __first_ < 2) [[unlikely]]
180 case 3: {
181 if (__last_ - __first_ < 3 || !__unicode::__is_continuation(__first_ + 1, 2)) [[unlikely]]
158182 break;
159183
160 if (__unicode::__is_continuation(__first_ + 1, 1)) {
161 char32_t __value = static_cast<unsigned char>(*__first_++) & 0x1f;
162 __value <<= 6;
163 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
164 return {0, __value};
165 }
166 break;
184 char32_t __value = static_cast<unsigned char>(*__first_++) & 0x0f;
185 __value <<= 6;
186 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
187 __value <<= 6;
188 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
167189
168 case 3:
169 if (__last_ - __first_ < 3) [[unlikely]]
170 break;
190 // These values should be encoded in 1 or 2 UTF-8 code units.
191 if (__value < 0x0800) [[unlikely]]
192 return __consume_result_error;
171193
172 if (__unicode::__is_continuation(__first_ + 1, 2)) {
173 char32_t __value = static_cast<unsigned char>(*__first_++) & 0x0f;
174 __value <<= 6;
175 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
176 __value <<= 6;
177 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
178 return {0, __value};
179 }
180 break;
194 // A surrogate value is always encoded in 3 UTF-8 code units.
195 if (__unicode::__is_surrogate(__value)) [[unlikely]]
196 return __consume_result_error;
197
198 return {__value};
199 }
181200
182 case 4:
183 if (__last_ - __first_ < 4) [[unlikely]]
201 case 4: {
202 if (__last_ - __first_ < 4 || !__unicode::__is_continuation(__first_ + 1, 3)) [[unlikely]]
184203 break;
185204
186 if (__unicode::__is_continuation(__first_ + 1, 3)) {
187 char32_t __value = static_cast<unsigned char>(*__first_++) & 0x07;
188 __value <<= 6;
189 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
190 __value <<= 6;
191 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
192 __value <<= 6;
193 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
205 char32_t __value = static_cast<unsigned char>(*__first_++) & 0x07;
206 __value <<= 6;
207 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
208 __value <<= 6;
209 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
210 __value <<= 6;
211 __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
194212
195 if (__value > 0x10FFFF) // Outside the valid Unicode range?
196 return {4, __value};
213 // These values should be encoded in 1, 2, or 3 UTF-8 code units.
214 if (__value < 0x10000) [[unlikely]]
215 return __consume_result_error;
197216
198 return {0, __value};
199 }
200 break;
217 // A value too large is always encoded in 4 UTF-8 code units.
218 if (!__unicode::__is_code_point(__value)) [[unlikely]]
219 return __consume_result_error;
220
221 return {__value};
222 }
201223 }
202224 // An invalid number of leading ones can be garbage or a code unit in the
203225 // middle of a code point. By consuming one code unit the parser may get
204226 // "in sync" after a few code units.
205 return {1, static_cast<unsigned char>(*__first_++)};
227 ++__first_;
228 return __consume_result_error;
206229 }
207# endif // _LIBCPP_STD_VER > 20
208230
209231private:
210 const char* __first_;
211 const char* __last_;
232 _Iterator __first_;
233 _Iterator __last_;
212234};
213235
214236# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
......@@ -225,75 +247,48 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __is_surrogate_pair_low(wchar_t __value) {
225247/// - 4 UTF-32 (for example Linux)
226248template <>
227249class __code_point_view<wchar_t> {
250 using _Iterator = typename basic_string_view<wchar_t>::const_iterator;
251
228252public:
229253 static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "sizeof(wchar_t) has a not implemented value");
230254
231 _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const wchar_t* __first, const wchar_t* __last)
255 _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
232256 : __first_(__first), __last_(__last) {}
233257
234 _LIBCPP_HIDE_FROM_ABI constexpr const wchar_t* __position() const noexcept { return __first_; }
258 _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; }
235259 _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; }
236260
237 _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept {
238 _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
261 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept {
262 _LIBCPP_ASSERT_UNCATEGORIZED(__first_ != __last_, "can't move beyond the end of input");
239263
264 char32_t __value = static_cast<char32_t>(*__first_++);
240265 if constexpr (sizeof(wchar_t) == 2) {
241 char32_t __result = *__first_++;
242 // Is the code unit part of a surrogate pair? See
243 // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF
244 if (__result >= 0xd800 && __result <= 0xDfff) {
245 // Malformed Unicode.
246 if (__first_ == __last_) [[unlikely]]
247 return __replacement_character;
248
249 __result -= 0xd800;
250 __result <<= 10;
251 __result += *__first_++ - 0xdc00;
252 __result += 0x10000;
253 }
254 return __result;
266 if (__unicode::__is_low_surrogate(__value)) [[unlikely]]
267 return __consume_result_error;
255268
256 } else if constexpr (sizeof(wchar_t) == 4) {
257 char32_t __result = *__first_++;
258 if (__result > 0x10FFFF) [[unlikely]]
259 return __replacement_character;
260 return __result;
261 } else {
262 __libcpp_unreachable();
263 }
264 }
269 if (__unicode::__is_high_surrogate(__value)) {
270 if (__first_ == __last_ || !__unicode::__is_low_surrogate(static_cast<char32_t>(*__first_))) [[unlikely]]
271 return __consume_result_error;
265272
266# if _LIBCPP_STD_VER > 20
267 _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept {
268 _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
273 __value -= 0xd800;
274 __value <<= 10;
275 __value += static_cast<char32_t>(*__first_++) - 0xdc00;
276 __value += 0x10000;
269277
270 char32_t __result = *__first_++;
271 if constexpr (sizeof(wchar_t) == 2) {
272 // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF
273 if (__is_surrogate_pair_high(__result)) {
274 // Malformed Unicode.
275 if (__first_ == __last_ || !__is_surrogate_pair_low(*(__first_ + 1))) [[unlikely]]
276 return {1, __result};
277
278 __result -= 0xd800;
279 __result <<= 10;
280 __result += *__first_++ - 0xdc00;
281 __result += 0x10000;
282 } else if (__is_surrogate_pair_low(__result))
283 // A code point shouldn't start with the low surrogate pair
284 return {1, __result};
278 if (!__unicode::__is_code_point(__value)) [[unlikely]]
279 return __consume_result_error;
280 }
285281 } else {
286 if (__result > 0x10FFFF) [[unlikely]]
287 return {1, __result};
282 if (!__unicode::__is_scalar_value(__value)) [[unlikely]]
283 return __consume_result_error;
288284 }
289285
290 return {0, __result};
286 return {__value};
291287 }
292# endif // _LIBCPP_STD_VER > 20
293288
294289private:
295 const wchar_t* __first_;
296 const wchar_t* __last_;
290 _Iterator __first_;
291 _Iterator __last_;
297292};
298293# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
299294
......@@ -310,8 +305,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __at_extended_grapheme_cluster_break(
310305
311306 // *** Break at the start and end of text, unless the text is empty. ***
312307
313 _LIBCPP_ASSERT(__prev != __property::__sot, "should be handled in the constructor"); // GB1
314 _LIBCPP_ASSERT(__prev != __property::__eot, "should be handled by our caller"); // GB2
308 _LIBCPP_ASSERT_UNCATEGORIZED(__prev != __property::__sot, "should be handled in the constructor"); // GB1
309 _LIBCPP_ASSERT_UNCATEGORIZED(__prev != __property::__eot, "should be handled by our caller"); // GB2
315310
316311 // *** Do not break between a CR and LF. Otherwise, break before and after controls. ***
317312 if (__prev == __property::__CR && __next == __property::__LF) // GB3
......@@ -384,10 +379,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __at_extended_grapheme_cluster_break(
384379/// Therefore only this code point is extracted.
385380template <class _CharT>
386381class __extended_grapheme_cluster_view {
382 using _Iterator = typename basic_string_view<_CharT>::const_iterator;
383
387384public:
388 _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(const _CharT* __first, const _CharT* __last)
385 _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(_Iterator __first, _Iterator __last)
389386 : __code_point_view_(__first, __last),
390 __next_code_point_(__code_point_view_.__consume()),
387 __next_code_point_(__code_point_view_.__consume().__code_point),
391388 __next_prop_(__extended_grapheme_custer_property_boundary::__get_property(__next_code_point_)) {}
392389
393390 struct __cluster {
......@@ -401,13 +398,14 @@ public:
401398 ///
402399 /// It's expected the caller has the start position and thus can determine
403400 /// the code unit range of the extended grapheme cluster.
404 const _CharT* __last_;
401 _Iterator __last_;
405402 };
406403
407404 _LIBCPP_HIDE_FROM_ABI constexpr __cluster __consume() {
408 _LIBCPP_ASSERT(
405 _LIBCPP_ASSERT_UNCATEGORIZED(
409406 __next_prop_ != __extended_grapheme_custer_property_boundary::__property::__eot,
410407 "can't move beyond the end of input");
408
411409 char32_t __code_point = __next_code_point_;
412410 if (!__code_point_view_.__at_end())
413411 return {__code_point, __get_break()};
......@@ -422,17 +420,17 @@ private:
422420 char32_t __next_code_point_;
423421 __extended_grapheme_custer_property_boundary::__property __next_prop_;
424422
425 _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __get_break() {
423 _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __get_break() {
426424 bool __ri_break_allowed = true;
427425 bool __has_extened_pictographic = false;
428426 while (true) {
429 const _CharT* __result = __code_point_view_.__position();
427 _Iterator __result = __code_point_view_.__position();
430428 __extended_grapheme_custer_property_boundary::__property __prev = __next_prop_;
431429 if (__code_point_view_.__at_end()) {
432430 __next_prop_ = __extended_grapheme_custer_property_boundary::__property::__eot;
433431 return __result;
434432 }
435 __next_code_point_ = __code_point_view_.__consume();
433 __next_code_point_ = __code_point_view_.__consume().__code_point;
436434 __next_prop_ = __extended_grapheme_custer_property_boundary::__get_property(__next_code_point_);
437435
438436 __has_extened_pictographic |=
......@@ -444,8 +442,8 @@ private:
444442 }
445443};
446444
447template <class _CharT>
448__extended_grapheme_cluster_view(const _CharT*, const _CharT*) -> __extended_grapheme_cluster_view<_CharT>;
445template <contiguous_iterator _Iterator>
446__extended_grapheme_cluster_view(_Iterator, _Iterator) -> __extended_grapheme_cluster_view<iter_value_t<_Iterator>>;
449447
450448# else // _LIBCPP_HAS_NO_UNICODE
451449
......@@ -453,36 +451,30 @@ __extended_grapheme_cluster_view(const _CharT*, const _CharT*) -> __extended_gra
453451// This makes it easier to write code agnostic of the _LIBCPP_HAS_NO_UNICODE define.
454452template <class _CharT>
455453class __code_point_view {
454 using _Iterator = typename basic_string_view<_CharT>::const_iterator;
455
456456public:
457 _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const _CharT* __first, const _CharT* __last)
457 _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
458458 : __first_(__first), __last_(__last) {}
459459
460460 _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; }
461 _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __position() const noexcept { return __first_; }
462
463 _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept {
464 _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
465 return *__first_++;
466 }
467
468# if _LIBCPP_STD_VER > 20
469 _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept {
470 _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
461 _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; }
471462
472 return {0, std::make_unsigned_t<_CharT>(*__first_++)};
463 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept {
464 _LIBCPP_ASSERT_UNCATEGORIZED(__first_ != __last_, "can't move beyond the end of input");
465 return {static_cast<char32_t>(*__first_++)};
473466 }
474# endif // _LIBCPP_STD_VER > 20
475467
476468private:
477 const _CharT* __first_;
478 const _CharT* __last_;
469 _Iterator __first_;
470 _Iterator __last_;
479471};
480472
481473# endif // _LIBCPP_HAS_NO_UNICODE
482474
483475} // namespace __unicode
484476
485#endif //_LIBCPP_STD_VER > 17
477#endif //_LIBCPP_STD_VER >= 20
486478
487479_LIBCPP_END_NAMESPACE_STD
488480
lib/libcxx/include/__format/width_estimation_table.h created+271
......@@ -0,0 +1,271 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10// WARNING, this entire header is generated by
11// utils/generate_width_estimation_table.py
12// DO NOT MODIFY!
13
14// UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
15//
16// See Terms of Use <https://www.unicode.org/copyright.html>
17// for definitions of Unicode Inc.'s Data Files and Software.
18//
19// NOTICE TO USER: Carefully read the following legal agreement.
20// BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S
21// DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"),
22// YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
23// TERMS AND CONDITIONS OF THIS AGREEMENT.
24// IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE
25// THE DATA FILES OR SOFTWARE.
26//
27// COPYRIGHT AND PERMISSION NOTICE
28//
29// Copyright (c) 1991-2022 Unicode, Inc. All rights reserved.
30// Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
31//
32// Permission is hereby granted, free of charge, to any person obtaining
33// a copy of the Unicode data files and any associated documentation
34// (the "Data Files") or Unicode software and any associated documentation
35// (the "Software") to deal in the Data Files or Software
36// without restriction, including without limitation the rights to use,
37// copy, modify, merge, publish, distribute, and/or sell copies of
38// the Data Files or Software, and to permit persons to whom the Data Files
39// or Software are furnished to do so, provided that either
40// (a) this copyright and permission notice appear with all copies
41// of the Data Files or Software, or
42// (b) this copyright and permission notice appear in associated
43// Documentation.
44//
45// THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
46// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
47// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
48// NONINFRINGEMENT OF THIRD PARTY RIGHTS.
49// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
50// NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
51// DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
52// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
53// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
54// PERFORMANCE OF THE DATA FILES OR SOFTWARE.
55//
56// Except as contained in this notice, the name of a copyright holder
57// shall not be used in advertising or otherwise to promote the sale,
58// use or other dealings in these Data Files or Software without prior
59// written authorization of the copyright holder.
60
61#ifndef _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H
62#define _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H
63
64#include <__algorithm/ranges_upper_bound.h>
65#include <__config>
66#include <cstddef>
67#include <cstdint>
68
69#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
70# pragma GCC system_header
71#endif
72
73_LIBCPP_BEGIN_NAMESPACE_STD
74
75#if _LIBCPP_STD_VER >= 20
76
77namespace __width_estimation_table {
78
79/// The entries of the characters with an estimated width of 2.
80///
81/// Contains the entries for [format.string.std]/12
82/// - Any code point with the East_Asian_Width="W" or East_Asian_Width="F"
83/// Derived Extracted Property as described by UAX #44
84/// - U+4DC0 - U+4DFF (Yijing Hexagram Symbols)
85/// - U+1F300 - U+1F5FF (Miscellaneous Symbols and Pictographs)
86/// - U+1F900 - U+1F9FF (Supplemental Symbols and Pictographs)
87///
88/// The data is generated from
89/// - https://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt
90/// - The "overrides" in [format.string.std]/12
91///
92/// The format of EastAsianWidth.txt is two fields separated by a semicolon.
93/// Field 0: Unicode code point value or range of code point values
94/// Field 1: East_Asian_Width property, consisting of one of the following values:
95/// "A", "F", "H", "N", "Na", "W"
96/// - All code points, assigned or unassigned, that are not listed
97/// explicitly are given the value "N".
98/// - The unassigned code points in the following blocks default to "W":
99/// CJK Unified Ideographs Extension A: U+3400..U+4DBF
100/// CJK Unified Ideographs: U+4E00..U+9FFF
101/// CJK Compatibility Ideographs: U+F900..U+FAFF
102/// - All undesignated code points in Planes 2 and 3, whether inside or
103/// outside of allocated blocks, default to "W":
104/// Plane 2: U+20000..U+2FFFD
105/// Plane 3: U+30000..U+3FFFD
106///
107/// The table is similar to the table
108/// __extended_grapheme_custer_property_boundary::__entries
109/// which explains the details of these classes. The only difference is this
110/// table lacks a property, thus having more bits available for the size.
111///
112/// The maximum code point that has an estimated width of 2 is U+3FFFD. This
113/// value can be encoded in 18 bits. Thus the upper 3 bits of the code point
114/// are always 0. These 3 bits are used to enlarge the offset range. This
115/// optimization reduces the table in Unicode 15 from 184 to 104 entries,
116/// saving 320 bytes.
117///
118/// The data has 2 values:
119/// - bits [0, 13] The size of the range, allowing 16384 elements.
120/// - bits [14, 31] The lower bound code point of the range. The upper bound of
121/// the range is lower bound + size.
122inline constexpr uint32_t __entries[108] = {
123 0x0440005f /* 00001100 - 0000115f [ 96] */, //
124 0x08c68001 /* 0000231a - 0000231b [ 2] */, //
125 0x08ca4001 /* 00002329 - 0000232a [ 2] */, //
126 0x08fa4003 /* 000023e9 - 000023ec [ 4] */, //
127 0x08fc0000 /* 000023f0 - 000023f0 [ 1] */, //
128 0x08fcc000 /* 000023f3 - 000023f3 [ 1] */, //
129 0x097f4001 /* 000025fd - 000025fe [ 2] */, //
130 0x09850001 /* 00002614 - 00002615 [ 2] */, //
131 0x0992000b /* 00002648 - 00002653 [ 12] */, //
132 0x099fc000 /* 0000267f - 0000267f [ 1] */, //
133 0x09a4c000 /* 00002693 - 00002693 [ 1] */, //
134 0x09a84000 /* 000026a1 - 000026a1 [ 1] */, //
135 0x09aa8001 /* 000026aa - 000026ab [ 2] */, //
136 0x09af4001 /* 000026bd - 000026be [ 2] */, //
137 0x09b10001 /* 000026c4 - 000026c5 [ 2] */, //
138 0x09b38000 /* 000026ce - 000026ce [ 1] */, //
139 0x09b50000 /* 000026d4 - 000026d4 [ 1] */, //
140 0x09ba8000 /* 000026ea - 000026ea [ 1] */, //
141 0x09bc8001 /* 000026f2 - 000026f3 [ 2] */, //
142 0x09bd4000 /* 000026f5 - 000026f5 [ 1] */, //
143 0x09be8000 /* 000026fa - 000026fa [ 1] */, //
144 0x09bf4000 /* 000026fd - 000026fd [ 1] */, //
145 0x09c14000 /* 00002705 - 00002705 [ 1] */, //
146 0x09c28001 /* 0000270a - 0000270b [ 2] */, //
147 0x09ca0000 /* 00002728 - 00002728 [ 1] */, //
148 0x09d30000 /* 0000274c - 0000274c [ 1] */, //
149 0x09d38000 /* 0000274e - 0000274e [ 1] */, //
150 0x09d4c002 /* 00002753 - 00002755 [ 3] */, //
151 0x09d5c000 /* 00002757 - 00002757 [ 1] */, //
152 0x09e54002 /* 00002795 - 00002797 [ 3] */, //
153 0x09ec0000 /* 000027b0 - 000027b0 [ 1] */, //
154 0x09efc000 /* 000027bf - 000027bf [ 1] */, //
155 0x0ac6c001 /* 00002b1b - 00002b1c [ 2] */, //
156 0x0ad40000 /* 00002b50 - 00002b50 [ 1] */, //
157 0x0ad54000 /* 00002b55 - 00002b55 [ 1] */, //
158 0x0ba00019 /* 00002e80 - 00002e99 [ 26] */, //
159 0x0ba6c058 /* 00002e9b - 00002ef3 [ 89] */, //
160 0x0bc000d5 /* 00002f00 - 00002fd5 [ 214] */, //
161 0x0bfc000b /* 00002ff0 - 00002ffb [ 12] */, //
162 0x0c00003e /* 00003000 - 0000303e [ 63] */, //
163 0x0c104055 /* 00003041 - 00003096 [ 86] */, //
164 0x0c264066 /* 00003099 - 000030ff [ 103] */, //
165 0x0c41402a /* 00003105 - 0000312f [ 43] */, //
166 0x0c4c405d /* 00003131 - 0000318e [ 94] */, //
167 0x0c640053 /* 00003190 - 000031e3 [ 84] */, //
168 0x0c7c002e /* 000031f0 - 0000321e [ 47] */, //
169 0x0c880027 /* 00003220 - 00003247 [ 40] */, //
170 0x0c943fff /* 00003250 - 0000724f [16384] */, //
171 0x1c94323c /* 00007250 - 0000a48c [12861] */, //
172 0x29240036 /* 0000a490 - 0000a4c6 [ 55] */, //
173 0x2a58001c /* 0000a960 - 0000a97c [ 29] */, //
174 0x2b002ba3 /* 0000ac00 - 0000d7a3 [11172] */, //
175 0x3e4001ff /* 0000f900 - 0000faff [ 512] */, //
176 0x3f840009 /* 0000fe10 - 0000fe19 [ 10] */, //
177 0x3f8c0022 /* 0000fe30 - 0000fe52 [ 35] */, //
178 0x3f950012 /* 0000fe54 - 0000fe66 [ 19] */, //
179 0x3f9a0003 /* 0000fe68 - 0000fe6b [ 4] */, //
180 0x3fc0405f /* 0000ff01 - 0000ff60 [ 96] */, //
181 0x3ff80006 /* 0000ffe0 - 0000ffe6 [ 7] */, //
182 0x5bf80004 /* 00016fe0 - 00016fe4 [ 5] */, //
183 0x5bfc0001 /* 00016ff0 - 00016ff1 [ 2] */, //
184 0x5c0017f7 /* 00017000 - 000187f7 [ 6136] */, //
185 0x620004d5 /* 00018800 - 00018cd5 [ 1238] */, //
186 0x63400008 /* 00018d00 - 00018d08 [ 9] */, //
187 0x6bfc0003 /* 0001aff0 - 0001aff3 [ 4] */, //
188 0x6bfd4006 /* 0001aff5 - 0001affb [ 7] */, //
189 0x6bff4001 /* 0001affd - 0001affe [ 2] */, //
190 0x6c000122 /* 0001b000 - 0001b122 [ 291] */, //
191 0x6c4c8000 /* 0001b132 - 0001b132 [ 1] */, //
192 0x6c540002 /* 0001b150 - 0001b152 [ 3] */, //
193 0x6c554000 /* 0001b155 - 0001b155 [ 1] */, //
194 0x6c590003 /* 0001b164 - 0001b167 [ 4] */, //
195 0x6c5c018b /* 0001b170 - 0001b2fb [ 396] */, //
196 0x7c010000 /* 0001f004 - 0001f004 [ 1] */, //
197 0x7c33c000 /* 0001f0cf - 0001f0cf [ 1] */, //
198 0x7c638000 /* 0001f18e - 0001f18e [ 1] */, //
199 0x7c644009 /* 0001f191 - 0001f19a [ 10] */, //
200 0x7c800002 /* 0001f200 - 0001f202 [ 3] */, //
201 0x7c84002b /* 0001f210 - 0001f23b [ 44] */, //
202 0x7c900008 /* 0001f240 - 0001f248 [ 9] */, //
203 0x7c940001 /* 0001f250 - 0001f251 [ 2] */, //
204 0x7c980005 /* 0001f260 - 0001f265 [ 6] */, //
205 0x7cc0034f /* 0001f300 - 0001f64f [ 848] */, //
206 0x7da00045 /* 0001f680 - 0001f6c5 [ 70] */, //
207 0x7db30000 /* 0001f6cc - 0001f6cc [ 1] */, //
208 0x7db40002 /* 0001f6d0 - 0001f6d2 [ 3] */, //
209 0x7db54002 /* 0001f6d5 - 0001f6d7 [ 3] */, //
210 0x7db70003 /* 0001f6dc - 0001f6df [ 4] */, //
211 0x7dbac001 /* 0001f6eb - 0001f6ec [ 2] */, //
212 0x7dbd0008 /* 0001f6f4 - 0001f6fc [ 9] */, //
213 0x7df8000b /* 0001f7e0 - 0001f7eb [ 12] */, //
214 0x7dfc0000 /* 0001f7f0 - 0001f7f0 [ 1] */, //
215 0x7e4000ff /* 0001f900 - 0001f9ff [ 256] */, //
216 0x7e9c000c /* 0001fa70 - 0001fa7c [ 13] */, //
217 0x7ea00008 /* 0001fa80 - 0001fa88 [ 9] */, //
218 0x7ea4002d /* 0001fa90 - 0001fabd [ 46] */, //
219 0x7eafc006 /* 0001fabf - 0001fac5 [ 7] */, //
220 0x7eb3800d /* 0001face - 0001fadb [ 14] */, //
221 0x7eb80008 /* 0001fae0 - 0001fae8 [ 9] */, //
222 0x7ebc0008 /* 0001faf0 - 0001faf8 [ 9] */, //
223 0x80003fff /* 00020000 - 00023fff [16384] */, //
224 0x90003fff /* 00024000 - 00027fff [16384] */, //
225 0xa0003fff /* 00028000 - 0002bfff [16384] */, //
226 0xb0003ffd /* 0002c000 - 0002fffd [16382] */, //
227 0xc0003fff /* 00030000 - 00033fff [16384] */, //
228 0xd0003fff /* 00034000 - 00037fff [16384] */, //
229 0xe0003fff /* 00038000 - 0003bfff [16384] */, //
230 0xf0003ffd /* 0003c000 - 0003fffd [16382] */};
231
232/// The upper bound entry of EastAsianWidth.txt.
233///
234/// Values greater than this value may have more than 18 significant bits.
235/// They always have a width of 1. This property makes it possible to store
236/// the table in its compact form.
237inline constexpr uint32_t __table_upper_bound = 0x0003fffd;
238
239/// Returns the estimated width of a Unicode code point.
240///
241/// \pre The code point is a valid Unicode code point.
242[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int __estimated_width(const char32_t __code_point) noexcept {
243 // Since __table_upper_bound contains the unshifted range do the
244 // comparison without shifting.
245 if (__code_point > __table_upper_bound) [[unlikely]]
246 return 1;
247
248 // When the code-point is less than the first element in the table
249 // the lookup is quite expensive. Since quite some scripts are in
250 // that range, it makes sense to validate that first.
251 // The std_format_spec_string_unicode benchmark gives a measurable
252 // improvement.
253 if (__code_point < (__entries[0] >> 14))
254 return 1;
255
256 ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 14) | 0x3fffu) - __entries;
257 if (__i == 0)
258 return 1;
259
260 --__i;
261 uint32_t __upper_bound = (__entries[__i] >> 14) + (__entries[__i] & 0x3fffu);
262 return 1 + (__code_point <= __upper_bound);
263}
264
265} // namespace __width_estimation_table
266
267#endif //_LIBCPP_STD_VER >= 20
268
269_LIBCPP_END_NAMESPACE_STD
270
271#endif // _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H
lib/libcxx/include/__format/write_escaped.h created+222
......@@ -0,0 +1,222 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FORMAT_WRITE_ESCAPED_H
11#define _LIBCPP___FORMAT_WRITE_ESCAPED_H
12
13#include <__algorithm/ranges_copy.h>
14#include <__algorithm/ranges_for_each.h>
15#include <__charconv/to_chars_integral.h>
16#include <__charconv/to_chars_result.h>
17#include <__chrono/statically_widen.h>
18#include <__format/escaped_output_table.h>
19#include <__format/formatter_output.h>
20#include <__format/parser_std_format_spec.h>
21#include <__format/unicode.h>
22#include <__iterator/back_insert_iterator.h>
23#include <__memory/addressof.h>
24#include <__system_error/errc.h>
25#include <__type_traits/make_unsigned.h>
26#include <__utility/move.h>
27#include <string_view>
28
29#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
30# pragma GCC system_header
31#endif
32
33_LIBCPP_BEGIN_NAMESPACE_STD
34
35
36namespace __formatter {
37
38#if _LIBCPP_STD_VER >= 20
39
40/// Writes a string using format's width estimation algorithm.
41///
42/// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the
43/// input is ASCII.
44template <class _CharT>
45_LIBCPP_HIDE_FROM_ABI auto __write_string(
46 basic_string_view<_CharT> __str,
47 output_iterator<const _CharT&> auto __out_it,
48 __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
49 if (!__specs.__has_precision())
50 return __formatter::__write_string_no_precision(__str, _VSTD::move(__out_it), __specs);
51
52 int __size = __formatter::__truncate(__str, __specs.__precision_);
53
54 return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size);
55}
56
57# endif // _LIBCPP_STD_VER >= 20
58# if _LIBCPP_STD_VER >= 23
59
60struct __nul_terminator {};
61
62template <class _CharT>
63_LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __cstr, __nul_terminator) {
64 return *__cstr == _CharT('\0');
65}
66
67template <class _CharT>
68_LIBCPP_HIDE_FROM_ABI void
69__write_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value, const _CharT* __prefix) {
70 back_insert_iterator __out_it{__str};
71 std::ranges::copy(__prefix, __nul_terminator{}, __out_it);
72
73 char __buffer[8];
74 to_chars_result __r = std::to_chars(std::begin(__buffer), std::end(__buffer), __value, 16);
75 _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small");
76 std::ranges::copy(std::begin(__buffer), __r.ptr, __out_it);
77
78 __str += _CharT('}');
79}
80
81// [format.string.escaped]/2.2.1.2
82// ...
83// then the sequence \u{hex-digit-sequence} is appended to E, where
84// hex-digit-sequence is the shortest hexadecimal representation of C using
85// lower-case hexadecimal digits.
86template <class _CharT>
87_LIBCPP_HIDE_FROM_ABI void __write_well_formed_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value) {
88 __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\u{"));
89}
90
91// [format.string.escaped]/2.2.3
92// Otherwise (X is a sequence of ill-formed code units), each code unit U is
93// appended to E in order as the sequence \x{hex-digit-sequence}, where
94// hex-digit-sequence is the shortest hexadecimal representation of U using
95// lower-case hexadecimal digits.
96template <class _CharT>
97_LIBCPP_HIDE_FROM_ABI void __write_escape_ill_formed_code_unit(basic_string<_CharT>& __str, char32_t __value) {
98 __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\x{"));
99}
100
101template <class _CharT>
102[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool __is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value) {
103# ifdef _LIBCPP_HAS_NO_UNICODE
104 // For ASCII assume everything above 127 is printable.
105 if (__value > 127)
106 return false;
107# endif
108
109 if (!__escaped_output_table::__needs_escape(__value))
110 return false;
111
112 __formatter::__write_well_formed_escaped_code_unit(__str, __value);
113 return true;
114}
115
116template <class _CharT>
117[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr char32_t __to_char32(_CharT __value) {
118 return static_cast<make_unsigned_t<_CharT>>(__value);
119}
120
121enum class _LIBCPP_ENUM_VIS __escape_quotation_mark { __apostrophe, __double_quote };
122
123// [format.string.escaped]/2
124template <class _CharT>
125[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
126__is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value, __escape_quotation_mark __mark) {
127 // 2.2.1.1 - Mapped character in [tab:format.escape.sequences]
128 switch (__value) {
129 case _CharT('\t'):
130 __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\t");
131 return true;
132 case _CharT('\n'):
133 __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\n");
134 return true;
135 case _CharT('\r'):
136 __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\r");
137 return true;
138 case _CharT('\''):
139 if (__mark == __escape_quotation_mark::__apostrophe)
140 __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\')");
141 else
142 __str += __value;
143 return true;
144 case _CharT('"'):
145 if (__mark == __escape_quotation_mark::__double_quote)
146 __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\")");
147 else
148 __str += __value;
149 return true;
150 case _CharT('\\'):
151 __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\\)");
152 return true;
153
154 // 2.2.1.2 - Space
155 case _CharT(' '):
156 __str += __value;
157 return true;
158 }
159
160 // 2.2.2
161 // Otherwise, if X is a shift sequence, the effect on E and further
162 // decoding of S is unspecified.
163 // For now shift sequences are ignored and treated as Unicode. Other parts
164 // of the format library do the same. It's unknown how ostream treats them.
165 // TODO FMT determine what to do with shift sequences.
166
167 // 2.2.1.2.1 and 2.2.1.2.2 - Escape
168 return __formatter::__is_escaped_sequence_written(__str, __formatter::__to_char32(__value));
169}
170
171template <class _CharT>
172_LIBCPP_HIDE_FROM_ABI void
173__escape(basic_string<_CharT>& __str, basic_string_view<_CharT> __values, __escape_quotation_mark __mark) {
174 __unicode::__code_point_view<_CharT> __view{__values.begin(), __values.end()};
175
176 while (!__view.__at_end()) {
177 auto __first = __view.__position();
178 typename __unicode::__consume_result __result = __view.__consume();
179 if (__result.__status == __unicode::__consume_result::__ok) {
180 if (!__formatter::__is_escaped_sequence_written(__str, __result.__code_point, __mark))
181 // 2.2.1.3 - Add the character
182 ranges::copy(__first, __view.__position(), std::back_insert_iterator(__str));
183 } else {
184 // 2.2.3 sequence of ill-formed code units
185 ranges::for_each(__first, __view.__position(), [&](_CharT __value) {
186 __formatter::__write_escape_ill_formed_code_unit(__str, __formatter::__to_char32(__value));
187 });
188 }
189 }
190}
191
192template <class _CharT>
193_LIBCPP_HIDE_FROM_ABI auto
194__format_escaped_char(_CharT __value,
195 output_iterator<const _CharT&> auto __out_it,
196 __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
197 basic_string<_CharT> __str;
198 __str += _CharT('\'');
199 __formatter::__escape(__str, basic_string_view{std::addressof(__value), 1}, __escape_quotation_mark::__apostrophe);
200 __str += _CharT('\'');
201 return __formatter::__write(__str.data(), __str.data() + __str.size(), _VSTD::move(__out_it), __specs, __str.size());
202}
203
204template <class _CharT>
205_LIBCPP_HIDE_FROM_ABI auto
206__format_escaped_string(basic_string_view<_CharT> __values,
207 output_iterator<const _CharT&> auto __out_it,
208 __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
209 basic_string<_CharT> __str;
210 __str += _CharT('"');
211 __formatter::__escape(__str, __values, __escape_quotation_mark::__double_quote);
212 __str += _CharT('"');
213 return __formatter::__write_string(basic_string_view{__str}, _VSTD::move(__out_it), __specs);
214}
215
216# endif // _LIBCPP_STD_VER >= 23
217
218} // namespace __formatter
219
220_LIBCPP_END_NAMESPACE_STD
221
222#endif // _LIBCPP___FORMAT_WRITE_ESCAPED_H
lib/libcxx/include/__functional/bind.h+36-39
......@@ -13,9 +13,11 @@
1313#include <__config>
1414#include <__functional/invoke.h>
1515#include <__functional/weak_result_type.h>
16#include <__type_traits/decay.h>
17#include <__type_traits/is_reference_wrapper.h>
18#include <__type_traits/is_void.h>
1619#include <cstddef>
1720#include <tuple>
18#include <type_traits>
1921
2022#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2123# pragma GCC system_header
......@@ -30,9 +32,9 @@ struct is_bind_expression : _If<
3032 is_bind_expression<__remove_cvref_t<_Tp> >
3133> {};
3234
33#if _LIBCPP_STD_VER > 14
35#if _LIBCPP_STD_VER >= 17
3436template <class _Tp>
35inline constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value;
37inline constexpr bool is_bind_expression_v = is_bind_expression<_Tp>::value;
3638#endif
3739
3840template<class _Tp>
......@@ -42,9 +44,9 @@ struct is_placeholder : _If<
4244 is_placeholder<__remove_cvref_t<_Tp> >
4345> {};
4446
45#if _LIBCPP_STD_VER > 14
47#if _LIBCPP_STD_VER >= 17
4648template <class _Tp>
47inline constexpr size_t is_placeholder_v = is_placeholder<_Tp>::value;
49inline constexpr int is_placeholder_v = is_placeholder<_Tp>::value;
4850#endif
4951
5052namespace placeholders
......@@ -52,29 +54,24 @@ namespace placeholders
5254
5355template <int _Np> struct __ph {};
5456
55#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
56_LIBCPP_FUNC_VIS extern const __ph<1> _1;
57_LIBCPP_FUNC_VIS extern const __ph<2> _2;
58_LIBCPP_FUNC_VIS extern const __ph<3> _3;
59_LIBCPP_FUNC_VIS extern const __ph<4> _4;
60_LIBCPP_FUNC_VIS extern const __ph<5> _5;
61_LIBCPP_FUNC_VIS extern const __ph<6> _6;
62_LIBCPP_FUNC_VIS extern const __ph<7> _7;
63_LIBCPP_FUNC_VIS extern const __ph<8> _8;
64_LIBCPP_FUNC_VIS extern const __ph<9> _9;
65_LIBCPP_FUNC_VIS extern const __ph<10> _10;
66#else
67/* inline */ constexpr __ph<1> _1{};
68/* inline */ constexpr __ph<2> _2{};
69/* inline */ constexpr __ph<3> _3{};
70/* inline */ constexpr __ph<4> _4{};
71/* inline */ constexpr __ph<5> _5{};
72/* inline */ constexpr __ph<6> _6{};
73/* inline */ constexpr __ph<7> _7{};
74/* inline */ constexpr __ph<8> _8{};
75/* inline */ constexpr __ph<9> _9{};
76/* inline */ constexpr __ph<10> _10{};
77#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
57// C++17 recommends that we implement placeholders as `inline constexpr`, but allows
58// implementing them as `extern <implementation-defined>`. Libc++ implements them as
59// `extern const` in all standard modes to avoid an ABI break in C++03: making them
60// `inline constexpr` requires removing their definition in the shared library to
61// avoid ODR violations, which is an ABI break.
62//
63// In practice, since placeholders are empty, `extern const` is almost impossible
64// to distinguish from `inline constexpr` from a usage stand point.
65_LIBCPP_EXPORTED_FROM_ABI extern const __ph<1> _1;
66_LIBCPP_EXPORTED_FROM_ABI extern const __ph<2> _2;
67_LIBCPP_EXPORTED_FROM_ABI extern const __ph<3> _3;
68_LIBCPP_EXPORTED_FROM_ABI extern const __ph<4> _4;
69_LIBCPP_EXPORTED_FROM_ABI extern const __ph<5> _5;
70_LIBCPP_EXPORTED_FROM_ABI extern const __ph<6> _6;
71_LIBCPP_EXPORTED_FROM_ABI extern const __ph<7> _7;
72_LIBCPP_EXPORTED_FROM_ABI extern const __ph<8> _8;
73_LIBCPP_EXPORTED_FROM_ABI extern const __ph<9> _9;
74_LIBCPP_EXPORTED_FROM_ABI extern const __ph<10> _10;
7875
7976} // namespace placeholders
8077
......@@ -86,7 +83,7 @@ struct is_placeholder<placeholders::__ph<_Np> >
8683#ifndef _LIBCPP_CXX03_LANG
8784
8885template <class _Tp, class _Uj>
89inline _LIBCPP_INLINE_VISIBILITY
86inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
9087_Tp&
9188__mu(reference_wrapper<_Tp> __t, _Uj&)
9289{
......@@ -94,7 +91,7 @@ __mu(reference_wrapper<_Tp> __t, _Uj&)
9491}
9592
9693template <class _Ti, class ..._Uj, size_t ..._Indx>
97inline _LIBCPP_INLINE_VISIBILITY
94inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
9895typename __invoke_of<_Ti&, _Uj...>::type
9996__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>)
10097{
......@@ -102,7 +99,7 @@ __mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>)
10299}
103100
104101template <class _Ti, class ..._Uj>
105inline _LIBCPP_INLINE_VISIBILITY
102inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
106103typename __enable_if_t
107104<
108105 is_bind_expression<_Ti>::value,
......@@ -124,7 +121,7 @@ struct __mu_return2<true, _Ti, _Uj>
124121};
125122
126123template <class _Ti, class _Uj>
127inline _LIBCPP_INLINE_VISIBILITY
124inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
128125typename enable_if
129126<
130127 0 < is_placeholder<_Ti>::value,
......@@ -132,12 +129,12 @@ typename enable_if
132129>::type
133130__mu(_Ti&, _Uj& __uj)
134131{
135 const size_t _Indx = is_placeholder<_Ti>::value - 1;
136 return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj));
132 const size_t __indx = is_placeholder<_Ti>::value - 1;
133 return _VSTD::forward<typename tuple_element<__indx, _Uj>::type>(_VSTD::get<__indx>(__uj));
137134}
138135
139136template <class _Ti, class _Uj>
140inline _LIBCPP_INLINE_VISIBILITY
137inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
141138typename enable_if
142139<
143140 !is_bind_expression<_Ti>::value &&
......@@ -255,7 +252,7 @@ struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true>
255252};
256253
257254template <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>
258inline _LIBCPP_INLINE_VISIBILITY
255inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
259256typename __bind_return<_Fp, _BoundArgs, _Args>::type
260257__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
261258 _Args&& __args)
......@@ -264,11 +261,11 @@ __apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
264261}
265262
266263template<class _Fp, class ..._BoundArgs>
267class __bind : public __weak_result_type<typename decay<_Fp>::type>
264class __bind : public __weak_result_type<__decay_t<_Fp> >
268265{
269266protected:
270 typedef typename decay<_Fp>::type _Fd;
271 typedef tuple<typename decay<_BoundArgs>::type...> _Td;
267 using _Fd = __decay_t<_Fp>;
268 typedef tuple<__decay_t<_BoundArgs>...> _Td;
272269private:
273270 _Fd __f_;
274271 _Td __bound_args_;
lib/libcxx/include/__functional/bind_back.h+3-3
......@@ -13,10 +13,10 @@
1313#include <__config>
1414#include <__functional/invoke.h>
1515#include <__functional/perfect_forward.h>
16#include <__type_traits/decay.h>
1617#include <__utility/forward.h>
1718#include <__utility/integer_sequence.h>
1819#include <tuple>
19#include <type_traits>
2020
2121#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2222# pragma GCC system_header
......@@ -24,7 +24,7 @@
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929template <size_t _NBound, class = make_index_sequence<_NBound>>
3030struct __bind_back_op;
......@@ -57,7 +57,7 @@ constexpr auto __bind_back(_Fn&& __f, _Args&&... __args)
5757 -> decltype( __bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)))
5858 { return __bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); }
5959
60#endif // _LIBCPP_STD_VER > 17
60#endif // _LIBCPP_STD_VER >= 20
6161
6262_LIBCPP_END_NAMESPACE_STD
6363
lib/libcxx/include/__functional/bind_front.h+7-3
......@@ -13,8 +13,12 @@
1313#include <__config>
1414#include <__functional/invoke.h>
1515#include <__functional/perfect_forward.h>
16#include <__type_traits/conjunction.h>
17#include <__type_traits/decay.h>
18#include <__type_traits/enable_if.h>
19#include <__type_traits/is_constructible.h>
20#include <__type_traits/is_move_constructible.h>
1621#include <__utility/forward.h>
17#include <type_traits>
1822
1923#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2024# pragma GCC system_header
......@@ -22,7 +26,7 @@
2226
2327_LIBCPP_BEGIN_NAMESPACE_STD
2428
25#if _LIBCPP_STD_VER > 17
29#if _LIBCPP_STD_VER >= 20
2630
2731struct __bind_front_op {
2832 template <class ..._Args>
......@@ -51,7 +55,7 @@ constexpr auto bind_front(_Fn&& __f, _Args&&... __args) {
5155 return __bind_front_t<decay_t<_Fn>, decay_t<_Args>...>(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
5256}
5357
54#endif // _LIBCPP_STD_VER > 17
58#endif // _LIBCPP_STD_VER >= 20
5559
5660_LIBCPP_END_NAMESPACE_STD
5761
lib/libcxx/include/__functional/binder1st.h+14-14
......@@ -21,30 +21,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121
2222#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
2323
24template <class __Operation>
24template <class _Operation>
2525class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st
26 : public __unary_function<typename __Operation::second_argument_type, typename __Operation::result_type>
26 : public __unary_function<typename _Operation::second_argument_type, typename _Operation::result_type>
2727{
2828protected:
29 __Operation op;
30 typename __Operation::first_argument_type value;
29 _Operation op;
30 typename _Operation::first_argument_type value;
3131public:
32 _LIBCPP_INLINE_VISIBILITY binder1st(const __Operation& __x,
33 const typename __Operation::first_argument_type __y)
32 _LIBCPP_INLINE_VISIBILITY binder1st(const _Operation& __x,
33 const typename _Operation::first_argument_type __y)
3434 : op(__x), value(__y) {}
35 _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
36 (typename __Operation::second_argument_type& __x) const
35 _LIBCPP_INLINE_VISIBILITY typename _Operation::result_type operator()
36 (typename _Operation::second_argument_type& __x) const
3737 {return op(value, __x);}
38 _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
39 (const typename __Operation::second_argument_type& __x) const
38 _LIBCPP_INLINE_VISIBILITY typename _Operation::result_type operator()
39 (const typename _Operation::second_argument_type& __x) const
4040 {return op(value, __x);}
4141};
4242
43template <class __Operation, class _Tp>
43template <class _Operation, class _Tp>
4444_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
45binder1st<__Operation>
46bind1st(const __Operation& __op, const _Tp& __x)
47 {return binder1st<__Operation>(__op, __x);}
45binder1st<_Operation>
46bind1st(const _Operation& __op, const _Tp& __x)
47 {return binder1st<_Operation>(__op, __x);}
4848
4949#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
5050
lib/libcxx/include/__functional/binder2nd.h+13-13
......@@ -21,30 +21,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121
2222#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
2323
24template <class __Operation>
24template <class _Operation>
2525class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd
26 : public __unary_function<typename __Operation::first_argument_type, typename __Operation::result_type>
26 : public __unary_function<typename _Operation::first_argument_type, typename _Operation::result_type>
2727{
2828protected:
29 __Operation op;
30 typename __Operation::second_argument_type value;
29 _Operation op;
30 typename _Operation::second_argument_type value;
3131public:
3232 _LIBCPP_INLINE_VISIBILITY
33 binder2nd(const __Operation& __x, const typename __Operation::second_argument_type __y)
33 binder2nd(const _Operation& __x, const typename _Operation::second_argument_type __y)
3434 : op(__x), value(__y) {}
35 _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
36 ( typename __Operation::first_argument_type& __x) const
35 _LIBCPP_INLINE_VISIBILITY typename _Operation::result_type operator()
36 ( typename _Operation::first_argument_type& __x) const
3737 {return op(__x, value);}
38 _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
39 (const typename __Operation::first_argument_type& __x) const
38 _LIBCPP_INLINE_VISIBILITY typename _Operation::result_type operator()
39 (const typename _Operation::first_argument_type& __x) const
4040 {return op(__x, value);}
4141};
4242
43template <class __Operation, class _Tp>
43template <class _Operation, class _Tp>
4444_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
45binder2nd<__Operation>
46bind2nd(const __Operation& __op, const _Tp& __x)
47 {return binder2nd<__Operation>(__op, __x);}
45binder2nd<_Operation>
46bind2nd(const _Operation& __op, const _Tp& __x)
47 {return binder2nd<_Operation>(__op, __x);}
4848
4949#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
5050
lib/libcxx/include/__functional/boyer_moore_searcher.h+13-8
......@@ -20,12 +20,13 @@
2020#include <__iterator/distance.h>
2121#include <__iterator/iterator_traits.h>
2222#include <__memory/shared_ptr.h>
23#include <__type_traits/make_unsigned.h>
2324#include <__utility/pair.h>
2425#include <array>
2526#include <unordered_map>
2627#include <vector>
2728
28#if _LIBCPP_STD_VER > 14
29#if _LIBCPP_STD_VER >= 17
2930
3031_LIBCPP_PUSH_MACROS
3132#include <__undef_macros>
......@@ -113,6 +114,7 @@ private:
113114 && is_same_v<_BinaryPredicate, equal_to<>>>;
114115
115116public:
117 _LIBCPP_HIDE_FROM_ABI
116118 boyer_moore_searcher(_RandomAccessIterator1 __first,
117119 _RandomAccessIterator1 __last,
118120 _Hash __hash = _Hash(),
......@@ -134,7 +136,7 @@ public:
134136 }
135137
136138 template <class _RandomAccessIterator2>
137 pair<_RandomAccessIterator2, _RandomAccessIterator2>
139 _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2>
138140 operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const {
139141 static_assert(__is_same_uncvref<typename iterator_traits<_RandomAccessIterator1>::value_type,
140142 typename iterator_traits<_RandomAccessIterator2>::value_type>::value,
......@@ -158,7 +160,7 @@ private:
158160 shared_ptr<difference_type[]> __suffix_;
159161
160162 template <class _RandomAccessIterator2>
161 pair<_RandomAccessIterator2, _RandomAccessIterator2>
163 _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2>
162164 __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const {
163165 _RandomAccessIterator2 __current = __f;
164166 const _RandomAccessIterator2 __last = __l - __pattern_length_;
......@@ -183,7 +185,8 @@ private:
183185 }
184186
185187 template <class _Iterator, class _Container>
186 void __compute_bm_prefix(_Iterator __first, _Iterator __last, _BinaryPredicate __pred, _Container& __prefix) {
188 _LIBCPP_HIDE_FROM_ABI void
189 __compute_bm_prefix(_Iterator __first, _Iterator __last, _BinaryPredicate __pred, _Container& __prefix) {
187190 const size_t __count = __last - __first;
188191
189192 __prefix[0] = 0;
......@@ -199,7 +202,8 @@ private:
199202 }
200203 }
201204
202 void __build_suffix_table(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _BinaryPredicate __pred) {
205 _LIBCPP_HIDE_FROM_ABI void
206 __build_suffix_table(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _BinaryPredicate __pred) {
203207 const size_t __count = __last - __first;
204208
205209 if (__count == 0)
......@@ -241,6 +245,7 @@ private:
241245 && is_same_v<_Hash, hash<value_type>>
242246 && is_same_v<_BinaryPredicate, equal_to<>>>;
243247public:
248 _LIBCPP_HIDE_FROM_ABI
244249 boyer_moore_horspool_searcher(_RandomAccessIterator1 __first,
245250 _RandomAccessIterator1 __last,
246251 _Hash __hash = _Hash(),
......@@ -262,7 +267,7 @@ public:
262267 }
263268
264269 template <class _RandomAccessIterator2>
265 pair<_RandomAccessIterator2, _RandomAccessIterator2>
270 _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2>
266271 operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const {
267272 static_assert(__is_same_uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type,
268273 typename std::iterator_traits<_RandomAccessIterator2>::value_type>::value,
......@@ -286,7 +291,7 @@ private:
286291 shared_ptr<__skip_table_type> __skip_table_;
287292
288293 template <class _RandomAccessIterator2>
289 pair<_RandomAccessIterator2, _RandomAccessIterator2>
294 _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2>
290295 __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const {
291296 _RandomAccessIterator2 __current = __f;
292297 const _RandomAccessIterator2 __last = __l - __pattern_length_;
......@@ -310,6 +315,6 @@ _LIBCPP_END_NAMESPACE_STD
310315
311316_LIBCPP_POP_MACROS
312317
313#endif // _LIBCPP_STD_VER > 14
318#endif // _LIBCPP_STD_VER >= 17
314319
315320#endif // _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H
lib/libcxx/include/__functional/compose.h+3-3
......@@ -13,8 +13,8 @@
1313#include <__config>
1414#include <__functional/invoke.h>
1515#include <__functional/perfect_forward.h>
16#include <__type_traits/decay.h>
1617#include <__utility/forward.h>
17#include <type_traits>
1818
1919#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2020# pragma GCC system_header
......@@ -22,7 +22,7 @@
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727struct __compose_op {
2828 template<class _Fn1, class _Fn2, class ..._Args>
......@@ -45,7 +45,7 @@ constexpr auto __compose(_Fn1&& __f1, _Fn2&& __f2)
4545 -> decltype( __compose_t<decay_t<_Fn1>, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)))
4646 { return __compose_t<decay_t<_Fn1>, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)); }
4747
48#endif // _LIBCPP_STD_VER > 17
48#endif // _LIBCPP_STD_VER >= 20
4949
5050_LIBCPP_END_NAMESPACE_STD
5151
lib/libcxx/include/__functional/default_searcher.h+2-2
......@@ -23,7 +23,7 @@
2323
2424_LIBCPP_BEGIN_NAMESPACE_STD
2525
26#if _LIBCPP_STD_VER > 14
26#if _LIBCPP_STD_VER >= 17
2727
2828// default searcher
2929template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
......@@ -50,7 +50,7 @@ private:
5050};
5151_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(default_searcher);
5252
53#endif // _LIBCPP_STD_VER > 14
53#endif // _LIBCPP_STD_VER >= 17
5454
5555_LIBCPP_END_NAMESPACE_STD
5656
lib/libcxx/include/__functional/function.h+67-51
......@@ -12,6 +12,7 @@
1212
1313#include <__assert>
1414#include <__config>
15#include <__exception/exception.h>
1516#include <__functional/binary_function.h>
1617#include <__functional/invoke.h>
1718#include <__functional/unary_function.h>
......@@ -23,15 +24,21 @@
2324#include <__memory/builtin_new_allocator.h>
2425#include <__memory/compressed_pair.h>
2526#include <__memory/unique_ptr.h>
27#include <__type_traits/aligned_storage.h>
28#include <__type_traits/decay.h>
29#include <__type_traits/is_core_convertible.h>
30#include <__type_traits/is_scalar.h>
31#include <__type_traits/is_trivially_copy_constructible.h>
32#include <__type_traits/is_trivially_destructible.h>
33#include <__type_traits/is_void.h>
2634#include <__type_traits/strip_signature.h>
2735#include <__utility/forward.h>
2836#include <__utility/move.h>
2937#include <__utility/piecewise_construct.h>
3038#include <__utility/swap.h>
31#include <exception>
39#include <__verbose_abort>
3240#include <new>
3341#include <tuple>
34#include <type_traits>
3542#include <typeinfo>
3643
3744#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -46,7 +53,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
4653
4754_LIBCPP_DIAGNOSTIC_PUSH
4855_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
49class _LIBCPP_EXCEPTION_ABI bad_function_call
56class _LIBCPP_EXPORTED_FROM_ABI bad_function_call
5057 : public exception
5158{
5259public:
......@@ -56,7 +63,7 @@ public:
5663#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
5764 ~bad_function_call() _NOEXCEPT override;
5865#else
59 ~bad_function_call() _NOEXCEPT override {}
66 _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {}
6067#endif
6168
6269#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE
......@@ -68,10 +75,10 @@ _LIBCPP_DIAGNOSTIC_POP
6875_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
6976void __throw_bad_function_call()
7077{
71#ifndef _LIBCPP_NO_EXCEPTIONS
78#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
7279 throw bad_function_call();
7380#else
74 _VSTD::abort();
81 _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode");
7582#endif
7683}
7784
......@@ -201,7 +208,7 @@ class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
201208 _LIBCPP_INLINE_VISIBILITY
202209 void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
203210
204 static void __destroy_and_delete(__alloc_func* __f) {
211 _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) {
205212 typedef allocator_traits<_Alloc> __alloc_traits;
206213 typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc;
207214 _FunAlloc __a(__f->__get_allocator());
......@@ -245,7 +252,7 @@ public:
245252 _LIBCPP_INLINE_VISIBILITY
246253 void destroy() _NOEXCEPT { __f_.~_Target(); }
247254
248 static void __destroy_and_delete(__default_alloc_func* __f) {
255 _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__default_alloc_func* __f) {
249256 __f->destroy();
250257 __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1);
251258 }
......@@ -300,14 +307,14 @@ public:
300307 explicit __func(_Fp&& __f, _Alloc&& __a)
301308 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
302309
303 virtual __base<_Rp(_ArgTypes...)>* __clone() const;
304 virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
305 virtual void destroy() _NOEXCEPT;
306 virtual void destroy_deallocate() _NOEXCEPT;
307 virtual _Rp operator()(_ArgTypes&&... __arg);
310 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const;
311 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
312 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT;
313 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT;
314 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg);
308315#ifndef _LIBCPP_HAS_NO_RTTI
309 virtual const void* target(const type_info&) const _NOEXCEPT;
310 virtual const std::type_info& target_type() const _NOEXCEPT;
316 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT;
317 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT;
311318#endif // _LIBCPP_HAS_NO_RTTI
312319};
313320
......@@ -389,7 +396,7 @@ template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
389396 typedef __base<_Rp(_ArgTypes...)> __func;
390397 __func* __f_;
391398
392 _LIBCPP_NO_CFI static __func* __as_base(void* __p)
399 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p)
393400 {
394401 return reinterpret_cast<__func*>(__p);
395402 }
......@@ -427,7 +434,7 @@ template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
427434 }
428435
429436 template <class _Fp,
430 class = typename enable_if<!is_same<typename decay<_Fp>::type, __value_func>::value>::type>
437 class = typename enable_if<!is_same<__decay_t<_Fp>, __value_func>::value>::type>
431438 _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f)
432439 : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {}
433440
......@@ -614,33 +621,34 @@ struct __policy
614621 _LIBCPP_INLINE_VISIBILITY
615622 static const __policy* __create_empty()
616623 {
617 static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr,
618 true,
624 static const _LIBCPP_CONSTEXPR __policy __policy = {nullptr, nullptr,
625 true,
619626#ifndef _LIBCPP_HAS_NO_RTTI
620 &typeid(void)
627 &typeid(void)
621628#else
622 nullptr
629 nullptr
623630#endif
624631 };
625 return &__policy_;
632 return &__policy;
626633 }
627634
628635 private:
629 template <typename _Fun> static void* __large_clone(const void* __s)
636 template <typename _Fun>
637 _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s)
630638 {
631639 const _Fun* __f = static_cast<const _Fun*>(__s);
632640 return __f->__clone();
633641 }
634642
635643 template <typename _Fun>
636 static void __large_destroy(void* __s) {
644 _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) {
637645 _Fun::__destroy_and_delete(static_cast<_Fun*>(__s));
638646 }
639647
640648 template <typename _Fun>
641649 _LIBCPP_INLINE_VISIBILITY static const __policy*
642650 __choose_policy(/* is_small = */ false_type) {
643 static const _LIBCPP_CONSTEXPR __policy __policy_ = {
651 static const _LIBCPP_CONSTEXPR __policy __policy = {
644652 &__large_clone<_Fun>, &__large_destroy<_Fun>, false,
645653#ifndef _LIBCPP_HAS_NO_RTTI
646654 &typeid(typename _Fun::_Target)
......@@ -648,14 +656,14 @@ struct __policy
648656 nullptr
649657#endif
650658 };
651 return &__policy_;
659 return &__policy;
652660 }
653661
654662 template <typename _Fun>
655663 _LIBCPP_INLINE_VISIBILITY static const __policy*
656664 __choose_policy(/* is_small = */ true_type)
657665 {
658 static const _LIBCPP_CONSTEXPR __policy __policy_ = {
666 static const _LIBCPP_CONSTEXPR __policy __policy = {
659667 nullptr, nullptr, false,
660668#ifndef _LIBCPP_HAS_NO_RTTI
661669 &typeid(typename _Fun::_Target)
......@@ -663,7 +671,7 @@ struct __policy
663671 nullptr
664672#endif
665673 };
666 return &__policy_;
674 return &__policy;
667675 }
668676};
669677
......@@ -699,14 +707,14 @@ struct __policy_invoker<_Rp(_ArgTypes...)>
699707 _LIBCPP_INLINE_VISIBILITY
700708 explicit __policy_invoker(__Call __c) : __call_(__c) {}
701709
702 static _Rp __call_empty(const __policy_storage*,
710 _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*,
703711 __fast_forward<_ArgTypes>...)
704712 {
705713 __throw_bad_function_call();
706714 }
707715
708716 template <typename _Fun>
709 static _Rp __call_impl(const __policy_storage* __buf,
717 _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf,
710718 __fast_forward<_ArgTypes>... __args)
711719 {
712720 _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value
......@@ -770,7 +778,7 @@ template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
770778 }
771779 }
772780
773 template <class _Fp, class = typename enable_if<!is_same<typename decay<_Fp>::type, __policy_func>::value>::type>
781 template <class _Fp, class = typename enable_if<!is_same<__decay_t<_Fp>, __policy_func>::value>::type>
774782 _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f)
775783 : __policy_(__policy::__create_empty()) {
776784 typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun;
......@@ -915,7 +923,7 @@ public:
915923 { }
916924
917925 virtual __base<_Rp(_ArgTypes...)>* __clone() const {
918 _LIBCPP_ASSERT(false,
926 _LIBCPP_ASSERT_INTERNAL(false,
919927 "Block pointers are just pointers, so they should always fit into "
920928 "std::function's small buffer optimization. This function should "
921929 "never be invoked.");
......@@ -935,7 +943,7 @@ public:
935943 }
936944
937945 virtual void destroy_deallocate() _NOEXCEPT {
938 _LIBCPP_ASSERT(false,
946 _LIBCPP_ASSERT_INTERNAL(false,
939947 "Block pointers are just pointers, so they should always fit into "
940948 "std::function's small buffer optimization. This function should "
941949 "never be invoked.");
......@@ -1002,11 +1010,11 @@ public:
10021010 _LIBCPP_INLINE_VISIBILITY
10031011 function() _NOEXCEPT { }
10041012 _LIBCPP_INLINE_VISIBILITY
1005 function(nullptr_t) _NOEXCEPT {}
1006 function(const function&);
1007 function(function&&) _NOEXCEPT;
1013 _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {}
1014 _LIBCPP_HIDE_FROM_ABI function(const function&);
1015 _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT;
10081016 template<class _Fp, class = _EnableIfLValueCallable<_Fp>>
1009 function(_Fp);
1017 _LIBCPP_HIDE_FROM_ABI function(_Fp);
10101018
10111019#if _LIBCPP_STD_VER <= 14
10121020 template<class _Alloc>
......@@ -1016,23 +1024,23 @@ public:
10161024 _LIBCPP_INLINE_VISIBILITY
10171025 function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
10181026 template<class _Alloc>
1019 function(allocator_arg_t, const _Alloc&, const function&);
1027 _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&);
10201028 template<class _Alloc>
1021 function(allocator_arg_t, const _Alloc&, function&&);
1029 _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&);
10221030 template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
1023 function(allocator_arg_t, const _Alloc& __a, _Fp __f);
1031 _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f);
10241032#endif
10251033
1026 function& operator=(const function&);
1027 function& operator=(function&&) _NOEXCEPT;
1028 function& operator=(nullptr_t) _NOEXCEPT;
1029 template<class _Fp, class = _EnableIfLValueCallable<typename decay<_Fp>::type>>
1030 function& operator=(_Fp&&);
1034 _LIBCPP_HIDE_FROM_ABI function& operator=(const function&);
1035 _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT;
1036 _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT;
1037 template<class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>>
1038 _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&);
10311039
1032 ~function();
1040 _LIBCPP_HIDE_FROM_ABI ~function();
10331041
10341042 // function modifiers:
1035 void swap(function&) _NOEXCEPT;
1043 _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT;
10361044
10371045#if _LIBCPP_STD_VER <= 14
10381046 template<class _Fp, class _Alloc>
......@@ -1050,17 +1058,21 @@ public:
10501058 // deleted overloads close possible hole in the type system
10511059 template<class _R2, class... _ArgTypes2>
10521060 bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
1061#if _LIBCPP_STD_VER <= 17
10531062 template<class _R2, class... _ArgTypes2>
10541063 bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
1064#endif
10551065public:
10561066 // function invocation:
1057 _Rp operator()(_ArgTypes...) const;
1067 _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
10581068
10591069#ifndef _LIBCPP_HAS_NO_RTTI
10601070 // function target access:
1061 const std::type_info& target_type() const _NOEXCEPT;
1062 template <typename _Tp> _Tp* target() _NOEXCEPT;
1063 template <typename _Tp> const _Tp* target() const _NOEXCEPT;
1071 _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
1072 template <typename _Tp>
1073 _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
1074 template <typename _Tp>
1075 _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
10641076#endif // _LIBCPP_HAS_NO_RTTI
10651077};
10661078
......@@ -1188,6 +1200,8 @@ inline _LIBCPP_INLINE_VISIBILITY
11881200bool
11891201operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;}
11901202
1203#if _LIBCPP_STD_VER <= 17
1204
11911205template <class _Rp, class... _ArgTypes>
11921206inline _LIBCPP_INLINE_VISIBILITY
11931207bool
......@@ -1203,6 +1217,8 @@ inline _LIBCPP_INLINE_VISIBILITY
12031217bool
12041218operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;}
12051219
1220#endif // _LIBCPP_STD_VER <= 17
1221
12061222template <class _Rp, class... _ArgTypes>
12071223inline _LIBCPP_INLINE_VISIBILITY
12081224void
lib/libcxx/include/__functional/hash.h+125-135
......@@ -13,7 +13,7 @@
1313#include <__functional/invoke.h>
1414#include <__functional/unary_function.h>
1515#include <__fwd/hash.h>
16#include <__tuple_dir/sfinae_helpers.h>
16#include <__tuple/sfinae_helpers.h>
1717#include <__type_traits/is_copy_constructible.h>
1818#include <__type_traits/is_default_constructible.h>
1919#include <__type_traits/is_enum.h>
......@@ -35,7 +35,7 @@
3535_LIBCPP_BEGIN_NAMESPACE_STD
3636
3737template <class _Size>
38inline _LIBCPP_INLINE_VISIBILITY
38inline _LIBCPP_HIDE_FROM_ABI
3939_Size
4040__loadword(const void* __p)
4141{
......@@ -53,73 +53,113 @@ struct __murmur2_or_cityhash;
5353template <class _Size>
5454struct __murmur2_or_cityhash<_Size, 32>
5555{
56 inline _Size operator()(const void* __key, _Size __len)
57 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK;
56 _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
57 _Size operator()(const void* __key, _Size __len) const {
58 // murmur2
59 const _Size __m = 0x5bd1e995;
60 const _Size __r = 24;
61 _Size __h = __len;
62 const unsigned char* __data = static_cast<const unsigned char*>(__key);
63 for (; __len >= 4; __data += 4, __len -= 4)
64 {
65 _Size __k = std::__loadword<_Size>(__data);
66 __k *= __m;
67 __k ^= __k >> __r;
68 __k *= __m;
69 __h *= __m;
70 __h ^= __k;
71 }
72 switch (__len)
73 {
74 case 3:
75 __h ^= static_cast<_Size>(__data[2] << 16);
76 _LIBCPP_FALLTHROUGH();
77 case 2:
78 __h ^= static_cast<_Size>(__data[1] << 8);
79 _LIBCPP_FALLTHROUGH();
80 case 1:
81 __h ^= __data[0];
82 __h *= __m;
83 }
84 __h ^= __h >> 13;
85 __h *= __m;
86 __h ^= __h >> 15;
87 return __h;
88 }
5889};
5990
60// murmur2
6191template <class _Size>
62_Size
63__murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len)
92struct __murmur2_or_cityhash<_Size, 64>
6493{
65 const _Size __m = 0x5bd1e995;
66 const _Size __r = 24;
67 _Size __h = __len;
68 const unsigned char* __data = static_cast<const unsigned char*>(__key);
69 for (; __len >= 4; __data += 4, __len -= 4)
70 {
71 _Size __k = std::__loadword<_Size>(__data);
72 __k *= __m;
73 __k ^= __k >> __r;
74 __k *= __m;
75 __h *= __m;
76 __h ^= __k;
77 }
78 switch (__len)
79 {
80 case 3:
81 __h ^= static_cast<_Size>(__data[2] << 16);
82 _LIBCPP_FALLTHROUGH();
83 case 2:
84 __h ^= static_cast<_Size>(__data[1] << 8);
85 _LIBCPP_FALLTHROUGH();
86 case 1:
87 __h ^= __data[0];
88 __h *= __m;
94 // cityhash64
95 _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
96 _Size operator()(const void* __key, _Size __len) const {
97 const char* __s = static_cast<const char*>(__key);
98 if (__len <= 32) {
99 if (__len <= 16) {
100 return __hash_len_0_to_16(__s, __len);
101 } else {
102 return __hash_len_17_to_32(__s, __len);
103 }
104 } else if (__len <= 64) {
105 return __hash_len_33_to_64(__s, __len);
89106 }
90 __h ^= __h >> 13;
91 __h *= __m;
92 __h ^= __h >> 15;
93 return __h;
94}
95107
96template <class _Size>
97struct __murmur2_or_cityhash<_Size, 64>
98{
99 inline _Size operator()(const void* __key, _Size __len) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK;
108 // For strings over 64 bytes we hash the end first, and then as we
109 // loop we keep 56 bytes of state: v, w, x, y, and z.
110 _Size __x = std::__loadword<_Size>(__s + __len - 40);
111 _Size __y = std::__loadword<_Size>(__s + __len - 16) +
112 std::__loadword<_Size>(__s + __len - 56);
113 _Size __z = __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len,
114 std::__loadword<_Size>(__s + __len - 24));
115 pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);
116 pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);
117 __x = __x * __k1 + std::__loadword<_Size>(__s);
118
119 // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
120 __len = (__len - 1) & ~static_cast<_Size>(63);
121 do {
122 __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1;
123 __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1;
124 __x ^= __w.second;
125 __y += __v.first + std::__loadword<_Size>(__s + 40);
126 __z = __rotate(__z + __w.first, 33) * __k1;
127 __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first);
128 __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second,
129 __y + std::__loadword<_Size>(__s + 16));
130 _VSTD::swap(__z, __x);
131 __s += 64;
132 __len -= 64;
133 } while (__len != 0);
134 return __hash_len_16(
135 __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z,
136 __hash_len_16(__v.second, __w.second) + __x);
137 }
100138
101 private:
102 // Some primes between 2^63 and 2^64.
103 static const _Size __k0 = 0xc3a5c85c97cb3127ULL;
104 static const _Size __k1 = 0xb492b66fbe98f273ULL;
105 static const _Size __k2 = 0x9ae16a3b2f90404fULL;
106 static const _Size __k3 = 0xc949d7c7509e6557ULL;
139 private:
140 // Some primes between 2^63 and 2^64.
141 static const _Size __k0 = 0xc3a5c85c97cb3127ULL;
142 static const _Size __k1 = 0xb492b66fbe98f273ULL;
143 static const _Size __k2 = 0x9ae16a3b2f90404fULL;
144 static const _Size __k3 = 0xc949d7c7509e6557ULL;
107145
146 _LIBCPP_HIDE_FROM_ABI
108147 static _Size __rotate(_Size __val, int __shift) {
109148 return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift)));
110149 }
111150
151 _LIBCPP_HIDE_FROM_ABI
112152 static _Size __rotate_by_at_least_1(_Size __val, int __shift) {
113153 return (__val >> __shift) | (__val << (64 - __shift));
114154 }
115155
156 _LIBCPP_HIDE_FROM_ABI
116157 static _Size __shift_mix(_Size __val) {
117158 return __val ^ (__val >> 47);
118159 }
119160
120 static _Size __hash_len_16(_Size __u, _Size __v)
121 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
122 {
161 _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
162 static _Size __hash_len_16(_Size __u, _Size __v) {
123163 const _Size __mul = 0x9ddfea08eb382d69ULL;
124164 _Size __a = (__u ^ __v) * __mul;
125165 __a ^= (__a >> 47);
......@@ -129,9 +169,8 @@ struct __murmur2_or_cityhash<_Size, 64>
129169 return __b;
130170 }
131171
132 static _Size __hash_len_0_to_16(const char* __s, _Size __len)
133 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
134 {
172 _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
173 static _Size __hash_len_0_to_16(const char* __s, _Size __len) {
135174 if (__len > 8) {
136175 const _Size __a = std::__loadword<_Size>(__s);
137176 const _Size __b = std::__loadword<_Size>(__s + __len - 8);
......@@ -158,9 +197,8 @@ struct __murmur2_or_cityhash<_Size, 64>
158197 return __k2;
159198 }
160199
161 static _Size __hash_len_17_to_32(const char *__s, _Size __len)
162 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
163 {
200 _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
201 static _Size __hash_len_17_to_32(const char *__s, _Size __len) {
164202 const _Size __a = std::__loadword<_Size>(__s) * __k1;
165203 const _Size __b = std::__loadword<_Size>(__s + 8);
166204 const _Size __c = std::__loadword<_Size>(__s + __len - 8) * __k2;
......@@ -171,9 +209,9 @@ struct __murmur2_or_cityhash<_Size, 64>
171209
172210 // Return a 16-byte hash for 48 bytes. Quick and dirty.
173211 // Callers do best to use "random-looking" values for a and b.
212 _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
174213 static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
175214 _Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b)
176 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
177215 {
178216 __a += __w;
179217 __b = __rotate(__b + __a + __z, 21);
......@@ -185,9 +223,9 @@ struct __murmur2_or_cityhash<_Size, 64>
185223 }
186224
187225 // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
226 _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
188227 static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
189228 const char* __s, _Size __a, _Size __b)
190 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
191229 {
192230 return __weak_hash_len_32_with_seeds(std::__loadword<_Size>(__s),
193231 std::__loadword<_Size>(__s + 8),
......@@ -198,9 +236,8 @@ struct __murmur2_or_cityhash<_Size, 64>
198236 }
199237
200238 // Return an 8-byte hash for 33 to 64 bytes.
201 static _Size __hash_len_33_to_64(const char *__s, size_t __len)
202 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
203 {
239 _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
240 static _Size __hash_len_33_to_64(const char *__s, size_t __len) {
204241 _Size __z = std::__loadword<_Size>(__s + 24);
205242 _Size __a = std::__loadword<_Size>(__s) +
206243 (__len + std::__loadword<_Size>(__s + __len - 16)) * __k0;
......@@ -225,53 +262,6 @@ struct __murmur2_or_cityhash<_Size, 64>
225262 }
226263};
227264
228// cityhash64
229template <class _Size>
230_Size
231__murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len)
232{
233 const char* __s = static_cast<const char*>(__key);
234 if (__len <= 32) {
235 if (__len <= 16) {
236 return __hash_len_0_to_16(__s, __len);
237 } else {
238 return __hash_len_17_to_32(__s, __len);
239 }
240 } else if (__len <= 64) {
241 return __hash_len_33_to_64(__s, __len);
242 }
243
244 // For strings over 64 bytes we hash the end first, and then as we
245 // loop we keep 56 bytes of state: v, w, x, y, and z.
246 _Size __x = std::__loadword<_Size>(__s + __len - 40);
247 _Size __y = std::__loadword<_Size>(__s + __len - 16) +
248 std::__loadword<_Size>(__s + __len - 56);
249 _Size __z = __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len,
250 std::__loadword<_Size>(__s + __len - 24));
251 pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);
252 pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);
253 __x = __x * __k1 + std::__loadword<_Size>(__s);
254
255 // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
256 __len = (__len - 1) & ~static_cast<_Size>(63);
257 do {
258 __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1;
259 __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1;
260 __x ^= __w.second;
261 __y += __v.first + std::__loadword<_Size>(__s + 40);
262 __z = __rotate(__z + __w.first, 33) * __k1;
263 __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first);
264 __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second,
265 __y + std::__loadword<_Size>(__s + 16));
266 _VSTD::swap(__z, __x);
267 __s += 64;
268 __len -= 64;
269 } while (__len != 0);
270 return __hash_len_16(
271 __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z,
272 __hash_len_16(__v.second, __w.second) + __x);
273}
274
275265template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)>
276266struct __scalar_hash;
277267
......@@ -279,7 +269,7 @@ template <class _Tp>
279269struct __scalar_hash<_Tp, 0>
280270 : public __unary_function<_Tp, size_t>
281271{
282 _LIBCPP_INLINE_VISIBILITY
272 _LIBCPP_HIDE_FROM_ABI
283273 size_t operator()(_Tp __v) const _NOEXCEPT
284274 {
285275 union
......@@ -297,7 +287,7 @@ template <class _Tp>
297287struct __scalar_hash<_Tp, 1>
298288 : public __unary_function<_Tp, size_t>
299289{
300 _LIBCPP_INLINE_VISIBILITY
290 _LIBCPP_HIDE_FROM_ABI
301291 size_t operator()(_Tp __v) const _NOEXCEPT
302292 {
303293 union
......@@ -314,7 +304,7 @@ template <class _Tp>
314304struct __scalar_hash<_Tp, 2>
315305 : public __unary_function<_Tp, size_t>
316306{
317 _LIBCPP_INLINE_VISIBILITY
307 _LIBCPP_HIDE_FROM_ABI
318308 size_t operator()(_Tp __v) const _NOEXCEPT
319309 {
320310 union
......@@ -335,7 +325,7 @@ template <class _Tp>
335325struct __scalar_hash<_Tp, 3>
336326 : public __unary_function<_Tp, size_t>
337327{
338 _LIBCPP_INLINE_VISIBILITY
328 _LIBCPP_HIDE_FROM_ABI
339329 size_t operator()(_Tp __v) const _NOEXCEPT
340330 {
341331 union
......@@ -357,7 +347,7 @@ template <class _Tp>
357347struct __scalar_hash<_Tp, 4>
358348 : public __unary_function<_Tp, size_t>
359349{
360 _LIBCPP_INLINE_VISIBILITY
350 _LIBCPP_HIDE_FROM_ABI
361351 size_t operator()(_Tp __v) const _NOEXCEPT
362352 {
363353 union
......@@ -381,7 +371,7 @@ struct _PairT {
381371 size_t second;
382372};
383373
384_LIBCPP_INLINE_VISIBILITY
374_LIBCPP_HIDE_FROM_ABI
385375inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT {
386376 typedef __scalar_hash<_PairT> _HashT;
387377 const _PairT __p = {__lhs, __rhs};
......@@ -392,7 +382,7 @@ template<class _Tp>
392382struct _LIBCPP_TEMPLATE_VIS hash<_Tp*>
393383 : public __unary_function<_Tp*, size_t>
394384{
395 _LIBCPP_INLINE_VISIBILITY
385 _LIBCPP_HIDE_FROM_ABI
396386 size_t operator()(_Tp* __v) const _NOEXCEPT
397387 {
398388 union
......@@ -409,7 +399,7 @@ template <>
409399struct _LIBCPP_TEMPLATE_VIS hash<bool>
410400 : public __unary_function<bool, size_t>
411401{
412 _LIBCPP_INLINE_VISIBILITY
402 _LIBCPP_HIDE_FROM_ABI
413403 size_t operator()(bool __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
414404};
415405
......@@ -417,7 +407,7 @@ template <>
417407struct _LIBCPP_TEMPLATE_VIS hash<char>
418408 : public __unary_function<char, size_t>
419409{
420 _LIBCPP_INLINE_VISIBILITY
410 _LIBCPP_HIDE_FROM_ABI
421411 size_t operator()(char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
422412};
423413
......@@ -425,7 +415,7 @@ template <>
425415struct _LIBCPP_TEMPLATE_VIS hash<signed char>
426416 : public __unary_function<signed char, size_t>
427417{
428 _LIBCPP_INLINE_VISIBILITY
418 _LIBCPP_HIDE_FROM_ABI
429419 size_t operator()(signed char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
430420};
431421
......@@ -433,7 +423,7 @@ template <>
433423struct _LIBCPP_TEMPLATE_VIS hash<unsigned char>
434424 : public __unary_function<unsigned char, size_t>
435425{
436 _LIBCPP_INLINE_VISIBILITY
426 _LIBCPP_HIDE_FROM_ABI
437427 size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
438428};
439429
......@@ -442,7 +432,7 @@ template <>
442432struct _LIBCPP_TEMPLATE_VIS hash<char8_t>
443433 : public __unary_function<char8_t, size_t>
444434{
445 _LIBCPP_INLINE_VISIBILITY
435 _LIBCPP_HIDE_FROM_ABI
446436 size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
447437};
448438#endif // !_LIBCPP_HAS_NO_CHAR8_T
......@@ -451,7 +441,7 @@ template <>
451441struct _LIBCPP_TEMPLATE_VIS hash<char16_t>
452442 : public __unary_function<char16_t, size_t>
453443{
454 _LIBCPP_INLINE_VISIBILITY
444 _LIBCPP_HIDE_FROM_ABI
455445 size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
456446};
457447
......@@ -459,7 +449,7 @@ template <>
459449struct _LIBCPP_TEMPLATE_VIS hash<char32_t>
460450 : public __unary_function<char32_t, size_t>
461451{
462 _LIBCPP_INLINE_VISIBILITY
452 _LIBCPP_HIDE_FROM_ABI
463453 size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
464454};
465455
......@@ -468,7 +458,7 @@ template <>
468458struct _LIBCPP_TEMPLATE_VIS hash<wchar_t>
469459 : public __unary_function<wchar_t, size_t>
470460{
471 _LIBCPP_INLINE_VISIBILITY
461 _LIBCPP_HIDE_FROM_ABI
472462 size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
473463};
474464#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
......@@ -477,7 +467,7 @@ template <>
477467struct _LIBCPP_TEMPLATE_VIS hash<short>
478468 : public __unary_function<short, size_t>
479469{
480 _LIBCPP_INLINE_VISIBILITY
470 _LIBCPP_HIDE_FROM_ABI
481471 size_t operator()(short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
482472};
483473
......@@ -485,7 +475,7 @@ template <>
485475struct _LIBCPP_TEMPLATE_VIS hash<unsigned short>
486476 : public __unary_function<unsigned short, size_t>
487477{
488 _LIBCPP_INLINE_VISIBILITY
478 _LIBCPP_HIDE_FROM_ABI
489479 size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
490480};
491481
......@@ -493,7 +483,7 @@ template <>
493483struct _LIBCPP_TEMPLATE_VIS hash<int>
494484 : public __unary_function<int, size_t>
495485{
496 _LIBCPP_INLINE_VISIBILITY
486 _LIBCPP_HIDE_FROM_ABI
497487 size_t operator()(int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
498488};
499489
......@@ -501,7 +491,7 @@ template <>
501491struct _LIBCPP_TEMPLATE_VIS hash<unsigned int>
502492 : public __unary_function<unsigned int, size_t>
503493{
504 _LIBCPP_INLINE_VISIBILITY
494 _LIBCPP_HIDE_FROM_ABI
505495 size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
506496};
507497
......@@ -509,7 +499,7 @@ template <>
509499struct _LIBCPP_TEMPLATE_VIS hash<long>
510500 : public __unary_function<long, size_t>
511501{
512 _LIBCPP_INLINE_VISIBILITY
502 _LIBCPP_HIDE_FROM_ABI
513503 size_t operator()(long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
514504};
515505
......@@ -517,7 +507,7 @@ template <>
517507struct _LIBCPP_TEMPLATE_VIS hash<unsigned long>
518508 : public __unary_function<unsigned long, size_t>
519509{
520 _LIBCPP_INLINE_VISIBILITY
510 _LIBCPP_HIDE_FROM_ABI
521511 size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
522512};
523513
......@@ -553,7 +543,7 @@ template <>
553543struct _LIBCPP_TEMPLATE_VIS hash<float>
554544 : public __scalar_hash<float>
555545{
556 _LIBCPP_INLINE_VISIBILITY
546 _LIBCPP_HIDE_FROM_ABI
557547 size_t operator()(float __v) const _NOEXCEPT
558548 {
559549 // -0.0 and 0.0 should return same hash
......@@ -567,7 +557,7 @@ template <>
567557struct _LIBCPP_TEMPLATE_VIS hash<double>
568558 : public __scalar_hash<double>
569559{
570 _LIBCPP_INLINE_VISIBILITY
560 _LIBCPP_HIDE_FROM_ABI
571561 size_t operator()(double __v) const _NOEXCEPT
572562 {
573563 // -0.0 and 0.0 should return same hash
......@@ -581,7 +571,7 @@ template <>
581571struct _LIBCPP_TEMPLATE_VIS hash<long double>
582572 : public __scalar_hash<long double>
583573{
584 _LIBCPP_INLINE_VISIBILITY
574 _LIBCPP_HIDE_FROM_ABI
585575 size_t operator()(long double __v) const _NOEXCEPT
586576 {
587577 // -0.0 and 0.0 should return same hash
......@@ -631,7 +621,7 @@ template <class _Tp, bool = is_enum<_Tp>::value>
631621struct _LIBCPP_TEMPLATE_VIS __enum_hash
632622 : public __unary_function<_Tp, size_t>
633623{
634 _LIBCPP_INLINE_VISIBILITY
624 _LIBCPP_HIDE_FROM_ABI
635625 size_t operator()(_Tp __v) const _NOEXCEPT
636626 {
637627 typedef typename underlying_type<_Tp>::type type;
......@@ -650,13 +640,13 @@ struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp>
650640{
651641};
652642
653#if _LIBCPP_STD_VER > 14
643#if _LIBCPP_STD_VER >= 17
654644
655645template <>
656646struct _LIBCPP_TEMPLATE_VIS hash<nullptr_t>
657647 : public __unary_function<nullptr_t, size_t>
658648{
659 _LIBCPP_INLINE_VISIBILITY
649 _LIBCPP_HIDE_FROM_ABI
660650 size_t operator()(nullptr_t) const _NOEXCEPT {
661651 return 662607004ull;
662652 }
......@@ -677,7 +667,7 @@ using __has_enabled_hash _LIBCPP_NODEBUG = integral_constant<bool,
677667 is_default_constructible<_Hash>::value
678668>;
679669
680#if _LIBCPP_STD_VER > 14
670#if _LIBCPP_STD_VER >= 17
681671template <class _Type, class>
682672using __enable_hash_helper_imp _LIBCPP_NODEBUG = _Type;
683673
lib/libcxx/include/__functional/identity.h+15-4
......@@ -11,6 +11,7 @@
1111#define _LIBCPP___FUNCTIONAL_IDENTITY_H
1212
1313#include <__config>
14#include <__type_traits/integral_constant.h>
1415#include <__utility/forward.h>
1516
1617#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -19,27 +20,37 @@
1920
2021_LIBCPP_BEGIN_NAMESPACE_STD
2122
23template <class _Tp>
24struct __is_identity : false_type {};
25
2226struct __identity {
2327 template <class _Tp>
24 _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR _Tp&& operator()(_Tp&& __t) const _NOEXCEPT {
28 _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp&& operator()(_Tp&& __t) const _NOEXCEPT {
2529 return std::forward<_Tp>(__t);
2630 }
2731
2832 using is_transparent = void;
2933};
3034
31#if _LIBCPP_STD_VER > 17
35template <>
36struct __is_identity<__identity> : true_type {};
37
38#if _LIBCPP_STD_VER >= 20
3239
3340struct identity {
3441 template<class _Tp>
35 _LIBCPP_NODISCARD_EXT constexpr _Tp&& operator()(_Tp&& __t) const noexcept
42 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_Tp&& __t) const noexcept
3643 {
3744 return _VSTD::forward<_Tp>(__t);
3845 }
3946
4047 using is_transparent = void;
4148};
42#endif // _LIBCPP_STD_VER > 17
49
50template <>
51struct __is_identity<identity> : true_type {};
52
53#endif // _LIBCPP_STD_VER >= 20
4354
4455_LIBCPP_END_NAMESPACE_STD
4556
lib/libcxx/include/__functional/invoke.h+22-512
......@@ -11,525 +11,16 @@
1111#define _LIBCPP___FUNCTIONAL_INVOKE_H
1212
1313#include <__config>
14#include <__type_traits/add_lvalue_reference.h>
15#include <__type_traits/apply_cv.h>
16#include <__type_traits/conditional.h>
17#include <__type_traits/decay.h>
18#include <__type_traits/enable_if.h>
19#include <__type_traits/integral_constant.h>
20#include <__type_traits/is_base_of.h>
21#include <__type_traits/is_core_convertible.h>
22#include <__type_traits/is_member_function_pointer.h>
23#include <__type_traits/is_member_object_pointer.h>
24#include <__type_traits/is_reference_wrapper.h>
25#include <__type_traits/is_same.h>
26#include <__type_traits/is_void.h>
27#include <__type_traits/nat.h>
28#include <__type_traits/remove_cv.h>
29#include <__utility/declval.h>
14#include <__type_traits/invoke.h>
3015#include <__utility/forward.h>
3116
3217#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3318# pragma GCC system_header
3419#endif
3520
36// TODO: Disentangle the type traits and std::invoke properly
37
3821_LIBCPP_BEGIN_NAMESPACE_STD
3922
40struct __any
41{
42 __any(...);
43};
44
45template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
46struct __member_pointer_traits_imp
47{
48};
49
50template <class _Rp, class _Class, class ..._Param>
51struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false>
52{
53 typedef _Class _ClassType;
54 typedef _Rp _ReturnType;
55 typedef _Rp (_FnType) (_Param...);
56};
57
58template <class _Rp, class _Class, class ..._Param>
59struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false>
60{
61 typedef _Class _ClassType;
62 typedef _Rp _ReturnType;
63 typedef _Rp (_FnType) (_Param..., ...);
64};
65
66template <class _Rp, class _Class, class ..._Param>
67struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false>
68{
69 typedef _Class const _ClassType;
70 typedef _Rp _ReturnType;
71 typedef _Rp (_FnType) (_Param...);
72};
73
74template <class _Rp, class _Class, class ..._Param>
75struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false>
76{
77 typedef _Class const _ClassType;
78 typedef _Rp _ReturnType;
79 typedef _Rp (_FnType) (_Param..., ...);
80};
81
82template <class _Rp, class _Class, class ..._Param>
83struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false>
84{
85 typedef _Class volatile _ClassType;
86 typedef _Rp _ReturnType;
87 typedef _Rp (_FnType) (_Param...);
88};
89
90template <class _Rp, class _Class, class ..._Param>
91struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false>
92{
93 typedef _Class volatile _ClassType;
94 typedef _Rp _ReturnType;
95 typedef _Rp (_FnType) (_Param..., ...);
96};
97
98template <class _Rp, class _Class, class ..._Param>
99struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false>
100{
101 typedef _Class const volatile _ClassType;
102 typedef _Rp _ReturnType;
103 typedef _Rp (_FnType) (_Param...);
104};
105
106template <class _Rp, class _Class, class ..._Param>
107struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false>
108{
109 typedef _Class const volatile _ClassType;
110 typedef _Rp _ReturnType;
111 typedef _Rp (_FnType) (_Param..., ...);
112};
113
114template <class _Rp, class _Class, class ..._Param>
115struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false>
116{
117 typedef _Class& _ClassType;
118 typedef _Rp _ReturnType;
119 typedef _Rp (_FnType) (_Param...);
120};
121
122template <class _Rp, class _Class, class ..._Param>
123struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &, true, false>
124{
125 typedef _Class& _ClassType;
126 typedef _Rp _ReturnType;
127 typedef _Rp (_FnType) (_Param..., ...);
128};
129
130template <class _Rp, class _Class, class ..._Param>
131struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false>
132{
133 typedef _Class const& _ClassType;
134 typedef _Rp _ReturnType;
135 typedef _Rp (_FnType) (_Param...);
136};
137
138template <class _Rp, class _Class, class ..._Param>
139struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false>
140{
141 typedef _Class const& _ClassType;
142 typedef _Rp _ReturnType;
143 typedef _Rp (_FnType) (_Param..., ...);
144};
145
146template <class _Rp, class _Class, class ..._Param>
147struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false>
148{
149 typedef _Class volatile& _ClassType;
150 typedef _Rp _ReturnType;
151 typedef _Rp (_FnType) (_Param...);
152};
153
154template <class _Rp, class _Class, class ..._Param>
155struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false>
156{
157 typedef _Class volatile& _ClassType;
158 typedef _Rp _ReturnType;
159 typedef _Rp (_FnType) (_Param..., ...);
160};
161
162template <class _Rp, class _Class, class ..._Param>
163struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false>
164{
165 typedef _Class const volatile& _ClassType;
166 typedef _Rp _ReturnType;
167 typedef _Rp (_FnType) (_Param...);
168};
169
170template <class _Rp, class _Class, class ..._Param>
171struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false>
172{
173 typedef _Class const volatile& _ClassType;
174 typedef _Rp _ReturnType;
175 typedef _Rp (_FnType) (_Param..., ...);
176};
177
178template <class _Rp, class _Class, class ..._Param>
179struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false>
180{
181 typedef _Class&& _ClassType;
182 typedef _Rp _ReturnType;
183 typedef _Rp (_FnType) (_Param...);
184};
185
186template <class _Rp, class _Class, class ..._Param>
187struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &&, true, false>
188{
189 typedef _Class&& _ClassType;
190 typedef _Rp _ReturnType;
191 typedef _Rp (_FnType) (_Param..., ...);
192};
193
194template <class _Rp, class _Class, class ..._Param>
195struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false>
196{
197 typedef _Class const&& _ClassType;
198 typedef _Rp _ReturnType;
199 typedef _Rp (_FnType) (_Param...);
200};
201
202template <class _Rp, class _Class, class ..._Param>
203struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false>
204{
205 typedef _Class const&& _ClassType;
206 typedef _Rp _ReturnType;
207 typedef _Rp (_FnType) (_Param..., ...);
208};
209
210template <class _Rp, class _Class, class ..._Param>
211struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false>
212{
213 typedef _Class volatile&& _ClassType;
214 typedef _Rp _ReturnType;
215 typedef _Rp (_FnType) (_Param...);
216};
217
218template <class _Rp, class _Class, class ..._Param>
219struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false>
220{
221 typedef _Class volatile&& _ClassType;
222 typedef _Rp _ReturnType;
223 typedef _Rp (_FnType) (_Param..., ...);
224};
225
226template <class _Rp, class _Class, class ..._Param>
227struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false>
228{
229 typedef _Class const volatile&& _ClassType;
230 typedef _Rp _ReturnType;
231 typedef _Rp (_FnType) (_Param...);
232};
233
234template <class _Rp, class _Class, class ..._Param>
235struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false>
236{
237 typedef _Class const volatile&& _ClassType;
238 typedef _Rp _ReturnType;
239 typedef _Rp (_FnType) (_Param..., ...);
240};
241
242template <class _Rp, class _Class>
243struct __member_pointer_traits_imp<_Rp _Class::*, false, true>
244{
245 typedef _Class _ClassType;
246 typedef _Rp _ReturnType;
247};
248
249template <class _MP>
250struct __member_pointer_traits
251 : public __member_pointer_traits_imp<__remove_cv_t<_MP>,
252 is_member_function_pointer<_MP>::value,
253 is_member_object_pointer<_MP>::value>
254{
255// typedef ... _ClassType;
256// typedef ... _ReturnType;
257// typedef ... _FnType;
258};
259
260template <class _DecayedFp>
261struct __member_pointer_class_type {};
262
263template <class _Ret, class _ClassType>
264struct __member_pointer_class_type<_Ret _ClassType::*> {
265 typedef _ClassType type;
266};
267
268template <class _Fp, class _A0,
269 class _DecayFp = typename decay<_Fp>::type,
270 class _DecayA0 = typename decay<_A0>::type,
271 class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
272using __enable_if_bullet1 = typename enable_if
273 <
274 is_member_function_pointer<_DecayFp>::value
275 && is_base_of<_ClassT, _DecayA0>::value
276 >::type;
277
278template <class _Fp, class _A0,
279 class _DecayFp = typename decay<_Fp>::type,
280 class _DecayA0 = typename decay<_A0>::type>
281using __enable_if_bullet2 = typename enable_if
282 <
283 is_member_function_pointer<_DecayFp>::value
284 && __is_reference_wrapper<_DecayA0>::value
285 >::type;
286
287template <class _Fp, class _A0,
288 class _DecayFp = typename decay<_Fp>::type,
289 class _DecayA0 = typename decay<_A0>::type,
290 class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
291using __enable_if_bullet3 = typename enable_if
292 <
293 is_member_function_pointer<_DecayFp>::value
294 && !is_base_of<_ClassT, _DecayA0>::value
295 && !__is_reference_wrapper<_DecayA0>::value
296 >::type;
297
298template <class _Fp, class _A0,
299 class _DecayFp = typename decay<_Fp>::type,
300 class _DecayA0 = typename decay<_A0>::type,
301 class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
302using __enable_if_bullet4 = typename enable_if
303 <
304 is_member_object_pointer<_DecayFp>::value
305 && is_base_of<_ClassT, _DecayA0>::value
306 >::type;
307
308template <class _Fp, class _A0,
309 class _DecayFp = typename decay<_Fp>::type,
310 class _DecayA0 = typename decay<_A0>::type>
311using __enable_if_bullet5 = typename enable_if
312 <
313 is_member_object_pointer<_DecayFp>::value
314 && __is_reference_wrapper<_DecayA0>::value
315 >::type;
316
317template <class _Fp, class _A0,
318 class _DecayFp = typename decay<_Fp>::type,
319 class _DecayA0 = typename decay<_A0>::type,
320 class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
321using __enable_if_bullet6 = typename enable_if
322 <
323 is_member_object_pointer<_DecayFp>::value
324 && !is_base_of<_ClassT, _DecayA0>::value
325 && !__is_reference_wrapper<_DecayA0>::value
326 >::type;
327
328// __invoke forward declarations
329
330// fall back - none of the bullets
331
332template <class ..._Args>
333__nat __invoke(__any, _Args&& ...__args);
334
335// bullets 1, 2 and 3
336
337template <class _Fp, class _A0, class ..._Args,
338 class = __enable_if_bullet1<_Fp, _A0> >
339inline _LIBCPP_INLINE_VISIBILITY
340_LIBCPP_CONSTEXPR decltype((std::declval<_A0>().*std::declval<_Fp>())(std::declval<_Args>()...))
341__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
342 _NOEXCEPT_(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...)))
343 { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); }
344
345template <class _Fp, class _A0, class ..._Args,
346 class = __enable_if_bullet2<_Fp, _A0> >
347inline _LIBCPP_INLINE_VISIBILITY
348_LIBCPP_CONSTEXPR decltype((std::declval<_A0>().get().*std::declval<_Fp>())(std::declval<_Args>()...))
349__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
350 _NOEXCEPT_(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...)))
351 { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); }
352
353template <class _Fp, class _A0, class ..._Args,
354 class = __enable_if_bullet3<_Fp, _A0> >
355inline _LIBCPP_INLINE_VISIBILITY
356_LIBCPP_CONSTEXPR decltype(((*std::declval<_A0>()).*std::declval<_Fp>())(std::declval<_Args>()...))
357__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
358 _NOEXCEPT_(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...)))
359 { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); }
360
361// bullets 4, 5 and 6
362
363template <class _Fp, class _A0,
364 class = __enable_if_bullet4<_Fp, _A0> >
365inline _LIBCPP_INLINE_VISIBILITY
366_LIBCPP_CONSTEXPR decltype(std::declval<_A0>().*std::declval<_Fp>())
367__invoke(_Fp&& __f, _A0&& __a0)
368 _NOEXCEPT_(noexcept(static_cast<_A0&&>(__a0).*__f))
369 { return static_cast<_A0&&>(__a0).*__f; }
370
371template <class _Fp, class _A0,
372 class = __enable_if_bullet5<_Fp, _A0> >
373inline _LIBCPP_INLINE_VISIBILITY
374_LIBCPP_CONSTEXPR decltype(std::declval<_A0>().get().*std::declval<_Fp>())
375__invoke(_Fp&& __f, _A0&& __a0)
376 _NOEXCEPT_(noexcept(__a0.get().*__f))
377 { return __a0.get().*__f; }
378
379template <class _Fp, class _A0,
380 class = __enable_if_bullet6<_Fp, _A0> >
381inline _LIBCPP_INLINE_VISIBILITY
382_LIBCPP_CONSTEXPR decltype((*std::declval<_A0>()).*std::declval<_Fp>())
383__invoke(_Fp&& __f, _A0&& __a0)
384 _NOEXCEPT_(noexcept((*static_cast<_A0&&>(__a0)).*__f))
385 { return (*static_cast<_A0&&>(__a0)).*__f; }
386
387// bullet 7
388
389template <class _Fp, class ..._Args>
390inline _LIBCPP_INLINE_VISIBILITY
391_LIBCPP_CONSTEXPR decltype(std::declval<_Fp>()(std::declval<_Args>()...))
392__invoke(_Fp&& __f, _Args&& ...__args)
393 _NOEXCEPT_(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...)))
394 { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); }
395
396// __invokable
397template <class _Ret, class _Fp, class ..._Args>
398struct __invokable_r
399{
400 template <class _XFp, class ..._XArgs>
401 static decltype(std::__invoke(std::declval<_XFp>(), std::declval<_XArgs>()...)) __try_call(int);
402 template <class _XFp, class ..._XArgs>
403 static __nat __try_call(...);
404
405 // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void,
406 // or incomplete array types as required by the standard.
407 using _Result = decltype(__try_call<_Fp, _Args...>(0));
408
409 using type = __conditional_t<
410 _IsNotSame<_Result, __nat>::value,
411 __conditional_t<is_void<_Ret>::value, true_type, __is_core_convertible<_Result, _Ret> >,
412 false_type>;
413 static const bool value = type::value;
414};
415template <class _Fp, class ..._Args>
416using __invokable = __invokable_r<void, _Fp, _Args...>;
417
418template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class ..._Args>
419struct __nothrow_invokable_r_imp {
420 static const bool value = false;
421};
422
423template <class _Ret, class _Fp, class ..._Args>
424struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...>
425{
426 typedef __nothrow_invokable_r_imp _ThisT;
427
428 template <class _Tp>
429 static void __test_noexcept(_Tp) _NOEXCEPT;
430
431#ifdef _LIBCPP_CXX03_LANG
432 static const bool value = false;
433#else
434 static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>(
435 _VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...)));
436#endif
437};
438
439template <class _Ret, class _Fp, class ..._Args>
440struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...>
441{
442#ifdef _LIBCPP_CXX03_LANG
443 static const bool value = false;
444#else
445 static const bool value = noexcept(
446 _VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...));
447#endif
448};
449
450template <class _Ret, class _Fp, class ..._Args>
451using __nothrow_invokable_r =
452 __nothrow_invokable_r_imp<
453 __invokable_r<_Ret, _Fp, _Args...>::value,
454 is_void<_Ret>::value,
455 _Ret, _Fp, _Args...
456 >;
457
458template <class _Fp, class ..._Args>
459using __nothrow_invokable =
460 __nothrow_invokable_r_imp<
461 __invokable<_Fp, _Args...>::value,
462 true, void, _Fp, _Args...
463 >;
464
465template <class _Fp, class ..._Args>
466struct __invoke_of
467 : public enable_if<
468 __invokable<_Fp, _Args...>::value,
469 typename __invokable_r<void, _Fp, _Args...>::_Result>
470{
471};
472
473template <class _Ret, bool = is_void<_Ret>::value>
474struct __invoke_void_return_wrapper
475{
476 template <class ..._Args>
477 static _Ret __call(_Args&&... __args) {
478 return std::__invoke(std::forward<_Args>(__args)...);
479 }
480};
481
482template <class _Ret>
483struct __invoke_void_return_wrapper<_Ret, true>
484{
485 template <class ..._Args>
486 static void __call(_Args&&... __args) {
487 std::__invoke(std::forward<_Args>(__args)...);
488 }
489};
490
491#if _LIBCPP_STD_VER > 14
492
493// is_invocable
494
495template <class _Fn, class ..._Args>
496struct _LIBCPP_TEMPLATE_VIS is_invocable
497 : integral_constant<bool, __invokable<_Fn, _Args...>::value> {};
498
499template <class _Ret, class _Fn, class ..._Args>
500struct _LIBCPP_TEMPLATE_VIS is_invocable_r
501 : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {};
502
503template <class _Fn, class ..._Args>
504inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
505
506template <class _Ret, class _Fn, class ..._Args>
507inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value;
508
509// is_nothrow_invocable
510
511template <class _Fn, class ..._Args>
512struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable
513 : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {};
514
515template <class _Ret, class _Fn, class ..._Args>
516struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r
517 : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {};
518
519template <class _Fn, class ..._Args>
520inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value;
521
522template <class _Ret, class _Fn, class ..._Args>
523inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
524
525template <class _Fn, class... _Args>
526struct _LIBCPP_TEMPLATE_VIS invoke_result
527 : __invoke_of<_Fn, _Args...>
528{
529};
530
531template <class _Fn, class... _Args>
532using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
23#if _LIBCPP_STD_VER >= 17
53324
53425template <class _Fn, class ..._Args>
53526_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 invoke_result_t<_Fn, _Args...>
......@@ -539,7 +30,26 @@ invoke(_Fn&& __f, _Args&&... __args)
53930 return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
54031}
54132
542#endif // _LIBCPP_STD_VER > 14
33#endif // _LIBCPP_STD_VER >= 17
34
35#if _LIBCPP_STD_VER >= 23
36template <class _Result, class _Fn, class... _Args>
37 requires is_invocable_r_v<_Result, _Fn, _Args...>
38_LIBCPP_HIDE_FROM_ABI constexpr _Result
39invoke_r(_Fn&& __f, _Args&&... __args) noexcept(is_nothrow_invocable_r_v<_Result, _Fn, _Args...>) {
40 if constexpr (is_void_v<_Result>) {
41 static_cast<void>(std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...));
42 } else {
43 // TODO: Use reference_converts_from_temporary_v once implemented
44 // using _ImplicitInvokeResult = invoke_result_t<_Fn, _Args...>;
45 // static_assert(!reference_converts_from_temporary_v<_Result, _ImplicitInvokeResult>,
46 static_assert(true,
47 "Returning from invoke_r would bind a temporary object to the reference return type, "
48 "which would result in a dangling reference.");
49 return std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...);
50 }
51}
52#endif
54353
54454_LIBCPP_END_NAMESPACE_STD
54555
lib/libcxx/include/__functional/is_transparent.h+3-2
......@@ -11,7 +11,8 @@
1111#define _LIBCPP___FUNCTIONAL_IS_TRANSPARENT
1212
1313#include <__config>
14#include <type_traits>
14#include <__type_traits/integral_constant.h>
15#include <__type_traits/void_t.h>
1516
1617#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1718# pragma GCC system_header
......@@ -19,7 +20,7 @@
1920
2021_LIBCPP_BEGIN_NAMESPACE_STD
2122
22#if _LIBCPP_STD_VER > 11
23#if _LIBCPP_STD_VER >= 14
2324
2425template <class _Tp, class, class = void>
2526struct __is_transparent : false_type {};
lib/libcxx/include/__functional/mem_fn.h-1
......@@ -15,7 +15,6 @@
1515#include <__functional/invoke.h>
1616#include <__functional/weak_result_type.h>
1717#include <__utility/forward.h>
18#include <type_traits>
1918
2019#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2120# pragma GCC system_header
lib/libcxx/include/__functional/not_fn.h+6-3
......@@ -13,8 +13,11 @@
1313#include <__config>
1414#include <__functional/invoke.h>
1515#include <__functional/perfect_forward.h>
16#include <__type_traits/decay.h>
17#include <__type_traits/enable_if.h>
18#include <__type_traits/is_constructible.h>
19#include <__type_traits/is_move_constructible.h>
1620#include <__utility/forward.h>
17#include <type_traits>
1821
1922#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2023# pragma GCC system_header
......@@ -22,7 +25,7 @@
2225
2326_LIBCPP_BEGIN_NAMESPACE_STD
2427
25#if _LIBCPP_STD_VER > 14
28#if _LIBCPP_STD_VER >= 17
2629
2730struct __not_fn_op {
2831 template <class... _Args>
......@@ -47,7 +50,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 auto not_fn(_Fn&& __f) {
4750 return __not_fn_t<decay_t<_Fn>>(_VSTD::forward<_Fn>(__f));
4851}
4952
50#endif // _LIBCPP_STD_VER > 14
53#endif // _LIBCPP_STD_VER >= 17
5154
5255_LIBCPP_END_NAMESPACE_STD
5356
lib/libcxx/include/__functional/operations.h+56-37
......@@ -13,6 +13,9 @@
1313#include <__config>
1414#include <__functional/binary_function.h>
1515#include <__functional/unary_function.h>
16#include <__type_traits/integral_constant.h>
17#include <__type_traits/operation_traits.h>
18#include <__type_traits/predicate_traits.h>
1619#include <__utility/forward.h>
1720
1821#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -23,7 +26,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2326
2427// Arithmetic operations
2528
26#if _LIBCPP_STD_VER > 11
29#if _LIBCPP_STD_VER >= 14
2730template <class _Tp = void>
2831#else
2932template <class _Tp>
......@@ -38,7 +41,15 @@ struct _LIBCPP_TEMPLATE_VIS plus
3841};
3942_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus);
4043
41#if _LIBCPP_STD_VER > 11
44template <class _Tp>
45struct __is_trivial_plus_operation<plus<_Tp>, _Tp, _Tp> : true_type {};
46
47#if _LIBCPP_STD_VER >= 14
48template <class _Tp, class _Up>
49struct __is_trivial_plus_operation<plus<>, _Tp, _Up> : true_type {};
50#endif
51
52#if _LIBCPP_STD_VER >= 14
4253template <>
4354struct _LIBCPP_TEMPLATE_VIS plus<void>
4455{
......@@ -52,7 +63,7 @@ struct _LIBCPP_TEMPLATE_VIS plus<void>
5263};
5364#endif
5465
55#if _LIBCPP_STD_VER > 11
66#if _LIBCPP_STD_VER >= 14
5667template <class _Tp = void>
5768#else
5869template <class _Tp>
......@@ -67,7 +78,7 @@ struct _LIBCPP_TEMPLATE_VIS minus
6778};
6879_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus);
6980
70#if _LIBCPP_STD_VER > 11
81#if _LIBCPP_STD_VER >= 14
7182template <>
7283struct _LIBCPP_TEMPLATE_VIS minus<void>
7384{
......@@ -81,7 +92,7 @@ struct _LIBCPP_TEMPLATE_VIS minus<void>
8192};
8293#endif
8394
84#if _LIBCPP_STD_VER > 11
95#if _LIBCPP_STD_VER >= 14
8596template <class _Tp = void>
8697#else
8798template <class _Tp>
......@@ -96,7 +107,7 @@ struct _LIBCPP_TEMPLATE_VIS multiplies
96107};
97108_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies);
98109
99#if _LIBCPP_STD_VER > 11
110#if _LIBCPP_STD_VER >= 14
100111template <>
101112struct _LIBCPP_TEMPLATE_VIS multiplies<void>
102113{
......@@ -110,7 +121,7 @@ struct _LIBCPP_TEMPLATE_VIS multiplies<void>
110121};
111122#endif
112123
113#if _LIBCPP_STD_VER > 11
124#if _LIBCPP_STD_VER >= 14
114125template <class _Tp = void>
115126#else
116127template <class _Tp>
......@@ -125,7 +136,7 @@ struct _LIBCPP_TEMPLATE_VIS divides
125136};
126137_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides);
127138
128#if _LIBCPP_STD_VER > 11
139#if _LIBCPP_STD_VER >= 14
129140template <>
130141struct _LIBCPP_TEMPLATE_VIS divides<void>
131142{
......@@ -139,7 +150,7 @@ struct _LIBCPP_TEMPLATE_VIS divides<void>
139150};
140151#endif
141152
142#if _LIBCPP_STD_VER > 11
153#if _LIBCPP_STD_VER >= 14
143154template <class _Tp = void>
144155#else
145156template <class _Tp>
......@@ -154,7 +165,7 @@ struct _LIBCPP_TEMPLATE_VIS modulus
154165};
155166_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus);
156167
157#if _LIBCPP_STD_VER > 11
168#if _LIBCPP_STD_VER >= 14
158169template <>
159170struct _LIBCPP_TEMPLATE_VIS modulus<void>
160171{
......@@ -168,7 +179,7 @@ struct _LIBCPP_TEMPLATE_VIS modulus<void>
168179};
169180#endif
170181
171#if _LIBCPP_STD_VER > 11
182#if _LIBCPP_STD_VER >= 14
172183template <class _Tp = void>
173184#else
174185template <class _Tp>
......@@ -183,7 +194,7 @@ struct _LIBCPP_TEMPLATE_VIS negate
183194};
184195_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate);
185196
186#if _LIBCPP_STD_VER > 11
197#if _LIBCPP_STD_VER >= 14
187198template <>
188199struct _LIBCPP_TEMPLATE_VIS negate<void>
189200{
......@@ -199,7 +210,7 @@ struct _LIBCPP_TEMPLATE_VIS negate<void>
199210
200211// Bitwise operations
201212
202#if _LIBCPP_STD_VER > 11
213#if _LIBCPP_STD_VER >= 14
203214template <class _Tp = void>
204215#else
205216template <class _Tp>
......@@ -214,7 +225,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_and
214225};
215226_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and);
216227
217#if _LIBCPP_STD_VER > 11
228#if _LIBCPP_STD_VER >= 14
218229template <>
219230struct _LIBCPP_TEMPLATE_VIS bit_and<void>
220231{
......@@ -228,7 +239,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_and<void>
228239};
229240#endif
230241
231#if _LIBCPP_STD_VER > 11
242#if _LIBCPP_STD_VER >= 14
232243template <class _Tp = void>
233244struct _LIBCPP_TEMPLATE_VIS bit_not
234245 : __unary_function<_Tp, _Tp>
......@@ -252,7 +263,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_not<void>
252263};
253264#endif
254265
255#if _LIBCPP_STD_VER > 11
266#if _LIBCPP_STD_VER >= 14
256267template <class _Tp = void>
257268#else
258269template <class _Tp>
......@@ -267,7 +278,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_or
267278};
268279_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or);
269280
270#if _LIBCPP_STD_VER > 11
281#if _LIBCPP_STD_VER >= 14
271282template <>
272283struct _LIBCPP_TEMPLATE_VIS bit_or<void>
273284{
......@@ -281,7 +292,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_or<void>
281292};
282293#endif
283294
284#if _LIBCPP_STD_VER > 11
295#if _LIBCPP_STD_VER >= 14
285296template <class _Tp = void>
286297#else
287298template <class _Tp>
......@@ -296,7 +307,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_xor
296307};
297308_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor);
298309
299#if _LIBCPP_STD_VER > 11
310#if _LIBCPP_STD_VER >= 14
300311template <>
301312struct _LIBCPP_TEMPLATE_VIS bit_xor<void>
302313{
......@@ -312,7 +323,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_xor<void>
312323
313324// Comparison operations
314325
315#if _LIBCPP_STD_VER > 11
326#if _LIBCPP_STD_VER >= 14
316327template <class _Tp = void>
317328#else
318329template <class _Tp>
......@@ -327,7 +338,7 @@ struct _LIBCPP_TEMPLATE_VIS equal_to
327338};
328339_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to);
329340
330#if _LIBCPP_STD_VER > 11
341#if _LIBCPP_STD_VER >= 14
331342template <>
332343struct _LIBCPP_TEMPLATE_VIS equal_to<void>
333344{
......@@ -341,7 +352,15 @@ struct _LIBCPP_TEMPLATE_VIS equal_to<void>
341352};
342353#endif
343354
344#if _LIBCPP_STD_VER > 11
355template <class _Tp>
356struct __is_trivial_equality_predicate<equal_to<_Tp>, _Tp, _Tp> : true_type {};
357
358#if _LIBCPP_STD_VER >= 14
359template <class _Tp>
360struct __is_trivial_equality_predicate<equal_to<>, _Tp, _Tp> : true_type {};
361#endif
362
363#if _LIBCPP_STD_VER >= 14
345364template <class _Tp = void>
346365#else
347366template <class _Tp>
......@@ -356,7 +375,7 @@ struct _LIBCPP_TEMPLATE_VIS not_equal_to
356375};
357376_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to);
358377
359#if _LIBCPP_STD_VER > 11
378#if _LIBCPP_STD_VER >= 14
360379template <>
361380struct _LIBCPP_TEMPLATE_VIS not_equal_to<void>
362381{
......@@ -370,7 +389,7 @@ struct _LIBCPP_TEMPLATE_VIS not_equal_to<void>
370389};
371390#endif
372391
373#if _LIBCPP_STD_VER > 11
392#if _LIBCPP_STD_VER >= 14
374393template <class _Tp = void>
375394#else
376395template <class _Tp>
......@@ -385,7 +404,7 @@ struct _LIBCPP_TEMPLATE_VIS less
385404};
386405_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less);
387406
388#if _LIBCPP_STD_VER > 11
407#if _LIBCPP_STD_VER >= 14
389408template <>
390409struct _LIBCPP_TEMPLATE_VIS less<void>
391410{
......@@ -399,7 +418,7 @@ struct _LIBCPP_TEMPLATE_VIS less<void>
399418};
400419#endif
401420
402#if _LIBCPP_STD_VER > 11
421#if _LIBCPP_STD_VER >= 14
403422template <class _Tp = void>
404423#else
405424template <class _Tp>
......@@ -414,7 +433,7 @@ struct _LIBCPP_TEMPLATE_VIS less_equal
414433};
415434_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal);
416435
417#if _LIBCPP_STD_VER > 11
436#if _LIBCPP_STD_VER >= 14
418437template <>
419438struct _LIBCPP_TEMPLATE_VIS less_equal<void>
420439{
......@@ -428,7 +447,7 @@ struct _LIBCPP_TEMPLATE_VIS less_equal<void>
428447};
429448#endif
430449
431#if _LIBCPP_STD_VER > 11
450#if _LIBCPP_STD_VER >= 14
432451template <class _Tp = void>
433452#else
434453template <class _Tp>
......@@ -443,7 +462,7 @@ struct _LIBCPP_TEMPLATE_VIS greater_equal
443462};
444463_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal);
445464
446#if _LIBCPP_STD_VER > 11
465#if _LIBCPP_STD_VER >= 14
447466template <>
448467struct _LIBCPP_TEMPLATE_VIS greater_equal<void>
449468{
......@@ -457,7 +476,7 @@ struct _LIBCPP_TEMPLATE_VIS greater_equal<void>
457476};
458477#endif
459478
460#if _LIBCPP_STD_VER > 11
479#if _LIBCPP_STD_VER >= 14
461480template <class _Tp = void>
462481#else
463482template <class _Tp>
......@@ -472,7 +491,7 @@ struct _LIBCPP_TEMPLATE_VIS greater
472491};
473492_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater);
474493
475#if _LIBCPP_STD_VER > 11
494#if _LIBCPP_STD_VER >= 14
476495template <>
477496struct _LIBCPP_TEMPLATE_VIS greater<void>
478497{
......@@ -488,7 +507,7 @@ struct _LIBCPP_TEMPLATE_VIS greater<void>
488507
489508// Logical operations
490509
491#if _LIBCPP_STD_VER > 11
510#if _LIBCPP_STD_VER >= 14
492511template <class _Tp = void>
493512#else
494513template <class _Tp>
......@@ -503,7 +522,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_and
503522};
504523_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and);
505524
506#if _LIBCPP_STD_VER > 11
525#if _LIBCPP_STD_VER >= 14
507526template <>
508527struct _LIBCPP_TEMPLATE_VIS logical_and<void>
509528{
......@@ -517,7 +536,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_and<void>
517536};
518537#endif
519538
520#if _LIBCPP_STD_VER > 11
539#if _LIBCPP_STD_VER >= 14
521540template <class _Tp = void>
522541#else
523542template <class _Tp>
......@@ -532,7 +551,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_not
532551};
533552_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not);
534553
535#if _LIBCPP_STD_VER > 11
554#if _LIBCPP_STD_VER >= 14
536555template <>
537556struct _LIBCPP_TEMPLATE_VIS logical_not<void>
538557{
......@@ -546,7 +565,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_not<void>
546565};
547566#endif
548567
549#if _LIBCPP_STD_VER > 11
568#if _LIBCPP_STD_VER >= 14
550569template <class _Tp = void>
551570#else
552571template <class _Tp>
......@@ -561,7 +580,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_or
561580};
562581_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or);
563582
564#if _LIBCPP_STD_VER > 11
583#if _LIBCPP_STD_VER >= 14
565584template <>
566585struct _LIBCPP_TEMPLATE_VIS logical_or<void>
567586{
lib/libcxx/include/__functional/perfect_forward.h+16-8
......@@ -11,19 +11,25 @@
1111#define _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H
1212
1313#include <__config>
14#include <__type_traits/enable_if.h>
15#include <__type_traits/invoke.h>
16#include <__type_traits/is_constructible.h>
1417#include <__utility/declval.h>
1518#include <__utility/forward.h>
19#include <__utility/integer_sequence.h>
1620#include <__utility/move.h>
1721#include <tuple>
18#include <type_traits>
1922
2023#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2124# pragma GCC system_header
2225#endif
2326
27_LIBCPP_PUSH_MACROS
28#include <__undef_macros>
29
2430_LIBCPP_BEGIN_NAMESPACE_STD
2531
26#if _LIBCPP_STD_VER > 14
32#if _LIBCPP_STD_VER >= 17
2733
2834template <class _Op, class _Indices, class... _BoundArgs>
2935struct __perfect_forward_impl;
......@@ -37,14 +43,14 @@ public:
3743 template <class... _Args, class = enable_if_t<
3844 is_constructible_v<tuple<_BoundArgs...>, _Args&&...>
3945 >>
40 explicit constexpr __perfect_forward_impl(_Args&&... __bound_args)
46 _LIBCPP_HIDE_FROM_ABI explicit constexpr __perfect_forward_impl(_Args&&... __bound_args)
4147 : __bound_args_(_VSTD::forward<_Args>(__bound_args)...) {}
4248
43 __perfect_forward_impl(__perfect_forward_impl const&) = default;
44 __perfect_forward_impl(__perfect_forward_impl&&) = default;
49 _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl(__perfect_forward_impl const&) = default;
50 _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl(__perfect_forward_impl&&) = default;
4551
46 __perfect_forward_impl& operator=(__perfect_forward_impl const&) = default;
47 __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default;
52 _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl& operator=(__perfect_forward_impl const&) = default;
53 _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default;
4854
4955 template <class... _Args, class = enable_if_t<is_invocable_v<_Op, _BoundArgs&..., _Args...>>>
5056 _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) &
......@@ -87,8 +93,10 @@ public:
8793template <class _Op, class ..._Args>
8894using __perfect_forward = __perfect_forward_impl<_Op, index_sequence_for<_Args...>, _Args...>;
8995
90#endif // _LIBCPP_STD_VER > 14
96#endif // _LIBCPP_STD_VER >= 17
9197
9298_LIBCPP_END_NAMESPACE_STD
9399
100_LIBCPP_POP_MACROS
101
94102#endif // _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H
lib/libcxx/include/__functional/ranges_operations.h+13-8
......@@ -13,6 +13,8 @@
1313#include <__concepts/equality_comparable.h>
1414#include <__concepts/totally_ordered.h>
1515#include <__config>
16#include <__type_traits/integral_constant.h>
17#include <__type_traits/predicate_traits.h>
1618#include <__utility/forward.h>
1719
1820#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -21,14 +23,14 @@
2123
2224_LIBCPP_BEGIN_NAMESPACE_STD
2325
24#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2527
2628namespace ranges {
2729
2830struct equal_to {
2931 template <class _Tp, class _Up>
3032 requires equality_comparable_with<_Tp, _Up>
31 [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
33 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const
3234 noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)))) {
3335 return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u);
3436 }
......@@ -39,7 +41,7 @@ struct equal_to {
3941struct not_equal_to {
4042 template <class _Tp, class _Up>
4143 requires equality_comparable_with<_Tp, _Up>
42 [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
44 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const
4345 noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u))))) {
4446 return !(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u));
4547 }
......@@ -50,7 +52,7 @@ struct not_equal_to {
5052struct less {
5153 template <class _Tp, class _Up>
5254 requires totally_ordered_with<_Tp, _Up>
53 [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
55 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const
5456 noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)))) {
5557 return _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u);
5658 }
......@@ -61,7 +63,7 @@ struct less {
6163struct less_equal {
6264 template <class _Tp, class _Up>
6365 requires totally_ordered_with<_Tp, _Up>
64 [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
66 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const
6567 noexcept(noexcept(bool(!(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t))))) {
6668 return !(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t));
6769 }
......@@ -72,7 +74,7 @@ struct less_equal {
7274struct greater {
7375 template <class _Tp, class _Up>
7476 requires totally_ordered_with<_Tp, _Up>
75 [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
77 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const
7678 noexcept(noexcept(bool(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)))) {
7779 return _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t);
7880 }
......@@ -83,7 +85,7 @@ struct greater {
8385struct greater_equal {
8486 template <class _Tp, class _Up>
8587 requires totally_ordered_with<_Tp, _Up>
86 [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
88 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const
8789 noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u))))) {
8890 return !(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u));
8991 }
......@@ -93,7 +95,10 @@ struct greater_equal {
9395
9496} // namespace ranges
9597
96#endif // _LIBCPP_STD_VER > 17
98template <class _Lhs, class _Rhs>
99struct __is_trivial_equality_predicate<ranges::equal_to, _Lhs, _Rhs> : true_type {};
100
101#endif // _LIBCPP_STD_VER >= 20
97102
98103_LIBCPP_END_NAMESPACE_STD
99104
lib/libcxx/include/__functional/reference_wrapper.h+8-2
......@@ -55,12 +55,18 @@ public:
5555 template <class... _ArgTypes>
5656 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
5757 typename __invoke_of<type&, _ArgTypes...>::type
58 operator() (_ArgTypes&&... __args) const {
58 operator() (_ArgTypes&&... __args) const
59#if _LIBCPP_STD_VER >= 17
60 // Since is_nothrow_invocable requires C++17 LWG3764 is not backported
61 // to earlier versions.
62 noexcept(is_nothrow_invocable_v<_Tp&, _ArgTypes...>)
63#endif
64 {
5965 return std::__invoke(get(), std::forward<_ArgTypes>(__args)...);
6066 }
6167};
6268
63#if _LIBCPP_STD_VER > 14
69#if _LIBCPP_STD_VER >= 17
6470template <class _Tp>
6571reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
6672#endif
lib/libcxx/include/__functional/unwrap_ref.h deleted-58
......@@ -1,58 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___FUNCTIONAL_UNWRAP_REF_H
10#define _LIBCPP___FUNCTIONAL_UNWRAP_REF_H
11
12#include <__config>
13#include <__type_traits/decay.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21template <class _Tp>
22struct __unwrap_reference { typedef _LIBCPP_NODEBUG _Tp type; };
23
24template <class _Tp>
25class reference_wrapper;
26
27template <class _Tp>
28struct __unwrap_reference<reference_wrapper<_Tp> > { typedef _LIBCPP_NODEBUG _Tp& type; };
29
30template <class _Tp>
31struct decay;
32
33#if _LIBCPP_STD_VER > 17
34template <class _Tp>
35struct unwrap_reference : __unwrap_reference<_Tp> { };
36
37template <class _Tp>
38using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
39
40template <class _Tp>
41struct unwrap_ref_decay : unwrap_reference<typename decay<_Tp>::type> { };
42
43template <class _Tp>
44using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
45#endif // > C++17
46
47template <class _Tp>
48struct __unwrap_ref_decay
49#if _LIBCPP_STD_VER > 17
50 : unwrap_ref_decay<_Tp>
51#else
52 : __unwrap_reference<typename decay<_Tp>::type>
53#endif
54{ };
55
56_LIBCPP_END_NAMESPACE_STD
57
58#endif // _LIBCPP___FUNCTIONAL_UNWRAP_REF_H
lib/libcxx/include/__fwd/fstream.h created+53
......@@ -0,0 +1,53 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___FWD_FSTREAM_H
10#define _LIBCPP___FWD_FSTREAM_H
11
12#include <__config>
13#include <__fwd/string.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21template <class _CharT, class _Traits = char_traits<_CharT> >
22class _LIBCPP_TEMPLATE_VIS basic_filebuf;
23template <class _CharT, class _Traits = char_traits<_CharT> >
24class _LIBCPP_TEMPLATE_VIS basic_ifstream;
25template <class _CharT, class _Traits = char_traits<_CharT> >
26class _LIBCPP_TEMPLATE_VIS basic_ofstream;
27template <class _CharT, class _Traits = char_traits<_CharT> >
28class _LIBCPP_TEMPLATE_VIS basic_fstream;
29
30using filebuf = basic_filebuf<char>;
31using ifstream = basic_ifstream<char>;
32using ofstream = basic_ofstream<char>;
33using fstream = basic_fstream<char>;
34
35#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
36using wfilebuf = basic_filebuf<wchar_t>;
37using wifstream = basic_ifstream<wchar_t>;
38using wofstream = basic_ofstream<wchar_t>;
39using wfstream = basic_fstream<wchar_t>;
40#endif
41
42template <class _CharT, class _Traits>
43class _LIBCPP_PREFERRED_NAME(filebuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wfilebuf)) basic_filebuf;
44template <class _CharT, class _Traits>
45class _LIBCPP_PREFERRED_NAME(ifstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wifstream)) basic_ifstream;
46template <class _CharT, class _Traits>
47class _LIBCPP_PREFERRED_NAME(ofstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wofstream)) basic_ofstream;
48template <class _CharT, class _Traits>
49class _LIBCPP_PREFERRED_NAME(fstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wfstream)) basic_fstream;
50
51_LIBCPP_END_NAMESPACE_STD
52
53#endif // _LIBCPP___FWD_FSTREAM_H
lib/libcxx/include/__fwd/get.h+1-1
......@@ -15,7 +15,7 @@
1515#include <__fwd/pair.h>
1616#include <__fwd/subrange.h>
1717#include <__fwd/tuple.h>
18#include <__tuple_dir/tuple_element.h>
18#include <__tuple/tuple_element.h>
1919#include <cstddef>
2020
2121#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
lib/libcxx/include/__fwd/ios.h created+41
......@@ -0,0 +1,41 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___FWD_IOS_H
10#define _LIBCPP___FWD_IOS_H
11
12#include <__config>
13#include <__fwd/string.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21template <class _CharT, class _Traits = char_traits<_CharT> >
22class _LIBCPP_TEMPLATE_VIS basic_ios;
23
24using ios = basic_ios<char>;
25#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
26using wios = basic_ios<wchar_t>;
27#endif
28
29template <class _CharT, class _Traits>
30class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios;
31
32#if defined(_NEWLIB_VERSION)
33// On newlib, off_t is 'long int'
34using streamoff = long int; // for char_traits in <string>
35#else
36using streamoff = long long; // for char_traits in <string>
37#endif
38
39_LIBCPP_END_NAMESPACE_STD
40
41#endif // _LIBCPP___FWD_IOS_H
lib/libcxx/include/__fwd/istream.h created+43
......@@ -0,0 +1,43 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___FWD_ISTREAM_H
10#define _LIBCPP___FWD_ISTREAM_H
11
12#include <__config>
13#include <__fwd/string.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21template <class _CharT, class _Traits = char_traits<_CharT> >
22class _LIBCPP_TEMPLATE_VIS basic_istream;
23
24template <class _CharT, class _Traits = char_traits<_CharT> >
25class _LIBCPP_TEMPLATE_VIS basic_iostream;
26
27using istream = basic_istream<char>;
28using iostream = basic_iostream<char>;
29
30#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
31using wistream = basic_istream<wchar_t>;
32using wiostream = basic_iostream<wchar_t>;
33#endif
34
35template <class _CharT, class _Traits>
36class _LIBCPP_PREFERRED_NAME(istream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wistream)) basic_istream;
37
38template <class _CharT, class _Traits>
39class _LIBCPP_PREFERRED_NAME(iostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wiostream)) basic_iostream;
40
41_LIBCPP_END_NAMESPACE_STD
42
43#endif // _LIBCPP___FWD_ISTREAM_H
lib/libcxx/include/__fwd/mdspan.h created+60
......@@ -0,0 +1,60 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8// Kokkos v. 4.0
9// Copyright (2022) National Technology & Engineering
10// Solutions of Sandia, LLC (NTESS).
11//
12// Under the terms of Contract DE-NA0003525 with NTESS,
13// the U.S. Government retains certain rights in this software.
14//
15//===---------------------------------------------------------------------===//
16
17#ifndef _LIBCPP___MDSPAN_LAYOUTS_H
18#define _LIBCPP___MDSPAN_LAYOUTS_H
19
20#include <__config>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23# pragma GCC system_header
24#endif
25
26_LIBCPP_PUSH_MACROS
27#include <__undef_macros>
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31#if _LIBCPP_STD_VER >= 23
32
33// Layout policy with a mapping which corresponds to FORTRAN-style array layouts
34struct layout_left {
35 template <class _Extents>
36 class mapping;
37};
38
39// Layout policy with a mapping which corresponds to C-style array layouts
40struct layout_right {
41 template <class _Extents>
42 class mapping;
43};
44
45/*
46// Will be implemented with follow on revision
47// Layout policy with a unique mapping where strides are arbitrary
48struct layout_stride {
49 template<class Extents>
50 class mapping;
51};
52*/
53
54#endif // _LIBCPP_STD_VER >= 23
55
56_LIBCPP_END_NAMESPACE_STD
57
58_LIBCPP_POP_MACROS
59
60#endif // _LIBCPP___MDSPAN_LAYOUTS_H
lib/libcxx/include/__fwd/memory_resource.h+2-1
......@@ -9,6 +9,7 @@
99#ifndef _LIBCPP___FWD_MEMORY_RESOURCE_H
1010#define _LIBCPP___FWD_MEMORY_RESOURCE_H
1111
12#include <__availability>
1213#include <__config>
1314
1415#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -19,7 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
1920
2021namespace pmr {
2122template <class _ValueType>
22class _LIBCPP_TEMPLATE_VIS polymorphic_allocator;
23class _LIBCPP_AVAILABILITY_PMR _LIBCPP_TEMPLATE_VIS polymorphic_allocator;
2324} // namespace pmr
2425
2526_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__fwd/ostream.h created+35
......@@ -0,0 +1,35 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___FWD_OSTREAM_H
10#define _LIBCPP___FWD_OSTREAM_H
11
12#include <__config>
13#include <__fwd/string.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21template <class _CharT, class _Traits = char_traits<_CharT> >
22class _LIBCPP_TEMPLATE_VIS basic_ostream;
23
24using ostream = basic_ostream<char>;
25
26#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
27using wostream = basic_ostream<wchar_t>;
28#endif
29
30template <class _CharT, class _Traits>
31class _LIBCPP_PREFERRED_NAME(ostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wostream)) basic_ostream;
32
33_LIBCPP_END_NAMESPACE_STD
34
35#endif // _LIBCPP___FWD_OSTREAM_H
lib/libcxx/include/__fwd/span.h+1-1
......@@ -23,7 +23,7 @@ _LIBCPP_PUSH_MACROS
2323
2424_LIBCPP_BEGIN_NAMESPACE_STD
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
2929template <typename _Tp, size_t _Extent = dynamic_extent> class span;
lib/libcxx/include/__fwd/sstream.h created+57
......@@ -0,0 +1,57 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___FWD_SSTREAM_H
10#define _LIBCPP___FWD_SSTREAM_H
11
12#include <__config>
13#include <__fwd/string.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> >
22class _LIBCPP_TEMPLATE_VIS basic_stringbuf;
23
24template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> >
25class _LIBCPP_TEMPLATE_VIS basic_istringstream;
26template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> >
27class _LIBCPP_TEMPLATE_VIS basic_ostringstream;
28template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> >
29class _LIBCPP_TEMPLATE_VIS basic_stringstream;
30
31using stringbuf = basic_stringbuf<char>;
32using istringstream = basic_istringstream<char>;
33using ostringstream = basic_ostringstream<char>;
34using stringstream = basic_stringstream<char>;
35
36#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
37using wstringbuf = basic_stringbuf<wchar_t>;
38using wistringstream = basic_istringstream<wchar_t>;
39using wostringstream = basic_ostringstream<wchar_t>;
40using wstringstream = basic_stringstream<wchar_t>;
41#endif
42
43template <class _CharT, class _Traits, class _Allocator>
44class _LIBCPP_PREFERRED_NAME(stringbuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstringbuf)) basic_stringbuf;
45template <class _CharT, class _Traits, class _Allocator>
46class _LIBCPP_PREFERRED_NAME(istringstream)
47 _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wistringstream)) basic_istringstream;
48template <class _CharT, class _Traits, class _Allocator>
49class _LIBCPP_PREFERRED_NAME(ostringstream)
50 _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wostringstream)) basic_ostringstream;
51template <class _CharT, class _Traits, class _Allocator>
52class _LIBCPP_PREFERRED_NAME(stringstream)
53 _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstringstream)) basic_stringstream;
54
55_LIBCPP_END_NAMESPACE_STD
56
57#endif // _LIBCPP___FWD_SSTREAM_H
lib/libcxx/include/__fwd/streambuf.h created+35
......@@ -0,0 +1,35 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___FWD_STREAMBUF_H
10#define _LIBCPP___FWD_STREAMBUF_H
11
12#include <__config>
13#include <__fwd/string.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21template <class _CharT, class _Traits = char_traits<_CharT> >
22class _LIBCPP_TEMPLATE_VIS basic_streambuf;
23
24using streambuf = basic_streambuf<char>;
25
26#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
27using wstreambuf = basic_streambuf<wchar_t>;
28#endif
29
30template <class _CharT, class _Traits>
31class _LIBCPP_PREFERRED_NAME(streambuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstreambuf)) basic_streambuf;
32
33_LIBCPP_END_NAMESPACE_STD
34
35#endif // _LIBCPP___FWD_STREAMBUF_H
lib/libcxx/include/__fwd/string.h+7-7
......@@ -9,6 +9,7 @@
99#ifndef _LIBCPP___FWD_STRING_H
1010#define _LIBCPP___FWD_STRING_H
1111
12#include <__availability>
1213#include <__config>
1314#include <__fwd/memory_resource.h>
1415
......@@ -61,21 +62,20 @@ using u32string = basic_string<char32_t>;
6162
6263namespace pmr {
6364template <class _CharT, class _Traits = char_traits<_CharT>>
64using basic_string = std::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>;
65using basic_string _LIBCPP_AVAILABILITY_PMR = std::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>;
6566
66using string = basic_string<char>;
67using string _LIBCPP_AVAILABILITY_PMR = basic_string<char>;
6768
6869# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
69using wstring = basic_string<wchar_t>;
70using wstring _LIBCPP_AVAILABILITY_PMR = basic_string<wchar_t>;
7071# endif
7172
7273# ifndef _LIBCPP_HAS_NO_CHAR8_T
73using u8string = basic_string<char8_t>;
74using u8string _LIBCPP_AVAILABILITY_PMR = basic_string<char8_t>;
7475# endif
7576
76using u16string = basic_string<char16_t>;
77using u32string = basic_string<char32_t>;
78
77using u16string _LIBCPP_AVAILABILITY_PMR = basic_string<char16_t>;
78using u32string _LIBCPP_AVAILABILITY_PMR = basic_string<char32_t>;
7979} // namespace pmr
8080
8181#endif // _LIBCPP_STD_VER >= 17
lib/libcxx/include/__hash_table+112-344
......@@ -15,8 +15,8 @@
1515#include <__assert>
1616#include <__bit/countl.h>
1717#include <__config>
18#include <__debug>
1918#include <__functional/hash.h>
19#include <__functional/invoke.h>
2020#include <__iterator/iterator_traits.h>
2121#include <__memory/addressof.h>
2222#include <__memory/allocator_traits.h>
......@@ -25,6 +25,19 @@
2525#include <__memory/swap_allocator.h>
2626#include <__memory/unique_ptr.h>
2727#include <__type_traits/can_extract_key.h>
28#include <__type_traits/conditional.h>
29#include <__type_traits/is_const.h>
30#include <__type_traits/is_copy_constructible.h>
31#include <__type_traits/is_nothrow_constructible.h>
32#include <__type_traits/is_nothrow_copy_constructible.h>
33#include <__type_traits/is_nothrow_default_constructible.h>
34#include <__type_traits/is_nothrow_move_assignable.h>
35#include <__type_traits/is_nothrow_move_constructible.h>
36#include <__type_traits/is_pointer.h>
37#include <__type_traits/is_reference.h>
38#include <__type_traits/is_swappable.h>
39#include <__type_traits/remove_const.h>
40#include <__type_traits/remove_cvref.h>
2841#include <__utility/forward.h>
2942#include <__utility/move.h>
3043#include <__utility/pair.h>
......@@ -32,7 +45,6 @@
3245#include <cmath>
3346#include <cstring>
3447#include <initializer_list>
35#include <type_traits>
3648
3749#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3850# pragma GCC system_header
......@@ -59,8 +71,7 @@ struct __is_hash_value_type : false_type {};
5971template <class _One>
6072struct __is_hash_value_type<_One> : __is_hash_value_type_imp<__remove_cvref_t<_One> > {};
6173
62_LIBCPP_FUNC_VIS
63size_t __next_prime(size_t __n);
74_LIBCPP_EXPORTED_FROM_ABI size_t __next_prime(size_t __n);
6475
6576template <class _NodePtr>
6677struct __hash_node_base
......@@ -296,53 +307,20 @@ public:
296307 typedef typename _NodeTypes::__node_value_type_pointer pointer;
297308
298309 _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) {
299 _VSTD::__debug_db_insert_i(this);
300310 }
301311
302#ifdef _LIBCPP_ENABLE_DEBUG_MODE
303 _LIBCPP_INLINE_VISIBILITY
304 __hash_iterator(const __hash_iterator& __i)
305 : __node_(__i.__node_)
306 {
307 __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
308 }
309
310 _LIBCPP_INLINE_VISIBILITY
311 ~__hash_iterator()
312 {
313 __get_db()->__erase_i(this);
314 }
315
316 _LIBCPP_INLINE_VISIBILITY
317 __hash_iterator& operator=(const __hash_iterator& __i)
318 {
319 if (this != _VSTD::addressof(__i))
320 {
321 __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
322 __node_ = __i.__node_;
323 }
324 return *this;
325 }
326#endif // _LIBCPP_ENABLE_DEBUG_MODE
327
328312 _LIBCPP_INLINE_VISIBILITY
329313 reference operator*() const {
330 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
331 "Attempted to dereference a non-dereferenceable unordered container iterator");
332314 return __node_->__upcast()->__value_;
333315 }
334316
335317 _LIBCPP_INLINE_VISIBILITY
336318 pointer operator->() const {
337 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
338 "Attempted to dereference a non-dereferenceable unordered container iterator");
339319 return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
340320 }
341321
342322 _LIBCPP_INLINE_VISIBILITY
343323 __hash_iterator& operator++() {
344 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
345 "Attempted to increment a non-incrementable unordered container iterator");
346324 __node_ = __node_->__next_;
347325 return *this;
348326 }
......@@ -366,14 +344,11 @@ public:
366344
367345private:
368346 _LIBCPP_INLINE_VISIBILITY
369 explicit __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
347 explicit __hash_iterator(__next_pointer __node) _NOEXCEPT
370348 : __node_(__node)
371349 {
372 (void)__c;
373#ifdef _LIBCPP_ENABLE_DEBUG_MODE
374 __get_db()->__insert_ic(this, __c);
375#endif
376350 }
351
377352 template <class, class, class, class> friend class __hash_table;
378353 template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
379354 template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
......@@ -402,61 +377,25 @@ public:
402377
403378
404379 _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) {
405 _VSTD::__debug_db_insert_i(this);
406380 }
407381
408382 _LIBCPP_INLINE_VISIBILITY
409383 __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT
410384 : __node_(__x.__node_)
411385 {
412#ifdef _LIBCPP_ENABLE_DEBUG_MODE
413 __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
414#endif
415386 }
416387
417#ifdef _LIBCPP_ENABLE_DEBUG_MODE
418 _LIBCPP_INLINE_VISIBILITY
419 __hash_const_iterator(const __hash_const_iterator& __i)
420 : __node_(__i.__node_)
421 {
422 __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
423 }
424
425 _LIBCPP_INLINE_VISIBILITY
426 ~__hash_const_iterator()
427 {
428 __get_db()->__erase_i(this);
429 }
430
431 _LIBCPP_INLINE_VISIBILITY
432 __hash_const_iterator& operator=(const __hash_const_iterator& __i)
433 {
434 if (this != _VSTD::addressof(__i))
435 {
436 __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
437 __node_ = __i.__node_;
438 }
439 return *this;
440 }
441#endif // _LIBCPP_ENABLE_DEBUG_MODE
442
443388 _LIBCPP_INLINE_VISIBILITY
444389 reference operator*() const {
445 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
446 "Attempted to dereference a non-dereferenceable unordered container const_iterator");
447390 return __node_->__upcast()->__value_;
448391 }
449392 _LIBCPP_INLINE_VISIBILITY
450393 pointer operator->() const {
451 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
452 "Attempted to dereference a non-dereferenceable unordered container const_iterator");
453394 return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
454395 }
455396
456397 _LIBCPP_INLINE_VISIBILITY
457398 __hash_const_iterator& operator++() {
458 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
459 "Attempted to increment a non-incrementable unordered container const_iterator");
460399 __node_ = __node_->__next_;
461400 return *this;
462401 }
......@@ -480,14 +419,11 @@ public:
480419
481420private:
482421 _LIBCPP_INLINE_VISIBILITY
483 explicit __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
422 explicit __hash_const_iterator(__next_pointer __node) _NOEXCEPT
484423 : __node_(__node)
485424 {
486 (void)__c;
487#ifdef _LIBCPP_ENABLE_DEBUG_MODE
488 __get_db()->__insert_ic(this, __c);
489#endif
490425 }
426
491427 template <class, class, class, class> friend class __hash_table;
492428 template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
493429 template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
......@@ -513,57 +449,20 @@ public:
513449 typedef typename _NodeTypes::__node_value_type_pointer pointer;
514450
515451 _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) {
516 _VSTD::__debug_db_insert_i(this);
517 }
518
519#ifdef _LIBCPP_ENABLE_DEBUG_MODE
520 _LIBCPP_INLINE_VISIBILITY
521 __hash_local_iterator(const __hash_local_iterator& __i)
522 : __node_(__i.__node_),
523 __bucket_(__i.__bucket_),
524 __bucket_count_(__i.__bucket_count_)
525 {
526 __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
527 }
528
529 _LIBCPP_INLINE_VISIBILITY
530 ~__hash_local_iterator()
531 {
532 __get_db()->__erase_i(this);
533452 }
534453
535 _LIBCPP_INLINE_VISIBILITY
536 __hash_local_iterator& operator=(const __hash_local_iterator& __i)
537 {
538 if (this != _VSTD::addressof(__i))
539 {
540 __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
541 __node_ = __i.__node_;
542 __bucket_ = __i.__bucket_;
543 __bucket_count_ = __i.__bucket_count_;
544 }
545 return *this;
546 }
547#endif // _LIBCPP_ENABLE_DEBUG_MODE
548
549454 _LIBCPP_INLINE_VISIBILITY
550455 reference operator*() const {
551 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
552 "Attempted to dereference a non-dereferenceable unordered container local_iterator");
553456 return __node_->__upcast()->__value_;
554457 }
555458
556459 _LIBCPP_INLINE_VISIBILITY
557460 pointer operator->() const {
558 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
559 "Attempted to dereference a non-dereferenceable unordered container local_iterator");
560461 return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
561462 }
562463
563464 _LIBCPP_INLINE_VISIBILITY
564465 __hash_local_iterator& operator++() {
565 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
566 "Attempted to increment a non-incrementable unordered container local_iterator");
567466 __node_ = __node_->__next_;
568467 if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
569468 __node_ = nullptr;
......@@ -590,18 +489,15 @@ public:
590489private:
591490 _LIBCPP_INLINE_VISIBILITY
592491 explicit __hash_local_iterator(__next_pointer __node, size_t __bucket,
593 size_t __bucket_count, const void* __c) _NOEXCEPT
492 size_t __bucket_count) _NOEXCEPT
594493 : __node_(__node),
595494 __bucket_(__bucket),
596495 __bucket_count_(__bucket_count)
597496 {
598 (void)__c;
599#ifdef _LIBCPP_ENABLE_DEBUG_MODE
600 __get_db()->__insert_ic(this, __c);
601#endif
602497 if (__node_ != nullptr)
603498 __node_ = __node_->__next_;
604499 }
500
605501 template <class, class, class, class> friend class __hash_table;
606502 template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
607503 template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
......@@ -635,7 +531,6 @@ public:
635531
636532
637533 _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) {
638 _VSTD::__debug_db_insert_i(this);
639534 }
640535
641536 _LIBCPP_INLINE_VISIBILITY
......@@ -644,59 +539,20 @@ public:
644539 __bucket_(__x.__bucket_),
645540 __bucket_count_(__x.__bucket_count_)
646541 {
647#ifdef _LIBCPP_ENABLE_DEBUG_MODE
648 __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
649#endif
650542 }
651543
652#ifdef _LIBCPP_ENABLE_DEBUG_MODE
653 _LIBCPP_INLINE_VISIBILITY
654 __hash_const_local_iterator(const __hash_const_local_iterator& __i)
655 : __node_(__i.__node_),
656 __bucket_(__i.__bucket_),
657 __bucket_count_(__i.__bucket_count_)
658 {
659 __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
660 }
661
662 _LIBCPP_INLINE_VISIBILITY
663 ~__hash_const_local_iterator()
664 {
665 __get_db()->__erase_i(this);
666 }
667
668 _LIBCPP_INLINE_VISIBILITY
669 __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i)
670 {
671 if (this != _VSTD::addressof(__i))
672 {
673 __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
674 __node_ = __i.__node_;
675 __bucket_ = __i.__bucket_;
676 __bucket_count_ = __i.__bucket_count_;
677 }
678 return *this;
679 }
680#endif // _LIBCPP_ENABLE_DEBUG_MODE
681
682544 _LIBCPP_INLINE_VISIBILITY
683545 reference operator*() const {
684 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
685 "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
686546 return __node_->__upcast()->__value_;
687547 }
688548
689549 _LIBCPP_INLINE_VISIBILITY
690550 pointer operator->() const {
691 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
692 "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
693551 return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
694552 }
695553
696554 _LIBCPP_INLINE_VISIBILITY
697555 __hash_const_local_iterator& operator++() {
698 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
699 "Attempted to increment a non-incrementable unordered container const_local_iterator");
700556 __node_ = __node_->__next_;
701557 if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
702558 __node_ = nullptr;
......@@ -723,18 +579,15 @@ public:
723579private:
724580 _LIBCPP_INLINE_VISIBILITY
725581 explicit __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket,
726 size_t __bucket_count, const void* __c) _NOEXCEPT
582 size_t __bucket_count) _NOEXCEPT
727583 : __node_(__node_ptr),
728584 __bucket_(__bucket),
729585 __bucket_count_(__bucket_count)
730586 {
731 (void)__c;
732#ifdef _LIBCPP_ENABLE_DEBUG_MODE
733 __get_db()->__insert_ic(this, __c);
734#endif
735587 if (__node_ != nullptr)
736588 __node_ = __node_->__next_;
737589 }
590
738591 template <class, class, class, class> friend class __hash_table;
739592 template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
740593};
......@@ -803,8 +656,8 @@ private:
803656public:
804657 bool __value_constructed;
805658
806 __hash_node_destructor(__hash_node_destructor const&) = default;
807 __hash_node_destructor& operator=(const __hash_node_destructor&) = delete;
659 _LIBCPP_HIDE_FROM_ABI __hash_node_destructor(__hash_node_destructor const&) = default;
660 _LIBCPP_HIDE_FROM_ABI __hash_node_destructor& operator=(const __hash_node_destructor&) = delete;
808661
809662
810663 _LIBCPP_INLINE_VISIBILITY
......@@ -826,7 +679,7 @@ public:
826679 template <class> friend class __hash_map_node_destructor;
827680};
828681
829#if _LIBCPP_STD_VER > 14
682#if _LIBCPP_STD_VER >= 17
830683template <class _NodeType, class _Alloc>
831684struct __generic_container_node_destructor;
832685
......@@ -976,22 +829,22 @@ public:
976829 is_nothrow_default_constructible<key_equal>::value);
977830 _LIBCPP_INLINE_VISIBILITY
978831 __hash_table(const hasher& __hf, const key_equal& __eql);
979 __hash_table(const hasher& __hf, const key_equal& __eql,
832 _LIBCPP_HIDE_FROM_ABI __hash_table(const hasher& __hf, const key_equal& __eql,
980833 const allocator_type& __a);
981 explicit __hash_table(const allocator_type& __a);
982 __hash_table(const __hash_table& __u);
983 __hash_table(const __hash_table& __u, const allocator_type& __a);
984 __hash_table(__hash_table&& __u)
834 _LIBCPP_HIDE_FROM_ABI explicit __hash_table(const allocator_type& __a);
835 _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u);
836 _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u, const allocator_type& __a);
837 _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u)
985838 _NOEXCEPT_(
986839 is_nothrow_move_constructible<__bucket_list>::value &&
987840 is_nothrow_move_constructible<__first_node>::value &&
988841 is_nothrow_move_constructible<__node_allocator>::value &&
989842 is_nothrow_move_constructible<hasher>::value &&
990843 is_nothrow_move_constructible<key_equal>::value);
991 __hash_table(__hash_table&& __u, const allocator_type& __a);
992 ~__hash_table();
844 _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u, const allocator_type& __a);
845 _LIBCPP_HIDE_FROM_ABI ~__hash_table();
993846
994 __hash_table& operator=(const __hash_table& __u);
847 _LIBCPP_HIDE_FROM_ABI __hash_table& operator=(const __hash_table& __u);
995848 _LIBCPP_INLINE_VISIBILITY
996849 __hash_table& operator=(__hash_table&& __u)
997850 _NOEXCEPT_(
......@@ -1000,9 +853,9 @@ public:
1000853 is_nothrow_move_assignable<hasher>::value &&
1001854 is_nothrow_move_assignable<key_equal>::value);
1002855 template <class _InputIterator>
1003 void __assign_unique(_InputIterator __first, _InputIterator __last);
856 _LIBCPP_HIDE_FROM_ABI void __assign_unique(_InputIterator __first, _InputIterator __last);
1004857 template <class _InputIterator>
1005 void __assign_multi(_InputIterator __first, _InputIterator __last);
858 _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last);
1006859
1007860 _LIBCPP_INLINE_VISIBILITY
1008861 size_type max_size() const _NOEXCEPT
......@@ -1121,7 +974,7 @@ public:
1121974 return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x);
1122975 }
1123976
1124#if _LIBCPP_STD_VER > 14
977#if _LIBCPP_STD_VER >= 17
1125978 template <class _NodeHandle, class _InsertReturnType>
1126979 _LIBCPP_INLINE_VISIBILITY
1127980 _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh);
......@@ -1151,7 +1004,7 @@ public:
11511004 _NodeHandle __node_handle_extract(const_iterator __it);
11521005#endif
11531006
1154 void clear() _NOEXCEPT;
1007 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
11551008 _LIBCPP_INLINE_VISIBILITY void __rehash_unique(size_type __n) { __rehash<true>(__n); }
11561009 _LIBCPP_INLINE_VISIBILITY void __rehash_multi(size_type __n) { __rehash<false>(__n); }
11571010 _LIBCPP_INLINE_VISIBILITY void __reserve_unique(size_type __n)
......@@ -1182,48 +1035,48 @@ public:
11821035 _LIBCPP_INLINE_VISIBILITY
11831036 size_type bucket(const _Key& __k) const
11841037 {
1185 _LIBCPP_ASSERT(bucket_count() > 0,
1038 _LIBCPP_ASSERT_UNCATEGORIZED(bucket_count() > 0,
11861039 "unordered container::bucket(key) called when bucket_count() == 0");
11871040 return std::__constrain_hash(hash_function()(__k), bucket_count());
11881041 }
11891042
11901043 template <class _Key>
1191 iterator find(const _Key& __x);
1044 _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __x);
11921045 template <class _Key>
1193 const_iterator find(const _Key& __x) const;
1046 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __x) const;
11941047
11951048 typedef __hash_node_destructor<__node_allocator> _Dp;
11961049 typedef unique_ptr<__node, _Dp> __node_holder;
11971050
1198 iterator erase(const_iterator __p);
1199 iterator erase(const_iterator __first, const_iterator __last);
1051 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
1052 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last);
12001053 template <class _Key>
1201 size_type __erase_unique(const _Key& __k);
1054 _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k);
12021055 template <class _Key>
1203 size_type __erase_multi(const _Key& __k);
1204 __node_holder remove(const_iterator __p) _NOEXCEPT;
1056 _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k);
1057 _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT;
12051058
12061059 template <class _Key>
12071060 _LIBCPP_INLINE_VISIBILITY
12081061 size_type __count_unique(const _Key& __k) const;
12091062 template <class _Key>
1210 size_type __count_multi(const _Key& __k) const;
1063 _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const;
12111064
12121065 template <class _Key>
1213 pair<iterator, iterator>
1066 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator>
12141067 __equal_range_unique(const _Key& __k);
12151068 template <class _Key>
1216 pair<const_iterator, const_iterator>
1069 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator>
12171070 __equal_range_unique(const _Key& __k) const;
12181071
12191072 template <class _Key>
1220 pair<iterator, iterator>
1073 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator>
12211074 __equal_range_multi(const _Key& __k);
12221075 template <class _Key>
1223 pair<const_iterator, const_iterator>
1076 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator>
12241077 __equal_range_multi(const _Key& __k) const;
12251078
1226 void swap(__hash_table& __u)
1079 _LIBCPP_HIDE_FROM_ABI void swap(__hash_table& __u)
12271080#if _LIBCPP_STD_VER <= 11
12281081 _NOEXCEPT_(
12291082 __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
......@@ -1239,7 +1092,7 @@ public:
12391092 _LIBCPP_INLINE_VISIBILITY
12401093 size_type max_bucket_count() const _NOEXCEPT
12411094 {return max_size(); }
1242 size_type bucket_size(size_type __n) const;
1095 _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const;
12431096 _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT
12441097 {
12451098 size_type __bc = bucket_count();
......@@ -1247,7 +1100,7 @@ public:
12471100 }
12481101 _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT
12491102 {
1250 _LIBCPP_ASSERT(__mlf > 0,
1103 _LIBCPP_ASSERT_UNCATEGORIZED(__mlf > 0,
12511104 "unordered container::max_load_factor(lf) called with lf <= 0");
12521105 max_load_factor() = _VSTD::max(__mlf, load_factor());
12531106 }
......@@ -1256,68 +1109,61 @@ public:
12561109 local_iterator
12571110 begin(size_type __n)
12581111 {
1259 _LIBCPP_ASSERT(__n < bucket_count(),
1112 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
12601113 "unordered container::begin(n) called with n >= bucket_count()");
1261 return local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
1114 return local_iterator(__bucket_list_[__n], __n, bucket_count());
12621115 }
12631116
12641117 _LIBCPP_INLINE_VISIBILITY
12651118 local_iterator
12661119 end(size_type __n)
12671120 {
1268 _LIBCPP_ASSERT(__n < bucket_count(),
1121 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
12691122 "unordered container::end(n) called with n >= bucket_count()");
1270 return local_iterator(nullptr, __n, bucket_count(), this);
1123 return local_iterator(nullptr, __n, bucket_count());
12711124 }
12721125
12731126 _LIBCPP_INLINE_VISIBILITY
12741127 const_local_iterator
12751128 cbegin(size_type __n) const
12761129 {
1277 _LIBCPP_ASSERT(__n < bucket_count(),
1130 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
12781131 "unordered container::cbegin(n) called with n >= bucket_count()");
1279 return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
1132 return const_local_iterator(__bucket_list_[__n], __n, bucket_count());
12801133 }
12811134
12821135 _LIBCPP_INLINE_VISIBILITY
12831136 const_local_iterator
12841137 cend(size_type __n) const
12851138 {
1286 _LIBCPP_ASSERT(__n < bucket_count(),
1139 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
12871140 "unordered container::cend(n) called with n >= bucket_count()");
1288 return const_local_iterator(nullptr, __n, bucket_count(), this);
1141 return const_local_iterator(nullptr, __n, bucket_count());
12891142 }
12901143
1291#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1292
1293 bool __dereferenceable(const const_iterator* __i) const;
1294 bool __decrementable(const const_iterator* __i) const;
1295 bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
1296 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
1297
1298#endif // _LIBCPP_ENABLE_DEBUG_MODE
1299
13001144private:
1301 template <bool _UniqueKeys> void __rehash(size_type __n);
1302 template <bool _UniqueKeys> void __do_rehash(size_type __n);
1145 template <bool _UniqueKeys>
1146 _LIBCPP_HIDE_FROM_ABI void __rehash(size_type __n);
1147 template <bool _UniqueKeys>
1148 _LIBCPP_HIDE_FROM_ABI void __do_rehash(size_type __n);
13031149
13041150 template <class ..._Args>
1305 __node_holder __construct_node(_Args&& ...__args);
1151 _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&& ...__args);
13061152
13071153 template <class _First, class ..._Rest>
1308 __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest);
1154 _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest);
13091155
13101156
13111157 _LIBCPP_INLINE_VISIBILITY
13121158 void __copy_assign_alloc(const __hash_table& __u)
13131159 {__copy_assign_alloc(__u, integral_constant<bool,
13141160 __node_traits::propagate_on_container_copy_assignment::value>());}
1315 void __copy_assign_alloc(const __hash_table& __u, true_type);
1161 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table& __u, true_type);
13161162 _LIBCPP_INLINE_VISIBILITY
13171163 void __copy_assign_alloc(const __hash_table&, false_type) {}
13181164
1319 void __move_assign(__hash_table& __u, false_type);
1320 void __move_assign(__hash_table& __u, true_type)
1165 _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, false_type);
1166 _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, true_type)
13211167 _NOEXCEPT_(
13221168 is_nothrow_move_assignable<__node_allocator>::value &&
13231169 is_nothrow_move_assignable<hasher>::value &&
......@@ -1343,8 +1189,8 @@ private:
13431189 _LIBCPP_INLINE_VISIBILITY
13441190 void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
13451191
1346 void __deallocate_node(__next_pointer __np) _NOEXCEPT;
1347 __next_pointer __detach() _NOEXCEPT;
1192 _LIBCPP_HIDE_FROM_ABI void __deallocate_node(__next_pointer __np) _NOEXCEPT;
1193 _LIBCPP_HIDE_FROM_ABI __next_pointer __detach() _NOEXCEPT;
13481194
13491195 template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
13501196 template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
......@@ -1476,7 +1322,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table()
14761322#endif
14771323
14781324 __deallocate_node(__p1_.first().__next_);
1479 std::__debug_db_erase_c(this);
14801325}
14811326
14821327template <class _Tp, class _Hash, class _Equal, class _Alloc>
......@@ -1518,21 +1363,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np)
15181363 while (__np != nullptr)
15191364 {
15201365 __next_pointer __next = __np->__next_;
1521#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1522 __c_node* __c = __get_db()->__find_c_and_lock(this);
1523 for (__i_node** __p = __c->end_; __p != __c->beg_; )
1524 {
1525 --__p;
1526 iterator* __i = static_cast<iterator*>((*__p)->__i_);
1527 if (__i->__node_ == __np)
1528 {
1529 (*__p)->__c_ = nullptr;
1530 if (--__c->end_ != __p)
1531 _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
1532 }
1533 }
1534 __get_db()->unlock();
1535#endif
15361366 __node_pointer __real_np = __np->__upcast();
15371367 __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_));
15381368 __node_traits::deallocate(__na, __real_np, 1);
......@@ -1579,7 +1409,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
15791409 __u.__p1_.first().__next_ = nullptr;
15801410 __u.size() = 0;
15811411 }
1582 std::__debug_db_swap(this, std::addressof(__u));
15831412}
15841413
15851414template <class _Tp, class _Hash, class _Equal, class _Alloc>
......@@ -1597,10 +1426,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
15971426 if (bucket_count() != 0)
15981427 {
15991428 __next_pointer __cache = __detach();
1600#ifndef _LIBCPP_NO_EXCEPTIONS
1429#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
16011430 try
16021431 {
1603#endif // _LIBCPP_NO_EXCEPTIONS
1432#endif // _LIBCPP_HAS_NO_EXCEPTIONS
16041433 const_iterator __i = __u.begin();
16051434 while (__cache != nullptr && __u.size() != 0)
16061435 {
......@@ -1610,14 +1439,14 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
16101439 __node_insert_multi(__cache->__upcast());
16111440 __cache = __next;
16121441 }
1613#ifndef _LIBCPP_NO_EXCEPTIONS
1442#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
16141443 }
16151444 catch (...)
16161445 {
16171446 __deallocate_node(__cache);
16181447 throw;
16191448 }
1620#endif // _LIBCPP_NO_EXCEPTIONS
1449#endif // _LIBCPP_HAS_NO_EXCEPTIONS
16211450 __deallocate_node(__cache);
16221451 }
16231452 const_iterator __i = __u.begin();
......@@ -1659,10 +1488,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first
16591488 if (bucket_count() != 0)
16601489 {
16611490 __next_pointer __cache = __detach();
1662#ifndef _LIBCPP_NO_EXCEPTIONS
1491#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
16631492 try
16641493 {
1665#endif // _LIBCPP_NO_EXCEPTIONS
1494#endif // _LIBCPP_HAS_NO_EXCEPTIONS
16661495 for (; __cache != nullptr && __first != __last; ++__first)
16671496 {
16681497 __cache->__upcast()->__value_ = *__first;
......@@ -1670,14 +1499,14 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first
16701499 __node_insert_unique(__cache->__upcast());
16711500 __cache = __next;
16721501 }
1673#ifndef _LIBCPP_NO_EXCEPTIONS
1502#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
16741503 }
16751504 catch (...)
16761505 {
16771506 __deallocate_node(__cache);
16781507 throw;
16791508 }
1680#endif // _LIBCPP_NO_EXCEPTIONS
1509#endif // _LIBCPP_HAS_NO_EXCEPTIONS
16811510 __deallocate_node(__cache);
16821511 }
16831512 for (; __first != __last; ++__first)
......@@ -1699,10 +1528,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,
16991528 if (bucket_count() != 0)
17001529 {
17011530 __next_pointer __cache = __detach();
1702#ifndef _LIBCPP_NO_EXCEPTIONS
1531#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
17031532 try
17041533 {
1705#endif // _LIBCPP_NO_EXCEPTIONS
1534#endif // _LIBCPP_HAS_NO_EXCEPTIONS
17061535 for (; __cache != nullptr && __first != __last; ++__first)
17071536 {
17081537 __cache->__upcast()->__value_ = *__first;
......@@ -1710,14 +1539,14 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,
17101539 __node_insert_multi(__cache->__upcast());
17111540 __cache = __next;
17121541 }
1713#ifndef _LIBCPP_NO_EXCEPTIONS
1542#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
17141543 }
17151544 catch (...)
17161545 {
17171546 __deallocate_node(__cache);
17181547 throw;
17191548 }
1720#endif // _LIBCPP_NO_EXCEPTIONS
1549#endif // _LIBCPP_HAS_NO_EXCEPTIONS
17211550 __deallocate_node(__cache);
17221551 }
17231552 for (; __first != __last; ++__first)
......@@ -1729,7 +1558,7 @@ inline
17291558typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
17301559__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT
17311560{
1732 return iterator(__p1_.first().__next_, this);
1561 return iterator(__p1_.first().__next_);
17331562}
17341563
17351564template <class _Tp, class _Hash, class _Equal, class _Alloc>
......@@ -1737,7 +1566,7 @@ inline
17371566typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
17381567__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT
17391568{
1740 return iterator(nullptr, this);
1569 return iterator(nullptr);
17411570}
17421571
17431572template <class _Tp, class _Hash, class _Equal, class _Alloc>
......@@ -1745,7 +1574,7 @@ inline
17451574typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
17461575__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT
17471576{
1748 return const_iterator(__p1_.first().__next_, this);
1577 return const_iterator(__p1_.first().__next_);
17491578}
17501579
17511580template <class _Tp, class _Hash, class _Equal, class _Alloc>
......@@ -1753,7 +1582,7 @@ inline
17531582typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
17541583__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT
17551584{
1756 return const_iterator(nullptr, this);
1585 return const_iterator(nullptr);
17571586}
17581587
17591588template <class _Tp, class _Hash, class _Equal, class _Alloc>
......@@ -1794,10 +1623,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(
17941623 if (__ndptr != nullptr)
17951624 {
17961625 for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&
1797 std::__constrain_hash(__ndptr->__hash(), __bc) == __chash;
1626 (__ndptr->__hash() == __hash ||
1627 std::__constrain_hash(__ndptr->__hash(), __bc) == __chash);
17981628 __ndptr = __ndptr->__next_)
17991629 {
1800 if (key_eq()(__ndptr->__upcast()->__value_, __value))
1630 if ((__ndptr->__hash() == __hash) &&
1631 key_eq()(__ndptr->__upcast()->__value_, __value))
18011632 return __ndptr;
18021633 }
18031634 }
......@@ -1858,7 +1689,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __
18581689 __existing_node = __nd->__ptr();
18591690 __inserted = true;
18601691 }
1861 return pair<iterator, bool>(iterator(__existing_node, this), __inserted);
1692 return pair<iterator, bool>(iterator(__existing_node), __inserted);
18621693}
18631694
18641695// Prepare the container for an insertion of the value __cp_val with the hash
......@@ -1952,7 +1783,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c
19521783 __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_);
19531784 __node_insert_multi_perform(__cp, __pn);
19541785
1955 return iterator(__cp->__ptr(), this);
1786 return iterator(__cp->__ptr());
19561787}
19571788
19581789template <class _Tp, class _Hash, class _Equal, class _Alloc>
......@@ -1960,9 +1791,6 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
19601791__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
19611792 const_iterator __p, __node_pointer __cp)
19621793{
1963 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1964 "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
1965 " referring to this unordered container");
19661794 if (__p != end() && key_eq()(*__p, __cp->__value_))
19671795 {
19681796 __next_pointer __np = __p.__node_;
......@@ -1981,7 +1809,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
19811809 __cp->__next_ = __np;
19821810 __pp->__next_ = static_cast<__next_pointer>(__cp);
19831811 ++size();
1984 return iterator(static_cast<__next_pointer>(__cp), this);
1812 return iterator(static_cast<__next_pointer>(__cp));
19851813 }
19861814 return __node_insert_multi(__cp);
19871815}
......@@ -2009,7 +1837,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const&
20091837 (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
20101838 __nd = __nd->__next_)
20111839 {
2012 if (key_eq()(__nd->__upcast()->__value_, __k))
1840 if ((__nd->__hash() == __hash) &&
1841 key_eq()(__nd->__upcast()->__value_, __k))
20131842 goto __done;
20141843 }
20151844 }
......@@ -2047,7 +1876,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const&
20471876 __inserted = true;
20481877 }
20491878__done:
2050 return pair<iterator, bool>(iterator(__nd, this), __inserted);
1879 return pair<iterator, bool>(iterator(__nd), __inserted);
20511880}
20521881
20531882template <class _Tp, class _Hash, class _Equal, class _Alloc>
......@@ -2079,16 +1908,13 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
20791908__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(
20801909 const_iterator __p, _Args&&... __args)
20811910{
2082 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
2083 "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
2084 " referring to this unordered container");
20851911 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
20861912 iterator __r = __node_insert_multi(__p, __h.get());
20871913 __h.release();
20881914 return __r;
20891915}
20901916
2091#if _LIBCPP_STD_VER > 14
1917#if _LIBCPP_STD_VER >= 17
20921918template <class _Tp, class _Hash, class _Equal, class _Alloc>
20931919template <class _NodeHandle, class _InsertReturnType>
20941920_LIBCPP_INLINE_VISIBILITY
......@@ -2218,7 +2044,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(
22182044 __node_insert_multi_perform(__src_ptr, __pn);
22192045 }
22202046}
2221#endif // _LIBCPP_STD_VER > 14
2047#endif // _LIBCPP_STD_VER >= 17
22222048
22232049template <class _Tp, class _Hash, class _Equal, class _Alloc>
22242050template <bool _UniqueKeys>
......@@ -2251,7 +2077,6 @@ template <bool _UniqueKeys>
22512077void
22522078__hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc)
22532079{
2254 std::__debug_db_invalidate_all(this);
22552080 __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
22562081 __bucket_list_.reset(__nbc > 0 ?
22572082 __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
......@@ -2323,7 +2148,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k)
23232148 {
23242149 if ((__nd->__hash() == __hash)
23252150 && key_eq()(__nd->__upcast()->__value_, __k))
2326 return iterator(__nd, this);
2151 return iterator(__nd);
23272152 }
23282153 }
23292154 }
......@@ -2350,7 +2175,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const
23502175 {
23512176 if ((__nd->__hash() == __hash)
23522177 && key_eq()(__nd->__upcast()->__value_, __k))
2353 return const_iterator(__nd, this);
2178 return const_iterator(__nd);
23542179 }
23552180 }
23562181
......@@ -2398,12 +2223,9 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
23982223__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p)
23992224{
24002225 __next_pointer __np = __p.__node_;
2401 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
2402 "unordered container erase(iterator) called with an iterator not"
2403 " referring to this container");
2404 _LIBCPP_ASSERT(__p != end(),
2405 "unordered container erase(iterator) called with a non-dereferenceable iterator");
2406 iterator __r(__np, this);
2226 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p != end(),
2227 "unordered container::erase(iterator) called with a non-dereferenceable iterator");
2228 iterator __r(__np);
24072229 ++__r;
24082230 remove(__p);
24092231 return __r;
......@@ -2414,19 +2236,13 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
24142236__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first,
24152237 const_iterator __last)
24162238{
2417 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this,
2418 "unordered container::erase(iterator, iterator) called with an iterator not"
2419 " referring to this container");
2420 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this,
2421 "unordered container::erase(iterator, iterator) called with an iterator not"
2422 " referring to this container");
24232239 for (const_iterator __p = __first; __first != __last; __p = __first)
24242240 {
24252241 ++__first;
24262242 erase(__p);
24272243 }
24282244 __next_pointer __np = __last.__node_;
2429 return iterator (__np, this);
2245 return iterator (__np);
24302246}
24312247
24322248template <class _Tp, class _Hash, class _Equal, class _Alloc>
......@@ -2493,21 +2309,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
24932309 __pn->__next_ = __cn->__next_;
24942310 __cn->__next_ = nullptr;
24952311 --size();
2496#ifdef _LIBCPP_ENABLE_DEBUG_MODE
2497 __c_node* __c = __get_db()->__find_c_and_lock(this);
2498 for (__i_node** __dp = __c->end_; __dp != __c->beg_; )
2499 {
2500 --__dp;
2501 iterator* __i = static_cast<iterator*>((*__dp)->__i_);
2502 if (__i->__node_ == __cn)
2503 {
2504 (*__dp)->__c_ = nullptr;
2505 if (--__c->end_ != __dp)
2506 _VSTD::memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*));
2507 }
2508 }
2509 __get_db()->unlock();
2510#endif
25112312 return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true));
25122313}
25132314
......@@ -2622,10 +2423,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
26222423 _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value)
26232424#endif
26242425{
2625 _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value ||
2626 this->__node_alloc() == __u.__node_alloc(),
2627 "list::swap: Either propagate_on_container_swap must be true"
2628 " or the allocators must compare equal");
2426 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__node_traits::propagate_on_container_swap::value ||
2427 this->__node_alloc() == __u.__node_alloc(),
2428 "unordered container::swap: Either propagate_on_container_swap "
2429 "must be true or the allocators must compare equal");
26292430 {
26302431 __node_pointer_pointer __npp = __bucket_list_.release();
26312432 __bucket_list_.reset(__u.__bucket_list_.release());
......@@ -2644,14 +2445,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
26442445 if (__u.size() > 0)
26452446 __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] =
26462447 __u.__p1_.first().__ptr();
2647 std::__debug_db_swap(this, std::addressof(__u));
26482448}
26492449
26502450template <class _Tp, class _Hash, class _Equal, class _Alloc>
26512451typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
26522452__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const
26532453{
2654 _LIBCPP_ASSERT(__n < bucket_count(),
2454 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
26552455 "unordered container::bucket_size(n) called with n >= bucket_count()");
26562456 __next_pointer __np = __bucket_list_[__n];
26572457 size_type __bc = bucket_count();
......@@ -2676,38 +2476,6 @@ swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x,
26762476 __x.swap(__y);
26772477}
26782478
2679#ifdef _LIBCPP_ENABLE_DEBUG_MODE
2680
2681template <class _Tp, class _Hash, class _Equal, class _Alloc>
2682bool
2683__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const
2684{
2685 return __i->__node_ != nullptr;
2686}
2687
2688template <class _Tp, class _Hash, class _Equal, class _Alloc>
2689bool
2690__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const
2691{
2692 return false;
2693}
2694
2695template <class _Tp, class _Hash, class _Equal, class _Alloc>
2696bool
2697__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const
2698{
2699 return false;
2700}
2701
2702template <class _Tp, class _Hash, class _Equal, class _Alloc>
2703bool
2704__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const
2705{
2706 return false;
2707}
2708
2709#endif // _LIBCPP_ENABLE_DEBUG_MODE
2710
27112479_LIBCPP_END_NAMESPACE_STD
27122480
27132481_LIBCPP_POP_MACROS
lib/libcxx/include/__iterator/access.h+1-1
......@@ -69,7 +69,7 @@ end(const _Cp& __c) -> decltype(__c.end())
6969 return __c.end();
7070}
7171
72#if _LIBCPP_STD_VER > 11
72#if _LIBCPP_STD_VER >= 14
7373
7474template <class _Cp>
7575_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
lib/libcxx/include/__iterator/advance.h+15-11
......@@ -23,13 +23,15 @@
2323#include <__utility/declval.h>
2424#include <__utility/move.h>
2525#include <__utility/unreachable.h>
26#include <cstdlib>
2726#include <limits>
2827
2928#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3029# pragma GCC system_header
3130#endif
3231
32_LIBCPP_PUSH_MACROS
33#include <__undef_macros>
34
3335_LIBCPP_BEGIN_NAMESPACE_STD
3436
3537template <class _InputIter>
......@@ -64,12 +66,12 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
6466void advance(_InputIter& __i, _Distance __orig_n) {
6567 typedef typename iterator_traits<_InputIter>::difference_type _Difference;
6668 _Difference __n = static_cast<_Difference>(_VSTD::__convert_to_integral(__orig_n));
67 _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
68 "Attempt to advance(it, n) with negative n on a non-bidirectional iterator");
69 _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value,
70 "Attempt to advance(it, n) with negative n on a non-bidirectional iterator");
6971 _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
7072}
7173
72#if _LIBCPP_STD_VER > 17
74#if _LIBCPP_STD_VER >= 20
7375
7476// [range.iter.op.advance]
7577
......@@ -101,8 +103,8 @@ public:
101103 template <input_or_output_iterator _Ip>
102104 _LIBCPP_HIDE_FROM_ABI
103105 constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const {
104 _LIBCPP_ASSERT(__n >= 0 || bidirectional_iterator<_Ip>,
105 "If `n < 0`, then `bidirectional_iterator<I>` must be true.");
106 _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0 || bidirectional_iterator<_Ip>,
107 "If `n < 0`, then `bidirectional_iterator<I>` must be true.");
106108
107109 // If `I` models `random_access_iterator`, equivalent to `i += n`.
108110 if constexpr (random_access_iterator<_Ip>) {
......@@ -148,8 +150,8 @@ public:
148150 template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
149151 _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n,
150152 _Sp __bound_sentinel) const {
151 _LIBCPP_ASSERT((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>),
152 "If `n < 0`, then `bidirectional_iterator<I> && same_as<I, S>` must be true.");
153 _LIBCPP_ASSERT_UNCATEGORIZED((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>),
154 "If `n < 0`, then `bidirectional_iterator<I> && same_as<I, S>` must be true.");
153155 // If `S` and `I` model `sized_sentinel_for<S, I>`:
154156 if constexpr (sized_sentinel_for<_Sp, _Ip>) {
155157 // If |n| >= |bound_sentinel - i|, equivalent to `ranges::advance(i, bound_sentinel)`.
......@@ -159,9 +161,9 @@ public:
159161 __a > 0 ? __a >= __b :
160162 __a <= __b;
161163 };
162 if (const auto __M = __bound_sentinel - __i; __magnitude_geq(__n, __M)) {
164 if (const auto __m = __bound_sentinel - __i; __magnitude_geq(__n, __m)) {
163165 (*this)(__i, __bound_sentinel);
164 return __n - __M;
166 return __n - __m;
165167 }
166168
167169 // Otherwise, equivalent to `ranges::advance(i, n)`.
......@@ -196,8 +198,10 @@ inline namespace __cpo {
196198} // namespace __cpo
197199} // namespace ranges
198200
199#endif // _LIBCPP_STD_VER > 17
201#endif // _LIBCPP_STD_VER >= 20
200202
201203_LIBCPP_END_NAMESPACE_STD
202204
205_LIBCPP_POP_MACROS
206
203207#endif // _LIBCPP___ITERATOR_ADVANCE_H
lib/libcxx/include/__iterator/back_insert_iterator.h+6-1
......@@ -21,6 +21,9 @@
2121# pragma GCC system_header
2222#endif
2323
24_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
2427_LIBCPP_BEGIN_NAMESPACE_STD
2528
2629_LIBCPP_SUPPRESS_DEPRECATED_PUSH
......@@ -36,7 +39,7 @@ protected:
3639public:
3740 typedef output_iterator_tag iterator_category;
3841 typedef void value_type;
39#if _LIBCPP_STD_VER > 17
42#if _LIBCPP_STD_VER >= 20
4043 typedef ptrdiff_t difference_type;
4144#else
4245 typedef void difference_type;
......@@ -70,4 +73,6 @@ back_inserter(_Container& __x)
7073
7174_LIBCPP_END_NAMESPACE_STD
7275
76_LIBCPP_POP_MACROS
77
7378#endif // _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H
lib/libcxx/include/__iterator/bounded_iter.h+12-7
......@@ -23,6 +23,9 @@
2323# pragma GCC system_header
2424#endif
2525
26_LIBCPP_PUSH_MACROS
27#include <__undef_macros>
28
2629_LIBCPP_BEGIN_NAMESPACE_STD
2730
2831// Iterator wrapper that carries the valid range it is allowed to access.
......@@ -35,14 +38,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3538// Arithmetic operations are allowed and the bounds of the resulting iterator
3639// are not checked. Hence, it is possible to create an iterator pointing outside
3740// its range, but it is not possible to dereference it.
38template <class _Iterator, class = __enable_if_t< __is_cpp17_contiguous_iterator<_Iterator>::value > >
41template <class _Iterator, class = __enable_if_t< __libcpp_is_contiguous_iterator<_Iterator>::value > >
3942struct __bounded_iter {
4043 using value_type = typename iterator_traits<_Iterator>::value_type;
4144 using difference_type = typename iterator_traits<_Iterator>::difference_type;
4245 using pointer = typename iterator_traits<_Iterator>::pointer;
4346 using reference = typename iterator_traits<_Iterator>::reference;
4447 using iterator_category = typename iterator_traits<_Iterator>::iterator_category;
45#if _LIBCPP_STD_VER > 17
48#if _LIBCPP_STD_VER >= 20
4649 using iterator_concept = contiguous_iterator_tag;
4750#endif
4851
......@@ -78,7 +81,7 @@ private:
7881 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __bounded_iter(
7982 _Iterator __current, _Iterator __begin, _Iterator __end)
8083 : __current_(__current), __begin_(__begin), __end_(__end) {
81 _LIBCPP_ASSERT(__begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range");
84 _LIBCPP_ASSERT_INTERNAL(__begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range");
8285 }
8386
8487 template <class _It>
......@@ -89,19 +92,19 @@ public:
8992 //
9093 // These operations check that the iterator is dereferenceable, that is within [begin, end).
9194 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT {
92 _LIBCPP_ASSERT(
95 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
9396 __in_bounds(__current_), "__bounded_iter::operator*: Attempt to dereference an out-of-range iterator");
9497 return *__current_;
9598 }
9699
97100 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT {
98 _LIBCPP_ASSERT(
101 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
99102 __in_bounds(__current_), "__bounded_iter::operator->: Attempt to dereference an out-of-range iterator");
100103 return std::__to_address(__current_);
101104 }
102105
103106 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT {
104 _LIBCPP_ASSERT(
107 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
105108 __in_bounds(__current_ + __n), "__bounded_iter::operator[]: Attempt to index an iterator out-of-range");
106109 return __current_[__n];
107110 }
......@@ -212,7 +215,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(
212215
213216#if _LIBCPP_STD_VER <= 17
214217template <class _Iterator>
215struct __is_cpp17_contiguous_iterator<__bounded_iter<_Iterator> > : true_type {};
218struct __libcpp_is_contiguous_iterator<__bounded_iter<_Iterator> > : true_type {};
216219#endif
217220
218221template <class _Iterator>
......@@ -228,4 +231,6 @@ struct pointer_traits<__bounded_iter<_Iterator> > {
228231
229232_LIBCPP_END_NAMESPACE_STD
230233
234_LIBCPP_POP_MACROS
235
231236#endif // _LIBCPP___ITERATOR_BOUNDED_ITER_H
lib/libcxx/include/__iterator/common_iterator.h+52-30
......@@ -25,6 +25,7 @@
2525#include <__iterator/iter_swap.h>
2626#include <__iterator/iterator_traits.h>
2727#include <__iterator/readable_traits.h>
28#include <__memory/addressof.h>
2829#include <__type_traits/is_pointer.h>
2930#include <__utility/declval.h>
3031#include <variant>
......@@ -33,9 +34,12 @@
3334# pragma GCC system_header
3435#endif
3536
37_LIBCPP_PUSH_MACROS
38#include <__undef_macros>
39
3640_LIBCPP_BEGIN_NAMESPACE_STD
3741
38#if _LIBCPP_STD_VER > 17
42#if _LIBCPP_STD_VER >= 20
3943
4044template<class _Iter>
4145concept __can_use_postfix_proxy =
......@@ -46,14 +50,14 @@ template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent>
4650 requires (!same_as<_Iter, _Sent> && copyable<_Iter>)
4751class common_iterator {
4852 struct __proxy {
49 constexpr const iter_value_t<_Iter>* operator->() const noexcept {
53 _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>* operator->() const noexcept {
5054 return _VSTD::addressof(__value_);
5155 }
5256 iter_value_t<_Iter> __value_;
5357 };
5458
5559 struct __postfix_proxy {
56 constexpr const iter_value_t<_Iter>& operator*() const noexcept {
60 _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>& operator*() const noexcept {
5761 return __value_;
5862 }
5963 iter_value_t<_Iter> __value_;
......@@ -62,16 +66,17 @@ class common_iterator {
6266public:
6367 variant<_Iter, _Sent> __hold_;
6468
65 common_iterator() requires default_initializable<_Iter> = default;
69 _LIBCPP_HIDE_FROM_ABI common_iterator() requires default_initializable<_Iter> = default;
6670
67 constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, _VSTD::move(__i)) {}
68 constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, _VSTD::move(__s)) {}
71 _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, _VSTD::move(__i)) {}
72 _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, _VSTD::move(__s)) {}
6973
7074 template<class _I2, class _S2>
7175 requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent>
72 constexpr common_iterator(const common_iterator<_I2, _S2>& __other)
76 _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(const common_iterator<_I2, _S2>& __other)
7377 : __hold_([&]() -> variant<_Iter, _Sent> {
74 _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to construct from a valueless common_iterator");
78 _LIBCPP_ASSERT_UNCATEGORIZED(!__other.__hold_.valueless_by_exception(),
79 "Attempted to construct from a valueless common_iterator");
7580 if (__other.__hold_.index() == 0)
7681 return variant<_Iter, _Sent>{in_place_index<0>, _VSTD::__unchecked_get<0>(__other.__hold_)};
7782 return variant<_Iter, _Sent>{in_place_index<1>, _VSTD::__unchecked_get<1>(__other.__hold_)};
......@@ -80,8 +85,9 @@ public:
8085 template<class _I2, class _S2>
8186 requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent> &&
8287 assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&>
83 common_iterator& operator=(const common_iterator<_I2, _S2>& __other) {
84 _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to assign from a valueless common_iterator");
88 _LIBCPP_HIDE_FROM_ABI common_iterator& operator=(const common_iterator<_I2, _S2>& __other) {
89 _LIBCPP_ASSERT_UNCATEGORIZED(!__other.__hold_.valueless_by_exception(),
90 "Attempted to assign from a valueless common_iterator");
8591
8692 auto __idx = __hold_.index();
8793 auto __other_idx = __other.__hold_.index();
......@@ -101,27 +107,30 @@ public:
101107 return *this;
102108 }
103109
104 constexpr decltype(auto) operator*()
110 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*()
105111 {
106 _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
112 _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_),
113 "Attempted to dereference a non-dereferenceable common_iterator");
107114 return *_VSTD::__unchecked_get<_Iter>(__hold_);
108115 }
109116
110 constexpr decltype(auto) operator*() const
117 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const
111118 requires __dereferenceable<const _Iter>
112119 {
113 _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
120 _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_),
121 "Attempted to dereference a non-dereferenceable common_iterator");
114122 return *_VSTD::__unchecked_get<_Iter>(__hold_);
115123 }
116124
117125 template<class _I2 = _Iter>
118 decltype(auto) operator->() const
126 _LIBCPP_HIDE_FROM_ABI decltype(auto) operator->() const
119127 requires indirectly_readable<const _I2> &&
120128 (requires(const _I2& __i) { __i.operator->(); } ||
121129 is_reference_v<iter_reference_t<_I2>> ||
122130 constructible_from<iter_value_t<_I2>, iter_reference_t<_I2>>)
123131 {
124 _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
132 _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_),
133 "Attempted to dereference a non-dereferenceable common_iterator");
125134 if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) {
126135 return _VSTD::__unchecked_get<_Iter>(__hold_);
127136 } else if constexpr (is_reference_v<iter_reference_t<_Iter>>) {
......@@ -132,13 +141,15 @@ public:
132141 }
133142 }
134143
135 common_iterator& operator++() {
136 _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator");
144 _LIBCPP_HIDE_FROM_ABI common_iterator& operator++() {
145 _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_),
146 "Attempted to increment a non-dereferenceable common_iterator");
137147 ++_VSTD::__unchecked_get<_Iter>(__hold_); return *this;
138148 }
139149
140 decltype(auto) operator++(int) {
141 _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator");
150 _LIBCPP_HIDE_FROM_ABI decltype(auto) operator++(int) {
151 _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_),
152 "Attempted to increment a non-dereferenceable common_iterator");
142153 if constexpr (forward_iterator<_Iter>) {
143154 auto __tmp = *this;
144155 ++*this;
......@@ -157,8 +168,10 @@ public:
157168 requires sentinel_for<_Sent, _I2>
158169 _LIBCPP_HIDE_FROM_ABI
159170 friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
160 _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator");
161 _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator");
171 _LIBCPP_ASSERT_UNCATEGORIZED(!__x.__hold_.valueless_by_exception(),
172 "Attempted to compare a valueless common_iterator");
173 _LIBCPP_ASSERT_UNCATEGORIZED(!__y.__hold_.valueless_by_exception(),
174 "Attempted to compare a valueless common_iterator");
162175
163176 auto __x_index = __x.__hold_.index();
164177 auto __y_index = __y.__hold_.index();
......@@ -176,8 +189,10 @@ public:
176189 requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2>
177190 _LIBCPP_HIDE_FROM_ABI
178191 friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
179 _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator");
180 _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator");
192 _LIBCPP_ASSERT_UNCATEGORIZED(!__x.__hold_.valueless_by_exception(),
193 "Attempted to compare a valueless common_iterator");
194 _LIBCPP_ASSERT_UNCATEGORIZED(!__y.__hold_.valueless_by_exception(),
195 "Attempted to compare a valueless common_iterator");
181196
182197 auto __x_index = __x.__hold_.index();
183198 auto __y_index = __y.__hold_.index();
......@@ -198,8 +213,10 @@ public:
198213 requires sized_sentinel_for<_Sent, _I2>
199214 _LIBCPP_HIDE_FROM_ABI
200215 friend constexpr iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
201 _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to subtract from a valueless common_iterator");
202 _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to subtract a valueless common_iterator");
216 _LIBCPP_ASSERT_UNCATEGORIZED(!__x.__hold_.valueless_by_exception(),
217 "Attempted to subtract from a valueless common_iterator");
218 _LIBCPP_ASSERT_UNCATEGORIZED(!__y.__hold_.valueless_by_exception(),
219 "Attempted to subtract a valueless common_iterator");
203220
204221 auto __x_index = __x.__hold_.index();
205222 auto __y_index = __y.__hold_.index();
......@@ -220,7 +237,8 @@ public:
220237 noexcept(noexcept(ranges::iter_move(std::declval<const _Iter&>())))
221238 requires input_iterator<_Iter>
222239 {
223 _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator");
240 _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__i.__hold_),
241 "Attempted to iter_move a non-dereferenceable common_iterator");
224242 return ranges::iter_move( _VSTD::__unchecked_get<_Iter>(__i.__hold_));
225243 }
226244
......@@ -228,8 +246,10 @@ public:
228246 _LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y)
229247 noexcept(noexcept(ranges::iter_swap(std::declval<const _Iter&>(), std::declval<const _I2&>())))
230248 {
231 _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator");
232 _LIBCPP_ASSERT(std::holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator");
249 _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__x.__hold_),
250 "Attempted to iter_swap a non-dereferenceable common_iterator");
251 _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_I2>(__y.__hold_),
252 "Attempted to iter_swap a non-dereferenceable common_iterator");
233253 return ranges::iter_swap(_VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_I2>(__y.__hold_));
234254 }
235255};
......@@ -274,8 +294,10 @@ struct iterator_traits<common_iterator<_Iter, _Sent>> {
274294 using reference = iter_reference_t<_Iter>;
275295};
276296
277#endif // _LIBCPP_STD_VER > 17
297#endif // _LIBCPP_STD_VER >= 20
278298
279299_LIBCPP_END_NAMESPACE_STD
280300
301_LIBCPP_POP_MACROS
302
281303#endif // _LIBCPP___ITERATOR_COMMON_ITERATOR_H
lib/libcxx/include/__iterator/concepts.h+2-2
......@@ -46,7 +46,7 @@
4646
4747_LIBCPP_BEGIN_NAMESPACE_STD
4848
49#if _LIBCPP_STD_VER > 17
49#if _LIBCPP_STD_VER >= 20
5050
5151// [iterator.concept.readable]
5252template<class _In>
......@@ -293,7 +293,7 @@ concept indirectly_copyable_storable =
293293// Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle
294294// (both iter_swap and indirectly_swappable require indirectly_readable).
295295
296#endif // _LIBCPP_STD_VER > 17
296#endif // _LIBCPP_STD_VER >= 20
297297
298298_LIBCPP_END_NAMESPACE_STD
299299
lib/libcxx/include/__iterator/counted_iterator.h+24-18
......@@ -34,9 +34,12 @@
3434# pragma GCC system_header
3535#endif
3636
37_LIBCPP_PUSH_MACROS
38#include <__undef_macros>
39
3740_LIBCPP_BEGIN_NAMESPACE_STD
3841
39#if _LIBCPP_STD_VER > 17
42#if _LIBCPP_STD_VER >= 20
4043
4144template<class>
4245struct __counted_iterator_concept {};
......@@ -83,7 +86,7 @@ public:
8386 _LIBCPP_HIDE_FROM_ABI
8487 constexpr counted_iterator(_Iter __iter, iter_difference_t<_Iter> __n)
8588 : __current_(_VSTD::move(__iter)), __count_(__n) {
86 _LIBCPP_ASSERT(__n >= 0, "__n must not be negative.");
89 _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0, "__n must not be negative.");
8790 }
8891
8992 template<class _I2>
......@@ -112,7 +115,7 @@ public:
112115
113116 _LIBCPP_HIDE_FROM_ABI
114117 constexpr decltype(auto) operator*() {
115 _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end.");
118 _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator is equal to or past end.");
116119 return *__current_;
117120 }
118121
......@@ -120,7 +123,7 @@ public:
120123 constexpr decltype(auto) operator*() const
121124 requires __dereferenceable<const _Iter>
122125 {
123 _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end.");
126 _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator is equal to or past end.");
124127 return *__current_;
125128 }
126129
......@@ -133,7 +136,7 @@ public:
133136
134137 _LIBCPP_HIDE_FROM_ABI
135138 constexpr counted_iterator& operator++() {
136 _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
139 _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end.");
137140 ++__current_;
138141 --__count_;
139142 return *this;
......@@ -141,21 +144,21 @@ public:
141144
142145 _LIBCPP_HIDE_FROM_ABI
143146 decltype(auto) operator++(int) {
144 _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
147 _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end.");
145148 --__count_;
146#ifndef _LIBCPP_NO_EXCEPTIONS
149#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
147150 try { return __current_++; }
148151 catch(...) { ++__count_; throw; }
149152#else
150153 return __current_++;
151#endif // _LIBCPP_NO_EXCEPTIONS
154#endif // _LIBCPP_HAS_NO_EXCEPTIONS
152155 }
153156
154157 _LIBCPP_HIDE_FROM_ABI
155158 constexpr counted_iterator operator++(int)
156159 requires forward_iterator<_Iter>
157160 {
158 _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
161 _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end.");
159162 counted_iterator __tmp = *this;
160163 ++*this;
161164 return __tmp;
......@@ -198,7 +201,7 @@ public:
198201 constexpr counted_iterator& operator+=(iter_difference_t<_Iter> __n)
199202 requires random_access_iterator<_Iter>
200203 {
201 _LIBCPP_ASSERT(__n <= __count_, "Cannot advance iterator past end.");
204 _LIBCPP_ASSERT_UNCATEGORIZED(__n <= __count_, "Cannot advance iterator past end.");
202205 __current_ += __n;
203206 __count_ -= __n;
204207 return *this;
......@@ -237,9 +240,10 @@ public:
237240 constexpr counted_iterator& operator-=(iter_difference_t<_Iter> __n)
238241 requires random_access_iterator<_Iter>
239242 {
240 _LIBCPP_ASSERT(-__n <= __count_, "Attempt to subtract too large of a size: "
241 "counted_iterator would be decremented before the "
242 "first element of its range.");
243 _LIBCPP_ASSERT_UNCATEGORIZED(-__n <= __count_,
244 "Attempt to subtract too large of a size: "
245 "counted_iterator would be decremented before the "
246 "first element of its range.");
243247 __current_ -= __n;
244248 __count_ += __n;
245249 return *this;
......@@ -249,7 +253,7 @@ public:
249253 constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const
250254 requires random_access_iterator<_Iter>
251255 {
252 _LIBCPP_ASSERT(__n < __count_, "Subscript argument must be less than size.");
256 _LIBCPP_ASSERT_UNCATEGORIZED(__n < __count_, "Subscript argument must be less than size.");
253257 return __current_[__n];
254258 }
255259
......@@ -280,7 +284,7 @@ public:
280284 noexcept(noexcept(ranges::iter_move(__i.__current_)))
281285 requires input_iterator<_Iter>
282286 {
283 _LIBCPP_ASSERT(__i.__count_ > 0, "Iterator must not be past end of range.");
287 _LIBCPP_ASSERT_UNCATEGORIZED(__i.__count_ > 0, "Iterator must not be past end of range.");
284288 return ranges::iter_move(__i.__current_);
285289 }
286290
......@@ -289,8 +293,8 @@ public:
289293 friend constexpr void iter_swap(const counted_iterator& __x, const counted_iterator<_I2>& __y)
290294 noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_)))
291295 {
292 _LIBCPP_ASSERT(__x.__count_ > 0 && __y.__count_ > 0,
293 "Iterators must not be past end of range.");
296 _LIBCPP_ASSERT_UNCATEGORIZED(__x.__count_ > 0 && __y.__count_ > 0,
297 "Iterators must not be past end of range.");
294298 return ranges::iter_swap(__x.__current_, __y.__current_);
295299 }
296300};
......@@ -303,8 +307,10 @@ struct iterator_traits<counted_iterator<_Iter>> : iterator_traits<_Iter> {
303307 add_pointer_t<iter_reference_t<_Iter>>, void>;
304308};
305309
306#endif // _LIBCPP_STD_VER > 17
310#endif // _LIBCPP_STD_VER >= 20
307311
308312_LIBCPP_END_NAMESPACE_STD
309313
314_LIBCPP_POP_MACROS
315
310316#endif // _LIBCPP___ITERATOR_COUNTED_ITERATOR_H
lib/libcxx/include/__iterator/cpp17_iterator_concepts.h created+185
......@@ -0,0 +1,185 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H
10#define _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H
11
12#include <__concepts/boolean_testable.h>
13#include <__concepts/convertible_to.h>
14#include <__concepts/same_as.h>
15#include <__config>
16#include <__iterator/iterator_traits.h>
17#include <__type_traits/is_convertible.h>
18#include <__type_traits/is_copy_constructible.h>
19#include <__type_traits/is_default_constructible.h>
20#include <__type_traits/is_move_constructible.h>
21#include <__type_traits/is_signed.h>
22#include <__type_traits/is_void.h>
23#include <__utility/as_const.h>
24#include <__utility/forward.h>
25#include <__utility/move.h>
26#include <__utility/swap.h>
27
28#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
29# pragma GCC system_header
30#endif
31
32#if _LIBCPP_STD_VER >= 20
33
34_LIBCPP_BEGIN_NAMESPACE_STD
35
36template <class _Tp>
37concept __cpp17_move_constructible = is_move_constructible_v<_Tp>;
38
39template <class _Tp>
40concept __cpp17_copy_constructible = __cpp17_move_constructible<_Tp> && is_copy_constructible_v<_Tp>;
41
42template <class _Tp>
43concept __cpp17_move_assignable = requires(_Tp __lhs, _Tp __rhs) {
44 { __lhs = std::move(__rhs) } -> same_as<_Tp&>;
45};
46
47template <class _Tp>
48concept __cpp17_copy_assignable = __cpp17_move_assignable<_Tp> && requires(_Tp __lhs, _Tp __rhs) {
49 { __lhs = __rhs } -> same_as<_Tp&>;
50 { __lhs = std::as_const(__rhs) } -> same_as<_Tp&>;
51};
52
53template <class _Tp>
54concept __cpp17_destructible = requires(_Tp __v) { __v.~_Tp(); };
55
56template <class _Tp>
57concept __cpp17_equality_comparable = requires(_Tp __lhs, _Tp __rhs) {
58 { __lhs == __rhs } -> __boolean_testable;
59 { std::as_const(__lhs) == __rhs } -> __boolean_testable;
60 { __lhs == std::as_const(__rhs) } -> __boolean_testable;
61 { std::as_const(__lhs) == std::as_const(__rhs) } -> __boolean_testable;
62};
63
64template <class _Tp>
65concept __cpp17_default_constructible = is_default_constructible_v<_Tp>;
66
67template <class _Iter>
68concept __cpp17_iterator =
69 __cpp17_copy_constructible<_Iter> && __cpp17_copy_assignable<_Iter> && __cpp17_destructible<_Iter> &&
70 (is_signed_v<__iter_diff_t<_Iter>> || is_void_v<__iter_diff_t<_Iter>>)&&requires(_Iter __iter) {
71 { *__iter };
72 { ++__iter } -> same_as<_Iter&>;
73 };
74
75template <class _Iter>
76concept __cpp17_input_iterator =
77 __cpp17_iterator<_Iter> && __cpp17_equality_comparable<_Iter> && requires(_Iter __lhs, _Iter __rhs) {
78 { __lhs != __rhs } -> __boolean_testable;
79 { std::as_const(__lhs) != __rhs } -> __boolean_testable;
80 { __lhs != std::as_const(__rhs) } -> __boolean_testable;
81 { std::as_const(__lhs) != std::as_const(__rhs) } -> __boolean_testable;
82
83 { *__lhs } -> same_as<__iter_reference<_Iter>>;
84 { *std::as_const(__lhs) } -> same_as<__iter_reference<_Iter>>;
85
86 { ++__lhs } -> same_as<_Iter&>;
87 { (void)__lhs++ };
88 { *__lhs++ };
89 };
90
91template <class _Iter, class _WriteTo>
92concept __cpp17_output_iterator = __cpp17_iterator<_Iter> && requires(_Iter __iter, _WriteTo __write) {
93 { *__iter = std::forward<_WriteTo>(__write) };
94 { ++__iter } -> same_as<_Iter&>;
95 { __iter++ } -> convertible_to<const _Iter&>;
96 { *__iter++ = std::forward<_WriteTo>(__write) };
97};
98
99template <class _Iter>
100concept __cpp17_forward_iterator =
101 __cpp17_input_iterator<_Iter> && __cpp17_default_constructible<_Iter> && requires(_Iter __iter) {
102 { __iter++ } -> convertible_to<const _Iter&>;
103 { *__iter++ } -> same_as<__iter_reference<_Iter>>;
104 };
105
106template <class _Iter>
107concept __cpp17_bidirectional_iterator = __cpp17_forward_iterator<_Iter> && requires(_Iter __iter) {
108 { --__iter } -> same_as<_Iter&>;
109 { __iter-- } -> convertible_to<const _Iter&>;
110 { *__iter-- } -> same_as<__iter_reference<_Iter>>;
111};
112
113template <class _Iter>
114concept __cpp17_random_access_iterator =
115 __cpp17_bidirectional_iterator<_Iter> && requires(_Iter __iter, __iter_diff_t<_Iter> __n) {
116 { __iter += __n } -> same_as<_Iter&>;
117
118 { __iter + __n } -> same_as<_Iter>;
119 { __n + __iter } -> same_as<_Iter>;
120 { std::as_const(__iter) + __n } -> same_as<_Iter>;
121 { __n + std::as_const(__iter) } -> same_as<_Iter>;
122
123 { __iter -= __n } -> same_as<_Iter&>;
124 { __iter - __n } -> same_as<_Iter>;
125 { std::as_const(__iter) - __n } -> same_as<_Iter>;
126
127 { __iter - __iter } -> same_as<__iter_diff_t<_Iter>>;
128 { std::as_const(__iter) - __iter } -> same_as<__iter_diff_t<_Iter>>;
129 { __iter - std::as_const(__iter) } -> same_as<__iter_diff_t<_Iter>>;
130 { std::as_const(__iter) - std::as_const(__iter) } -> same_as<__iter_diff_t<_Iter>>;
131
132 { __iter[__n] } -> convertible_to<__iter_reference<_Iter>>;
133 { std::as_const(__iter)[__n] } -> convertible_to<__iter_reference<_Iter>>;
134
135 { __iter < __iter } -> __boolean_testable;
136 { std::as_const(__iter) < __iter } -> __boolean_testable;
137 { __iter < std::as_const(__iter) } -> __boolean_testable;
138 { std::as_const(__iter) < std::as_const(__iter) } -> __boolean_testable;
139
140 { __iter > __iter } -> __boolean_testable;
141 { std::as_const(__iter) > __iter } -> __boolean_testable;
142 { __iter > std::as_const(__iter) } -> __boolean_testable;
143 { std::as_const(__iter) > std::as_const(__iter) } -> __boolean_testable;
144
145 { __iter >= __iter } -> __boolean_testable;
146 { std::as_const(__iter) >= __iter } -> __boolean_testable;
147 { __iter >= std::as_const(__iter) } -> __boolean_testable;
148 { std::as_const(__iter) >= std::as_const(__iter) } -> __boolean_testable;
149
150 { __iter <= __iter } -> __boolean_testable;
151 { std::as_const(__iter) <= __iter } -> __boolean_testable;
152 { __iter <= std::as_const(__iter) } -> __boolean_testable;
153 { std::as_const(__iter) <= std::as_const(__iter) } -> __boolean_testable;
154 };
155
156_LIBCPP_END_NAMESPACE_STD
157
158# ifndef _LIBCPP_DISABLE_ITERATOR_CHECKS
159# define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t) static_assert(::std::__cpp17_input_iterator<iter_t>);
160# define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t) \
161 static_assert(::std::__cpp17_output_iterator<iter_t, write_t>);
162# define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t) static_assert(::std::__cpp17_forward_iterator<iter_t>);
163# define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t) \
164 static_assert(::std::__cpp17_bidirectional_iterator<iter_t>);
165# define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t) \
166 static_assert(::std::__cpp17_random_access_iterator<iter_t>);
167# else
168# define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t)
169# define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t)
170# define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t)
171# define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t)
172# define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t)
173# endif
174
175#else // _LIBCPP_STD_VER >= 20
176
177# define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t)
178# define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t)
179# define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t)
180# define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t)
181# define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t)
182
183#endif // _LIBCPP_STD_VER >= 20
184
185#endif // _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H
lib/libcxx/include/__iterator/data.h+1-1
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 14
23#if _LIBCPP_STD_VER >= 17
2424
2525template <class _Cont> constexpr
2626_LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__iterator/default_sentinel.h+2-2
......@@ -18,12 +18,12 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323struct default_sentinel_t { };
2424inline constexpr default_sentinel_t default_sentinel{};
2525
26#endif // _LIBCPP_STD_VER > 17
26#endif // _LIBCPP_STD_VER >= 20
2727
2828_LIBCPP_END_NAMESPACE_STD
2929
lib/libcxx/include/__iterator/distance.h+2-2
......@@ -53,7 +53,7 @@ distance(_InputIter __first, _InputIter __last)
5353 return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
5454}
5555
56#if _LIBCPP_STD_VER > 17
56#if _LIBCPP_STD_VER >= 20
5757
5858// [range.iter.op.distance]
5959
......@@ -101,7 +101,7 @@ inline namespace __cpo {
101101} // namespace __cpo
102102} // namespace ranges
103103
104#endif // _LIBCPP_STD_VER > 17
104#endif // _LIBCPP_STD_VER >= 20
105105
106106_LIBCPP_END_NAMESPACE_STD
107107
lib/libcxx/include/__iterator/empty.h+2-2
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 14
23#if _LIBCPP_STD_VER >= 17
2424
2525template <class _Cont>
2626_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
......@@ -37,7 +37,7 @@ template <class _Ep>
3737_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
3838constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; }
3939
40#endif // _LIBCPP_STD_VER > 14
40#endif // _LIBCPP_STD_VER >= 17
4141
4242_LIBCPP_END_NAMESPACE_STD
4343
lib/libcxx/include/__iterator/erase_if_container.h+5
......@@ -16,6 +16,9 @@
1616# pragma GCC system_header
1717#endif
1818
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
1922_LIBCPP_BEGIN_NAMESPACE_STD
2023
2124template <class _Container, class _Predicate>
......@@ -37,4 +40,6 @@ __libcpp_erase_if_container(_Container& __c, _Predicate& __pred) {
3740
3841_LIBCPP_END_NAMESPACE_STD
3942
43_LIBCPP_POP_MACROS
44
4045#endif // _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H
lib/libcxx/include/__iterator/front_insert_iterator.h+6-1
......@@ -21,6 +21,9 @@
2121# pragma GCC system_header
2222#endif
2323
24_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
2427_LIBCPP_BEGIN_NAMESPACE_STD
2528
2629_LIBCPP_SUPPRESS_DEPRECATED_PUSH
......@@ -36,7 +39,7 @@ protected:
3639public:
3740 typedef output_iterator_tag iterator_category;
3841 typedef void value_type;
39#if _LIBCPP_STD_VER > 17
42#if _LIBCPP_STD_VER >= 20
4043 typedef ptrdiff_t difference_type;
4144#else
4245 typedef void difference_type;
......@@ -68,4 +71,6 @@ front_inserter(_Container& __x)
6871
6972_LIBCPP_END_NAMESPACE_STD
7073
74_LIBCPP_POP_MACROS
75
7176#endif // _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H
lib/libcxx/include/__iterator/incrementable_traits.h+2-2
......@@ -26,7 +26,7 @@
2626
2727_LIBCPP_BEGIN_NAMESPACE_STD
2828
29#if _LIBCPP_STD_VER > 17
29#if _LIBCPP_STD_VER >= 20
3030
3131// [incrementable.traits]
3232template<class> struct incrementable_traits {};
......@@ -71,7 +71,7 @@ using iter_difference_t = typename conditional_t<__is_primary_template<iterator_
7171 incrementable_traits<remove_cvref_t<_Ip> >,
7272 iterator_traits<remove_cvref_t<_Ip> > >::difference_type;
7373
74#endif // _LIBCPP_STD_VER > 17
74#endif // _LIBCPP_STD_VER >= 20
7575
7676_LIBCPP_END_NAMESPACE_STD
7777
lib/libcxx/include/__iterator/indirectly_comparable.h+2-2
......@@ -21,13 +21,13 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24#if _LIBCPP_STD_VER > 17
24#if _LIBCPP_STD_VER >= 20
2525
2626template <class _I1, class _I2, class _Rp, class _P1 = identity, class _P2 = identity>
2727concept indirectly_comparable =
2828 indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>;
2929
30#endif // _LIBCPP_STD_VER > 17
30#endif // _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_END_NAMESPACE_STD
3333
lib/libcxx/include/__iterator/insert_iterator.h+7-2
......@@ -22,9 +22,12 @@
2222# pragma GCC system_header
2323#endif
2424
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
2528_LIBCPP_BEGIN_NAMESPACE_STD
2629
27#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
2831template <class _Container>
2932using __insert_iterator_iter_t = ranges::iterator_t<_Container>;
3033#else
......@@ -46,7 +49,7 @@ protected:
4649public:
4750 typedef output_iterator_tag iterator_category;
4851 typedef void value_type;
49#if _LIBCPP_STD_VER > 17
52#if _LIBCPP_STD_VER >= 20
5053 typedef ptrdiff_t difference_type;
5154#else
5255 typedef void difference_type;
......@@ -78,4 +81,6 @@ inserter(_Container& __x, __insert_iterator_iter_t<_Container> __i)
7881
7982_LIBCPP_END_NAMESPACE_STD
8083
84_LIBCPP_POP_MACROS
85
8186#endif // _LIBCPP___ITERATOR_INSERT_ITERATOR_H
lib/libcxx/include/__iterator/istream_iterator.h+4-4
......@@ -47,9 +47,9 @@ private:
4747 _Tp __value_;
4848public:
4949 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {}
50#if _LIBCPP_STD_VER > 17
50#if _LIBCPP_STD_VER >= 20
5151 _LIBCPP_HIDE_FROM_ABI constexpr istream_iterator(default_sentinel_t) : istream_iterator() {}
52#endif // _LIBCPP_STD_VER > 17
52#endif // _LIBCPP_STD_VER >= 20
5353 _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s))
5454 {
5555 if (!(*__in_stream_ >> __value_))
......@@ -73,11 +73,11 @@ public:
7373 operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
7474 const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
7575
76#if _LIBCPP_STD_VER > 17
76#if _LIBCPP_STD_VER >= 20
7777 friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator& __i, default_sentinel_t) {
7878 return __i.__in_stream_ == nullptr;
7979 }
80#endif // _LIBCPP_STD_VER > 17
80#endif // _LIBCPP_STD_VER >= 20
8181};
8282
8383template <class _Tp, class _CharT, class _Traits, class _Distance>
lib/libcxx/include/__iterator/istreambuf_iterator.h+4-4
......@@ -67,10 +67,10 @@ private:
6767 }
6868public:
6969 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {}
70#if _LIBCPP_STD_VER > 17
70#if _LIBCPP_STD_VER >= 20
7171 _LIBCPP_INLINE_VISIBILITY constexpr istreambuf_iterator(default_sentinel_t) noexcept
7272 : istreambuf_iterator() {}
73#endif // _LIBCPP_STD_VER > 17
73#endif // _LIBCPP_STD_VER >= 20
7474 _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
7575 : __sbuf_(__s.rdbuf()) {}
7676 _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
......@@ -93,11 +93,11 @@ public:
9393 _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
9494 {return __test_for_eof() == __b.__test_for_eof();}
9595
96#if _LIBCPP_STD_VER > 17
96#if _LIBCPP_STD_VER >= 20
9797 friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) {
9898 return __i.__test_for_eof();
9999 }
100#endif // _LIBCPP_STD_VER > 17
100#endif // _LIBCPP_STD_VER >= 20
101101};
102102
103103template <class _CharT, class _Traits>
lib/libcxx/include/__iterator/iter_move.h+7-2
......@@ -23,9 +23,12 @@
2323# pragma GCC system_header
2424#endif
2525
26_LIBCPP_PUSH_MACROS
27#include <__undef_macros>
28
2629_LIBCPP_BEGIN_NAMESPACE_STD
2730
28#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
2932
3033// [iterator.cust.move]
3134
......@@ -97,8 +100,10 @@ template<__dereferenceable _Tp>
97100 requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __can_reference; }
98101using iter_rvalue_reference_t = decltype(ranges::iter_move(std::declval<_Tp&>()));
99102
100#endif // _LIBCPP_STD_VER > 17
103#endif // _LIBCPP_STD_VER >= 20
101104
102105_LIBCPP_END_NAMESPACE_STD
103106
107_LIBCPP_POP_MACROS
108
104109#endif // _LIBCPP___ITERATOR_ITER_MOVE_H
lib/libcxx/include/__iterator/iter_swap.h+7-2
......@@ -26,9 +26,12 @@
2626# pragma GCC system_header
2727#endif
2828
29_LIBCPP_PUSH_MACROS
30#include <__undef_macros>
31
2932_LIBCPP_BEGIN_NAMESPACE_STD
3033
31#if _LIBCPP_STD_VER > 17
34#if _LIBCPP_STD_VER >= 20
3235
3336// [iter.cust.swap]
3437
......@@ -106,8 +109,10 @@ concept indirectly_swappable =
106109 ranges::iter_swap(__i2, __i1);
107110 };
108111
109#endif // _LIBCPP_STD_VER > 17
112#endif // _LIBCPP_STD_VER >= 20
110113
111114_LIBCPP_END_NAMESPACE_STD
112115
116_LIBCPP_POP_MACROS
117
113118#endif // _LIBCPP___ITERATOR_ITER_SWAP_H
lib/libcxx/include/__iterator/iterator_traits.h+44-29
......@@ -43,7 +43,7 @@
4343
4444_LIBCPP_BEGIN_NAMESPACE_STD
4545
46#if _LIBCPP_STD_VER > 17
46#if _LIBCPP_STD_VER >= 20
4747
4848template <class _Tp>
4949using __with_reference = _Tp&;
......@@ -62,7 +62,7 @@ concept __dereferenceable = requires(_Tp& __t) {
6262template<__dereferenceable _Tp>
6363using iter_reference_t = decltype(*std::declval<_Tp&>());
6464
65#endif // _LIBCPP_STD_VER > 17
65#endif // _LIBCPP_STD_VER >= 20
6666
6767template <class _Iter>
6868struct _LIBCPP_TEMPLATE_VIS iterator_traits;
......@@ -72,7 +72,7 @@ struct _LIBCPP_TEMPLATE_VIS output_iterator_tag {};
7272struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_tag {};
7373struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {};
7474struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {};
75#if _LIBCPP_STD_VER > 17
75#if _LIBCPP_STD_VER >= 20
7676struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag : public random_access_iterator_tag {};
7777#endif
7878
......@@ -157,7 +157,7 @@ public:
157157 static const bool value = decltype(__test<_Tp>(nullptr))::value;
158158};
159159
160#if _LIBCPP_STD_VER > 17
160#if _LIBCPP_STD_VER >= 20
161161
162162// The `cpp17-*-iterator` exposition-only concepts have very similar names to the `Cpp17*Iterator` named requirements
163163// from `[iterator.cpp17]`. To avoid confusion between the two, the exposition-only concepts have been banished to
......@@ -190,7 +190,7 @@ template<class _Ip>
190190concept __cpp17_forward_iterator =
191191 __cpp17_input_iterator<_Ip> &&
192192 constructible_from<_Ip> &&
193 is_lvalue_reference_v<iter_reference_t<_Ip>> &&
193 is_reference_v<iter_reference_t<_Ip>> &&
194194 same_as<remove_cvref_t<iter_reference_t<_Ip>>,
195195 typename indirectly_readable_traits<_Ip>::value_type> &&
196196 requires(_Ip __i) {
......@@ -381,7 +381,7 @@ struct iterator_traits : __iterator_traits<_Ip> {
381381 using __primary_template = iterator_traits;
382382};
383383
384#else // _LIBCPP_STD_VER > 17
384#else // _LIBCPP_STD_VER >= 20
385385
386386template <class _Iter, bool> struct __iterator_traits {};
387387
......@@ -418,10 +418,10 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits
418418
419419 using __primary_template = iterator_traits;
420420};
421#endif // _LIBCPP_STD_VER > 17
421#endif // _LIBCPP_STD_VER >= 20
422422
423423template<class _Tp>
424#if _LIBCPP_STD_VER > 17
424#if _LIBCPP_STD_VER >= 20
425425requires is_object_v<_Tp>
426426#endif
427427struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>
......@@ -431,7 +431,7 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>
431431 typedef _Tp* pointer;
432432 typedef _Tp& reference;
433433 typedef random_access_iterator_tag iterator_category;
434#if _LIBCPP_STD_VER > 17
434#if _LIBCPP_STD_VER >= 20
435435 typedef contiguous_iterator_tag iterator_concept;
436436#endif
437437};
......@@ -453,60 +453,60 @@ template <class _Tp, class _Up>
453453struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {};
454454
455455template <class _Tp>
456struct __is_cpp17_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {};
456using __has_input_iterator_category = __has_iterator_category_convertible_to<_Tp, input_iterator_tag>;
457457
458458template <class _Tp>
459struct __is_cpp17_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {};
459using __has_forward_iterator_category = __has_iterator_category_convertible_to<_Tp, forward_iterator_tag>;
460460
461461template <class _Tp>
462struct __is_cpp17_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {};
462using __has_bidirectional_iterator_category = __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>;
463463
464464template <class _Tp>
465struct __is_cpp17_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {};
465using __has_random_access_iterator_category = __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>;
466466
467// __is_cpp17_contiguous_iterator determines if an iterator is known by
467// __libcpp_is_contiguous_iterator determines if an iterator is known by
468468// libc++ to be contiguous, either because it advertises itself as such
469469// (in C++20) or because it is a pointer type or a known trivial wrapper
470470// around a (possibly fancy) pointer type, such as __wrap_iter<T*>.
471471// Such iterators receive special "contiguous" optimizations in
472472// std::copy and std::sort.
473473//
474#if _LIBCPP_STD_VER > 17
474#if _LIBCPP_STD_VER >= 20
475475template <class _Tp>
476struct __is_cpp17_contiguous_iterator : _Or<
476struct __libcpp_is_contiguous_iterator : _Or<
477477 __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag>,
478478 __has_iterator_concept_convertible_to<_Tp, contiguous_iterator_tag>
479479> {};
480480#else
481481template <class _Tp>
482struct __is_cpp17_contiguous_iterator : false_type {};
482struct __libcpp_is_contiguous_iterator : false_type {};
483483#endif
484484
485485// Any native pointer which is an iterator is also a contiguous iterator.
486486template <class _Up>
487struct __is_cpp17_contiguous_iterator<_Up*> : true_type {};
487struct __libcpp_is_contiguous_iterator<_Up*> : true_type {};
488488
489489
490490template <class _Iter>
491491class __wrap_iter;
492492
493493template <class _Tp>
494struct __is_exactly_cpp17_input_iterator
495 : public integral_constant<bool,
494using __has_exactly_input_iterator_category
495 = integral_constant<bool,
496496 __has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value &&
497 !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {};
497 !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value>;
498498
499499template <class _Tp>
500struct __is_exactly_cpp17_forward_iterator
501 : public integral_constant<bool,
500using __has_exactly_forward_iterator_category
501 = integral_constant<bool,
502502 __has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value &&
503 !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value> {};
503 !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value>;
504504
505505template <class _Tp>
506struct __is_exactly_cpp17_bidirectional_iterator
507 : public integral_constant<bool,
506using __has_exactly_bidirectional_iterator_category
507 = integral_constant<bool,
508508 __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value &&
509 !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value> {};
509 !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value>;
510510
511511template<class _InputIterator>
512512using __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
......@@ -531,8 +531,23 @@ using __iterator_pointer_type = typename iterator_traits<_Iter>::pointer;
531531template <class _Iter>
532532using __iter_diff_t = typename iterator_traits<_Iter>::difference_type;
533533
534template<class _InputIterator>
535using __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
534template <class _Iter>
535using __iter_reference = typename iterator_traits<_Iter>::reference;
536
537#if _LIBCPP_STD_VER >= 20
538
539// [readable.traits]
540
541// Let `RI` be `remove_cvref_t<I>`. The type `iter_value_t<I>` denotes
542// `indirectly_readable_traits<RI>::value_type` if `iterator_traits<RI>` names a specialization
543// generated from the primary template, and `iterator_traits<RI>::value_type` otherwise.
544// This has to be in this file and not readable_traits.h to break the include cycle between the two.
545template <class _Ip>
546using iter_value_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value,
547 indirectly_readable_traits<remove_cvref_t<_Ip> >,
548 iterator_traits<remove_cvref_t<_Ip> > >::value_type;
549
550#endif // _LIBCPP_STD_VER >= 20
536551
537552_LIBCPP_END_NAMESPACE_STD
538553
lib/libcxx/include/__iterator/mergeable.h+2-2
......@@ -22,7 +22,7 @@
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727template <class _Input1, class _Input2, class _Output,
2828 class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity>
......@@ -34,7 +34,7 @@ concept mergeable =
3434 indirectly_copyable<_Input2, _Output> &&
3535 indirect_strict_weak_order<_Comp, projected<_Input1, _Proj1>, projected<_Input2, _Proj2>>;
3636
37#endif // _LIBCPP_STD_VER > 17
37#endif // _LIBCPP_STD_VER >= 20
3838
3939_LIBCPP_END_NAMESPACE_STD
4040
lib/libcxx/include/__iterator/move_iterator.h+35-15
......@@ -39,9 +39,12 @@
3939# pragma GCC system_header
4040#endif
4141
42_LIBCPP_PUSH_MACROS
43#include <__undef_macros>
44
4245_LIBCPP_BEGIN_NAMESPACE_STD
4346
44#if _LIBCPP_STD_VER > 17
47#if _LIBCPP_STD_VER >= 20
4548template<class _Iter, class = void>
4649struct __move_iter_category_base {};
4750
......@@ -59,18 +62,33 @@ template<class _Iter, class _Sent>
5962concept __move_iter_comparable = requires {
6063 { std::declval<const _Iter&>() == std::declval<_Sent>() } -> convertible_to<bool>;
6164};
62#endif // _LIBCPP_STD_VER > 17
65#endif // _LIBCPP_STD_VER >= 20
6366
6467template <class _Iter>
6568class _LIBCPP_TEMPLATE_VIS move_iterator
66#if _LIBCPP_STD_VER > 17
69#if _LIBCPP_STD_VER >= 20
6770 : public __move_iter_category_base<_Iter>
6871#endif
6972{
73 #if _LIBCPP_STD_VER >= 20
74private:
75 _LIBCPP_HIDE_FROM_ABI
76 static constexpr auto __get_iter_concept() {
77 if constexpr (random_access_iterator<_Iter>) {
78 return random_access_iterator_tag{};
79 } else if constexpr (bidirectional_iterator<_Iter>) {
80 return bidirectional_iterator_tag{};
81 } else if constexpr (forward_iterator<_Iter>) {
82 return forward_iterator_tag{};
83 } else {
84 return input_iterator_tag{};
85 }
86 }
87#endif // _LIBCPP_STD_VER >= 20
7088public:
71#if _LIBCPP_STD_VER > 17
89#if _LIBCPP_STD_VER >= 20
7290 using iterator_type = _Iter;
73 using iterator_concept = input_iterator_tag;
91 using iterator_concept = decltype(__get_iter_concept());
7492 // iterator_category is inherited and not always present
7593 using value_type = iter_value_t<_Iter>;
7694 using difference_type = iter_difference_t<_Iter>;
......@@ -79,7 +97,7 @@ public:
7997#else
8098 typedef _Iter iterator_type;
8199 typedef _If<
82 __is_cpp17_random_access_iterator<_Iter>::value,
100 __has_random_access_iterator_category<_Iter>::value,
83101 random_access_iterator_tag,
84102 typename iterator_traits<_Iter>::iterator_category
85103 > iterator_category;
......@@ -93,7 +111,7 @@ public:
93111 __libcpp_remove_reference_t<__reference>&&,
94112 __reference
95113 >::type reference;
96#endif // _LIBCPP_STD_VER > 17
114#endif // _LIBCPP_STD_VER >= 20
97115
98116 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
99117 explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {}
......@@ -104,7 +122,7 @@ public:
104122 _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
105123 pointer operator->() const { return __current_; }
106124
107#if _LIBCPP_STD_VER > 17
125#if _LIBCPP_STD_VER >= 20
108126 _LIBCPP_HIDE_FROM_ABI constexpr
109127 move_iterator() requires is_constructible_v<_Iter> : __current_() {}
110128
......@@ -171,7 +189,7 @@ public:
171189
172190 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
173191 move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; }
174#endif // _LIBCPP_STD_VER > 17
192#endif // _LIBCPP_STD_VER >= 20
175193
176194 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
177195 move_iterator& operator--() { --__current_; return *this; }
......@@ -186,7 +204,7 @@ public:
186204 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
187205 move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; }
188206
189#if _LIBCPP_STD_VER > 17
207#if _LIBCPP_STD_VER >= 20
190208 template<sentinel_for<_Iter> _Sent>
191209 friend _LIBCPP_HIDE_FROM_ABI constexpr
192210 bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y)
......@@ -223,7 +241,7 @@ public:
223241 {
224242 return ranges::iter_swap(__x.__current_, __y.__current_);
225243 }
226#endif // _LIBCPP_STD_VER > 17
244#endif // _LIBCPP_STD_VER >= 20
227245
228246private:
229247 template<class _It2> friend class move_iterator;
......@@ -276,7 +294,7 @@ bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& _
276294 return __x.base() >= __y.base();
277295}
278296
279#if _LIBCPP_STD_VER > 17
297#if _LIBCPP_STD_VER >= 20
280298template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
281299inline _LIBCPP_HIDE_FROM_ABI constexpr
282300auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
......@@ -284,7 +302,7 @@ auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>&
284302{
285303 return __x.base() <=> __y.base();
286304}
287#endif // _LIBCPP_STD_VER > 17
305#endif // _LIBCPP_STD_VER >= 20
288306
289307#ifndef _LIBCPP_CXX03_LANG
290308template <class _Iter1, class _Iter2>
......@@ -304,7 +322,7 @@ operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
304322}
305323#endif // !_LIBCPP_CXX03_LANG
306324
307#if _LIBCPP_STD_VER > 17
325#if _LIBCPP_STD_VER >= 20
308326template <class _Iter>
309327inline _LIBCPP_HIDE_FROM_ABI constexpr
310328move_iterator<_Iter> operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x)
......@@ -320,7 +338,7 @@ operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterato
320338{
321339 return move_iterator<_Iter>(__x.base() + __n);
322340}
323#endif // _LIBCPP_STD_VER > 17
341#endif // _LIBCPP_STD_VER >= 20
324342
325343template <class _Iter>
326344inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
......@@ -332,4 +350,6 @@ make_move_iterator(_Iter __i)
332350
333351_LIBCPP_END_NAMESPACE_STD
334352
353_LIBCPP_POP_MACROS
354
335355#endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H
lib/libcxx/include/__iterator/move_sentinel.h+8-3
......@@ -19,9 +19,12 @@
1919# pragma GCC system_header
2020#endif
2121
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
2225_LIBCPP_BEGIN_NAMESPACE_STD
2326
24#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2528
2629template <semiregular _Sent>
2730class _LIBCPP_TEMPLATE_VIS move_sentinel
......@@ -44,7 +47,7 @@ public:
4447 move_sentinel& operator=(const move_sentinel<_S2>& __s)
4548 { __last_ = __s.base(); return *this; }
4649
47 constexpr _Sent base() const { return __last_; }
50 _LIBCPP_HIDE_FROM_ABI constexpr _Sent base() const { return __last_; }
4851
4952private:
5053 _Sent __last_ = _Sent();
......@@ -52,8 +55,10 @@ private:
5255
5356_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_sentinel);
5457
55#endif // _LIBCPP_STD_VER > 17
58#endif // _LIBCPP_STD_VER >= 20
5659
5760_LIBCPP_END_NAMESPACE_STD
5861
62_LIBCPP_POP_MACROS
63
5964#endif // _LIBCPP___ITERATOR_MOVE_SENTINEL_H
lib/libcxx/include/__iterator/next.h+5-5
......@@ -26,16 +26,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2626
2727template <class _InputIter>
2828inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
29 typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type
29 typename enable_if<__has_input_iterator_category<_InputIter>::value, _InputIter>::type
3030 next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) {
31 _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
32 "Attempt to next(it, n) with negative n on a non-bidirectional iterator");
31 _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value,
32 "Attempt to next(it, n) with negative n on a non-bidirectional iterator");
3333
3434 _VSTD::advance(__x, __n);
3535 return __x;
3636}
3737
38#if _LIBCPP_STD_VER > 17
38#if _LIBCPP_STD_VER >= 20
3939
4040// [range.iter.op.next]
4141
......@@ -77,7 +77,7 @@ inline namespace __cpo {
7777} // namespace __cpo
7878} // namespace ranges
7979
80#endif // _LIBCPP_STD_VER > 17
80#endif // _LIBCPP_STD_VER >= 20
8181
8282_LIBCPP_END_NAMESPACE_STD
8383
lib/libcxx/include/__iterator/ostream_iterator.h+1-1
......@@ -34,7 +34,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
3434public:
3535 typedef output_iterator_tag iterator_category;
3636 typedef void value_type;
37#if _LIBCPP_STD_VER > 17
37#if _LIBCPP_STD_VER >= 20
3838 typedef ptrdiff_t difference_type;
3939#else
4040 typedef void difference_type;
lib/libcxx/include/__iterator/ostreambuf_iterator.h+1-1
......@@ -33,7 +33,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
3333public:
3434 typedef output_iterator_tag iterator_category;
3535 typedef void value_type;
36#if _LIBCPP_STD_VER > 17
36#if _LIBCPP_STD_VER >= 20
3737 typedef ptrdiff_t difference_type;
3838#else
3939 typedef void difference_type;
lib/libcxx/include/__iterator/permutable.h+2-2
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 17
23#if _LIBCPP_STD_VER >= 20
2424
2525template <class _Iterator>
2626concept permutable =
......@@ -28,7 +28,7 @@ concept permutable =
2828 indirectly_movable_storable<_Iterator, _Iterator> &&
2929 indirectly_swappable<_Iterator, _Iterator>;
3030
31#endif // _LIBCPP_STD_VER > 17
31#endif // _LIBCPP_STD_VER >= 20
3232
3333_LIBCPP_END_NAMESPACE_STD
3434
lib/libcxx/include/__iterator/prev.h+5-5
......@@ -26,15 +26,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2626
2727template <class _InputIter>
2828inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
29 typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type
29 typename enable_if<__has_input_iterator_category<_InputIter>::value, _InputIter>::type
3030 prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) {
31 _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
32 "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator");
31 _LIBCPP_ASSERT_UNCATEGORIZED(__n <= 0 || __has_bidirectional_iterator_category<_InputIter>::value,
32 "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator");
3333 _VSTD::advance(__x, -__n);
3434 return __x;
3535}
3636
37#if _LIBCPP_STD_VER > 17
37#if _LIBCPP_STD_VER >= 20
3838
3939// [range.iter.op.prev]
4040
......@@ -70,7 +70,7 @@ inline namespace __cpo {
7070} // namespace __cpo
7171} // namespace ranges
7272
73#endif // _LIBCPP_STD_VER > 17
73#endif // _LIBCPP_STD_VER >= 20
7474
7575_LIBCPP_END_NAMESPACE_STD
7676
lib/libcxx/include/__iterator/projected.h+2-2
......@@ -21,7 +21,7 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24#if _LIBCPP_STD_VER > 17
24#if _LIBCPP_STD_VER >= 20
2525
2626template<indirectly_readable _It, indirectly_regular_unary_invocable<_It> _Proj>
2727struct projected {
......@@ -34,7 +34,7 @@ struct incrementable_traits<projected<_It, _Proj>> {
3434 using difference_type = iter_difference_t<_It>;
3535};
3636
37#endif // _LIBCPP_STD_VER > 17
37#endif // _LIBCPP_STD_VER >= 20
3838
3939_LIBCPP_END_NAMESPACE_STD
4040
lib/libcxx/include/__iterator/ranges_iterator_traits.h created+42
......@@ -0,0 +1,42 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H
11#define _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H
12
13#include <__config>
14#include <__fwd/pair.h>
15#include <__ranges/concepts.h>
16#include <__type_traits/add_const.h>
17#include <__type_traits/remove_const.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#if _LIBCPP_STD_VER >= 23
26
27template <ranges::input_range _Range>
28using __range_key_type = __remove_const_t<typename ranges::range_value_t<_Range>::first_type>;
29
30template <ranges::input_range _Range>
31using __range_mapped_type = typename ranges::range_value_t<_Range>::second_type;
32
33template <ranges::input_range _Range>
34using __range_to_alloc_type =
35 pair<add_const_t<typename ranges::range_value_t<_Range>::first_type>,
36 typename ranges::range_value_t<_Range>::second_type>;
37
38#endif
39
40_LIBCPP_END_NAMESPACE_STD
41
42#endif // _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H
lib/libcxx/include/__iterator/readable_traits.h+2-13
......@@ -26,7 +26,7 @@
2626
2727_LIBCPP_BEGIN_NAMESPACE_STD
2828
29#if _LIBCPP_STD_VER > 17
29#if _LIBCPP_STD_VER >= 20
3030
3131// [readable.traits]
3232template<class> struct __cond_value_type {};
......@@ -74,18 +74,7 @@ template<__has_member_value_type _Tp>
7474struct indirectly_readable_traits<_Tp>
7575 : __cond_value_type<typename _Tp::value_type> {};
7676
77template <class>
78struct iterator_traits;
79
80// Let `RI` be `remove_cvref_t<I>`. The type `iter_value_t<I>` denotes
81// `indirectly_readable_traits<RI>::value_type` if `iterator_traits<RI>` names a specialization
82// generated from the primary template, and `iterator_traits<RI>::value_type` otherwise.
83template <class _Ip>
84using iter_value_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value,
85 indirectly_readable_traits<remove_cvref_t<_Ip> >,
86 iterator_traits<remove_cvref_t<_Ip> > >::value_type;
87
88#endif // _LIBCPP_STD_VER > 17
77#endif // _LIBCPP_STD_VER >= 20
8978
9079_LIBCPP_END_NAMESPACE_STD
9180
lib/libcxx/include/__iterator/reverse_access.h+2-2
......@@ -21,7 +21,7 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24#if _LIBCPP_STD_VER > 11
24#if _LIBCPP_STD_VER >= 14
2525
2626template <class _Tp, size_t _Np>
2727_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
......@@ -93,7 +93,7 @@ auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c))
9393 return _VSTD::rend(__c);
9494}
9595
96#endif // _LIBCPP_STD_VER > 11
96#endif // _LIBCPP_STD_VER >= 14
9797
9898_LIBCPP_END_NAMESPACE_STD
9999
lib/libcxx/include/__iterator/reverse_iterator.h+31-31
......@@ -63,21 +63,21 @@ private:
6363 _Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break
6464#endif
6565
66#if _LIBCPP_STD_VER > 17
67 static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>,
66#if _LIBCPP_STD_VER >= 20
67 static_assert(__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>,
6868 "reverse_iterator<It> requires It to be a bidirectional iterator.");
69#endif // _LIBCPP_STD_VER > 17
69#endif // _LIBCPP_STD_VER >= 20
7070
7171protected:
7272 _Iter current;
7373public:
7474 using iterator_type = _Iter;
7575
76 using iterator_category = _If<__is_cpp17_random_access_iterator<_Iter>::value,
76 using iterator_category = _If<__has_random_access_iterator_category<_Iter>::value,
7777 random_access_iterator_tag,
7878 typename iterator_traits<_Iter>::iterator_category>;
7979 using pointer = typename iterator_traits<_Iter>::pointer;
80#if _LIBCPP_STD_VER > 17
80#if _LIBCPP_STD_VER >= 20
8181 using iterator_concept = _If<random_access_iterator<_Iter>, random_access_iterator_tag, bidirectional_iterator_tag>;
8282 using value_type = iter_value_t<_Iter>;
8383 using difference_type = iter_difference_t<_Iter>;
......@@ -144,7 +144,7 @@ public:
144144 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
145145 reference operator*() const {_Iter __tmp = current; return *--__tmp;}
146146
147#if _LIBCPP_STD_VER > 17
147#if _LIBCPP_STD_VER >= 20
148148 _LIBCPP_INLINE_VISIBILITY
149149 constexpr pointer operator->() const
150150 requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); }
......@@ -160,7 +160,7 @@ public:
160160 pointer operator->() const {
161161 return std::addressof(operator*());
162162 }
163#endif // _LIBCPP_STD_VER > 17
163#endif // _LIBCPP_STD_VER >= 20
164164
165165 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
166166 reverse_iterator& operator++() {--current; return *this;}
......@@ -181,7 +181,7 @@ public:
181181 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
182182 reference operator[](difference_type __n) const {return *(*this + __n);}
183183
184#if _LIBCPP_STD_VER > 17
184#if _LIBCPP_STD_VER >= 20
185185 _LIBCPP_HIDE_FROM_ABI friend constexpr
186186 iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i)
187187 noexcept(is_nothrow_copy_constructible_v<_Iter> &&
......@@ -200,18 +200,18 @@ public:
200200 auto __ytmp = __y.base();
201201 ranges::iter_swap(--__xtmp, --__ytmp);
202202 }
203#endif // _LIBCPP_STD_VER > 17
203#endif // _LIBCPP_STD_VER >= 20
204204};
205205
206206template <class _Iter1, class _Iter2>
207207inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
208208bool
209209operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
210#if _LIBCPP_STD_VER > 17
210#if _LIBCPP_STD_VER >= 20
211211 requires requires {
212212 { __x.base() == __y.base() } -> convertible_to<bool>;
213213 }
214#endif // _LIBCPP_STD_VER > 17
214#endif // _LIBCPP_STD_VER >= 20
215215{
216216 return __x.base() == __y.base();
217217}
......@@ -220,11 +220,11 @@ template <class _Iter1, class _Iter2>
220220inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
221221bool
222222operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
223#if _LIBCPP_STD_VER > 17
223#if _LIBCPP_STD_VER >= 20
224224 requires requires {
225225 { __x.base() > __y.base() } -> convertible_to<bool>;
226226 }
227#endif // _LIBCPP_STD_VER > 17
227#endif // _LIBCPP_STD_VER >= 20
228228{
229229 return __x.base() > __y.base();
230230}
......@@ -233,11 +233,11 @@ template <class _Iter1, class _Iter2>
233233inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
234234bool
235235operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
236#if _LIBCPP_STD_VER > 17
236#if _LIBCPP_STD_VER >= 20
237237 requires requires {
238238 { __x.base() != __y.base() } -> convertible_to<bool>;
239239 }
240#endif // _LIBCPP_STD_VER > 17
240#endif // _LIBCPP_STD_VER >= 20
241241{
242242 return __x.base() != __y.base();
243243}
......@@ -246,11 +246,11 @@ template <class _Iter1, class _Iter2>
246246inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
247247bool
248248operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
249#if _LIBCPP_STD_VER > 17
249#if _LIBCPP_STD_VER >= 20
250250 requires requires {
251251 { __x.base() < __y.base() } -> convertible_to<bool>;
252252 }
253#endif // _LIBCPP_STD_VER > 17
253#endif // _LIBCPP_STD_VER >= 20
254254{
255255 return __x.base() < __y.base();
256256}
......@@ -259,11 +259,11 @@ template <class _Iter1, class _Iter2>
259259inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
260260bool
261261operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
262#if _LIBCPP_STD_VER > 17
262#if _LIBCPP_STD_VER >= 20
263263 requires requires {
264264 { __x.base() <= __y.base() } -> convertible_to<bool>;
265265 }
266#endif // _LIBCPP_STD_VER > 17
266#endif // _LIBCPP_STD_VER >= 20
267267{
268268 return __x.base() <= __y.base();
269269}
......@@ -272,16 +272,16 @@ template <class _Iter1, class _Iter2>
272272inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
273273bool
274274operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
275#if _LIBCPP_STD_VER > 17
275#if _LIBCPP_STD_VER >= 20
276276 requires requires {
277277 { __x.base() >= __y.base() } -> convertible_to<bool>;
278278 }
279#endif // _LIBCPP_STD_VER > 17
279#endif // _LIBCPP_STD_VER >= 20
280280{
281281 return __x.base() >= __y.base();
282282}
283283
284#if _LIBCPP_STD_VER > 17
284#if _LIBCPP_STD_VER >= 20
285285template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
286286_LIBCPP_HIDE_FROM_ABI constexpr
287287compare_three_way_result_t<_Iter1, _Iter2>
......@@ -289,7 +289,7 @@ operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>&
289289{
290290 return __y.base() <=> __x.base();
291291}
292#endif // _LIBCPP_STD_VER > 17
292#endif // _LIBCPP_STD_VER >= 20
293293
294294#ifndef _LIBCPP_CXX03_LANG
295295template <class _Iter1, class _Iter2>
......@@ -318,13 +318,13 @@ operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_i
318318 return reverse_iterator<_Iter>(__x.base() - __n);
319319}
320320
321#if _LIBCPP_STD_VER > 17
321#if _LIBCPP_STD_VER >= 20
322322template <class _Iter1, class _Iter2>
323323 requires (!sized_sentinel_for<_Iter1, _Iter2>)
324324inline constexpr bool disable_sized_sentinel_for<reverse_iterator<_Iter1>, reverse_iterator<_Iter2>> = true;
325#endif // _LIBCPP_STD_VER > 17
325#endif // _LIBCPP_STD_VER >= 20
326326
327#if _LIBCPP_STD_VER > 11
327#if _LIBCPP_STD_VER >= 14
328328template <class _Iter>
329329inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
330330reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
......@@ -365,11 +365,11 @@ class __unconstrained_reverse_iterator {
365365 _Iter __iter_;
366366
367367public:
368 static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>);
368 static_assert(__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>);
369369
370370 using iterator_type = _Iter;
371371 using iterator_category =
372 _If<__is_cpp17_random_access_iterator<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>;
372 _If<__has_random_access_iterator_category<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>;
373373 using pointer = __iterator_pointer_type<_Iter>;
374374 using value_type = iter_value_t<_Iter>;
375375 using difference_type = iter_difference_t<_Iter>;
......@@ -498,7 +498,7 @@ struct __unwrap_reverse_iter_impl {
498498 }
499499};
500500
501#if _LIBCPP_STD_VER > 17
501#if _LIBCPP_STD_VER >= 20
502502template <ranges::bidirectional_range _Range>
503503_LIBCPP_HIDE_FROM_ABI constexpr ranges::
504504 subrange<reverse_iterator<ranges::iterator_t<_Range>>, reverse_iterator<ranges::iterator_t<_Range>>>
......@@ -512,7 +512,7 @@ template <class _Iter, bool __b>
512512struct __unwrap_iter_impl<reverse_iterator<reverse_iterator<_Iter> >, __b>
513513 : __unwrap_reverse_iter_impl<reverse_iterator, reverse_iterator, _Iter> {};
514514
515#if _LIBCPP_STD_VER > 17
515#if _LIBCPP_STD_VER >= 20
516516
517517template <class _Iter, bool __b>
518518struct __unwrap_iter_impl<reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b>
......@@ -526,7 +526,7 @@ template <class _Iter, bool __b>
526526struct __unwrap_iter_impl<__unconstrained_reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b>
527527 : __unwrap_reverse_iter_impl<__unconstrained_reverse_iterator, __unconstrained_reverse_iterator, _Iter> {};
528528
529#endif // _LIBCPP_STD_VER > 17
529#endif // _LIBCPP_STD_VER >= 20
530530
531531_LIBCPP_END_NAMESPACE_STD
532532
lib/libcxx/include/__iterator/size.h+3-3
......@@ -21,7 +21,7 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2525
2626template <class _Cont>
2727_LIBCPP_INLINE_VISIBILITY
......@@ -34,7 +34,7 @@ template <class _Tp, size_t _Sz>
3434_LIBCPP_INLINE_VISIBILITY
3535constexpr size_t size(const _Tp (&)[_Sz]) noexcept { return _Sz; }
3636
37#if _LIBCPP_STD_VER > 17
37#if _LIBCPP_STD_VER >= 20
3838template <class _Cont>
3939_LIBCPP_INLINE_VISIBILITY
4040constexpr auto ssize(const _Cont& __c)
......@@ -52,7 +52,7 @@ constexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; }
5252_LIBCPP_DIAGNOSTIC_POP
5353#endif
5454
55#endif // _LIBCPP_STD_VER > 14
55#endif // _LIBCPP_STD_VER >= 17
5656
5757_LIBCPP_END_NAMESPACE_STD
5858
lib/libcxx/include/__iterator/sortable.h+2-2
......@@ -23,14 +23,14 @@
2323
2424_LIBCPP_BEGIN_NAMESPACE_STD
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828template <class _Iter, class _Comp = ranges::less, class _Proj = identity>
2929concept sortable =
3030 permutable<_Iter> &&
3131 indirect_strict_weak_order<_Comp, projected<_Iter, _Proj>>;
3232
33#endif // _LIBCPP_STD_VER > 17
33#endif // _LIBCPP_STD_VER >= 20
3434
3535_LIBCPP_END_NAMESPACE_STD
3636
lib/libcxx/include/__iterator/unreachable_sentinel.h+2-2
......@@ -19,7 +19,7 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 17
22#if _LIBCPP_STD_VER >= 20
2323
2424struct unreachable_sentinel_t {
2525 template<weakly_incrementable _Iter>
......@@ -31,7 +31,7 @@ struct unreachable_sentinel_t {
3131
3232inline constexpr unreachable_sentinel_t unreachable_sentinel{};
3333
34#endif // _LIBCPP_STD_VER > 17
34#endif // _LIBCPP_STD_VER >= 20
3535
3636_LIBCPP_END_NAMESPACE_STD
3737
lib/libcxx/include/__iterator/wrap_iter.h+4-58
......@@ -11,12 +11,12 @@
1111#define _LIBCPP___ITERATOR_WRAP_ITER_H
1212
1313#include <__config>
14#include <__debug>
1514#include <__iterator/iterator_traits.h>
1615#include <__memory/addressof.h>
1716#include <__memory/pointer_traits.h>
1817#include <__type_traits/enable_if.h>
1918#include <__type_traits/is_convertible.h>
19#include <cstddef>
2020
2121#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2222# pragma GCC system_header
......@@ -34,7 +34,7 @@ public:
3434 typedef typename iterator_traits<iterator_type>::pointer pointer;
3535 typedef typename iterator_traits<iterator_type>::reference reference;
3636 typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
37#if _LIBCPP_STD_VER > 17
37#if _LIBCPP_STD_VER >= 20
3838 typedef contiguous_iterator_tag iterator_concept;
3939#endif
4040
......@@ -44,60 +44,23 @@ public:
4444 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter() _NOEXCEPT
4545 : __i_()
4646 {
47 _VSTD::__debug_db_insert_i(this);
4847 }
4948 template <class _Up> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
5049 __wrap_iter(const __wrap_iter<_Up>& __u,
5150 typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = nullptr) _NOEXCEPT
5251 : __i_(__u.base())
5352 {
54#ifdef _LIBCPP_ENABLE_DEBUG_MODE
55 if (!__libcpp_is_constant_evaluated())
56 __get_db()->__iterator_copy(this, _VSTD::addressof(__u));
57#endif
58 }
59#ifdef _LIBCPP_ENABLE_DEBUG_MODE
60 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
61 __wrap_iter(const __wrap_iter& __x)
62 : __i_(__x.base())
63 {
64 if (!__libcpp_is_constant_evaluated())
65 __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
66 }
67 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
68 __wrap_iter& operator=(const __wrap_iter& __x)
69 {
70 if (this != _VSTD::addressof(__x))
71 {
72 if (!__libcpp_is_constant_evaluated())
73 __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
74 __i_ = __x.__i_;
75 }
76 return *this;
77 }
78 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
79 ~__wrap_iter()
80 {
81 if (!__libcpp_is_constant_evaluated())
82 __get_db()->__erase_i(this);
8353 }
84#endif
8554 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT
8655 {
87 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
88 "Attempted to dereference a non-dereferenceable iterator");
8956 return *__i_;
9057 }
9158 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT
9259 {
93 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
94 "Attempted to dereference a non-dereferenceable iterator");
9560 return _VSTD::__to_address(__i_);
9661 }
9762 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator++() _NOEXCEPT
9863 {
99 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
100 "Attempted to increment a non-incrementable iterator");
10164 ++__i_;
10265 return *this;
10366 }
......@@ -106,8 +69,6 @@ public:
10669
10770 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator--() _NOEXCEPT
10871 {
109 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this),
110 "Attempted to decrement a non-decrementable iterator");
11172 --__i_;
11273 return *this;
11374 }
......@@ -117,8 +78,6 @@ public:
11778 {__wrap_iter __w(*this); __w += __n; return __w;}
11879 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator+=(difference_type __n) _NOEXCEPT
11980 {
120 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__addable(this, __n),
121 "Attempted to add/subtract an iterator outside its valid range");
12281 __i_ += __n;
12382 return *this;
12483 }
......@@ -128,8 +87,6 @@ public:
12887 {*this += -__n; return *this;}
12988 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT
13089 {
131 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__subscriptable(this, __n),
132 "Attempted to subscript an iterator outside its valid range");
13390 return __i_[__n];
13491 }
13592
......@@ -137,13 +94,8 @@ public:
13794
13895private:
13996 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
140 explicit __wrap_iter(const void* __p, iterator_type __x) _NOEXCEPT : __i_(__x)
97 explicit __wrap_iter(iterator_type __x) _NOEXCEPT : __i_(__x)
14198 {
142 (void)__p;
143#ifdef _LIBCPP_ENABLE_DEBUG_MODE
144 if (!__libcpp_is_constant_evaluated())
145 __get_db()->__insert_ic(this, __p);
146#endif
14799 }
148100
149101 template <class _Up> friend class __wrap_iter;
......@@ -170,8 +122,6 @@ template <class _Iter1>
170122_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
171123bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
172124{
173 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)),
174 "Attempted to compare incomparable iterators");
175125 return __x.base() < __y.base();
176126}
177127
......@@ -179,8 +129,6 @@ template <class _Iter1, class _Iter2>
179129_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
180130bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
181131{
182 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
183 "Attempted to compare incomparable iterators");
184132 return __x.base() < __y.base();
185133}
186134
......@@ -250,8 +198,6 @@ typename __wrap_iter<_Iter1>::difference_type
250198operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
251199#endif // C++03
252200{
253 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)),
254 "Attempted to subtract incompatible iterators");
255201 return __x.base() - __y.base();
256202}
257203
......@@ -265,7 +211,7 @@ __wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type __n,
265211
266212#if _LIBCPP_STD_VER <= 17
267213template <class _It>
268struct __is_cpp17_contiguous_iterator<__wrap_iter<_It> > : true_type {};
214struct __libcpp_is_contiguous_iterator<__wrap_iter<_It> > : true_type {};
269215#endif
270216
271217template <class _It>
lib/libcxx/include/__locale+47-95
......@@ -12,9 +12,12 @@
1212
1313#include <__availability>
1414#include <__config>
15#include <__memory/shared_ptr.h> // __shared_count
16#include <__type_traits/make_unsigned.h>
1517#include <cctype>
18#include <clocale>
1619#include <cstdint>
17#include <locale.h>
20#include <cstdlib>
1821#include <mutex>
1922#include <string>
2023
......@@ -22,15 +25,18 @@
2225#include <cstddef>
2326#include <cstring>
2427
28#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
29# include <cwchar>
30#else
31# include <__std_mbstate_t.h>
32#endif
33
2534#if defined(_LIBCPP_MSVCRT_LIKE)
2635# include <__support/win32/locale_win32.h>
2736#elif defined(_AIX) || defined(__MVS__)
2837# include <__support/ibm/xlocale.h>
2938#elif defined(__ANDROID__)
3039# include <__support/android/locale_bionic.h>
31#elif defined(__sun__)
32# include <__support/solaris/xlocale.h>
33# include <xlocale.h>
3440#elif defined(_NEWLIB_VERSION)
3541# include <__support/newlib/xlocale.h>
3642#elif defined(__OpenBSD__)
......@@ -52,64 +58,7 @@
5258
5359_LIBCPP_BEGIN_NAMESPACE_STD
5460
55#if !defined(_LIBCPP_LOCALE__L_EXTENSIONS)
56struct __libcpp_locale_guard {
57 _LIBCPP_INLINE_VISIBILITY
58 __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {}
59
60 _LIBCPP_INLINE_VISIBILITY
61 ~__libcpp_locale_guard() {
62 if (__old_loc_)
63 uselocale(__old_loc_);
64 }
65
66 locale_t __old_loc_;
67private:
68 __libcpp_locale_guard(__libcpp_locale_guard const&);
69 __libcpp_locale_guard& operator=(__libcpp_locale_guard const&);
70};
71#elif defined(_LIBCPP_MSVCRT_LIKE)
72struct __libcpp_locale_guard {
73 __libcpp_locale_guard(locale_t __l) :
74 __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
75 // Setting the locale can be expensive even when the locale given is
76 // already the current locale, so do an explicit check to see if the
77 // current locale is already the one we want.
78 const char* __lc = __setlocale(nullptr);
79 // If every category is the same, the locale string will simply be the
80 // locale name, otherwise it will be a semicolon-separated string listing
81 // each category. In the second case, we know at least one category won't
82 // be what we want, so we only have to check the first case.
83 if (_VSTD::strcmp(__l.__get_locale(), __lc) != 0) {
84 __locale_all = _strdup(__lc);
85 if (__locale_all == nullptr)
86 __throw_bad_alloc();
87 __setlocale(__l.__get_locale());
88 }
89 }
90 ~__libcpp_locale_guard() {
91 // The CRT documentation doesn't explicitly say, but setlocale() does the
92 // right thing when given a semicolon-separated list of locale settings
93 // for the different categories in the same format as returned by
94 // setlocale(LC_ALL, nullptr).
95 if (__locale_all != nullptr) {
96 __setlocale(__locale_all);
97 free(__locale_all);
98 }
99 _configthreadlocale(__status);
100 }
101 static const char* __setlocale(const char* __locale) {
102 const char* __new_locale = setlocale(LC_ALL, __locale);
103 if (__new_locale == nullptr)
104 __throw_bad_alloc();
105 return __new_locale;
106 }
107 int __status;
108 char* __locale_all = nullptr;
109};
110#endif
111
112class _LIBCPP_TYPE_VIS locale;
61class _LIBCPP_EXPORTED_FROM_ABI locale;
11362
11463template <class _Facet>
11564_LIBCPP_INLINE_VISIBILITY
......@@ -121,12 +70,12 @@ _LIBCPP_INLINE_VISIBILITY
12170const _Facet&
12271use_facet(const locale&);
12372
124class _LIBCPP_TYPE_VIS locale
73class _LIBCPP_EXPORTED_FROM_ABI locale
12574{
12675public:
12776 // types:
128 class _LIBCPP_TYPE_VIS facet;
129 class _LIBCPP_TYPE_VIS id;
77 class _LIBCPP_EXPORTED_FROM_ABI facet;
78 class _LIBCPP_EXPORTED_FROM_ABI id;
13079
13180 typedef int category;
13281 _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
......@@ -162,7 +111,9 @@ public:
162111 // locale operations:
163112 string name() const;
164113 bool operator==(const locale&) const;
165 bool operator!=(const locale& __y) const {return !(*this == __y);}
114#if _LIBCPP_STD_VER <= 17
115 _LIBCPP_HIDE_FROM_ABI bool operator!=(const locale& __y) const {return !(*this == __y);}
116#endif
166117 template <class _CharT, class _Traits, class _Allocator>
167118 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
168119 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
......@@ -185,7 +136,7 @@ private:
185136 template <class _Facet> friend const _Facet& use_facet(const locale&);
186137};
187138
188class _LIBCPP_TYPE_VIS locale::facet
139class _LIBCPP_EXPORTED_FROM_ABI locale::facet
189140 : public __shared_count
190141{
191142protected:
......@@ -201,7 +152,7 @@ private:
201152 void __on_zero_shared() _NOEXCEPT override;
202153};
203154
204class _LIBCPP_TYPE_VIS locale::id
155class _LIBCPP_EXPORTED_FROM_ABI locale::id
205156{
206157 once_flag __flag_;
207158 int32_t __id_;
......@@ -349,7 +300,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>;
349300template <class _CharT> class _LIBCPP_TEMPLATE_VIS collate_byname;
350301
351302template <>
352class _LIBCPP_TYPE_VIS collate_byname<char>
303class _LIBCPP_EXPORTED_FROM_ABI collate_byname<char>
353304 : public collate<char>
354305{
355306 locale_t __l_;
......@@ -369,7 +320,7 @@ protected:
369320
370321#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
371322template <>
372class _LIBCPP_TYPE_VIS collate_byname<wchar_t>
323class _LIBCPP_EXPORTED_FROM_ABI collate_byname<wchar_t>
373324 : public collate<wchar_t>
374325{
375326 locale_t __l_;
......@@ -401,7 +352,7 @@ locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
401352
402353// template <class charT> class ctype
403354
404class _LIBCPP_TYPE_VIS ctype_base
355class _LIBCPP_EXPORTED_FROM_ABI ctype_base
405356{
406357public:
407358#if defined(_LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE)
......@@ -482,7 +433,7 @@ public:
482433 static const mask blank = _CTYPE_B;
483434 static const mask __regex_word = 0x80;
484435# endif
485#elif defined(__sun__) || defined(_AIX)
436#elif defined(_AIX)
486437 typedef unsigned int mask;
487438 static const mask space = _ISSPACE;
488439 static const mask print = _ISPRINT;
......@@ -494,11 +445,7 @@ public:
494445 static const mask punct = _ISPUNCT;
495446 static const mask xdigit = _ISXDIGIT;
496447 static const mask blank = _ISBLANK;
497# if defined(_AIX)
498448 static const mask __regex_word = 0x8000;
499# else
500 static const mask __regex_word = 0x80;
501# endif
502449#elif defined(_NEWLIB_VERSION)
503450 // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
504451 typedef char mask;
......@@ -561,7 +508,7 @@ template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype;
561508
562509#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
563510template <>
564class _LIBCPP_TYPE_VIS ctype<wchar_t>
511class _LIBCPP_EXPORTED_FROM_ABI ctype<wchar_t>
565512 : public locale::facet,
566513 public ctype_base
567514{
......@@ -664,7 +611,7 @@ protected:
664611#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
665612
666613template <>
667class _LIBCPP_TYPE_VIS ctype<char>
614class _LIBCPP_EXPORTED_FROM_ABI ctype<char>
668615 : public locale::facet, public ctype_base
669616{
670617 const mask* __tab_;
......@@ -793,7 +740,7 @@ protected:
793740template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype_byname;
794741
795742template <>
796class _LIBCPP_TYPE_VIS ctype_byname<char>
743class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<char>
797744 : public ctype<char>
798745{
799746 locale_t __l_;
......@@ -812,7 +759,7 @@ protected:
812759
813760#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
814761template <>
815class _LIBCPP_TYPE_VIS ctype_byname<wchar_t>
762class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<wchar_t>
816763 : public ctype<wchar_t>
817764{
818765 locale_t __l_;
......@@ -926,6 +873,11 @@ isgraph(_CharT __c, const locale& __loc)
926873 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
927874}
928875
876template <class _CharT>
877_LIBCPP_HIDE_FROM_ABI bool isblank(_CharT __c, const locale& __loc) {
878 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::blank, __c);
879}
880
929881template <class _CharT>
930882inline _LIBCPP_INLINE_VISIBILITY
931883_CharT
......@@ -944,7 +896,7 @@ tolower(_CharT __c, const locale& __loc)
944896
945897// codecvt_base
946898
947class _LIBCPP_TYPE_VIS codecvt_base
899class _LIBCPP_EXPORTED_FROM_ABI codecvt_base
948900{
949901public:
950902 _LIBCPP_INLINE_VISIBILITY codecvt_base() {}
......@@ -958,7 +910,7 @@ template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TEMPLATE_
958910// template <> class codecvt<char, char, mbstate_t>
959911
960912template <>
961class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t>
913class _LIBCPP_EXPORTED_FROM_ABI codecvt<char, char, mbstate_t>
962914 : public locale::facet,
963915 public codecvt_base
964916{
......@@ -1045,7 +997,7 @@ protected:
1045997
1046998#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1047999template <>
1048class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t>
1000class _LIBCPP_EXPORTED_FROM_ABI codecvt<wchar_t, char, mbstate_t>
10491001 : public locale::facet,
10501002 public codecvt_base
10511003{
......@@ -1129,7 +1081,7 @@ protected:
11291081// template <> class codecvt<char16_t, char, mbstate_t> // deprecated in C++20
11301082
11311083template <>
1132class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
1084class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char, mbstate_t>
11331085 : public locale::facet,
11341086 public codecvt_base
11351087{
......@@ -1217,7 +1169,7 @@ protected:
12171169// template <> class codecvt<char16_t, char8_t, mbstate_t> // C++20
12181170
12191171template <>
1220class _LIBCPP_TYPE_VIS codecvt<char16_t, char8_t, mbstate_t>
1172class _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char8_t, mbstate_t>
12211173 : public locale::facet,
12221174 public codecvt_base
12231175{
......@@ -1305,7 +1257,7 @@ protected:
13051257// template <> class codecvt<char32_t, char, mbstate_t> // deprecated in C++20
13061258
13071259template <>
1308class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
1260class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char, mbstate_t>
13091261 : public locale::facet,
13101262 public codecvt_base
13111263{
......@@ -1393,7 +1345,7 @@ protected:
13931345// template <> class codecvt<char32_t, char8_t, mbstate_t> // C++20
13941346
13951347template <>
1396class _LIBCPP_TYPE_VIS codecvt<char32_t, char8_t, mbstate_t>
1348class _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char8_t, mbstate_t>
13971349 : public locale::facet,
13981350 public codecvt_base
13991351{
......@@ -1537,7 +1489,7 @@ struct __narrow_to_utf8<8>
15371489
15381490_LIBCPP_SUPPRESS_DEPRECATED_PUSH
15391491template <>
1540struct _LIBCPP_TYPE_VIS __narrow_to_utf8<16>
1492struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<16>
15411493 : public codecvt<char16_t, char, mbstate_t>
15421494{
15431495 _LIBCPP_INLINE_VISIBILITY
......@@ -1573,7 +1525,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
15731525
15741526_LIBCPP_SUPPRESS_DEPRECATED_PUSH
15751527template <>
1576struct _LIBCPP_TYPE_VIS __narrow_to_utf8<32>
1528struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<32>
15771529 : public codecvt<char32_t, char, mbstate_t>
15781530{
15791531 _LIBCPP_INLINE_VISIBILITY
......@@ -1631,7 +1583,7 @@ struct __widen_from_utf8<8>
16311583
16321584_LIBCPP_SUPPRESS_DEPRECATED_PUSH
16331585template <>
1634struct _LIBCPP_TYPE_VIS __widen_from_utf8<16>
1586struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<16>
16351587 : public codecvt<char16_t, char, mbstate_t>
16361588{
16371589 _LIBCPP_INLINE_VISIBILITY
......@@ -1667,7 +1619,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
16671619
16681620_LIBCPP_SUPPRESS_DEPRECATED_PUSH
16691621template <>
1670struct _LIBCPP_TYPE_VIS __widen_from_utf8<32>
1622struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<32>
16711623 : public codecvt<char32_t, char, mbstate_t>
16721624{
16731625 _LIBCPP_INLINE_VISIBILITY
......@@ -1706,7 +1658,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
17061658template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct;
17071659
17081660template <>
1709class _LIBCPP_TYPE_VIS numpunct<char>
1661class _LIBCPP_EXPORTED_FROM_ABI numpunct<char>
17101662 : public locale::facet
17111663{
17121664public:
......@@ -1738,7 +1690,7 @@ protected:
17381690
17391691#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
17401692template <>
1741class _LIBCPP_TYPE_VIS numpunct<wchar_t>
1693class _LIBCPP_EXPORTED_FROM_ABI numpunct<wchar_t>
17421694 : public locale::facet
17431695{
17441696public:
......@@ -1774,7 +1726,7 @@ protected:
17741726template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname;
17751727
17761728template <>
1777class _LIBCPP_TYPE_VIS numpunct_byname<char>
1729class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<char>
17781730: public numpunct<char>
17791731{
17801732public:
......@@ -1793,7 +1745,7 @@ private:
17931745
17941746#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
17951747template <>
1796class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t>
1748class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<wchar_t>
17971749: public numpunct<wchar_t>
17981750{
17991751public:
lib/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h created+36
......@@ -0,0 +1,36 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9// The BSDs have lots of *_l functions. We don't want to define those symbols
10// on other platforms though, for fear of conflicts with user code. So here,
11// we will define the mapping from an internal macro to the real BSD symbol.
12//===----------------------------------------------------------------------===//
13
14#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
15#define _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18# pragma GCC system_header
19#endif
20
21#define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc)
22#define __libcpp_btowc_l(ch, loc) btowc_l(ch, loc)
23#define __libcpp_wctob_l(wch, loc) wctob_l(wch, loc)
24#define __libcpp_wcsnrtombs_l(dst, src, nwc, len, ps, loc) wcsnrtombs_l(dst, src, nwc, len, ps, loc)
25#define __libcpp_wcrtomb_l(src, wc, ps, loc) wcrtomb_l(src, wc, ps, loc)
26#define __libcpp_mbsnrtowcs_l(dst, src, nms, len, ps, loc) mbsnrtowcs_l(dst, src, nms, len, ps, loc)
27#define __libcpp_mbrtowc_l(pwc, s, n, ps, l) mbrtowc_l(pwc, s, n, ps, l)
28#define __libcpp_mbtowc_l(pwc, pmb, max, l) mbtowc_l(pwc, pmb, max, l)
29#define __libcpp_mbrlen_l(s, n, ps, l) mbrlen_l(s, n, ps, l)
30#define __libcpp_localeconv_l(l) localeconv_l(l)
31#define __libcpp_mbsrtowcs_l(dest, src, len, ps, l) mbsrtowcs_l(dest, src, len, ps, l)
32#define __libcpp_snprintf_l(...) snprintf_l(__VA_ARGS__)
33#define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__)
34#define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__)
35
36#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
lib/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h created+148
......@@ -0,0 +1,148 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9// The BSDs have lots of *_l functions. This file provides reimplementations
10// of those functions for non-BSD platforms.
11//===----------------------------------------------------------------------===//
12
13#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
14#define _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
15
16#include <__locale_dir/locale_base_api/locale_guard.h>
17#include <cstdio>
18#include <stdarg.h>
19#include <stdlib.h>
20
21#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
22# include <cwchar>
23#endif
24
25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26# pragma GCC system_header
27#endif
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31inline _LIBCPP_INLINE_VISIBILITY
32decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l)
33{
34 __libcpp_locale_guard __current(__l);
35 return MB_CUR_MAX;
36}
37
38#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
39inline _LIBCPP_INLINE_VISIBILITY
40wint_t __libcpp_btowc_l(int __c, locale_t __l)
41{
42 __libcpp_locale_guard __current(__l);
43 return btowc(__c);
44}
45
46inline _LIBCPP_INLINE_VISIBILITY
47int __libcpp_wctob_l(wint_t __c, locale_t __l)
48{
49 __libcpp_locale_guard __current(__l);
50 return wctob(__c);
51}
52
53inline _LIBCPP_INLINE_VISIBILITY
54size_t __libcpp_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
55 size_t __len, mbstate_t *__ps, locale_t __l)
56{
57 __libcpp_locale_guard __current(__l);
58 return wcsnrtombs(__dest, __src, __nwc, __len, __ps);
59}
60
61inline _LIBCPP_INLINE_VISIBILITY
62size_t __libcpp_wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)
63{
64 __libcpp_locale_guard __current(__l);
65 return wcrtomb(__s, __wc, __ps);
66}
67
68inline _LIBCPP_INLINE_VISIBILITY
69size_t __libcpp_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
70 size_t __len, mbstate_t *__ps, locale_t __l)
71{
72 __libcpp_locale_guard __current(__l);
73 return mbsnrtowcs(__dest, __src, __nms, __len, __ps);
74}
75
76inline _LIBCPP_INLINE_VISIBILITY
77size_t __libcpp_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
78 mbstate_t *__ps, locale_t __l)
79{
80 __libcpp_locale_guard __current(__l);
81 return mbrtowc(__pwc, __s, __n, __ps);
82}
83
84inline _LIBCPP_INLINE_VISIBILITY
85int __libcpp_mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)
86{
87 __libcpp_locale_guard __current(__l);
88 return mbtowc(__pwc, __pmb, __max);
89}
90
91inline _LIBCPP_INLINE_VISIBILITY
92size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)
93{
94 __libcpp_locale_guard __current(__l);
95 return mbrlen(__s, __n, __ps);
96}
97#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
98
99inline _LIBCPP_INLINE_VISIBILITY
100lconv *__libcpp_localeconv_l(locale_t __l)
101{
102 __libcpp_locale_guard __current(__l);
103 return localeconv();
104}
105
106#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
107inline _LIBCPP_INLINE_VISIBILITY
108size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
109 mbstate_t *__ps, locale_t __l)
110{
111 __libcpp_locale_guard __current(__l);
112 return mbsrtowcs(__dest, __src, __len, __ps);
113}
114#endif
115
116inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5)
117int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) {
118 va_list __va;
119 va_start(__va, __format);
120 __libcpp_locale_guard __current(__l);
121 int __res = vsnprintf(__s, __n, __format, __va);
122 va_end(__va);
123 return __res;
124}
125
126inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
127int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) {
128 va_list __va;
129 va_start(__va, __format);
130 __libcpp_locale_guard __current(__l);
131 int __res = vasprintf(__s, __format, __va);
132 va_end(__va);
133 return __res;
134}
135
136inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4)
137int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {
138 va_list __va;
139 va_start(__va, __format);
140 __libcpp_locale_guard __current(__l);
141 int __res = vsscanf(__s, __format, __va);
142 va_end(__va);
143 return __res;
144}
145
146_LIBCPP_END_NAMESPACE_STD
147
148#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
lib/libcxx/include/__locale_dir/locale_base_api/locale_guard.h created+80
......@@ -0,0 +1,80 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H
10#define _LIBCPP___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H
11
12#include <__config>
13#include <__locale> // for locale_t
14#include <clocale>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22#if !defined(_LIBCPP_LOCALE__L_EXTENSIONS)
23struct __libcpp_locale_guard {
24 _LIBCPP_INLINE_VISIBILITY __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {}
25
26 _LIBCPP_INLINE_VISIBILITY ~__libcpp_locale_guard() {
27 if (__old_loc_)
28 uselocale(__old_loc_);
29 }
30
31 locale_t __old_loc_;
32
33private:
34 __libcpp_locale_guard(__libcpp_locale_guard const&);
35 __libcpp_locale_guard& operator=(__libcpp_locale_guard const&);
36};
37#elif defined(_LIBCPP_MSVCRT_LIKE)
38struct __libcpp_locale_guard {
39 __libcpp_locale_guard(locale_t __l) :
40 __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
41 // Setting the locale can be expensive even when the locale given is
42 // already the current locale, so do an explicit check to see if the
43 // current locale is already the one we want.
44 const char* __lc = __setlocale(nullptr);
45 // If every category is the same, the locale string will simply be the
46 // locale name, otherwise it will be a semicolon-separated string listing
47 // each category. In the second case, we know at least one category won't
48 // be what we want, so we only have to check the first case.
49 if (_VSTD::strcmp(__l.__get_locale(), __lc) != 0) {
50 __locale_all = _strdup(__lc);
51 if (__locale_all == nullptr)
52 __throw_bad_alloc();
53 __setlocale(__l.__get_locale());
54 }
55 }
56 ~__libcpp_locale_guard() {
57 // The CRT documentation doesn't explicitly say, but setlocale() does the
58 // right thing when given a semicolon-separated list of locale settings
59 // for the different categories in the same format as returned by
60 // setlocale(LC_ALL, nullptr).
61 if (__locale_all != nullptr) {
62 __setlocale(__locale_all);
63 free(__locale_all);
64 }
65 _configthreadlocale(__status);
66 }
67 static const char* __setlocale(const char* __locale) {
68 const char* __new_locale = setlocale(LC_ALL, __locale);
69 if (__new_locale == nullptr)
70 __throw_bad_alloc();
71 return __new_locale;
72 }
73 int __status;
74 char* __locale_all = nullptr;
75};
76#endif
77
78_LIBCPP_END_NAMESPACE_STD
79
80#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H
lib/libcxx/include/__mbstate_t.h+26-16
......@@ -16,29 +16,39 @@
1616# pragma GCC system_header
1717#endif
1818
19// TODO(ldionne):
20// The goal of this header is to provide mbstate_t without having to pull in
21// <wchar.h> or <uchar.h>. This is necessary because we need that type even
22// when we don't have (or try to provide) support for wchar_t, because several
23// types like std::fpos are defined in terms of mbstate_t.
19// The goal of this header is to provide mbstate_t without requiring all of
20// <uchar.h> or <wchar.h>. It's also used by the libc++ versions of <uchar.h>
21// and <wchar.h> to get mbstate_t when the C library doesn't provide <uchar.h>
22// or <wchar.h>, hence the #include_next of those headers instead of #include.
23// (e.g. if <wchar.h> isn't present in the C library, the libc++ <wchar.h>
24// will include this header. This header needs to not turn around and cyclically
25// include <wchar.h>, but fall through to <uchar.h>.)
2426//
25// This is a gruesome hack, but I don't know how to make it cleaner for
26// the time being.
27// This does not define std::mbstate_t -- this only brings in the declaration
28// in the global namespace.
29
30// We define this here to support older versions of glibc <wchar.h> that do
31// not define this for clang. This is also set in libc++'s <wchar.h> header,
32// and we need to do so here too to avoid a different function signature given
33// a different include order.
34#ifdef __cplusplus
35# define __CORRECT_ISO_CPP_WCHAR_H_PROTO
36#endif
2737
28#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
29# include <wchar.h> // for mbstate_t
38#if defined(_LIBCPP_HAS_MUSL_LIBC)
39# define __NEED_mbstate_t
40# include <bits/alltypes.h>
41# undef __NEED_mbstate_t
3042#elif __has_include(<bits/types/mbstate_t.h>)
3143# include <bits/types/mbstate_t.h> // works on most Unixes
3244#elif __has_include(<sys/_types/_mbstate_t.h>)
3345# include <sys/_types/_mbstate_t.h> // works on Darwin
46#elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) && __has_include_next(<wchar.h>)
47# include_next <wchar.h> // fall back to the C standard provider of mbstate_t
48#elif __has_include_next(<uchar.h>)
49# include_next <uchar.h> // <uchar.h> is also required to make mbstate_t visible
3450#else
35# error "The library was configured without support for wide-characters, but we don't know how to get the definition of mbstate_t without <wchar.h> on your platform."
51# error "We don't know how to get the definition of mbstate_t without <wchar.h> on your platform."
3652#endif
3753
38_LIBCPP_BEGIN_NAMESPACE_STD
39
40using ::mbstate_t _LIBCPP_USING_IF_EXISTS;
41
42_LIBCPP_END_NAMESPACE_STD
43
4454#endif // _LIBCPP___MBSTATE_T_H
lib/libcxx/include/__mdspan/default_accessor.h created+66
......@@ -0,0 +1,66 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8// Kokkos v. 4.0
9// Copyright (2022) National Technology & Engineering
10// Solutions of Sandia, LLC (NTESS).
11//
12// Under the terms of Contract DE-NA0003525 with NTESS,
13// the U.S. Government retains certain rights in this software.
14//
15//===---------------------------------------------------------------------===//
16
17#ifndef _LIBCPP___MDSPAN_DEFAULT_ACCESSOR_H
18#define _LIBCPP___MDSPAN_DEFAULT_ACCESSOR_H
19
20#include <__config>
21#include <__type_traits/is_abstract.h>
22#include <__type_traits/is_array.h>
23#include <__type_traits/is_convertible.h>
24#include <__type_traits/remove_const.h>
25#include <cinttypes>
26#include <cstddef>
27
28#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
29# pragma GCC system_header
30#endif
31
32_LIBCPP_PUSH_MACROS
33#include <__undef_macros>
34
35_LIBCPP_BEGIN_NAMESPACE_STD
36
37#if _LIBCPP_STD_VER >= 23
38
39template <class _ElementType>
40struct default_accessor {
41 static_assert(!is_array_v<_ElementType>, "default_accessor: template argument may not be an array type");
42 static_assert(!is_abstract_v<_ElementType>, "default_accessor: template argument may not be an abstract class");
43
44 using offset_policy = default_accessor;
45 using element_type = _ElementType;
46 using reference = _ElementType&;
47 using data_handle_type = _ElementType*;
48
49 _LIBCPP_HIDE_FROM_ABI constexpr default_accessor() noexcept = default;
50 template <class _OtherElementType>
51 requires(is_convertible_v<_OtherElementType (*)[], element_type (*)[]>)
52 _LIBCPP_HIDE_FROM_ABI constexpr default_accessor(default_accessor<_OtherElementType>) noexcept {}
53
54 _LIBCPP_HIDE_FROM_ABI constexpr reference access(data_handle_type __p, size_t __i) const noexcept { return __p[__i]; }
55 _LIBCPP_HIDE_FROM_ABI constexpr data_handle_type offset(data_handle_type __p, size_t __i) const noexcept {
56 return __p + __i;
57 }
58};
59
60#endif // _LIBCPP_STD_VER >= 23
61
62_LIBCPP_END_NAMESPACE_STD
63
64_LIBCPP_POP_MACROS
65
66#endif // _LIBCPP___MDSPAN_DEFAULT_ACCESSOR_H
lib/libcxx/include/__mdspan/extents.h created+519
......@@ -0,0 +1,519 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8// Kokkos v. 4.0
9// Copyright (2022) National Technology & Engineering
10// Solutions of Sandia, LLC (NTESS).
11//
12// Under the terms of Contract DE-NA0003525 with NTESS,
13// the U.S. Government retains certain rights in this software.
14//
15//===---------------------------------------------------------------------===//
16
17#ifndef _LIBCPP___MDSPAN_EXTENTS_H
18#define _LIBCPP___MDSPAN_EXTENTS_H
19
20#include <__assert>
21#include <__config>
22#include <__type_traits/common_type.h>
23#include <__type_traits/is_convertible.h>
24#include <__type_traits/is_nothrow_constructible.h>
25#include <__type_traits/is_same.h>
26#include <__type_traits/make_unsigned.h>
27#include <__utility/integer_sequence.h>
28#include <__utility/unreachable.h>
29#include <array>
30#include <cinttypes>
31#include <concepts>
32#include <cstddef>
33#include <limits>
34#include <span>
35
36#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
37# pragma GCC system_header
38#endif
39
40_LIBCPP_PUSH_MACROS
41#include <__undef_macros>
42
43_LIBCPP_BEGIN_NAMESPACE_STD
44
45#if _LIBCPP_STD_VER >= 23
46
47namespace __mdspan_detail {
48
49// ------------------------------------------------------------------
50// ------------ __static_array --------------------------------------
51// ------------------------------------------------------------------
52// array like class which provides an array of static values with get
53template <class _Tp, _Tp... _Values>
54struct __static_array {
55 static constexpr array<_Tp, sizeof...(_Values)> __array = {_Values...};
56
57public:
58 _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size() { return sizeof...(_Values); }
59 _LIBCPP_HIDE_FROM_ABI static constexpr _Tp __get(size_t __index) noexcept { return __array[__index]; }
60
61 template <size_t _Index>
62 _LIBCPP_HIDE_FROM_ABI static constexpr _Tp __get() {
63 return __get(_Index);
64 }
65};
66
67// ------------------------------------------------------------------
68// ------------ __possibly_empty_array -----------------------------
69// ------------------------------------------------------------------
70
71// array like class which provides get function and operator [], and
72// has a specialization for the size 0 case.
73// This is needed to make the __maybe_static_array be truly empty, for
74// all static values.
75
76template <class _Tp, size_t _Size>
77struct __possibly_empty_array {
78 _Tp __vals_[_Size];
79 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator[](size_t __index) { return __vals_[__index]; }
80 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](size_t __index) const { return __vals_[__index]; }
81};
82
83template <class _Tp>
84struct __possibly_empty_array<_Tp, 0> {
85 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator[](size_t) { __libcpp_unreachable(); }
86 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](size_t) const { __libcpp_unreachable(); }
87};
88
89// ------------------------------------------------------------------
90// ------------ static_partial_sums ---------------------------------
91// ------------------------------------------------------------------
92
93// Provides a compile time partial sum one can index into
94
95template <size_t... _Values>
96struct __static_partial_sums {
97 _LIBCPP_HIDE_FROM_ABI static constexpr array<size_t, sizeof...(_Values)> __static_partial_sums_impl() {
98 array<size_t, sizeof...(_Values)> __values{_Values...};
99 array<size_t, sizeof...(_Values)> __partial_sums{{}};
100 size_t __running_sum = 0;
101 for (int __i = 0; __i != sizeof...(_Values); ++__i) {
102 __partial_sums[__i] = __running_sum;
103 __running_sum += __values[__i];
104 }
105 return __partial_sums;
106 }
107 static constexpr array<size_t, sizeof...(_Values)> __result{__static_partial_sums_impl()};
108
109 _LIBCPP_HIDE_FROM_ABI static constexpr size_t __get(size_t __index) { return __result[__index]; }
110};
111
112// ------------------------------------------------------------------
113// ------------ __maybe_static_array --------------------------------
114// ------------------------------------------------------------------
115
116// array like class which has a mix of static and runtime values but
117// only stores the runtime values.
118// The type of the static and the runtime values can be different.
119// The position of a dynamic value is indicated through a tag value.
120template <class _TDynamic, class _TStatic, _TStatic _DynTag, _TStatic... _Values>
121struct __maybe_static_array {
122 static_assert(is_convertible<_TStatic, _TDynamic>::value,
123 "__maybe_static_array: _TStatic must be convertible to _TDynamic");
124 static_assert(is_convertible<_TDynamic, _TStatic>::value,
125 "__maybe_static_array: _TDynamic must be convertible to _TStatic");
126
127private:
128 // Static values member
129 static constexpr size_t __size_ = sizeof...(_Values);
130 static constexpr size_t __size_dynamic_ = ((_Values == _DynTag) + ... + 0);
131 using _StaticValues = __static_array<_TStatic, _Values...>;
132 using _DynamicValues = __possibly_empty_array<_TDynamic, __size_dynamic_>;
133
134 // Dynamic values member
135 _LIBCPP_NO_UNIQUE_ADDRESS _DynamicValues __dyn_vals_;
136
137 // static mapping of indices to the position in the dynamic values array
138 using _DynamicIdxMap = __static_partial_sums<static_cast<size_t>(_Values == _DynTag)...>;
139
140 template <size_t... Indices>
141 _LIBCPP_HIDE_FROM_ABI static constexpr _DynamicValues __zeros(index_sequence<Indices...>) noexcept {
142 return _DynamicValues{((void)Indices, 0)...};
143 }
144
145public:
146 _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array() noexcept
147 : __dyn_vals_{__zeros(make_index_sequence<__size_dynamic_>())} {}
148
149 // constructors from dynamic values only -- this covers the case for rank() == 0
150 template <class... _DynVals>
151 requires(sizeof...(_DynVals) == __size_dynamic_)
152 _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(_DynVals... __vals)
153 : __dyn_vals_{static_cast<_TDynamic>(__vals)...} {}
154
155 template <class _Tp, size_t _Size >
156 requires(_Size == __size_dynamic_)
157 _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array([[maybe_unused]] const span<_Tp, _Size>& __vals) {
158 if constexpr (_Size > 0) {
159 for (size_t __i = 0; __i < _Size; __i++)
160 __dyn_vals_[__i] = static_cast<_TDynamic>(__vals[__i]);
161 }
162 }
163
164 // constructors from all values -- here rank will be greater than 0
165 template <class... _DynVals>
166 requires(sizeof...(_DynVals) != __size_dynamic_)
167 _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(_DynVals... __vals) {
168 static_assert((sizeof...(_DynVals) == __size_), "Invalid number of values.");
169 _TDynamic __values[__size_] = {static_cast<_TDynamic>(__vals)...};
170 for (size_t __i = 0; __i < __size_; __i++) {
171 _TStatic __static_val = _StaticValues::__get(__i);
172 if (__static_val == _DynTag) {
173 __dyn_vals_[_DynamicIdxMap::__get(__i)] = __values[__i];
174 } else
175 // Not catching this could lead to out of bounds errors later
176 // e.g. using my_mdspan_t = mdspan<int, extents<int, 10>>; my_mdspan_t = m(new int[5], 5);
177 // Right-hand-side construction looks ok with allocation and size matching,
178 // but since (potentially elsewhere defined) my_mdspan_t has static size m now thinks its range is 10 not 5
179 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
180 __values[__i] == static_cast<_TDynamic>(__static_val),
181 "extents construction: mismatch of provided arguments with static extents.");
182 }
183 }
184
185 template <class _Tp, size_t _Size>
186 requires(_Size != __size_dynamic_)
187 _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(const span<_Tp, _Size>& __vals) {
188 static_assert((_Size == __size_) || (__size_ == dynamic_extent));
189 for (size_t __i = 0; __i < __size_; __i++) {
190 _TStatic __static_val = _StaticValues::__get(__i);
191 if (__static_val == _DynTag) {
192 __dyn_vals_[_DynamicIdxMap::__get(__i)] = static_cast<_TDynamic>(__vals[__i]);
193 } else
194 // Not catching this could lead to out of bounds errors later
195 // e.g. using my_mdspan_t = mdspan<int, extents<int, 10>>; my_mdspan_t = m(new int[N], span<int,1>(&N));
196 // Right-hand-side construction looks ok with allocation and size matching,
197 // but since (potentially elsewhere defined) my_mdspan_t has static size m now thinks its range is 10 not N
198 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
199 static_cast<_TDynamic>(__vals[__i]) == static_cast<_TDynamic>(__static_val),
200 "extents construction: mismatch of provided arguments with static extents.");
201 }
202 }
203
204 // access functions
205 _LIBCPP_HIDE_FROM_ABI static constexpr _TStatic __static_value(size_t __i) noexcept {
206 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank");
207 return _StaticValues::__get(__i);
208 }
209
210 _LIBCPP_HIDE_FROM_ABI constexpr _TDynamic __value(size_t __i) const {
211 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank");
212 _TStatic __static_val = _StaticValues::__get(__i);
213 return __static_val == _DynTag ? __dyn_vals_[_DynamicIdxMap::__get(__i)] : static_cast<_TDynamic>(__static_val);
214 }
215 _LIBCPP_HIDE_FROM_ABI constexpr _TDynamic operator[](size_t __i) const {
216 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank");
217 return __value(__i);
218 }
219
220 // observers
221 _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size() { return __size_; }
222 _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size_dynamic() { return __size_dynamic_; }
223};
224
225// Function to check whether a value is representable as another type
226// value must be a positive integer otherwise returns false
227// if _From is not an integral, we just check positivity
228template <integral _To, class _From>
229 requires(integral<_From>)
230_LIBCPP_HIDE_FROM_ABI constexpr bool __is_representable_as(_From __value) {
231 using _To_u = make_unsigned_t<_To>;
232 using _From_u = make_unsigned_t<_From>;
233 if constexpr (is_signed_v<_From>) {
234 if (__value < 0)
235 return false;
236 }
237 if constexpr (static_cast<_To_u>(numeric_limits<_To>::max()) >= static_cast<_From_u>(numeric_limits<_From>::max())) {
238 return true;
239 } else {
240 return static_cast<_To_u>(numeric_limits<_To>::max()) >= static_cast<_From_u>(__value);
241 }
242}
243
244template <integral _To, class _From>
245 requires(!integral<_From>)
246_LIBCPP_HIDE_FROM_ABI constexpr bool __is_representable_as(_From __value) {
247 if constexpr (is_signed_v<_To>) {
248 if (static_cast<_To>(__value) < 0)
249 return false;
250 }
251 return true;
252}
253
254template <integral _To, class... _From>
255_LIBCPP_HIDE_FROM_ABI constexpr bool __are_representable_as(_From... __values) {
256 return (__mdspan_detail::__is_representable_as<_To>(__values) && ... && true);
257}
258
259template <integral _To, class _From, size_t _Size>
260_LIBCPP_HIDE_FROM_ABI constexpr bool __are_representable_as(span<_From, _Size> __values) {
261 for (size_t __i = 0; __i < _Size; __i++)
262 if (!__mdspan_detail::__is_representable_as<_To>(__values[__i]))
263 return false;
264 return true;
265}
266
267} // namespace __mdspan_detail
268
269// ------------------------------------------------------------------
270// ------------ extents ---------------------------------------------
271// ------------------------------------------------------------------
272
273// Class to describe the extents of a multi dimensional array.
274// Used by mdspan, mdarray and layout mappings.
275// See ISO C++ standard [mdspan.extents]
276
277template <class _IndexType, size_t... _Extents>
278class extents {
279public:
280 // typedefs for integral types used
281 using index_type = _IndexType;
282 using size_type = make_unsigned_t<index_type>;
283 using rank_type = size_t;
284
285 static_assert(is_integral<index_type>::value && !is_same<index_type, bool>::value,
286 "extents::index_type must be a signed or unsigned integer type");
287 static_assert(((__mdspan_detail::__is_representable_as<index_type>(_Extents) || (_Extents == dynamic_extent)) && ...),
288 "extents ctor: arguments must be representable as index_type and nonnegative");
289
290private:
291 static constexpr rank_type __rank_ = sizeof...(_Extents);
292 static constexpr rank_type __rank_dynamic_ = ((_Extents == dynamic_extent) + ... + 0);
293
294 // internal storage type using __maybe_static_array
295 using _Values = __mdspan_detail::__maybe_static_array<_IndexType, size_t, dynamic_extent, _Extents...>;
296 [[no_unique_address]] _Values __vals_;
297
298public:
299 // [mdspan.extents.obs], observers of multidimensional index space
300 _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return __rank_; }
301 _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return __rank_dynamic_; }
302
303 _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept { return __vals_.__value(__r); }
304 _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept {
305 return _Values::__static_value(__r);
306 }
307
308 // [mdspan.extents.cons], constructors
309 _LIBCPP_HIDE_FROM_ABI constexpr extents() noexcept = default;
310
311 // Construction from just dynamic or all values.
312 // Precondition check is deferred to __maybe_static_array constructor
313 template <class... _OtherIndexTypes>
314 requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) &&
315 (is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) &&
316 (sizeof...(_OtherIndexTypes) == __rank_ || sizeof...(_OtherIndexTypes) == __rank_dynamic_))
317 _LIBCPP_HIDE_FROM_ABI constexpr explicit extents(_OtherIndexTypes... __dynvals) noexcept
318 : __vals_(static_cast<index_type>(__dynvals)...) {
319 // Not catching this could lead to out of bounds errors later
320 // e.g. mdspan m(ptr, dextents<char, 1>(200u)); leads to an extent of -56 on m
321 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(__dynvals...),
322 "extents ctor: arguments must be representable as index_type and nonnegative");
323 }
324
325 template <class _OtherIndexType, size_t _Size>
326 requires(is_convertible_v<const _OtherIndexType&, index_type> &&
327 is_nothrow_constructible_v<index_type, const _OtherIndexType&> &&
328 (_Size == __rank_ || _Size == __rank_dynamic_))
329 explicit(_Size != __rank_dynamic_)
330 _LIBCPP_HIDE_FROM_ABI constexpr extents(const array<_OtherIndexType, _Size>& __exts) noexcept
331 : __vals_(span(__exts)) {
332 // Not catching this could lead to out of bounds errors later
333 // e.g. mdspan m(ptr, dextents<char, 1>(array<unsigned,1>(200))); leads to an extent of -56 on m
334 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(span(__exts)),
335 "extents ctor: arguments must be representable as index_type and nonnegative");
336 }
337
338 template <class _OtherIndexType, size_t _Size>
339 requires(is_convertible_v<const _OtherIndexType&, index_type> &&
340 is_nothrow_constructible_v<index_type, const _OtherIndexType&> &&
341 (_Size == __rank_ || _Size == __rank_dynamic_))
342 explicit(_Size != __rank_dynamic_)
343 _LIBCPP_HIDE_FROM_ABI constexpr extents(const span<_OtherIndexType, _Size>& __exts) noexcept
344 : __vals_(__exts) {
345 // Not catching this could lead to out of bounds errors later
346 // e.g. array a{200u}; mdspan<int, dextents<char,1>> m(ptr, extents(span<unsigned,1>(a))); leads to an extent of -56
347 // on m
348 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(__exts),
349 "extents ctor: arguments must be representable as index_type and nonnegative");
350 }
351
352private:
353 // Function to construct extents storage from other extents.
354 template <size_t _DynCount, size_t _Idx, class _OtherExtents, class... _DynamicValues>
355 requires(_Idx < __rank_)
356 _LIBCPP_HIDE_FROM_ABI constexpr _Values __construct_vals_from_extents(
357 integral_constant<size_t, _DynCount>,
358 integral_constant<size_t, _Idx>,
359 const _OtherExtents& __exts,
360 _DynamicValues... __dynamic_values) noexcept {
361 if constexpr (static_extent(_Idx) == dynamic_extent)
362 return __construct_vals_from_extents(
363 integral_constant<size_t, _DynCount + 1>(),
364 integral_constant<size_t, _Idx + 1>(),
365 __exts,
366 __dynamic_values...,
367 __exts.extent(_Idx));
368 else
369 return __construct_vals_from_extents(
370 integral_constant<size_t, _DynCount>(), integral_constant<size_t, _Idx + 1>(), __exts, __dynamic_values...);
371 }
372
373 template <size_t _DynCount, size_t _Idx, class _OtherExtents, class... _DynamicValues>
374 requires((_Idx == __rank_) && (_DynCount == __rank_dynamic_))
375 _LIBCPP_HIDE_FROM_ABI constexpr _Values __construct_vals_from_extents(
376 integral_constant<size_t, _DynCount>,
377 integral_constant<size_t, _Idx>,
378 const _OtherExtents&,
379 _DynamicValues... __dynamic_values) noexcept {
380 return _Values{static_cast<index_type>(__dynamic_values)...};
381 }
382
383public:
384 // Converting constructor from other extents specializations
385 template <class _OtherIndexType, size_t... _OtherExtents>
386 requires((sizeof...(_OtherExtents) == sizeof...(_Extents)) &&
387 ((_OtherExtents == dynamic_extent || _Extents == dynamic_extent || _OtherExtents == _Extents) && ...))
388 explicit((((_Extents != dynamic_extent) && (_OtherExtents == dynamic_extent)) || ...) ||
389 (static_cast<make_unsigned_t<index_type>>(numeric_limits<index_type>::max()) <
390 static_cast<make_unsigned_t<_OtherIndexType>>(numeric_limits<_OtherIndexType>::max())))
391 _LIBCPP_HIDE_FROM_ABI constexpr extents(const extents<_OtherIndexType, _OtherExtents...>& __other) noexcept
392 : __vals_(
393 __construct_vals_from_extents(integral_constant<size_t, 0>(), integral_constant<size_t, 0>(), __other)) {
394 if constexpr (rank() > 0) {
395 for (size_t __r = 0; __r < rank(); __r++) {
396 if constexpr (static_cast<make_unsigned_t<index_type>>(numeric_limits<index_type>::max()) <
397 static_cast<make_unsigned_t<_OtherIndexType>>(numeric_limits<_OtherIndexType>::max())) {
398 // Not catching this could lead to out of bounds errors later
399 // e.g. dextents<char,1>> e(dextents<unsigned,1>(200)) leads to an extent of -56 on e
400 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
401 __mdspan_detail::__is_representable_as<index_type>(__other.extent(__r)),
402 "extents ctor: arguments must be representable as index_type and nonnegative");
403 }
404 // Not catching this could lead to out of bounds errors later
405 // e.g. mdspan<int, extents<int, 10>> m = mdspan<int, dextents<int, 1>>(new int[5], 5);
406 // Right-hand-side construction was ok, but m now thinks its range is 10 not 5
407 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
408 (_Values::__static_value(__r) == dynamic_extent) ||
409 (static_cast<index_type>(__other.extent(__r)) == static_cast<index_type>(_Values::__static_value(__r))),
410 "extents construction: mismatch of provided arguments with static extents.");
411 }
412 }
413 }
414
415 // Comparison operator
416 template <class _OtherIndexType, size_t... _OtherExtents>
417 _LIBCPP_HIDE_FROM_ABI friend constexpr bool
418 operator==(const extents& __lhs, const extents<_OtherIndexType, _OtherExtents...>& __rhs) noexcept {
419 if constexpr (rank() != sizeof...(_OtherExtents)) {
420 return false;
421 } else {
422 for (rank_type __r = 0; __r < __rank_; __r++) {
423 // avoid warning when comparing signed and unsigner integers and pick the wider of two types
424 using _CommonType = common_type_t<index_type, _OtherIndexType>;
425 if (static_cast<_CommonType>(__lhs.extent(__r)) != static_cast<_CommonType>(__rhs.extent(__r))) {
426 return false;
427 }
428 }
429 }
430 return true;
431 }
432};
433
434// Recursive helper classes to implement dextents alias for extents
435namespace __mdspan_detail {
436
437template <class _IndexType, size_t _Rank, class _Extents = extents<_IndexType>>
438struct __make_dextents;
439
440template <class _IndexType, size_t _Rank, size_t... _ExtentsPack>
441struct __make_dextents< _IndexType, _Rank, extents<_IndexType, _ExtentsPack...>> {
442 using type =
443 typename __make_dextents< _IndexType, _Rank - 1, extents<_IndexType, dynamic_extent, _ExtentsPack...>>::type;
444};
445
446template <class _IndexType, size_t... _ExtentsPack>
447struct __make_dextents< _IndexType, 0, extents<_IndexType, _ExtentsPack...>> {
448 using type = extents<_IndexType, _ExtentsPack...>;
449};
450
451} // end namespace __mdspan_detail
452
453// [mdspan.extents.dextents], alias template
454template <class _IndexType, size_t _Rank>
455using dextents = typename __mdspan_detail::__make_dextents<_IndexType, _Rank>::type;
456
457// Deduction guide for extents
458template <class... _IndexTypes>
459extents(_IndexTypes...) -> extents<size_t, size_t((_IndexTypes(), dynamic_extent))...>;
460
461namespace __mdspan_detail {
462
463// Helper type traits for identifying a class as extents.
464template <class _Tp>
465struct __is_extents : false_type {};
466
467template <class _IndexType, size_t... _ExtentsPack>
468struct __is_extents<extents<_IndexType, _ExtentsPack...>> : true_type {};
469
470template <class _Tp>
471inline constexpr bool __is_extents_v = __is_extents<_Tp>::value;
472
473// Function to check whether a set of indices are a multidimensional
474// index into extents. This is a word of power in the C++ standard
475// requiring that the indices are larger than 0 and smaller than
476// the respective extents.
477
478template <integral _IndexType, class _From>
479 requires(integral<_From>)
480_LIBCPP_HIDE_FROM_ABI constexpr bool __is_index_in_extent(_IndexType __extent, _From __value) {
481 if constexpr (is_signed_v<_From>) {
482 if (__value < 0)
483 return false;
484 }
485 using _Tp = common_type_t<_IndexType, _From>;
486 return static_cast<_Tp>(__value) < static_cast<_Tp>(__extent);
487}
488
489template <integral _IndexType, class _From>
490 requires(!integral<_From>)
491_LIBCPP_HIDE_FROM_ABI constexpr bool __is_index_in_extent(_IndexType __extent, _From __value) {
492 if constexpr (is_signed_v<_IndexType>) {
493 if (static_cast<_IndexType>(__value) < 0)
494 return false;
495 }
496 return static_cast<_IndexType>(__value) < __extent;
497}
498
499template <size_t... _Idxs, class _Extents, class... _From>
500_LIBCPP_HIDE_FROM_ABI constexpr bool
501__is_multidimensional_index_in_impl(index_sequence<_Idxs...>, const _Extents& __ext, _From... __values) {
502 return (__mdspan_detail::__is_index_in_extent(__ext.extent(_Idxs), __values) && ...);
503}
504
505template <class _Extents, class... _From>
506_LIBCPP_HIDE_FROM_ABI constexpr bool __is_multidimensional_index_in(const _Extents& __ext, _From... __values) {
507 return __mdspan_detail::__is_multidimensional_index_in_impl(
508 make_index_sequence<_Extents::rank()>(), __ext, __values...);
509}
510
511} // namespace __mdspan_detail
512
513#endif // _LIBCPP_STD_VER >= 23
514
515_LIBCPP_END_NAMESPACE_STD
516
517_LIBCPP_POP_MACROS
518
519#endif // _LIBCPP___MDSPAN_EXTENTS_H
lib/libcxx/include/__mdspan/layout_left.h created+189
......@@ -0,0 +1,189 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8// Kokkos v. 4.0
9// Copyright (2022) National Technology & Engineering
10// Solutions of Sandia, LLC (NTESS).
11//
12// Under the terms of Contract DE-NA0003525 with NTESS,
13// the U.S. Government retains certain rights in this software.
14//
15//===---------------------------------------------------------------------===//
16
17#ifndef _LIBCPP___MDSPAN_LAYOUT_LEFT_H
18#define _LIBCPP___MDSPAN_LAYOUT_LEFT_H
19
20#include <__assert>
21#include <__config>
22#include <__fwd/mdspan.h>
23#include <__mdspan/extents.h>
24#include <__type_traits/is_constructible.h>
25#include <__type_traits/is_convertible.h>
26#include <__type_traits/is_nothrow_constructible.h>
27#include <__utility/integer_sequence.h>
28#include <array>
29#include <cinttypes>
30#include <cstddef>
31#include <limits>
32
33#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
34# pragma GCC system_header
35#endif
36
37_LIBCPP_PUSH_MACROS
38#include <__undef_macros>
39
40_LIBCPP_BEGIN_NAMESPACE_STD
41
42#if _LIBCPP_STD_VER >= 23
43
44template <class _Extents>
45class layout_left::mapping {
46public:
47 static_assert(__mdspan_detail::__is_extents<_Extents>::value,
48 "layout_left::mapping template argument must be a specialization of extents.");
49
50 using extents_type = _Extents;
51 using index_type = typename extents_type::index_type;
52 using size_type = typename extents_type::size_type;
53 using rank_type = typename extents_type::rank_type;
54 using layout_type = layout_left;
55
56private:
57 _LIBCPP_HIDE_FROM_ABI static constexpr bool __required_span_size_is_representable(const extents_type& __ext) {
58 if constexpr (extents_type::rank() == 0)
59 return true;
60
61 index_type __prod = __ext.extent(0);
62 for (rank_type __r = 1; __r < extents_type::rank(); __r++) {
63 bool __overflowed = __builtin_mul_overflow(__prod, __ext.extent(__r), &__prod);
64 if (__overflowed)
65 return false;
66 }
67 return true;
68 }
69
70 static_assert((extents_type::rank_dynamic() > 0) || __required_span_size_is_representable(extents_type()),
71 "layout_left::mapping product of static extents must be representable as index_type.");
72
73public:
74 // [mdspan.layout.left.cons], constructors
75 _LIBCPP_HIDE_FROM_ABI constexpr mapping() noexcept = default;
76 _LIBCPP_HIDE_FROM_ABI constexpr mapping(const mapping&) noexcept = default;
77 _LIBCPP_HIDE_FROM_ABI constexpr mapping(const extents_type& __ext) noexcept : __extents_(__ext) {
78 // not catching this could lead to out-of-bounds access later when used inside mdspan
79 // mapping<dextents<char, 2>> map(dextents<char, 2>(40,40)); map(10, 3) == -126
80 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
81 __required_span_size_is_representable(__ext),
82 "layout_left::mapping extents ctor: product of extents must be representable as index_type.");
83 }
84
85 template <class _OtherExtents>
86 requires(is_constructible_v<extents_type, _OtherExtents>)
87 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>)
88 mapping(const mapping<_OtherExtents>& __other) noexcept
89 : __extents_(__other.extents()) {
90 // not catching this could lead to out-of-bounds access later when used inside mdspan
91 // mapping<dextents<char, 2>> map(mapping<dextents<int, 2>>(dextents<int, 2>(40,40))); map(10, 3) == -126
92 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
93 __mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()),
94 "layout_left::mapping converting ctor: other.required_span_size() must be representable as index_type.");
95 }
96
97 template <class _OtherExtents>
98 requires(is_constructible_v<extents_type, _OtherExtents> && _OtherExtents::rank() <= 1)
99 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>)
100 mapping(const layout_right::mapping<_OtherExtents>& __other) noexcept
101 : __extents_(__other.extents()) {
102 // not catching this could lead to out-of-bounds access later when used inside mdspan
103 // Note: since this is constraint to rank 1, extents itself would catch the invalid conversion first
104 // and thus this assertion should never be triggered, but keeping it here for consistency
105 // layout_left::mapping<dextents<char, 1>> map(
106 // layout_right::mapping<dextents<unsigned, 1>>(dextents<unsigned, 1>(200))); map.extents().extent(0) ==
107 // -56
108 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
109 __mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()),
110 "layout_left::mapping converting ctor: other.required_span_size() must be representable as index_type.");
111 }
112
113// FIXME: add when we add other layouts
114# if 0
115 template<class _OtherExtents>
116 constexpr explicit(extents_type::rank() > 0)
117 mapping(const layout_stride::mapping_<OtherExtents>&) noexcept;
118# endif
119
120 _LIBCPP_HIDE_FROM_ABI constexpr mapping& operator=(const mapping&) noexcept = default;
121
122 // [mdspan.layout.left.obs], observers
123 _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { return __extents_; }
124
125 _LIBCPP_HIDE_FROM_ABI constexpr index_type required_span_size() const noexcept {
126 index_type __size = 1;
127 for (size_t __r = 0; __r < extents_type::rank(); __r++)
128 __size *= __extents_.extent(__r);
129 return __size;
130 }
131
132 template <class... _Indices>
133 requires((sizeof...(_Indices) == extents_type::rank()) && (is_convertible_v<_Indices, index_type> && ...) &&
134 (is_nothrow_constructible_v<index_type, _Indices> && ...))
135 _LIBCPP_HIDE_FROM_ABI constexpr index_type operator()(_Indices... __idx) const noexcept {
136 // Mappings are generally meant to be used for accessing allocations and are meant to guarantee to never
137 // return a value exceeding required_span_size(), which is used to know how large an allocation one needs
138 // Thus, this is a canonical point in multi-dimensional data structures to make invalid element access checks
139 // However, mdspan does check this on its own, so for now we avoid double checking in hardened mode
140 _LIBCPP_ASSERT(__mdspan_detail::__is_multidimensional_index_in(__extents_, __idx...),
141 "layout_left::mapping: out of bounds indexing");
142 array<index_type, extents_type::rank()> __idx_a{static_cast<index_type>(__idx)...};
143 return [&]<size_t... _Pos>(index_sequence<_Pos...>) {
144 index_type __res = 0;
145 ((__res = __idx_a[extents_type::rank() - 1 - _Pos] + __extents_.extent(extents_type::rank() - 1 - _Pos) * __res),
146 ...);
147 return __res;
148 }(make_index_sequence<sizeof...(_Indices)>());
149 }
150
151 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept { return true; }
152 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept { return true; }
153 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept { return true; }
154
155 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_unique() noexcept { return true; }
156 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_exhaustive() noexcept { return true; }
157 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_strided() noexcept { return true; }
158
159 _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const noexcept
160 requires(extents_type::rank() > 0)
161 {
162 // While it would be caught by extents itself too, using a too large __r
163 // is functionally an out of bounds access on the stored information needed to compute strides
164 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
165 __r < extents_type::rank(), "layout_left::mapping::stride(): invalid rank index");
166 index_type __s = 1;
167 for (rank_type __i = 0; __i < __r; __i++)
168 __s *= __extents_.extent(__i);
169 return __s;
170 }
171
172 template <class _OtherExtents>
173 requires(_OtherExtents::rank() == extents_type::rank())
174 _LIBCPP_HIDE_FROM_ABI friend constexpr bool
175 operator==(const mapping& __lhs, const mapping<_OtherExtents>& __rhs) noexcept {
176 return __lhs.extents() == __rhs.extents();
177 }
178
179private:
180 _LIBCPP_NO_UNIQUE_ADDRESS extents_type __extents_{};
181};
182
183#endif // _LIBCPP_STD_VER >= 23
184
185_LIBCPP_END_NAMESPACE_STD
186
187_LIBCPP_POP_MACROS
188
189#endif // _LIBCPP___MDSPAN_LAYOUT_LEFT_H
lib/libcxx/include/__mdspan/layout_right.h created+186
......@@ -0,0 +1,186 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8// Kokkos v. 4.0
9// Copyright (2022) National Technology & Engineering
10// Solutions of Sandia, LLC (NTESS).
11//
12// Under the terms of Contract DE-NA0003525 with NTESS,
13// the U.S. Government retains certain rights in this software.
14//
15//===---------------------------------------------------------------------===//
16
17#ifndef _LIBCPP___MDSPAN_LAYOUT_RIGHT_H
18#define _LIBCPP___MDSPAN_LAYOUT_RIGHT_H
19
20#include <__assert>
21#include <__config>
22#include <__fwd/mdspan.h>
23#include <__mdspan/extents.h>
24#include <__type_traits/is_constructible.h>
25#include <__type_traits/is_convertible.h>
26#include <__type_traits/is_nothrow_constructible.h>
27#include <__utility/integer_sequence.h>
28#include <cinttypes>
29#include <cstddef>
30#include <limits>
31
32#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
33# pragma GCC system_header
34#endif
35
36_LIBCPP_PUSH_MACROS
37#include <__undef_macros>
38
39_LIBCPP_BEGIN_NAMESPACE_STD
40
41#if _LIBCPP_STD_VER >= 23
42
43template <class _Extents>
44class layout_right::mapping {
45public:
46 static_assert(__mdspan_detail::__is_extents<_Extents>::value,
47 "layout_right::mapping template argument must be a specialization of extents.");
48
49 using extents_type = _Extents;
50 using index_type = typename extents_type::index_type;
51 using size_type = typename extents_type::size_type;
52 using rank_type = typename extents_type::rank_type;
53 using layout_type = layout_right;
54
55private:
56 _LIBCPP_HIDE_FROM_ABI static constexpr bool __required_span_size_is_representable(const extents_type& __ext) {
57 if constexpr (extents_type::rank() == 0)
58 return true;
59
60 index_type __prod = __ext.extent(0);
61 for (rank_type __r = 1; __r < extents_type::rank(); __r++) {
62 bool __overflowed = __builtin_mul_overflow(__prod, __ext.extent(__r), &__prod);
63 if (__overflowed)
64 return false;
65 }
66 return true;
67 }
68
69 static_assert((extents_type::rank_dynamic() > 0) || __required_span_size_is_representable(extents_type()),
70 "layout_right::mapping product of static extents must be representable as index_type.");
71
72public:
73 // [mdspan.layout.right.cons], constructors
74 _LIBCPP_HIDE_FROM_ABI constexpr mapping() noexcept = default;
75 _LIBCPP_HIDE_FROM_ABI constexpr mapping(const mapping&) noexcept = default;
76 _LIBCPP_HIDE_FROM_ABI constexpr mapping(const extents_type& __ext) noexcept : __extents_(__ext) {
77 // not catching this could lead to out-of-bounds access later when used inside mdspan
78 // mapping<dextents<char, 2>> map(dextents<char, 2>(40,40)); map(3, 10) == -126
79 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
80 __required_span_size_is_representable(__ext),
81 "layout_right::mapping extents ctor: product of extents must be representable as index_type.");
82 }
83
84 template <class _OtherExtents>
85 requires(is_constructible_v<extents_type, _OtherExtents>)
86 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>)
87 mapping(const mapping<_OtherExtents>& __other) noexcept
88 : __extents_(__other.extents()) {
89 // not catching this could lead to out-of-bounds access later when used inside mdspan
90 // mapping<dextents<char, 2>> map(mapping<dextents<int, 2>>(dextents<int, 2>(40,40))); map(3, 10) == -126
91 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
92 __mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()),
93 "layout_right::mapping converting ctor: other.required_span_size() must be representable as index_type.");
94 }
95
96 template <class _OtherExtents>
97 requires(is_constructible_v<extents_type, _OtherExtents> && _OtherExtents::rank() <= 1)
98 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>)
99 mapping(const layout_left::mapping<_OtherExtents>& __other) noexcept
100 : __extents_(__other.extents()) {
101 // not catching this could lead to out-of-bounds access later when used inside mdspan
102 // Note: since this is constraint to rank 1, extents itself would catch the invalid conversion first
103 // and thus this assertion should never be triggered, but keeping it here for consistency
104 // layout_right::mapping<dextents<char, 1>> map(
105 // layout_left::mapping<dextents<unsigned, 1>>(dextents<unsigned, 1>(200))); map.extents().extent(0) ==
106 // -56
107 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
108 __mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()),
109 "layout_right::mapping converting ctor: other.required_span_size() must be representable as index_type.");
110 }
111
112// FIXME: add when we add other layouts
113# if 0
114 template<class _OtherExtents>
115 constexpr explicit(extents_type::rank() > 0)
116 mapping(const layout_stride::mapping_<OtherExtents>&) noexcept;
117# endif
118
119 _LIBCPP_HIDE_FROM_ABI constexpr mapping& operator=(const mapping&) noexcept = default;
120
121 // [mdspan.layout.right.obs], observers
122 _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { return __extents_; }
123
124 _LIBCPP_HIDE_FROM_ABI constexpr index_type required_span_size() const noexcept {
125 index_type __size = 1;
126 for (size_t __r = 0; __r < extents_type::rank(); __r++)
127 __size *= __extents_.extent(__r);
128 return __size;
129 }
130
131 template <class... _Indices>
132 requires((sizeof...(_Indices) == extents_type::rank()) && (is_convertible_v<_Indices, index_type> && ...) &&
133 (is_nothrow_constructible_v<index_type, _Indices> && ...))
134 _LIBCPP_HIDE_FROM_ABI constexpr index_type operator()(_Indices... __idx) const noexcept {
135 // Mappings are generally meant to be used for accessing allocations and are meant to guarantee to never
136 // return a value exceeding required_span_size(), which is used to know how large an allocation one needs
137 // Thus, this is a canonical point in multi-dimensional data structures to make invalid element access checks
138 // However, mdspan does check this on its own, so for now we avoid double checking in hardened mode
139 _LIBCPP_ASSERT(__mdspan_detail::__is_multidimensional_index_in(__extents_, __idx...),
140 "layout_right::mapping: out of bounds indexing");
141 return [&]<size_t... _Pos>(index_sequence<_Pos...>) {
142 index_type __res = 0;
143 ((__res = static_cast<index_type>(__idx) + __extents_.extent(_Pos) * __res), ...);
144 return __res;
145 }(make_index_sequence<sizeof...(_Indices)>());
146 }
147
148 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept { return true; }
149 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept { return true; }
150 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept { return true; }
151
152 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_unique() noexcept { return true; }
153 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_exhaustive() noexcept { return true; }
154 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_strided() noexcept { return true; }
155
156 _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const noexcept
157 requires(extents_type::rank() > 0)
158 {
159 // While it would be caught by extents itself too, using a too large __r
160 // is functionally an out of bounds access on the stored information needed to compute strides
161 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
162 __r < extents_type::rank(), "layout_right::mapping::stride(): invalid rank index");
163 index_type __s = 1;
164 for (rank_type __i = extents_type::rank() - 1; __i > __r; __i--)
165 __s *= __extents_.extent(__i);
166 return __s;
167 }
168
169 template <class _OtherExtents>
170 requires(_OtherExtents::rank() == extents_type::rank())
171 _LIBCPP_HIDE_FROM_ABI friend constexpr bool
172 operator==(const mapping& __lhs, const mapping<_OtherExtents>& __rhs) noexcept {
173 return __lhs.extents() == __rhs.extents();
174 }
175
176private:
177 _LIBCPP_NO_UNIQUE_ADDRESS extents_type __extents_{};
178};
179
180#endif // _LIBCPP_STD_VER >= 23
181
182_LIBCPP_END_NAMESPACE_STD
183
184_LIBCPP_POP_MACROS
185
186#endif // _LIBCPP___MDSPAN_LAYOUT_RIGHT_H
lib/libcxx/include/__mdspan/mdspan.h created+308
......@@ -0,0 +1,308 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8// Kokkos v. 4.0
9// Copyright (2022) National Technology & Engineering
10// Solutions of Sandia, LLC (NTESS).
11//
12// Under the terms of Contract DE-NA0003525 with NTESS,
13// the U.S. Government retains certain rights in this software.
14//
15//===---------------------------------------------------------------------===//
16
17#ifndef _LIBCPP___MDSPAN_MDSPAN_H
18#define _LIBCPP___MDSPAN_MDSPAN_H
19
20#include <__assert>
21#include <__config>
22#include <__fwd/mdspan.h>
23#include <__mdspan/default_accessor.h>
24#include <__mdspan/extents.h>
25#include <__type_traits/extent.h>
26#include <__type_traits/is_abstract.h>
27#include <__type_traits/is_array.h>
28#include <__type_traits/is_constructible.h>
29#include <__type_traits/is_convertible.h>
30#include <__type_traits/is_default_constructible.h>
31#include <__type_traits/is_nothrow_constructible.h>
32#include <__type_traits/is_pointer.h>
33#include <__type_traits/is_same.h>
34#include <__type_traits/rank.h>
35#include <__type_traits/remove_all_extents.h>
36#include <__type_traits/remove_cv.h>
37#include <__type_traits/remove_pointer.h>
38#include <__type_traits/remove_reference.h>
39#include <__utility/integer_sequence.h>
40#include <array>
41#include <cinttypes>
42#include <cstddef>
43#include <limits>
44#include <span>
45
46#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
47# pragma GCC system_header
48#endif
49
50_LIBCPP_PUSH_MACROS
51#include <__undef_macros>
52
53_LIBCPP_BEGIN_NAMESPACE_STD
54
55#if _LIBCPP_STD_VER >= 23
56
57// Helper for lightweight test checking that one did pass a layout policy as LayoutPolicy template argument
58namespace __mdspan_detail {
59template <class _Layout, class _Extents>
60concept __has_invalid_mapping = !requires { typename _Layout::template mapping<_Extents>; };
61} // namespace __mdspan_detail
62
63template <class _ElementType,
64 class _Extents,
65 class _LayoutPolicy = layout_right,
66 class _AccessorPolicy = default_accessor<_ElementType> >
67class mdspan {
68private:
69 static_assert(__mdspan_detail::__is_extents_v<_Extents>,
70 "mdspan: Extents template parameter must be a specialization of extents.");
71 static_assert(!is_array_v<_ElementType>, "mdspan: ElementType template parameter may not be an array type");
72 static_assert(!is_abstract_v<_ElementType>, "mdspan: ElementType template parameter may not be an abstract class");
73 static_assert(is_same_v<_ElementType, typename _AccessorPolicy::element_type>,
74 "mdspan: ElementType template parameter must match AccessorPolicy::element_type");
75 static_assert(!__mdspan_detail::__has_invalid_mapping<_LayoutPolicy, _Extents>,
76 "mdspan: LayoutPolicy template parameter is invalid. A common mistake is to pass a layout mapping "
77 "instead of a layout policy");
78
79public:
80 using extents_type = _Extents;
81 using layout_type = _LayoutPolicy;
82 using accessor_type = _AccessorPolicy;
83 using mapping_type = typename layout_type::template mapping<extents_type>;
84 using element_type = _ElementType;
85 using value_type = remove_cv_t<element_type>;
86 using index_type = typename extents_type::index_type;
87 using size_type = typename extents_type::size_type;
88 using rank_type = typename extents_type::rank_type;
89 using data_handle_type = typename accessor_type::data_handle_type;
90 using reference = typename accessor_type::reference;
91
92 _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return extents_type::rank(); }
93 _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
94 _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept {
95 return extents_type::static_extent(__r);
96 }
97 _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept {
98 return __map_.extents().extent(__r);
99 };
100
101public:
102 //--------------------------------------------------------------------------------
103 // [mdspan.mdspan.cons], mdspan constructors, assignment, and destructor
104
105 _LIBCPP_HIDE_FROM_ABI constexpr mdspan()
106 requires((extents_type::rank_dynamic() > 0) && is_default_constructible_v<data_handle_type> &&
107 is_default_constructible_v<mapping_type> && is_default_constructible_v<accessor_type>)
108 = default;
109 _LIBCPP_HIDE_FROM_ABI constexpr mdspan(const mdspan&) = default;
110 _LIBCPP_HIDE_FROM_ABI constexpr mdspan(mdspan&&) = default;
111
112 template <class... _OtherIndexTypes>
113 requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) &&
114 (is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) &&
115 ((sizeof...(_OtherIndexTypes) == rank()) || (sizeof...(_OtherIndexTypes) == rank_dynamic())) &&
116 is_constructible_v<mapping_type, extents_type> && is_default_constructible_v<accessor_type>)
117 _LIBCPP_HIDE_FROM_ABI explicit constexpr mdspan(data_handle_type __p, _OtherIndexTypes... __exts)
118 : __ptr_(std::move(__p)), __map_(extents_type(static_cast<index_type>(std::move(__exts))...)), __acc_{} {}
119
120 template <class _OtherIndexType, size_t _Size>
121 requires(is_convertible_v<const _OtherIndexType&, index_type> &&
122 is_nothrow_constructible_v<index_type, const _OtherIndexType&> &&
123 ((_Size == rank()) || (_Size == rank_dynamic())) && is_constructible_v<mapping_type, extents_type> &&
124 is_default_constructible_v<accessor_type>)
125 explicit(_Size != rank_dynamic())
126 _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const array<_OtherIndexType, _Size>& __exts)
127 : __ptr_(std::move(__p)), __map_(extents_type(__exts)), __acc_{} {}
128
129 template <class _OtherIndexType, size_t _Size>
130 requires(is_convertible_v<const _OtherIndexType&, index_type> &&
131 is_nothrow_constructible_v<index_type, const _OtherIndexType&> &&
132 ((_Size == rank()) || (_Size == rank_dynamic())) && is_constructible_v<mapping_type, extents_type> &&
133 is_default_constructible_v<accessor_type>)
134 explicit(_Size != rank_dynamic())
135 _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, span<_OtherIndexType, _Size> __exts)
136 : __ptr_(std::move(__p)), __map_(extents_type(__exts)), __acc_{} {}
137
138 _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const extents_type& __exts)
139 requires(is_default_constructible_v<accessor_type> && is_constructible_v<mapping_type, const extents_type&>)
140 : __ptr_(std::move(__p)), __map_(__exts), __acc_{} {}
141
142 _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const mapping_type& __m)
143 requires(is_default_constructible_v<accessor_type>)
144 : __ptr_(std::move(__p)), __map_(__m), __acc_{} {}
145
146 _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const mapping_type& __m, const accessor_type& __a)
147 : __ptr_(std::move(__p)), __map_(__m), __acc_(__a) {}
148
149 template <class _OtherElementType, class _OtherExtents, class _OtherLayoutPolicy, class _OtherAccessor>
150 requires(is_constructible_v<mapping_type, const typename _OtherLayoutPolicy::template mapping<_OtherExtents>&> &&
151 is_constructible_v<accessor_type, const _OtherAccessor&>)
152 explicit(!is_convertible_v<const typename _OtherLayoutPolicy::template mapping<_OtherExtents>&, mapping_type> ||
153 !is_convertible_v<const _OtherAccessor&, accessor_type>)
154 _LIBCPP_HIDE_FROM_ABI constexpr mdspan(
155 const mdspan<_OtherElementType, _OtherExtents, _OtherLayoutPolicy, _OtherAccessor>& __other)
156 : __ptr_(__other.__ptr_), __map_(__other.__map_), __acc_(__other.__acc_) {
157 static_assert(is_constructible_v<data_handle_type, const typename _OtherAccessor::data_handle_type&>,
158 "mdspan: incompatible data_handle_type for mdspan construction");
159 static_assert(
160 is_constructible_v<extents_type, _OtherExtents>, "mdspan: incompatible extents for mdspan construction");
161
162 // The following precondition is part of the standard, but is unlikely to be triggered.
163 // The extents constructor checks this and the mapping must be storing the extents, since
164 // its extents() function returns a const reference to extents_type.
165 // The only way this can be triggered is if the mapping conversion constructor would for example
166 // always construct its extents() only from the dynamic extents, instead of from the other extents.
167 if constexpr (rank() > 0) {
168 for (size_t __r = 0; __r < rank(); __r++) {
169 // Not catching this could lead to out of bounds errors later
170 // e.g. mdspan<int, dextents<char,1>, non_checking_layout> m =
171 // mdspan<int, dextents<unsigned, 1>, non_checking_layout>(ptr, 200); leads to an extent of -56 on m
172 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
173 (static_extent(__r) == dynamic_extent) ||
174 (static_cast<index_type>(__other.extent(__r)) == static_cast<index_type>(static_extent(__r))),
175 "mdspan: conversion mismatch of source dynamic extents with static extents");
176 }
177 }
178 }
179
180 _LIBCPP_HIDE_FROM_ABI constexpr mdspan& operator=(const mdspan&) = default;
181 _LIBCPP_HIDE_FROM_ABI constexpr mdspan& operator=(mdspan&&) = default;
182
183 //--------------------------------------------------------------------------------
184 // [mdspan.mdspan.members], members
185
186 template <class... _OtherIndexTypes>
187 requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) &&
188 (is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) &&
189 (sizeof...(_OtherIndexTypes) == rank()))
190 _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](_OtherIndexTypes... __indices) const {
191 // Note the standard layouts would also check this, but user provided ones may not, so we
192 // check the precondition here
193 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__is_multidimensional_index_in(extents(), __indices...),
194 "mdspan: operator[] out of bounds access");
195 return __acc_.access(__ptr_, __map_(static_cast<index_type>(std::move(__indices))...));
196 }
197
198 template <class _OtherIndexType>
199 requires(is_convertible_v<const _OtherIndexType&, index_type> &&
200 is_nothrow_constructible_v<index_type, const _OtherIndexType&>)
201 _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](const array< _OtherIndexType, rank()>& __indices) const {
202 return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
203 return __map_(__indices[_Idxs]...);
204 }(make_index_sequence<rank()>()));
205 }
206
207 template <class _OtherIndexType>
208 requires(is_convertible_v<const _OtherIndexType&, index_type> &&
209 is_nothrow_constructible_v<index_type, const _OtherIndexType&>)
210 _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](span<_OtherIndexType, rank()> __indices) const {
211 return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
212 return __map_(__indices[_Idxs]...);
213 }(make_index_sequence<rank()>()));
214 }
215
216 _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept {
217 // Could leave this as only checked in debug mode: semantically size() is never
218 // guaranteed to be related to any accessible range
219 _LIBCPP_ASSERT_UNCATEGORIZED(
220 false == ([&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
221 size_type __prod = 1;
222 return (__builtin_mul_overflow(__prod, extent(_Idxs), &__prod) || ... || false);
223 }(make_index_sequence<rank()>())),
224 "mdspan: size() is not representable as size_type");
225 return [&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
226 return ((static_cast<size_type>(__map_.extents().extent(_Idxs))) * ... * size_type(1));
227 }(make_index_sequence<rank()>());
228 }
229
230 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept {
231 return [&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
232 return (rank() > 0) && ((__map_.extents().extent(_Idxs) == index_type(0)) || ... || false);
233 }(make_index_sequence<rank()>());
234 }
235
236 _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(mdspan& __x, mdspan& __y) noexcept {
237 swap(__x.__ptr_, __y.__ptr_);
238 swap(__x.__map_, __y.__map_);
239 swap(__x.__acc_, __y.__acc_);
240 }
241
242 _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { return __map_.extents(); };
243 _LIBCPP_HIDE_FROM_ABI constexpr const data_handle_type& data_handle() const noexcept { return __ptr_; };
244 _LIBCPP_HIDE_FROM_ABI constexpr const mapping_type& mapping() const noexcept { return __map_; };
245 _LIBCPP_HIDE_FROM_ABI constexpr const accessor_type& accessor() const noexcept { return __acc_; };
246
247 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() { return mapping_type::is_always_unique(); };
248 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() { return mapping_type::is_always_exhaustive(); };
249 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() { return mapping_type::is_always_strided(); };
250
251 _LIBCPP_HIDE_FROM_ABI constexpr bool is_unique() const { return __map_.is_unique(); };
252 _LIBCPP_HIDE_FROM_ABI constexpr bool is_exhaustive() const { return __map_.is_exhaustive(); };
253 _LIBCPP_HIDE_FROM_ABI constexpr bool is_strided() const { return __map_.is_strided(); };
254 _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const { return __map_.stride(__r); };
255
256private:
257 _LIBCPP_NO_UNIQUE_ADDRESS data_handle_type __ptr_{};
258 _LIBCPP_NO_UNIQUE_ADDRESS mapping_type __map_{};
259 _LIBCPP_NO_UNIQUE_ADDRESS accessor_type __acc_{};
260
261 template <class, class, class, class>
262 friend class mdspan;
263};
264
265template <class _ElementType, class... _OtherIndexTypes>
266 requires((is_convertible_v<_OtherIndexTypes, size_t> && ...) && (sizeof...(_OtherIndexTypes) > 0))
267explicit mdspan(_ElementType*, _OtherIndexTypes...)
268 -> mdspan<_ElementType, dextents<size_t, sizeof...(_OtherIndexTypes)>>;
269
270template <class _Pointer>
271 requires(is_pointer_v<remove_reference_t<_Pointer>>)
272mdspan(_Pointer&&) -> mdspan<remove_pointer_t<remove_reference_t<_Pointer>>, extents<size_t>>;
273
274template <class _CArray>
275 requires(is_array_v<_CArray> && (rank_v<_CArray> == 1))
276mdspan(_CArray&) -> mdspan<remove_all_extents_t<_CArray>, extents<size_t, extent_v<_CArray, 0>>>;
277
278template <class _ElementType, class _OtherIndexType, size_t _Size>
279mdspan(_ElementType*, const array<_OtherIndexType, _Size>&) -> mdspan<_ElementType, dextents<size_t, _Size>>;
280
281template <class _ElementType, class _OtherIndexType, size_t _Size>
282mdspan(_ElementType*, span<_OtherIndexType, _Size>) -> mdspan<_ElementType, dextents<size_t, _Size>>;
283
284// This one is necessary because all the constructors take `data_handle_type`s, not
285// `_ElementType*`s, and `data_handle_type` is taken from `accessor_type::data_handle_type`, which
286// seems to throw off automatic deduction guides.
287template <class _ElementType, class _OtherIndexType, size_t... _ExtentsPack>
288mdspan(_ElementType*, const extents<_OtherIndexType, _ExtentsPack...>&)
289 -> mdspan<_ElementType, extents<_OtherIndexType, _ExtentsPack...>>;
290
291template <class _ElementType, class _MappingType>
292mdspan(_ElementType*, const _MappingType&)
293 -> mdspan<_ElementType, typename _MappingType::extents_type, typename _MappingType::layout_type>;
294
295template <class _MappingType, class _AccessorType>
296mdspan(const typename _AccessorType::data_handle_type, const _MappingType&, const _AccessorType&)
297 -> mdspan<typename _AccessorType::element_type,
298 typename _MappingType::extents_type,
299 typename _MappingType::layout_type,
300 _AccessorType>;
301
302#endif // _LIBCPP_STD_VER >= 23
303
304_LIBCPP_END_NAMESPACE_STD
305
306_LIBCPP_POP_MACROS
307
308#endif // _LIBCPP___MDSPAN_MDSPAN_H
lib/libcxx/include/__memory/align.h+1-1
......@@ -18,7 +18,7 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
21_LIBCPP_EXPORTED_FROM_ABI void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
2222
2323_LIBCPP_END_NAMESPACE_STD
2424
lib/libcxx/include/__memory/aligned_alloc.h created+66
......@@ -0,0 +1,66 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___MEMORY_ALIGNED_ALLOC_H
10#define _LIBCPP___MEMORY_ALIGNED_ALLOC_H
11
12#include <__config>
13#include <cstddef>
14#include <cstdlib>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
23
24// Low-level helpers to call the aligned allocation and deallocation functions
25// on the target platform. This is used to implement libc++'s own memory
26// allocation routines -- if you need to allocate memory inside the library,
27// chances are that you want to use `__libcpp_allocate` instead.
28//
29// Returns the allocated memory, or `nullptr` on failure.
30inline _LIBCPP_HIDE_FROM_ABI
31void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
32# if defined(_LIBCPP_MSVCRT_LIKE)
33 return ::_aligned_malloc(__size, __alignment);
34# elif _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC)
35 // aligned_alloc() requires that __size is a multiple of __alignment,
36 // but for C++ [new.delete.general], only states "if the value of an
37 // alignment argument passed to any of these functions is not a valid
38 // alignment value, the behavior is undefined".
39 // To handle calls such as ::operator new(1, std::align_val_t(128)), we
40 // round __size up to the next multiple of __alignment.
41 size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
42 // Rounding up could have wrapped around to zero, so we have to add another
43 // max() ternary to the actual call site to avoid succeeded in that case.
44 return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
45# else
46 void* __result = nullptr;
47 (void)::posix_memalign(&__result, __alignment, __size);
48 // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
49 return __result;
50# endif
51}
52
53inline _LIBCPP_HIDE_FROM_ABI
54void __libcpp_aligned_free(void* __ptr) {
55#if defined(_LIBCPP_MSVCRT_LIKE)
56 ::_aligned_free(__ptr);
57#else
58 ::free(__ptr);
59#endif
60}
61
62#endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
63
64_LIBCPP_END_NAMESPACE_STD
65
66#endif // _LIBCPP___MEMORY_ALIGNED_ALLOC_H
lib/libcxx/include/__memory/allocate_at_least.h+2-2
......@@ -19,7 +19,7 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 20
22#if _LIBCPP_STD_VER >= 23
2323template <class _Pointer>
2424struct allocation_result {
2525 _Pointer ptr;
......@@ -55,7 +55,7 @@ __allocation_result<typename allocator_traits<_Alloc>::pointer> __allocate_at_le
5555 return {__alloc.allocate(__n), __n};
5656}
5757
58#endif // _LIBCPP_STD_VER > 20
58#endif // _LIBCPP_STD_VER >= 23
5959
6060_LIBCPP_END_NAMESPACE_STD
6161
lib/libcxx/include/__memory/allocation_guard.h+35-2
......@@ -11,6 +11,7 @@
1111#define _LIBCPP___MEMORY_ALLOCATION_GUARD_H
1212
1313#include <__config>
14#include <__memory/addressof.h>
1415#include <__memory/allocator_traits.h>
1516#include <__utility/move.h>
1617#include <cstddef>
......@@ -19,6 +20,9 @@
1920# pragma GCC system_header
2021#endif
2122
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
2226_LIBCPP_BEGIN_NAMESPACE_STD
2327
2428// Helper class to allocate memory using an Allocator in an exception safe
......@@ -55,9 +59,29 @@ struct __allocation_guard {
5559
5660 _LIBCPP_HIDE_FROM_ABI
5761 ~__allocation_guard() _NOEXCEPT {
58 if (__ptr_ != nullptr) {
59 allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __n_);
62 __destroy();
63 }
64
65 _LIBCPP_HIDE_FROM_ABI __allocation_guard(const __allocation_guard&) = delete;
66 _LIBCPP_HIDE_FROM_ABI __allocation_guard(__allocation_guard&& __other) _NOEXCEPT
67 : __alloc_(std::move(__other.__alloc_))
68 , __n_(__other.__n_)
69 , __ptr_(__other.__ptr_) {
70 __other.__ptr_ = nullptr;
71 }
72
73 _LIBCPP_HIDE_FROM_ABI __allocation_guard& operator=(const __allocation_guard& __other) = delete;
74 _LIBCPP_HIDE_FROM_ABI __allocation_guard& operator=(__allocation_guard&& __other) _NOEXCEPT {
75 if (std::addressof(__other) != this) {
76 __destroy();
77
78 __alloc_ = std::move(__other.__alloc_);
79 __n_ = __other.__n_;
80 __ptr_ = __other.__ptr_;
81 __other.__ptr_ = nullptr;
6082 }
83
84 return *this;
6185 }
6286
6387 _LIBCPP_HIDE_FROM_ABI
......@@ -73,6 +97,13 @@ struct __allocation_guard {
7397 }
7498
7599private:
100 _LIBCPP_HIDE_FROM_ABI
101 void __destroy() _NOEXCEPT {
102 if (__ptr_ != nullptr) {
103 allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __n_);
104 }
105 }
106
76107 _Alloc __alloc_;
77108 _Size __n_;
78109 _Pointer __ptr_;
......@@ -80,4 +111,6 @@ private:
80111
81112_LIBCPP_END_NAMESPACE_STD
82113
114_LIBCPP_POP_MACROS
115
83116#endif // _LIBCPP___MEMORY_ALLOCATION_GUARD_H
lib/libcxx/include/__memory/allocator.h+10-8
......@@ -11,6 +11,7 @@
1111#define _LIBCPP___MEMORY_ALLOCATOR_H
1212
1313#include <__config>
14#include <__memory/addressof.h>
1415#include <__memory/allocate_at_least.h>
1516#include <__memory/allocator_traits.h>
1617#include <__type_traits/is_constant_evaluated.h>
......@@ -20,7 +21,6 @@
2021#include <__utility/forward.h>
2122#include <cstddef>
2223#include <new>
23#include <stdexcept>
2424
2525#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2626# pragma GCC system_header
......@@ -98,8 +98,7 @@ public:
9898 typedef true_type propagate_on_container_move_assignment;
9999 typedef true_type is_always_equal;
100100
101 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
102 allocator() _NOEXCEPT = default;
101 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator() _NOEXCEPT = default;
103102
104103 template <class _Up>
105104 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -116,7 +115,7 @@ public:
116115 }
117116 }
118117
119#if _LIBCPP_STD_VER > 20
118#if _LIBCPP_STD_VER >= 23
120119 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr
121120 allocation_result<_Tp*> allocate_at_least(size_t __n) {
122121 return {allocate(__n), __n};
......@@ -187,8 +186,7 @@ public:
187186 typedef true_type propagate_on_container_move_assignment;
188187 typedef true_type is_always_equal;
189188
190 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
191 allocator() _NOEXCEPT = default;
189 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator() _NOEXCEPT = default;
192190
193191 template <class _Up>
194192 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -205,7 +203,7 @@ public:
205203 }
206204 }
207205
208#if _LIBCPP_STD_VER > 20
206#if _LIBCPP_STD_VER >= 23
209207 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr
210208 allocation_result<const _Tp*> allocate_at_least(size_t __n) {
211209 return {allocate(__n), __n};
......@@ -264,10 +262,14 @@ template <class _Tp, class _Up>
264262inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
265263bool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;}
266264
265#if _LIBCPP_STD_VER <= 17
266
267267template <class _Tp, class _Up>
268inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
268inline _LIBCPP_INLINE_VISIBILITY
269269bool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;}
270270
271#endif
272
271273_LIBCPP_END_NAMESPACE_STD
272274
273275#endif // _LIBCPP___MEMORY_ALLOCATOR_H
lib/libcxx/include/__memory/allocator_arg_t.h+4-4
......@@ -25,10 +25,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2525
2626struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; };
2727
28#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
29extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg;
30#else
31/* inline */ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
28#if _LIBCPP_STD_VER >= 17
29inline constexpr allocator_arg_t allocator_arg = allocator_arg_t();
30#elif !defined(_LIBCPP_CXX03_LANG)
31constexpr allocator_arg_t allocator_arg = allocator_arg_t();
3232#endif
3333
3434#ifndef _LIBCPP_CXX03_LANG
lib/libcxx/include/__memory/allocator_traits.h+21-2
......@@ -300,7 +300,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
300300 __enable_if_t<!__has_construct<allocator_type, _Tp*, _Args...>::value> >
301301 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
302302 static void construct(allocator_type&, _Tp* __p, _Args&&... __args) {
303#if _LIBCPP_STD_VER > 17
303#if _LIBCPP_STD_VER >= 20
304304 _VSTD::construct_at(__p, _VSTD::forward<_Args>(__args)...);
305305#else
306306 ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);
......@@ -319,7 +319,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
319319 __enable_if_t<!__has_destroy<allocator_type, _Tp*>::value> >
320320 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
321321 static void destroy(allocator_type&, _Tp* __p) {
322#if _LIBCPP_STD_VER > 17
322#if _LIBCPP_STD_VER >= 20
323323 _VSTD::destroy_at(__p);
324324#else
325325 __p->~_Tp();
......@@ -401,6 +401,25 @@ struct __is_cpp17_copy_insertable<_Alloc, __enable_if_t<
401401 : __is_cpp17_move_insertable<_Alloc>
402402{ };
403403
404// ASan choices
405#ifndef _LIBCPP_HAS_NO_ASAN
406# define _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS 1
407#endif
408
409#ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS
410template <class _Alloc>
411struct __asan_annotate_container_with_allocator
412# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1600
413 : true_type {};
414# else
415 // TODO(LLVM-18): Remove the special-casing
416 : false_type {};
417# endif
418
419template <class _Tp>
420struct __asan_annotate_container_with_allocator<allocator<_Tp> > : true_type {};
421#endif
422
404423#undef _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX
405424
406425_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__memory/assume_aligned.h+3-3
......@@ -22,7 +22,7 @@
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727template <size_t _Np, class _Tp>
2828[[nodiscard]]
......@@ -34,12 +34,12 @@ constexpr _Tp* assume_aligned(_Tp* __ptr) {
3434 if (is_constant_evaluated()) {
3535 return __ptr;
3636 } else {
37 _LIBCPP_ASSERT(reinterpret_cast<uintptr_t>(__ptr) % _Np == 0, "Alignment assumption is violated");
37 _LIBCPP_ASSERT_UNCATEGORIZED(reinterpret_cast<uintptr_t>(__ptr) % _Np == 0, "Alignment assumption is violated");
3838 return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Np));
3939 }
4040}
4141
42#endif // _LIBCPP_STD_VER > 17
42#endif // _LIBCPP_STD_VER >= 20
4343
4444_LIBCPP_END_NAMESPACE_STD
4545
lib/libcxx/include/__memory/builtin_new_allocator.h+6-6
......@@ -28,10 +28,10 @@ struct __builtin_new_allocator {
2828 struct __builtin_new_deleter {
2929 typedef void* pointer_type;
3030
31 _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align)
31 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align)
3232 : __size_(__size), __align_(__align) {}
3333
34 void operator()(void* __p) const _NOEXCEPT {
34 _LIBCPP_HIDE_FROM_ABI void operator()(void* __p) const _NOEXCEPT {
3535 _VSTD::__libcpp_deallocate(__p, __size_, __align_);
3636 }
3737
......@@ -42,25 +42,25 @@ struct __builtin_new_allocator {
4242
4343 typedef unique_ptr<void, __builtin_new_deleter> __holder_t;
4444
45 static __holder_t __allocate_bytes(size_t __s, size_t __align) {
45 _LIBCPP_HIDE_FROM_ABI static __holder_t __allocate_bytes(size_t __s, size_t __align) {
4646 return __holder_t(_VSTD::__libcpp_allocate(__s, __align),
4747 __builtin_new_deleter(__s, __align));
4848 }
4949
50 static void __deallocate_bytes(void* __p, size_t __s,
50 _LIBCPP_HIDE_FROM_ABI static void __deallocate_bytes(void* __p, size_t __s,
5151 size_t __align) _NOEXCEPT {
5252 _VSTD::__libcpp_deallocate(__p, __s, __align);
5353 }
5454
5555 template <class _Tp>
5656 _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
57 static __holder_t __allocate_type(size_t __n) {
57 _LIBCPP_HIDE_FROM_ABI static __holder_t __allocate_type(size_t __n) {
5858 return __allocate_bytes(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
5959 }
6060
6161 template <class _Tp>
6262 _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
63 static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT {
63 _LIBCPP_HIDE_FROM_ABI static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT {
6464 __deallocate_bytes(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
6565 }
6666};
lib/libcxx/include/__memory/compressed_pair.h+8-3
......@@ -13,7 +13,7 @@
1313#include <__config>
1414#include <__fwd/get.h>
1515#include <__fwd/tuple.h>
16#include <__tuple_dir/tuple_indices.h>
16#include <__tuple/tuple_indices.h>
1717#include <__type_traits/decay.h>
1818#include <__type_traits/dependent_type.h>
1919#include <__type_traits/enable_if.h>
......@@ -31,6 +31,9 @@
3131# pragma GCC system_header
3232#endif
3333
34_LIBCPP_PUSH_MACROS
35#include <__undef_macros>
36
3437_LIBCPP_BEGIN_NAMESPACE_STD
3538
3639// Tag used to default initialize one or both of the pair's elements.
......@@ -46,7 +49,7 @@ struct __compressed_pair_elem {
4649 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__default_init_tag) {}
4750 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__value_init_tag) : __value_() {}
4851
49 template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, typename decay<_Up>::type>::value> >
52 template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, __decay_t<_Up> >::value> >
5053 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
5154 explicit __compressed_pair_elem(_Up&& __u) : __value_(std::forward<_Up>(__u)) {}
5255
......@@ -75,7 +78,7 @@ struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {
7578 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__default_init_tag) {}
7679 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__value_init_tag) : __value_type() {}
7780
78 template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, typename decay<_Up>::type>::value> >
81 template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, __decay_t<_Up> >::value> >
7982 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
8083 explicit __compressed_pair_elem(_Up&& __u) : __value_type(std::forward<_Up>(__u)) {}
8184
......@@ -174,4 +177,6 @@ void swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)
174177
175178_LIBCPP_END_NAMESPACE_STD
176179
180_LIBCPP_POP_MACROS
181
177182#endif // _LIBCPP___MEMORY_COMPRESSED_PAIR_H
lib/libcxx/include/__memory/concepts.h+3-2
......@@ -19,6 +19,7 @@
1919#include <__ranges/concepts.h>
2020#include <__type_traits/is_reference.h>
2121#include <__type_traits/remove_cvref.h>
22#include <__type_traits/remove_reference.h> // TODO(modules): This should not be required
2223
2324#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2425# pragma GCC system_header
......@@ -26,7 +27,7 @@
2627
2728_LIBCPP_BEGIN_NAMESPACE_STD
2829
29#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3031
3132namespace ranges {
3233
......@@ -62,7 +63,7 @@ concept __nothrow_forward_range =
6263
6364} // namespace ranges
6465
65#endif // _LIBCPP_STD_VER > 17
66#endif // _LIBCPP_STD_VER >= 20
6667
6768_LIBCPP_END_NAMESPACE_STD
6869
lib/libcxx/include/__memory/construct_at.h+22-17
......@@ -26,26 +26,29 @@
2626# pragma GCC system_header
2727#endif
2828
29_LIBCPP_PUSH_MACROS
30#include <__undef_macros>
31
2932_LIBCPP_BEGIN_NAMESPACE_STD
3033
3134// construct_at
3235
33#if _LIBCPP_STD_VER > 17
36#if _LIBCPP_STD_VER >= 20
3437
3538template <class _Tp, class... _Args, class = decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))>
3639_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&&... __args) {
37 _LIBCPP_ASSERT(__location != nullptr, "null pointer given to construct_at");
38 return ::new (_VSTD::__voidify(*__location)) _Tp(_VSTD::forward<_Args>(__args)...);
40 _LIBCPP_ASSERT_UNCATEGORIZED(__location != nullptr, "null pointer given to construct_at");
41 return ::new (std::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...);
3942}
4043
4144#endif
4245
4346template <class _Tp, class... _Args, class = decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))>
4447_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __construct_at(_Tp* __location, _Args&&... __args) {
45#if _LIBCPP_STD_VER > 17
48#if _LIBCPP_STD_VER >= 20
4649 return std::construct_at(__location, std::forward<_Args>(__args)...);
4750#else
48 return _LIBCPP_ASSERT(__location != nullptr, "null pointer given to construct_at"),
51 return _LIBCPP_ASSERT_UNCATEGORIZED(__location != nullptr, "null pointer given to construct_at"),
4952 ::new (std::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...);
5053#endif
5154}
......@@ -62,16 +65,16 @@ _ForwardIterator __destroy(_ForwardIterator, _ForwardIterator);
6265template <class _Tp, typename enable_if<!is_array<_Tp>::value, int>::type = 0>
6366_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
6467void __destroy_at(_Tp* __loc) {
65 _LIBCPP_ASSERT(__loc != nullptr, "null pointer given to destroy_at");
68 _LIBCPP_ASSERT_UNCATEGORIZED(__loc != nullptr, "null pointer given to destroy_at");
6669 __loc->~_Tp();
6770}
6871
69#if _LIBCPP_STD_VER > 17
72#if _LIBCPP_STD_VER >= 20
7073template <class _Tp, typename enable_if<is_array<_Tp>::value, int>::type = 0>
7174_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
7275void __destroy_at(_Tp* __loc) {
73 _LIBCPP_ASSERT(__loc != nullptr, "null pointer given to destroy_at");
74 _VSTD::__destroy(_VSTD::begin(*__loc), _VSTD::end(*__loc));
76 _LIBCPP_ASSERT_UNCATEGORIZED(__loc != nullptr, "null pointer given to destroy_at");
77 std::__destroy(std::begin(*__loc), std::end(*__loc));
7578}
7679#endif
7780
......@@ -79,7 +82,7 @@ template <class _ForwardIterator>
7982_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
8083_ForwardIterator __destroy(_ForwardIterator __first, _ForwardIterator __last) {
8184 for (; __first != __last; ++__first)
82 _VSTD::__destroy_at(_VSTD::addressof(*__first));
85 std::__destroy_at(std::addressof(*__first));
8386 return __first;
8487}
8588
......@@ -93,38 +96,40 @@ _BidirectionalIterator __reverse_destroy(_BidirectionalIterator __first, _Bidire
9396 return __last;
9497}
9598
96#if _LIBCPP_STD_VER > 14
99#if _LIBCPP_STD_VER >= 17
97100
98101template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
99102_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
100103void destroy_at(_Tp* __loc) {
101 _VSTD::__destroy_at(__loc);
104 std::__destroy_at(__loc);
102105}
103106
104#if _LIBCPP_STD_VER > 17
107#if _LIBCPP_STD_VER >= 20
105108template <class _Tp, enable_if_t<is_array_v<_Tp>, int> = 0>
106109_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
107110void destroy_at(_Tp* __loc) {
108 _VSTD::__destroy_at(__loc);
111 std::__destroy_at(__loc);
109112}
110113#endif
111114
112115template <class _ForwardIterator>
113116_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
114117void destroy(_ForwardIterator __first, _ForwardIterator __last) {
115 (void)_VSTD::__destroy(_VSTD::move(__first), _VSTD::move(__last));
118 (void)std::__destroy(std::move(__first), std::move(__last));
116119}
117120
118121template <class _ForwardIterator, class _Size>
119122_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
120123_ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
121124 for (; __n > 0; (void)++__first, --__n)
122 _VSTD::__destroy_at(_VSTD::addressof(*__first));
125 std::__destroy_at(std::addressof(*__first));
123126 return __first;
124127}
125128
126#endif // _LIBCPP_STD_VER > 14
129#endif // _LIBCPP_STD_VER >= 17
127130
128131_LIBCPP_END_NAMESPACE_STD
129132
133_LIBCPP_POP_MACROS
134
130135#endif // _LIBCPP___MEMORY_CONSTRUCT_AT_H
lib/libcxx/include/__memory/pointer_traits.h+2-2
......@@ -200,7 +200,7 @@ template <class _Pointer, class = __enable_if_t<
200200 _And<is_class<_Pointer>, _IsFancyPointer<_Pointer> >::value
201201> >
202202_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
203typename decay<decltype(__to_address_helper<_Pointer>::__call(std::declval<const _Pointer&>()))>::type
203__decay_t<decltype(__to_address_helper<_Pointer>::__call(std::declval<const _Pointer&>()))>
204204__to_address(const _Pointer& __p) _NOEXCEPT {
205205 return __to_address_helper<_Pointer>::__call(__p);
206206}
......@@ -223,7 +223,7 @@ struct __to_address_helper<_Pointer, decltype((void)pointer_traits<_Pointer>::to
223223 }
224224};
225225
226#if _LIBCPP_STD_VER > 17
226#if _LIBCPP_STD_VER >= 20
227227template <class _Tp>
228228inline _LIBCPP_INLINE_VISIBILITY constexpr
229229auto to_address(_Tp *__p) noexcept {
lib/libcxx/include/__memory/ranges_construct_at.h+8-3
......@@ -13,7 +13,7 @@
1313#include <__concepts/destructible.h>
1414#include <__config>
1515#include <__iterator/incrementable_traits.h>
16#include <__iterator/readable_traits.h>
16#include <__iterator/iterator_traits.h>
1717#include <__memory/concepts.h>
1818#include <__memory/construct_at.h>
1919#include <__ranges/access.h>
......@@ -28,9 +28,12 @@
2828# pragma GCC system_header
2929#endif
3030
31_LIBCPP_PUSH_MACROS
32#include <__undef_macros>
33
3134_LIBCPP_BEGIN_NAMESPACE_STD
3235
33#if _LIBCPP_STD_VER > 17
36#if _LIBCPP_STD_VER >= 20
3437namespace ranges {
3538
3639// construct_at
......@@ -118,8 +121,10 @@ inline namespace __cpo {
118121
119122} // namespace ranges
120123
121#endif // _LIBCPP_STD_VER > 17
124#endif // _LIBCPP_STD_VER >= 20
122125
123126_LIBCPP_END_NAMESPACE_STD
124127
128_LIBCPP_POP_MACROS
129
125130#endif // _LIBCPP___MEMORY_RANGES_CONSTRUCT_AT_H
lib/libcxx/include/__memory/ranges_uninitialized_algorithms.h+17-17
......@@ -33,7 +33,7 @@
3333
3434_LIBCPP_BEGIN_NAMESPACE_STD
3535
36#if _LIBCPP_STD_VER > 17
36#if _LIBCPP_STD_VER >= 20
3737
3838namespace ranges {
3939
......@@ -45,7 +45,7 @@ struct __fn {
4545 template <__nothrow_forward_iterator _ForwardIterator,
4646 __nothrow_sentinel_for<_ForwardIterator> _Sentinel>
4747 requires default_initializable<iter_value_t<_ForwardIterator>>
48 _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
48 _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
4949 using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
5050 return _VSTD::__uninitialized_default_construct<_ValueType>(
5151 _VSTD::move(__first), _VSTD::move(__last));
......@@ -53,7 +53,7 @@ struct __fn {
5353
5454 template <__nothrow_forward_range _ForwardRange>
5555 requires default_initializable<range_value_t<_ForwardRange>>
56 borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
56 _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
5757 return (*this)(ranges::begin(__range), ranges::end(__range));
5858 }
5959};
......@@ -71,7 +71,7 @@ namespace __uninitialized_default_construct_n {
7171struct __fn {
7272 template <__nothrow_forward_iterator _ForwardIterator>
7373 requires default_initializable<iter_value_t<_ForwardIterator>>
74 _ForwardIterator operator()(_ForwardIterator __first,
74 _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first,
7575 iter_difference_t<_ForwardIterator> __n) const {
7676 using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
7777 return _VSTD::__uninitialized_default_construct_n<_ValueType>(_VSTD::move(__first), __n);
......@@ -92,7 +92,7 @@ struct __fn {
9292 template <__nothrow_forward_iterator _ForwardIterator,
9393 __nothrow_sentinel_for<_ForwardIterator> _Sentinel>
9494 requires default_initializable<iter_value_t<_ForwardIterator>>
95 _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
95 _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
9696 using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
9797 return _VSTD::__uninitialized_value_construct<_ValueType>(
9898 _VSTD::move(__first), _VSTD::move(__last));
......@@ -100,7 +100,7 @@ struct __fn {
100100
101101 template <__nothrow_forward_range _ForwardRange>
102102 requires default_initializable<range_value_t<_ForwardRange>>
103 borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
103 _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
104104 return (*this)(ranges::begin(__range), ranges::end(__range));
105105 }
106106};
......@@ -118,7 +118,7 @@ namespace __uninitialized_value_construct_n {
118118struct __fn {
119119 template <__nothrow_forward_iterator _ForwardIterator>
120120 requires default_initializable<iter_value_t<_ForwardIterator>>
121 _ForwardIterator operator()(_ForwardIterator __first,
121 _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first,
122122 iter_difference_t<_ForwardIterator> __n) const {
123123 using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
124124 return _VSTD::__uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n);
......@@ -140,14 +140,14 @@ struct __fn {
140140 __nothrow_sentinel_for<_ForwardIterator> _Sentinel,
141141 class _Tp>
142142 requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&>
143 _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) const {
143 _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) const {
144144 using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
145145 return _VSTD::__uninitialized_fill<_ValueType>(_VSTD::move(__first), _VSTD::move(__last), __x);
146146 }
147147
148148 template <__nothrow_forward_range _ForwardRange, class _Tp>
149149 requires constructible_from<range_value_t<_ForwardRange>, const _Tp&>
150 borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const {
150 _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const {
151151 return (*this)(ranges::begin(__range), ranges::end(__range), __x);
152152 }
153153};
......@@ -165,7 +165,7 @@ namespace __uninitialized_fill_n {
165165struct __fn {
166166 template <__nothrow_forward_iterator _ForwardIterator, class _Tp>
167167 requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&>
168 _ForwardIterator operator()(_ForwardIterator __first,
168 _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first,
169169 iter_difference_t<_ForwardIterator> __n,
170170 const _Tp& __x) const {
171171 using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
......@@ -192,7 +192,7 @@ struct __fn {
192192 __nothrow_forward_iterator _OutputIterator,
193193 __nothrow_sentinel_for<_OutputIterator> _Sentinel2>
194194 requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
195 uninitialized_copy_result<_InputIterator, _OutputIterator>
195 _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result<_InputIterator, _OutputIterator>
196196 operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
197197 using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
198198
......@@ -203,7 +203,7 @@ struct __fn {
203203
204204 template <input_range _InputRange, __nothrow_forward_range _OutputRange>
205205 requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>>
206 uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
206 _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
207207 operator()( _InputRange&& __in_range, _OutputRange&& __out_range) const {
208208 return (*this)(ranges::begin(__in_range), ranges::end(__in_range),
209209 ranges::begin(__out_range), ranges::end(__out_range));
......@@ -228,7 +228,7 @@ struct __fn {
228228 __nothrow_forward_iterator _OutputIterator,
229229 __nothrow_sentinel_for<_OutputIterator> _Sentinel>
230230 requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
231 uninitialized_copy_n_result<_InputIterator, _OutputIterator>
231 _LIBCPP_HIDE_FROM_ABI uninitialized_copy_n_result<_InputIterator, _OutputIterator>
232232 operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n,
233233 _OutputIterator __ofirst, _Sentinel __olast) const {
234234 using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
......@@ -257,7 +257,7 @@ struct __fn {
257257 __nothrow_forward_iterator _OutputIterator,
258258 __nothrow_sentinel_for<_OutputIterator> _Sentinel2>
259259 requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>>
260 uninitialized_move_result<_InputIterator, _OutputIterator>
260 _LIBCPP_HIDE_FROM_ABI uninitialized_move_result<_InputIterator, _OutputIterator>
261261 operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
262262 using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
263263 auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); };
......@@ -268,7 +268,7 @@ struct __fn {
268268
269269 template <input_range _InputRange, __nothrow_forward_range _OutputRange>
270270 requires constructible_from<range_value_t<_OutputRange>, range_rvalue_reference_t<_InputRange>>
271 uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
271 _LIBCPP_HIDE_FROM_ABI uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
272272 operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const {
273273 return (*this)(ranges::begin(__in_range), ranges::end(__in_range),
274274 ranges::begin(__out_range), ranges::end(__out_range));
......@@ -293,7 +293,7 @@ struct __fn {
293293 __nothrow_forward_iterator _OutputIterator,
294294 __nothrow_sentinel_for<_OutputIterator> _Sentinel>
295295 requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>>
296 uninitialized_move_n_result<_InputIterator, _OutputIterator>
296 _LIBCPP_HIDE_FROM_ABI uninitialized_move_n_result<_InputIterator, _OutputIterator>
297297 operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n,
298298 _OutputIterator __ofirst, _Sentinel __olast) const {
299299 using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
......@@ -312,7 +312,7 @@ inline namespace __cpo {
312312
313313} // namespace ranges
314314
315#endif // _LIBCPP_STD_VER > 17
315#endif // _LIBCPP_STD_VER >= 20
316316
317317_LIBCPP_END_NAMESPACE_STD
318318
lib/libcxx/include/__memory/raw_storage_iterator.h+1-1
......@@ -39,7 +39,7 @@ private:
3939public:
4040 typedef output_iterator_tag iterator_category;
4141 typedef void value_type;
42#if _LIBCPP_STD_VER > 17
42#if _LIBCPP_STD_VER >= 20
4343 typedef ptrdiff_t difference_type;
4444#else
4545 typedef void difference_type;
lib/libcxx/include/__memory/shared_ptr.h+127-63
......@@ -29,17 +29,32 @@
2929#include <__memory/pointer_traits.h>
3030#include <__memory/uninitialized_algorithms.h>
3131#include <__memory/unique_ptr.h>
32#include <__type_traits/add_lvalue_reference.h>
33#include <__type_traits/conditional.h>
34#include <__type_traits/conjunction.h>
35#include <__type_traits/disjunction.h>
36#include <__type_traits/is_array.h>
37#include <__type_traits/is_bounded_array.h>
38#include <__type_traits/is_convertible.h>
39#include <__type_traits/is_move_constructible.h>
40#include <__type_traits/is_reference.h>
41#include <__type_traits/is_unbounded_array.h>
42#include <__type_traits/nat.h>
43#include <__type_traits/negation.h>
44#include <__type_traits/remove_extent.h>
45#include <__type_traits/remove_reference.h>
46#include <__utility/declval.h>
3247#include <__utility/forward.h>
3348#include <__utility/move.h>
3449#include <__utility/swap.h>
50#include <__verbose_abort>
3551#include <cstddef>
36#include <cstdlib> // abort
3752#include <iosfwd>
3853#include <new>
3954#include <stdexcept>
4055#include <typeinfo>
4156#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
42# include <atomic>
57# include <__atomic/memory_order.h>
4358#endif
4459
4560#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -105,12 +120,12 @@ __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT
105120#endif
106121}
107122
108class _LIBCPP_EXCEPTION_ABI bad_weak_ptr
123class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr
109124 : public std::exception
110125{
111126public:
112 bad_weak_ptr() _NOEXCEPT = default;
113 bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
127 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr() _NOEXCEPT = default;
128 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
114129 ~bad_weak_ptr() _NOEXCEPT override;
115130 const char* what() const _NOEXCEPT override;
116131};
......@@ -118,16 +133,16 @@ public:
118133_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
119134void __throw_bad_weak_ptr()
120135{
121#ifndef _LIBCPP_NO_EXCEPTIONS
136#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
122137 throw bad_weak_ptr();
123138#else
124 _VSTD::abort();
139 _LIBCPP_VERBOSE_ABORT("bad_weak_ptr was thrown in -fno-exceptions mode");
125140#endif
126141}
127142
128143template<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr;
129144
130class _LIBCPP_TYPE_VIS __shared_count
145class _LIBCPP_EXPORTED_FROM_ABI __shared_count
131146{
132147 __shared_count(const __shared_count&);
133148 __shared_count& operator=(const __shared_count&);
......@@ -166,7 +181,7 @@ public:
166181 }
167182};
168183
169class _LIBCPP_TYPE_VIS __shared_weak_count
184class _LIBCPP_EXPORTED_FROM_ABI __shared_weak_count
170185 : private __shared_count
171186{
172187 long __shared_weak_owners_;
......@@ -220,12 +235,12 @@ public:
220235 : __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
221236
222237#ifndef _LIBCPP_HAS_NO_RTTI
223 const void* __get_deleter(const type_info&) const _NOEXCEPT override;
238 _LIBCPP_HIDE_FROM_ABI_VIRTUAL const void* __get_deleter(const type_info&) const _NOEXCEPT override;
224239#endif
225240
226241private:
227 void __on_zero_shared() _NOEXCEPT override;
228 void __on_zero_shared_weak() _NOEXCEPT override;
242 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
243 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override;
229244};
230245
231246#ifndef _LIBCPP_HAS_NO_RTTI
......@@ -295,8 +310,8 @@ struct __shared_ptr_emplace
295310 _Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
296311
297312private:
298 void __on_zero_shared() _NOEXCEPT override {
299#if _LIBCPP_STD_VER > 17
313 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
314#if _LIBCPP_STD_VER >= 20
300315 if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
301316 __get_elem()->~_Tp();
302317 } else {
......@@ -309,7 +324,7 @@ private:
309324#endif
310325 }
311326
312 void __on_zero_shared_weak() _NOEXCEPT override {
327 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
313328 using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;
314329 using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;
315330 _ControlBlockAlloc __tmp(*__get_alloc());
......@@ -336,13 +351,13 @@ private:
336351 _LIBCPP_HIDE_FROM_ABI ~_Storage() {
337352 __get_alloc()->~_Alloc();
338353 }
339 _Alloc* __get_alloc() _NOEXCEPT {
354 _LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT {
340355 _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
341356 typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair);
342357 _Alloc *__alloc = reinterpret_cast<_Alloc*>(__first);
343358 return __alloc;
344359 }
345 _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT {
360 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT {
346361 _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
347362 typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair);
348363 _Tp *__elem = reinterpret_cast<_Tp*>(__second);
......@@ -433,10 +448,10 @@ struct __is_array_deletable<_Ptr, decltype(delete[] std::declval<_Ptr>())> : tru
433448
434449template <class _Dp, class _Pt,
435450 class = decltype(std::declval<_Dp>()(std::declval<_Pt>()))>
436static true_type __well_formed_deleter_test(int);
451true_type __well_formed_deleter_test(int);
437452
438453template <class, class>
439static false_type __well_formed_deleter_test(...);
454false_type __well_formed_deleter_test(...);
440455
441456template <class _Dp, class _Pt>
442457struct __well_formed_deleter : decltype(std::__well_formed_deleter_test<_Dp, _Pt>(0)) {};
......@@ -450,7 +465,7 @@ struct __shared_ptr_deleter_ctor_reqs
450465};
451466
452467#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
453# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
468# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
454469#else
455470# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
456471#endif
......@@ -459,7 +474,7 @@ template<class _Tp>
459474class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
460475{
461476public:
462#if _LIBCPP_STD_VER > 14
477#if _LIBCPP_STD_VER >= 17
463478 typedef weak_ptr<_Tp> weak_type;
464479 typedef remove_extent_t<_Tp> element_type;
465480#else
......@@ -494,7 +509,7 @@ public:
494509#endif
495510 >::value
496511 > >
497 explicit shared_ptr(_Yp* __p) : __ptr_(__p) {
512 _LIBCPP_HIDE_FROM_ABI explicit shared_ptr(_Yp* __p) : __ptr_(__p) {
498513 unique_ptr<_Yp> __hold(__p);
499514 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
500515 typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT> _CntrlBlk;
......@@ -508,10 +523,10 @@ public:
508523 shared_ptr(_Yp* __p, _Dp __d)
509524 : __ptr_(__p)
510525 {
511#ifndef _LIBCPP_NO_EXCEPTIONS
526#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
512527 try
513528 {
514#endif // _LIBCPP_NO_EXCEPTIONS
529#endif // _LIBCPP_HAS_NO_EXCEPTIONS
515530 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
516531 typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT> _CntrlBlk;
517532#ifndef _LIBCPP_CXX03_LANG
......@@ -520,14 +535,14 @@ public:
520535 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
521536#endif // not _LIBCPP_CXX03_LANG
522537 __enable_weak_this(__p, __p);
523#ifndef _LIBCPP_NO_EXCEPTIONS
538#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
524539 }
525540 catch (...)
526541 {
527542 __d(__p);
528543 throw;
529544 }
530#endif // _LIBCPP_NO_EXCEPTIONS
545#endif // _LIBCPP_HAS_NO_EXCEPTIONS
531546 }
532547
533548 template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
......@@ -535,10 +550,10 @@ public:
535550 shared_ptr(_Yp* __p, _Dp __d, _Alloc __a)
536551 : __ptr_(__p)
537552 {
538#ifndef _LIBCPP_NO_EXCEPTIONS
553#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
539554 try
540555 {
541#endif // _LIBCPP_NO_EXCEPTIONS
556#endif // _LIBCPP_HAS_NO_EXCEPTIONS
542557 typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
543558 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
544559 typedef __allocator_destructor<_A2> _D2;
......@@ -552,14 +567,14 @@ public:
552567#endif // not _LIBCPP_CXX03_LANG
553568 __cntrl_ = _VSTD::addressof(*__hold2.release());
554569 __enable_weak_this(__p, __p);
555#ifndef _LIBCPP_NO_EXCEPTIONS
570#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
556571 }
557572 catch (...)
558573 {
559574 __d(__p);
560575 throw;
561576 }
562#endif // _LIBCPP_NO_EXCEPTIONS
577#endif // _LIBCPP_HAS_NO_EXCEPTIONS
563578 }
564579
565580 template<class _Dp>
......@@ -567,10 +582,10 @@ public:
567582 shared_ptr(nullptr_t __p, _Dp __d)
568583 : __ptr_(nullptr)
569584 {
570#ifndef _LIBCPP_NO_EXCEPTIONS
585#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
571586 try
572587 {
573#endif // _LIBCPP_NO_EXCEPTIONS
588#endif // _LIBCPP_HAS_NO_EXCEPTIONS
574589 typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
575590 typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT> _CntrlBlk;
576591#ifndef _LIBCPP_CXX03_LANG
......@@ -578,14 +593,14 @@ public:
578593#else
579594 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
580595#endif // not _LIBCPP_CXX03_LANG
581#ifndef _LIBCPP_NO_EXCEPTIONS
596#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
582597 }
583598 catch (...)
584599 {
585600 __d(__p);
586601 throw;
587602 }
588#endif // _LIBCPP_NO_EXCEPTIONS
603#endif // _LIBCPP_HAS_NO_EXCEPTIONS
589604 }
590605
591606 template<class _Dp, class _Alloc>
......@@ -593,10 +608,10 @@ public:
593608 shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
594609 : __ptr_(nullptr)
595610 {
596#ifndef _LIBCPP_NO_EXCEPTIONS
611#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
597612 try
598613 {
599#endif // _LIBCPP_NO_EXCEPTIONS
614#endif // _LIBCPP_HAS_NO_EXCEPTIONS
600615 typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
601616 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
602617 typedef __allocator_destructor<_A2> _D2;
......@@ -609,14 +624,14 @@ public:
609624 _CntrlBlk(__p, __d, __a);
610625#endif // not _LIBCPP_CXX03_LANG
611626 __cntrl_ = _VSTD::addressof(*__hold2.release());
612#ifndef _LIBCPP_NO_EXCEPTIONS
627#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
613628 }
614629 catch (...)
615630 {
616631 __d(__p);
617632 throw;
618633 }
619#endif // _LIBCPP_NO_EXCEPTIONS
634#endif // _LIBCPP_HAS_NO_EXCEPTIONS
620635 }
621636
622637 template<class _Yp>
......@@ -629,6 +644,18 @@ public:
629644 __cntrl_->__add_shared();
630645 }
631646
647// LWG-2996
648// We don't backport because it is an evolutionary change.
649#if _LIBCPP_STD_VER >= 20
650 template <class _Yp>
651 _LIBCPP_HIDE_FROM_ABI shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept
652 : __ptr_(__p),
653 __cntrl_(__r.__cntrl_) {
654 __r.__ptr_ = nullptr;
655 __r.__cntrl_ = nullptr;
656 }
657#endif
658
632659 _LIBCPP_HIDE_FROM_ABI
633660 shared_ptr(const shared_ptr& __r) _NOEXCEPT
634661 : __ptr_(__r.__ptr_),
......@@ -699,7 +726,7 @@ public:
699726 shared_ptr(unique_ptr<_Yp, _Dp>&& __r)
700727 : __ptr_(__r.get())
701728 {
702#if _LIBCPP_STD_VER > 11
729#if _LIBCPP_STD_VER >= 14
703730 if (__ptr_ == nullptr)
704731 __cntrl_ = nullptr;
705732 else
......@@ -722,7 +749,7 @@ public:
722749 shared_ptr(unique_ptr<_Yp, _Dp>&& __r)
723750 : __ptr_(__r.get())
724751 {
725#if _LIBCPP_STD_VER > 11
752#if _LIBCPP_STD_VER >= 14
726753 if (__ptr_ == nullptr)
727754 __cntrl_ = nullptr;
728755 else
......@@ -895,7 +922,7 @@ public:
895922 return __cntrl_ == __p.__cntrl_;
896923 }
897924
898#if _LIBCPP_STD_VER > 14
925#if _LIBCPP_STD_VER >= 17
899926 _LIBCPP_HIDE_FROM_ABI
900927 __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const
901928 {
......@@ -975,7 +1002,7 @@ private:
9751002 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
9761003};
9771004
978#if _LIBCPP_STD_VER > 14
1005#if _LIBCPP_STD_VER >= 17
9791006template<class _Tp>
9801007shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
9811008template<class _Tp, class _Dp>
......@@ -1024,7 +1051,7 @@ shared_ptr<_Tp> make_shared_for_overwrite()
10241051
10251052#endif // _LIBCPP_STD_VER >= 20
10261053
1027#if _LIBCPP_STD_VER > 14
1054#if _LIBCPP_STD_VER >= 17
10281055
10291056template <size_t _Alignment>
10301057struct __sp_aligned_storage {
......@@ -1084,7 +1111,7 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count
10841111 ~__unbounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
10851112
10861113private:
1087 void __on_zero_shared() _NOEXCEPT override {
1114 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
10881115#if _LIBCPP_STD_VER >= 20
10891116 if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
10901117 std::__reverse_destroy(__data_, __data_ + __count_);
......@@ -1098,7 +1125,7 @@ private:
10981125#endif
10991126 }
11001127
1101 void __on_zero_shared_weak() _NOEXCEPT override {
1128 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
11021129 using _AlignedStorage = __sp_aligned_storage<alignof(__unbounded_array_control_block)>;
11031130 using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>;
11041131 using _PointerTraits = pointer_traits<typename allocator_traits<_StorageAlloc>::pointer>;
......@@ -1170,7 +1197,7 @@ struct __bounded_array_control_block<_Tp[_Count], _Alloc>
11701197 ~__bounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
11711198
11721199private:
1173 void __on_zero_shared() _NOEXCEPT override {
1200 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
11741201#if _LIBCPP_STD_VER >= 20
11751202 if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
11761203 std::__reverse_destroy(__data_, __data_ + _Count);
......@@ -1184,7 +1211,7 @@ private:
11841211#endif
11851212 }
11861213
1187 void __on_zero_shared_weak() _NOEXCEPT override {
1214 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
11881215 using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, __bounded_array_control_block>;
11891216 using _PointerTraits = pointer_traits<typename allocator_traits<_ControlBlockAlloc>::pointer>;
11901217
......@@ -1214,9 +1241,9 @@ shared_ptr<_Array> __allocate_shared_bounded_array(const _Alloc& __a, _Arg&& ...
12141241 return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block);
12151242}
12161243
1217#endif // _LIBCPP_STD_VER > 14
1244#endif // _LIBCPP_STD_VER >= 17
12181245
1219#if _LIBCPP_STD_VER > 17
1246#if _LIBCPP_STD_VER >= 20
12201247
12211248// bounded array variants
12221249template<class _Tp, class _Alloc, class = __enable_if_t<is_bounded_array<_Tp>::value>>
......@@ -1308,7 +1335,7 @@ shared_ptr<_Tp> make_shared_for_overwrite(size_t __n)
13081335 return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n);
13091336}
13101337
1311#endif // _LIBCPP_STD_VER > 17
1338#endif // _LIBCPP_STD_VER >= 20
13121339
13131340template<class _Tp, class _Up>
13141341inline _LIBCPP_INLINE_VISIBILITY
......@@ -1368,7 +1395,7 @@ operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
13681395
13691396#endif // _LIBCPP_STD_VER <= 17
13701397
1371#if _LIBCPP_STD_VER > 17
1398#if _LIBCPP_STD_VER >= 20
13721399template<class _Tp, class _Up>
13731400_LIBCPP_HIDE_FROM_ABI strong_ordering
13741401operator<=>(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) noexcept
......@@ -1477,7 +1504,7 @@ operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
14771504
14781505#endif // _LIBCPP_STD_VER <= 17
14791506
1480#if _LIBCPP_STD_VER > 17
1507#if _LIBCPP_STD_VER >= 20
14811508template<class _Tp>
14821509_LIBCPP_HIDE_FROM_ABI strong_ordering
14831510operator<=>(shared_ptr<_Tp> const& __x, nullptr_t) noexcept
......@@ -1504,6 +1531,15 @@ static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
15041531 typename shared_ptr<_Tp>::element_type*>(__r.get()));
15051532}
15061533
1534// LWG-2996
1535// We don't backport because it is an evolutionary change.
1536#if _LIBCPP_STD_VER >= 20
1537template <class _Tp, class _Up>
1538_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
1539 return shared_ptr<_Tp>(std::move(__r), static_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
1540}
1541#endif
1542
15071543template<class _Tp, class _Up>
15081544inline _LIBCPP_INLINE_VISIBILITY
15091545shared_ptr<_Tp>
......@@ -1514,6 +1550,16 @@ dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
15141550 return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
15151551}
15161552
1553// LWG-2996
1554// We don't backport because it is an evolutionary change.
1555#if _LIBCPP_STD_VER >= 20
1556template <class _Tp, class _Up>
1557_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
1558 auto* __p = dynamic_cast<typename shared_ptr<_Tp>::element_type*>(__r.get());
1559 return __p ? shared_ptr<_Tp>(std::move(__r), __p) : shared_ptr<_Tp>();
1560}
1561#endif
1562
15171563template<class _Tp, class _Up>
15181564_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
15191565const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
......@@ -1522,6 +1568,15 @@ const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
15221568 return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
15231569}
15241570
1571// LWG-2996
1572// We don't backport because it is an evolutionary change.
1573#if _LIBCPP_STD_VER >= 20
1574template <class _Tp, class _Up>
1575_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
1576 return shared_ptr<_Tp>(std::move(__r), const_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
1577}
1578#endif
1579
15251580template<class _Tp, class _Up>
15261581_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
15271582reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
......@@ -1531,6 +1586,15 @@ reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
15311586 typename shared_ptr<_Tp>::element_type*>(__r.get()));
15321587}
15331588
1589// LWG-2996
1590// We don't backport because it is an evolutionary change.
1591#if _LIBCPP_STD_VER >= 20
1592template <class _Tp, class _Up>
1593_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
1594 return shared_ptr<_Tp>(std::move(__r), reinterpret_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
1595}
1596#endif
1597
15341598#ifndef _LIBCPP_HAS_NO_RTTI
15351599
15361600template<class _Dp, class _Tp>
......@@ -1547,7 +1611,7 @@ template<class _Tp>
15471611class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
15481612{
15491613public:
1550#if _LIBCPP_STD_VER > 14
1614#if _LIBCPP_STD_VER >= 17
15511615 typedef remove_extent_t<_Tp> element_type;
15521616#else
15531617 typedef _Tp element_type;
......@@ -1574,7 +1638,7 @@ public:
15741638 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r,
15751639 typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type = 0)
15761640 _NOEXCEPT;
1577 ~weak_ptr();
1641 _LIBCPP_HIDE_FROM_ABI ~weak_ptr();
15781642
15791643 _LIBCPP_INLINE_VISIBILITY
15801644 weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
......@@ -1618,7 +1682,7 @@ public:
16181682 _LIBCPP_INLINE_VISIBILITY
16191683 bool expired() const _NOEXCEPT
16201684 {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;}
1621 shared_ptr<_Tp> lock() const _NOEXCEPT;
1685 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT;
16221686 template<class _Up>
16231687 _LIBCPP_INLINE_VISIBILITY
16241688 bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT
......@@ -1632,7 +1696,7 @@ public:
16321696 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
16331697};
16341698
1635#if _LIBCPP_STD_VER > 14
1699#if _LIBCPP_STD_VER >= 17
16361700template<class _Tp>
16371701weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
16381702#endif
......@@ -1808,7 +1872,7 @@ weak_ptr<_Tp>::lock() const _NOEXCEPT
18081872 return __r;
18091873}
18101874
1811#if _LIBCPP_STD_VER > 14
1875#if _LIBCPP_STD_VER >= 17
18121876template <class _Tp = void> struct owner_less;
18131877#else
18141878template <class _Tp> struct owner_less;
......@@ -1845,7 +1909,7 @@ struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> >
18451909 {return __x.owner_before(__y);}
18461910};
18471911
1848#if _LIBCPP_STD_VER > 14
1912#if _LIBCPP_STD_VER >= 17
18491913template <>
18501914struct _LIBCPP_TEMPLATE_VIS owner_less<void>
18511915{
......@@ -1891,7 +1955,7 @@ public:
18911955 shared_ptr<_Tp const> shared_from_this() const
18921956 {return shared_ptr<const _Tp>(__weak_this_);}
18931957
1894#if _LIBCPP_STD_VER > 14
1958#if _LIBCPP_STD_VER >= 17
18951959 _LIBCPP_INLINE_VISIBILITY
18961960 weak_ptr<_Tp> weak_from_this() _NOEXCEPT
18971961 { return __weak_this_; }
......@@ -1899,7 +1963,7 @@ public:
18991963 _LIBCPP_INLINE_VISIBILITY
19001964 weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
19011965 { return __weak_this_; }
1902#endif // _LIBCPP_STD_VER > 14
1966#endif // _LIBCPP_STD_VER >= 17
19031967
19041968 template <class _Up> friend class shared_ptr;
19051969};
......@@ -1929,7 +1993,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
19291993
19301994#if !defined(_LIBCPP_HAS_NO_THREADS)
19311995
1932class _LIBCPP_TYPE_VIS __sp_mut
1996class _LIBCPP_EXPORTED_FROM_ABI __sp_mut
19331997{
19341998 void* __lx_;
19351999public:
......@@ -1941,10 +2005,10 @@ private:
19412005 __sp_mut(const __sp_mut&);
19422006 __sp_mut& operator=(const __sp_mut&);
19432007
1944 friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
2008 friend _LIBCPP_EXPORTED_FROM_ABI __sp_mut& __get_sp_mut(const void*);
19452009};
19462010
1947_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2011_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
19482012__sp_mut& __get_sp_mut(const void*);
19492013
19502014template <class _Tp>
lib/libcxx/include/__memory/swap_allocator.h+2-2
......@@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2323
2424template <typename _Alloc>
2525_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __swap_allocator(_Alloc& __a1, _Alloc& __a2, true_type)
26#if _LIBCPP_STD_VER > 11
26#if _LIBCPP_STD_VER >= 14
2727 _NOEXCEPT
2828#else
2929 _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
......@@ -39,7 +39,7 @@ __swap_allocator(_Alloc&, _Alloc&, false_type) _NOEXCEPT {}
3939
4040template <typename _Alloc>
4141inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __swap_allocator(_Alloc& __a1, _Alloc& __a2)
42#if _LIBCPP_STD_VER > 11
42#if _LIBCPP_STD_VER >= 14
4343 _NOEXCEPT
4444#else
4545 _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
lib/libcxx/include/__memory/temp_value.h+4-4
......@@ -32,7 +32,7 @@ struct __temp_value {
3232#endif
3333 _Alloc &__a;
3434
35 _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp *__addr() {
35 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp *__addr() {
3636#ifdef _LIBCPP_CXX03_LANG
3737 return reinterpret_cast<_Tp*>(std::addressof(__v));
3838#else
......@@ -40,15 +40,15 @@ struct __temp_value {
4040#endif
4141 }
4242
43 _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp & get() { return *__addr(); }
43 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp & get() { return *__addr(); }
4444
4545 template<class... _Args>
46 _LIBCPP_NO_CFI
46 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI
4747 _LIBCPP_CONSTEXPR_SINCE_CXX20 __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) {
4848 _Traits::construct(__a, __addr(), std::forward<_Args>(__args)...);
4949 }
5050
51 _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__temp_value() { _Traits::destroy(__a, __addr()); }
51 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__temp_value() { _Traits::destroy(__a, __addr()); }
5252};
5353
5454_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__memory/uninitialized_algorithms.h+44-33
......@@ -12,6 +12,8 @@
1212
1313#include <__algorithm/copy.h>
1414#include <__algorithm/move.h>
15#include <__algorithm/unwrap_iter.h>
16#include <__algorithm/unwrap_range.h>
1517#include <__config>
1618#include <__iterator/iterator_traits.h>
1719#include <__iterator/reverse_iterator.h>
......@@ -58,12 +60,12 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator>
5860__uninitialized_copy(_InputIterator __ifirst, _Sentinel1 __ilast,
5961 _ForwardIterator __ofirst, _Sentinel2 __olast) {
6062 _ForwardIterator __idx = __ofirst;
61#ifndef _LIBCPP_NO_EXCEPTIONS
63#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
6264 try {
6365#endif
6466 for (; __ifirst != __ilast && __idx != __olast; ++__ifirst, (void)++__idx)
6567 ::new (_VSTD::__voidify(*__idx)) _ValueType(*__ifirst);
66#ifndef _LIBCPP_NO_EXCEPTIONS
68#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
6769 } catch (...) {
6870 _VSTD::__destroy(__ofirst, __idx);
6971 throw;
......@@ -90,12 +92,12 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator>
9092__uninitialized_copy_n(_InputIterator __ifirst, _Size __n,
9193 _ForwardIterator __ofirst, _Sentinel __olast) {
9294 _ForwardIterator __idx = __ofirst;
93#ifndef _LIBCPP_NO_EXCEPTIONS
95#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
9496 try {
9597#endif
9698 for (; __n > 0 && __idx != __olast; ++__ifirst, (void)++__idx, (void)--__n)
9799 ::new (_VSTD::__voidify(*__idx)) _ValueType(*__ifirst);
98#ifndef _LIBCPP_NO_EXCEPTIONS
100#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
99101 } catch (...) {
100102 _VSTD::__destroy(__ofirst, __idx);
101103 throw;
......@@ -121,13 +123,13 @@ inline _LIBCPP_HIDE_FROM_ABI
121123_ForwardIterator __uninitialized_fill(_ForwardIterator __first, _Sentinel __last, const _Tp& __x)
122124{
123125 _ForwardIterator __idx = __first;
124#ifndef _LIBCPP_NO_EXCEPTIONS
126#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
125127 try
126128 {
127129#endif
128130 for (; __idx != __last; ++__idx)
129131 ::new (_VSTD::__voidify(*__idx)) _ValueType(__x);
130#ifndef _LIBCPP_NO_EXCEPTIONS
132#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
131133 }
132134 catch (...)
133135 {
......@@ -154,13 +156,13 @@ inline _LIBCPP_HIDE_FROM_ABI
154156_ForwardIterator __uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
155157{
156158 _ForwardIterator __idx = __first;
157#ifndef _LIBCPP_NO_EXCEPTIONS
159#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
158160 try
159161 {
160162#endif
161163 for (; __n > 0; ++__idx, (void) --__n)
162164 ::new (_VSTD::__voidify(*__idx)) _ValueType(__x);
163#ifndef _LIBCPP_NO_EXCEPTIONS
165#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
164166 }
165167 catch (...)
166168 {
......@@ -180,7 +182,7 @@ _ForwardIterator uninitialized_fill_n(_ForwardIterator __first, _Size __n, const
180182 return _VSTD::__uninitialized_fill_n<_ValueType>(__first, __n, __x);
181183}
182184
183#if _LIBCPP_STD_VER > 14
185#if _LIBCPP_STD_VER >= 17
184186
185187// uninitialized_default_construct
186188
......@@ -188,12 +190,12 @@ template <class _ValueType, class _ForwardIterator, class _Sentinel>
188190inline _LIBCPP_HIDE_FROM_ABI
189191_ForwardIterator __uninitialized_default_construct(_ForwardIterator __first, _Sentinel __last) {
190192 auto __idx = __first;
191#ifndef _LIBCPP_NO_EXCEPTIONS
193#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
192194 try {
193195#endif
194196 for (; __idx != __last; ++__idx)
195197 ::new (_VSTD::__voidify(*__idx)) _ValueType;
196#ifndef _LIBCPP_NO_EXCEPTIONS
198#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
197199 } catch (...) {
198200 _VSTD::__destroy(__first, __idx);
199201 throw;
......@@ -217,12 +219,12 @@ template <class _ValueType, class _ForwardIterator, class _Size>
217219inline _LIBCPP_HIDE_FROM_ABI
218220_ForwardIterator __uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
219221 auto __idx = __first;
220#ifndef _LIBCPP_NO_EXCEPTIONS
222#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
221223 try {
222224#endif
223225 for (; __n > 0; ++__idx, (void) --__n)
224226 ::new (_VSTD::__voidify(*__idx)) _ValueType;
225#ifndef _LIBCPP_NO_EXCEPTIONS
227#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
226228 } catch (...) {
227229 _VSTD::__destroy(__first, __idx);
228230 throw;
......@@ -245,12 +247,12 @@ template <class _ValueType, class _ForwardIterator, class _Sentinel>
245247inline _LIBCPP_HIDE_FROM_ABI
246248_ForwardIterator __uninitialized_value_construct(_ForwardIterator __first, _Sentinel __last) {
247249 auto __idx = __first;
248#ifndef _LIBCPP_NO_EXCEPTIONS
250#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
249251 try {
250252#endif
251253 for (; __idx != __last; ++__idx)
252254 ::new (_VSTD::__voidify(*__idx)) _ValueType();
253#ifndef _LIBCPP_NO_EXCEPTIONS
255#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
254256 } catch (...) {
255257 _VSTD::__destroy(__first, __idx);
256258 throw;
......@@ -274,12 +276,12 @@ template <class _ValueType, class _ForwardIterator, class _Size>
274276inline _LIBCPP_HIDE_FROM_ABI
275277_ForwardIterator __uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
276278 auto __idx = __first;
277#ifndef _LIBCPP_NO_EXCEPTIONS
279#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
278280 try {
279281#endif
280282 for (; __n > 0; ++__idx, (void) --__n)
281283 ::new (_VSTD::__voidify(*__idx)) _ValueType();
282#ifndef _LIBCPP_NO_EXCEPTIONS
284#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
283285 } catch (...) {
284286 _VSTD::__destroy(__first, __idx);
285287 throw;
......@@ -304,13 +306,13 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator>
304306__uninitialized_move(_InputIterator __ifirst, _Sentinel1 __ilast,
305307 _ForwardIterator __ofirst, _Sentinel2 __olast, _IterMove __iter_move) {
306308 auto __idx = __ofirst;
307#ifndef _LIBCPP_NO_EXCEPTIONS
309#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
308310 try {
309311#endif
310312 for (; __ifirst != __ilast && __idx != __olast; ++__idx, (void)++__ifirst) {
311313 ::new (_VSTD::__voidify(*__idx)) _ValueType(__iter_move(__ifirst));
312314 }
313#ifndef _LIBCPP_NO_EXCEPTIONS
315#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
314316 } catch (...) {
315317 _VSTD::__destroy(__ofirst, __idx);
316318 throw;
......@@ -338,12 +340,12 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator>
338340__uninitialized_move_n(_InputIterator __ifirst, _Size __n,
339341 _ForwardIterator __ofirst, _Sentinel __olast, _IterMove __iter_move) {
340342 auto __idx = __ofirst;
341#ifndef _LIBCPP_NO_EXCEPTIONS
343#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
342344 try {
343345#endif
344346 for (; __n > 0 && __idx != __olast; ++__idx, (void)++__ifirst, --__n)
345347 ::new (_VSTD::__voidify(*__idx)) _ValueType(__iter_move(__ifirst));
346#ifndef _LIBCPP_NO_EXCEPTIONS
348#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
347349 } catch (...) {
348350 _VSTD::__destroy(__ofirst, __idx);
349351 throw;
......@@ -371,7 +373,7 @@ uninitialized_move_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __ofir
371373// This function assumes that destructors do not throw, and that the allocator is bound to
372374// the correct type.
373375template<class _Alloc, class _BidirIter, class = __enable_if_t<
374 __is_cpp17_bidirectional_iterator<_BidirIter>::value
376 __has_bidirectional_iterator_category<_BidirIter>::value
375377>>
376378_LIBCPP_HIDE_FROM_ABI
377379constexpr void __allocator_destroy_multidimensional(_Alloc& __alloc, _BidirIter __first, _BidirIter __last) noexcept {
......@@ -512,7 +514,7 @@ __uninitialized_allocator_value_construct_n_multidimensional(_Alloc& __alloc, _B
512514 __guard.__complete();
513515}
514516
515#endif // _LIBCPP_STD_VER > 14
517#endif // _LIBCPP_STD_VER >= 17
516518
517519// Destroy all elements in [__first, __last) from left to right using allocator destruction.
518520template <class _Alloc, class _Iter, class _Sent>
......@@ -545,7 +547,7 @@ private:
545547// already copied elements are destroyed in reverse order of their construction.
546548template <class _Alloc, class _Iter1, class _Sent1, class _Iter2>
547549_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2
548__uninitialized_allocator_copy(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
550__uninitialized_allocator_copy_impl(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
549551 auto __destruct_first = __first2;
550552 auto __guard =
551553 std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2));
......@@ -565,14 +567,16 @@ template <class _Type>
565567struct __allocator_has_trivial_copy_construct<allocator<_Type>, _Type> : true_type {};
566568
567569template <class _Alloc,
568 class _Type,
569 class _RawType = __remove_const_t<_Type>,
570 class _In,
571 class _RawTypeIn = __remove_const_t<_In>,
572 class _Out,
570573 __enable_if_t<
571 // using _RawType because of the allocator<T const> extension
572 is_trivially_copy_constructible<_RawType>::value && is_trivially_copy_assignable<_RawType>::value &&
573 __allocator_has_trivial_copy_construct<_Alloc, _RawType>::value>* = nullptr>
574_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Type*
575__uninitialized_allocator_copy(_Alloc&, const _Type* __first1, const _Type* __last1, _Type* __first2) {
574 // using _RawTypeIn because of the allocator<T const> extension
575 is_trivially_copy_constructible<_RawTypeIn>::value && is_trivially_copy_assignable<_RawTypeIn>::value &&
576 is_same<__remove_const_t<_In>, __remove_const_t<_Out> >::value &&
577 __allocator_has_trivial_copy_construct<_Alloc, _RawTypeIn>::value>* = nullptr>
578_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Out*
579__uninitialized_allocator_copy_impl(_Alloc&, _In* __first1, _In* __last1, _Out* __first2) {
576580 // TODO: Remove the const_cast once we drop support for std::allocator<T const>
577581 if (__libcpp_is_constant_evaluated()) {
578582 while (__first1 != __last1) {
......@@ -582,10 +586,17 @@ __uninitialized_allocator_copy(_Alloc&, const _Type* __first1, const _Type* __la
582586 }
583587 return __first2;
584588 } else {
585 return std::copy(__first1, __last1, const_cast<_RawType*>(__first2));
589 return std::copy(__first1, __last1, const_cast<_RawTypeIn*>(__first2));
586590 }
587591}
588592
593template <class _Alloc, class _Iter1, class _Sent1, class _Iter2>
594_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2 __uninitialized_allocator_copy(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
595 auto __unwrapped_range = std::__unwrap_range(__first1, __last1);
596 auto __result = std::__uninitialized_allocator_copy_impl(__alloc, __unwrapped_range.first, __unwrapped_range.second, std::__unwrap_iter(__first2));
597 return std::__rewrap_iter(__first2, __result);
598}
599
589600// Move-construct the elements [__first1, __last1) into [__first2, __first2 + N)
590601// if the move constructor is noexcept, where N is distance(__first1, __last1).
591602//
......@@ -600,7 +611,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2 __uninitialized_alloc
600611 auto __guard =
601612 std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2));
602613 while (__first1 != __last1) {
603#ifndef _LIBCPP_NO_EXCEPTIONS
614#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
604615 allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), std::move_if_noexcept(*__first1));
605616#else
606617 allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), std::move(*__first1));
lib/libcxx/include/__memory/unique_ptr.h+10-5
......@@ -44,6 +44,9 @@
4444# pragma GCC system_header
4545#endif
4646
47_LIBCPP_PUSH_MACROS
48#include <__undef_macros>
49
4750_LIBCPP_BEGIN_NAMESPACE_STD
4851
4952template <class _Tp>
......@@ -115,7 +118,7 @@ struct __unique_ptr_deleter_sfinae<_Deleter&> {
115118};
116119
117120#if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
118# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
121# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
119122#else
120123# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
121124#endif
......@@ -556,7 +559,7 @@ bool
556559operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
557560
558561
559#if _LIBCPP_STD_VER > 17
562#if _LIBCPP_STD_VER >= 20
560563template <class _T1, class _D1, class _T2, class _D2>
561564requires three_way_comparable_with<typename unique_ptr<_T1, _D1>::pointer,
562565 typename unique_ptr<_T2, _D2>::pointer>
......@@ -650,7 +653,7 @@ operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
650653 return !(nullptr < __x);
651654}
652655
653#if _LIBCPP_STD_VER > 17
656#if _LIBCPP_STD_VER >= 20
654657template <class _T1, class _D1>
655658 requires three_way_comparable<
656659 typename unique_ptr<_T1, _D1>::pointer> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
......@@ -660,7 +663,7 @@ operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
660663}
661664#endif
662665
663#if _LIBCPP_STD_VER > 11
666#if _LIBCPP_STD_VER >= 14
664667
665668template<class _Tp>
666669struct __unique_if
......@@ -697,7 +700,7 @@ template<class _Tp, class... _Args>
697700 typename __unique_if<_Tp>::__unique_array_known_bound
698701 make_unique(_Args&&...) = delete;
699702
700#endif // _LIBCPP_STD_VER > 11
703#endif // _LIBCPP_STD_VER >= 14
701704
702705#if _LIBCPP_STD_VER >= 20
703706
......@@ -743,4 +746,6 @@ struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
743746
744747_LIBCPP_END_NAMESPACE_STD
745748
749_LIBCPP_POP_MACROS
750
746751#endif // _LIBCPP___MEMORY_UNIQUE_PTR_H
lib/libcxx/include/__memory/uses_allocator.h+2-2
......@@ -49,9 +49,9 @@ struct _LIBCPP_TEMPLATE_VIS uses_allocator
4949{
5050};
5151
52#if _LIBCPP_STD_VER > 14
52#if _LIBCPP_STD_VER >= 17
5353template <class _Tp, class _Alloc>
54inline constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value;
54inline constexpr bool uses_allocator_v = uses_allocator<_Tp, _Alloc>::value;
5555#endif
5656
5757_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__memory/uses_allocator_construction.h+7-2
......@@ -23,6 +23,9 @@
2323# pragma GCC system_header
2424#endif
2525
26_LIBCPP_PUSH_MACROS
27#include <__undef_macros>
28
2629_LIBCPP_BEGIN_NAMESPACE_STD
2730
2831#if _LIBCPP_STD_VER >= 17
......@@ -83,7 +86,7 @@ __uses_allocator_construction_args(const _Alloc& __alloc, _Up&& __u, _Vp&& __v)
8386 std::forward_as_tuple(std::forward<_Vp>(__v)));
8487}
8588
86# if _LIBCPP_STD_VER > 20
89# if _LIBCPP_STD_VER >= 23
8790template <class _Pair, class _Alloc, class _Up, class _Vp, __enable_if_t<__is_std_pair<_Pair>, int> = 0>
8891_LIBCPP_HIDE_FROM_ABI constexpr auto
8992__uses_allocator_construction_args(const _Alloc& __alloc, pair<_Up, _Vp>& __pair) noexcept {
......@@ -109,7 +112,7 @@ __uses_allocator_construction_args(const _Alloc& __alloc, pair<_Up, _Vp>&& __pai
109112 std::forward_as_tuple(std::get<1>(std::move(__pair))));
110113}
111114
112# if _LIBCPP_STD_VER > 20
115# if _LIBCPP_STD_VER >= 23
113116template <class _Pair, class _Alloc, class _Up, class _Vp, __enable_if_t<__is_std_pair<_Pair>, int> = 0>
114117_LIBCPP_HIDE_FROM_ABI constexpr auto
115118__uses_allocator_construction_args(const _Alloc& __alloc, const pair<_Up, _Vp>&& __pair) noexcept {
......@@ -218,4 +221,6 @@ uninitialized_construct_using_allocator(_Type* __ptr, const _Alloc& __alloc, _Ar
218221
219222_LIBCPP_END_NAMESPACE_STD
220223
224_LIBCPP_POP_MACROS
225
221226#endif // _LIBCPP___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H
lib/libcxx/include/__memory_resource/memory_resource.h+24-9
......@@ -9,14 +9,16 @@
99#ifndef _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H
1010#define _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H
1111
12#include <__availability>
1213#include <__config>
14#include <__fwd/memory_resource.h>
1315#include <cstddef>
1416
1517#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1618# pragma GCC system_header
1719#endif
1820
19#if _LIBCPP_STD_VER > 14
21#if _LIBCPP_STD_VER >= 17
2022
2123_LIBCPP_BEGIN_NAMESPACE_STD
2224
......@@ -24,7 +26,7 @@ namespace pmr {
2426
2527// [mem.res.class]
2628
27class _LIBCPP_TYPE_VIS memory_resource {
29class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource {
2830 static const size_t __max_align = alignof(max_align_t);
2931
3032public:
......@@ -51,25 +53,38 @@ private:
5153
5254// [mem.res.eq]
5355
54inline _LIBCPP_HIDE_FROM_ABI bool operator==(const memory_resource& __lhs, const memory_resource& __rhs) noexcept {
56inline _LIBCPP_AVAILABILITY_PMR _LIBCPP_HIDE_FROM_ABI bool
57operator==(const memory_resource& __lhs, const memory_resource& __rhs) noexcept {
5558 return &__lhs == &__rhs || __lhs.is_equal(__rhs);
5659}
5760
58inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const memory_resource& __lhs, const memory_resource& __rhs) noexcept {
61# if _LIBCPP_STD_VER <= 17
62
63inline _LIBCPP_AVAILABILITY_PMR _LIBCPP_HIDE_FROM_ABI bool
64operator!=(const memory_resource& __lhs, const memory_resource& __rhs) noexcept {
5965 return !(__lhs == __rhs);
6066}
6167
68# endif
69
6270// [mem.res.global]
6371
64[[__gnu__::__returns_nonnull__]] _LIBCPP_FUNC_VIS memory_resource* get_default_resource() noexcept;
65[[__gnu__::__returns_nonnull__]] _LIBCPP_FUNC_VIS memory_resource* set_default_resource(memory_resource*) noexcept;
66[[using __gnu__: __returns_nonnull__, __const__]] _LIBCPP_FUNC_VIS memory_resource* new_delete_resource() noexcept;
67[[using __gnu__: __returns_nonnull__, __const__]] _LIBCPP_FUNC_VIS memory_resource* null_memory_resource() noexcept;
72[[__gnu__::__returns_nonnull__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource*
73get_default_resource() noexcept;
74
75[[__gnu__::__returns_nonnull__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource*
76set_default_resource(memory_resource*) noexcept;
77
78[[using __gnu__: __returns_nonnull__, __const__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource*
79new_delete_resource() noexcept;
80
81[[using __gnu__: __returns_nonnull__, __const__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource*
82null_memory_resource() noexcept;
6883
6984} // namespace pmr
7085
7186_LIBCPP_END_NAMESPACE_STD
7287
73#endif // _LIBCPP_STD_VER > 14
88#endif // _LIBCPP_STD_VER >= 17
7489
7590#endif // _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H
lib/libcxx/include/__memory_resource/monotonic_buffer_resource.h+7-4
......@@ -9,6 +9,7 @@
99#ifndef _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H
1010#define _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H
1111
12#include <__availability>
1213#include <__config>
1314#include <__memory/addressof.h>
1415#include <__memory_resource/memory_resource.h>
......@@ -18,7 +19,7 @@
1819# pragma GCC system_header
1920#endif
2021
21#if _LIBCPP_STD_VER > 14
22#if _LIBCPP_STD_VER >= 17
2223
2324_LIBCPP_BEGIN_NAMESPACE_STD
2425
......@@ -26,7 +27,7 @@ namespace pmr {
2627
2728// [mem.res.monotonic.buffer]
2829
29class _LIBCPP_TYPE_VIS monotonic_buffer_resource : public memory_resource {
30class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI monotonic_buffer_resource : public memory_resource {
3031 static const size_t __default_buffer_capacity = 1024;
3132 static const size_t __default_buffer_alignment = 16;
3233
......@@ -35,7 +36,9 @@ class _LIBCPP_TYPE_VIS monotonic_buffer_resource : public memory_resource {
3536 char* __start_;
3637 char* __cur_;
3738 size_t __align_;
38 size_t __allocation_size() { return (reinterpret_cast<char*>(this) - __start_) + sizeof(*this); }
39 _LIBCPP_HIDE_FROM_ABI size_t __allocation_size() {
40 return (reinterpret_cast<char*>(this) - __start_) + sizeof(*this);
41 }
3942 void* __try_allocate_from_chunk(size_t, size_t);
4043 };
4144
......@@ -115,6 +118,6 @@ private:
115118
116119_LIBCPP_END_NAMESPACE_STD
117120
118#endif // _LIBCPP_STD_VER > 14
121#endif // _LIBCPP_STD_VER >= 17
119122
120123#endif // _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H
lib/libcxx/include/__memory_resource/polymorphic_allocator.h+16-11
......@@ -10,6 +10,7 @@
1010#define _LIBCPP___MEMORY_RESOURCE_POLYMORPHIC_ALLOCATOR_H
1111
1212#include <__assert>
13#include <__availability>
1314#include <__config>
1415#include <__memory_resource/memory_resource.h>
1516#include <__utility/exception_guard.h>
......@@ -26,7 +27,7 @@
2627_LIBCPP_PUSH_MACROS
2728#include <__undef_macros>
2829
29#if _LIBCPP_STD_VER > 14
30#if _LIBCPP_STD_VER >= 17
3031
3132_LIBCPP_BEGIN_NAMESPACE_STD
3233
......@@ -39,7 +40,7 @@ template <class _ValueType
3940 = byte
4041# endif
4142 >
42class _LIBCPP_TEMPLATE_VIS polymorphic_allocator {
43class _LIBCPP_AVAILABILITY_PMR _LIBCPP_TEMPLATE_VIS polymorphic_allocator {
4344
4445public:
4546 using value_type = _ValueType;
......@@ -50,7 +51,7 @@ public:
5051
5152 _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(memory_resource* __r) noexcept : __res_(__r) {}
5253
53 polymorphic_allocator(const polymorphic_allocator&) = default;
54 _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(const polymorphic_allocator&) = default;
5455
5556 template <class _Tp>
5657 _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(const polymorphic_allocator<_Tp>& __other) noexcept
......@@ -68,35 +69,35 @@ public:
6869 }
6970
7071 _LIBCPP_HIDE_FROM_ABI void deallocate(_ValueType* __p, size_t __n) {
71 _LIBCPP_ASSERT(__n <= __max_size(), "deallocate called for size which exceeds max_size()");
72 _LIBCPP_ASSERT_UNCATEGORIZED(__n <= __max_size(), "deallocate called for size which exceeds max_size()");
7273 __res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType));
7374 }
7475
7576# if _LIBCPP_STD_VER >= 20
7677
77 [[nodiscard]] [[using __gnu__: __alloc_size__(2), __alloc_align__(3)]] void*
78 [[nodiscard]] [[using __gnu__: __alloc_size__(2), __alloc_align__(3)]] _LIBCPP_HIDE_FROM_ABI void*
7879 allocate_bytes(size_t __nbytes, size_t __alignment = alignof(max_align_t)) {
7980 return __res_->allocate(__nbytes, __alignment);
8081 }
8182
82 void deallocate_bytes(void* __ptr, size_t __nbytes, size_t __alignment = alignof(max_align_t)) {
83 _LIBCPP_HIDE_FROM_ABI void deallocate_bytes(void* __ptr, size_t __nbytes, size_t __alignment = alignof(max_align_t)) {
8384 __res_->deallocate(__ptr, __nbytes, __alignment);
8485 }
8586
8687 template <class _Type>
87 [[nodiscard]] _Type* allocate_object(size_t __n = 1) {
88 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Type* allocate_object(size_t __n = 1) {
8889 if (numeric_limits<size_t>::max() / sizeof(_Type) < __n)
8990 std::__throw_bad_array_new_length();
9091 return static_cast<_Type*>(allocate_bytes(__n * sizeof(_Type), alignof(_Type)));
9192 }
9293
9394 template <class _Type>
94 void deallocate_object(_Type* __ptr, size_t __n = 1) {
95 _LIBCPP_HIDE_FROM_ABI void deallocate_object(_Type* __ptr, size_t __n = 1) {
9596 deallocate_bytes(__ptr, __n * sizeof(_Type), alignof(_Type));
9697 }
9798
9899 template <class _Type, class... _CtorArgs>
99 [[nodiscard]] _Type* new_object(_CtorArgs&&... __ctor_args) {
100 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Type* new_object(_CtorArgs&&... __ctor_args) {
100101 _Type* __ptr = allocate_object<_Type>();
101102 auto __guard = std::__make_exception_guard([&] { deallocate_object(__ptr); });
102103 construct(__ptr, std::forward<_CtorArgs>(__ctor_args)...);
......@@ -105,7 +106,7 @@ public:
105106 }
106107
107108 template <class _Type>
108 void delete_object(_Type* __ptr) {
109 _LIBCPP_HIDE_FROM_ABI void delete_object(_Type* __ptr) {
109110 destroy(__ptr);
110111 deallocate_object(__ptr);
111112 }
......@@ -207,17 +208,21 @@ operator==(const polymorphic_allocator<_Tp>& __lhs, const polymorphic_allocator<
207208 return *__lhs.resource() == *__rhs.resource();
208209}
209210
211# if _LIBCPP_STD_VER <= 17
212
210213template <class _Tp, class _Up>
211214inline _LIBCPP_HIDE_FROM_ABI bool
212215operator!=(const polymorphic_allocator<_Tp>& __lhs, const polymorphic_allocator<_Up>& __rhs) noexcept {
213216 return !(__lhs == __rhs);
214217}
215218
219# endif
220
216221} // namespace pmr
217222
218223_LIBCPP_END_NAMESPACE_STD
219224
220#endif // _LIBCPP_STD_VER > 14
225#endif // _LIBCPP_STD_VER >= 17
221226
222227_LIBCPP_POP_MACROS
223228
lib/libcxx/include/__memory_resource/pool_options.h+3-3
......@@ -16,7 +16,7 @@
1616# pragma GCC system_header
1717#endif
1818
19#if _LIBCPP_STD_VER > 14
19#if _LIBCPP_STD_VER >= 17
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
......@@ -24,7 +24,7 @@ namespace pmr {
2424
2525// [mem.res.pool.options]
2626
27struct _LIBCPP_TYPE_VIS pool_options {
27struct _LIBCPP_EXPORTED_FROM_ABI pool_options {
2828 size_t max_blocks_per_chunk = 0;
2929 size_t largest_required_pool_block = 0;
3030};
......@@ -33,6 +33,6 @@ struct _LIBCPP_TYPE_VIS pool_options {
3333
3434_LIBCPP_END_NAMESPACE_STD
3535
36#endif // _LIBCPP_STD_VER > 14
36#endif // _LIBCPP_STD_VER >= 17
3737
3838#endif // _LIBCPP___MEMORY_RESOURCE_POOL_OPTIONS_H
lib/libcxx/include/__memory_resource/synchronized_pool_resource.h+6-7
......@@ -9,20 +9,19 @@
99#ifndef _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H
1010#define _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H
1111
12#include <__availability>
1213#include <__config>
1314#include <__memory_resource/memory_resource.h>
1415#include <__memory_resource/pool_options.h>
1516#include <__memory_resource/unsynchronized_pool_resource.h>
1617#include <cstddef>
17#if !defined(_LIBCPP_HAS_NO_THREADS)
18# include <mutex>
19#endif
18#include <mutex>
2019
2120#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2221# pragma GCC system_header
2322#endif
2423
25#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2625
2726_LIBCPP_BEGIN_NAMESPACE_STD
2827
......@@ -30,7 +29,7 @@ namespace pmr {
3029
3130// [mem.res.pool.overview]
3231
33class _LIBCPP_TYPE_VIS synchronized_pool_resource : public memory_resource {
32class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI synchronized_pool_resource : public memory_resource {
3433public:
3534 _LIBCPP_HIDE_FROM_ABI synchronized_pool_resource(const pool_options& __opts, memory_resource* __upstream)
3635 : __unsync_(__opts, __upstream) {}
......@@ -46,7 +45,7 @@ public:
4645
4746 synchronized_pool_resource(const synchronized_pool_resource&) = delete;
4847
49 ~synchronized_pool_resource() override = default;
48 _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~synchronized_pool_resource() override = default;
5049
5150 synchronized_pool_resource& operator=(const synchronized_pool_resource&) = delete;
5251
......@@ -89,6 +88,6 @@ private:
8988
9089_LIBCPP_END_NAMESPACE_STD
9190
92#endif // _LIBCPP_STD_VER > 14
91#endif // _LIBCPP_STD_VER >= 17
9392
9493#endif // _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H
lib/libcxx/include/__memory_resource/unsynchronized_pool_resource.h+4-3
......@@ -9,6 +9,7 @@
99#ifndef _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H
1010#define _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H
1111
12#include <__availability>
1213#include <__config>
1314#include <__memory_resource/memory_resource.h>
1415#include <__memory_resource/pool_options.h>
......@@ -19,7 +20,7 @@
1920# pragma GCC system_header
2021#endif
2122
22#if _LIBCPP_STD_VER > 14
23#if _LIBCPP_STD_VER >= 17
2324
2425_LIBCPP_BEGIN_NAMESPACE_STD
2526
......@@ -27,7 +28,7 @@ namespace pmr {
2728
2829// [mem.res.pool.overview]
2930
30class _LIBCPP_TYPE_VIS unsynchronized_pool_resource : public memory_resource {
31class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI unsynchronized_pool_resource : public memory_resource {
3132 class __fixed_pool;
3233
3334 class __adhoc_pool {
......@@ -101,6 +102,6 @@ private:
101102
102103_LIBCPP_END_NAMESPACE_STD
103104
104#endif // _LIBCPP_STD_VER > 14
105#endif // _LIBCPP_STD_VER >= 17
105106
106107#endif // _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H
lib/libcxx/include/__mutex/lock_guard.h created+53
......@@ -0,0 +1,53 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___MUTEX_LOCK_GUARD_H
10#define _LIBCPP___MUTEX_LOCK_GUARD_H
11
12#include <__config>
13#include <__mutex/tag_types.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19#ifndef _LIBCPP_HAS_NO_THREADS
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _Mutex>
24class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) lock_guard {
25public:
26 typedef _Mutex mutex_type;
27
28private:
29 mutex_type& __m_;
30
31public:
32 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI explicit lock_guard(mutex_type& __m)
33 _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
34 : __m_(__m) {
35 __m_.lock();
36 }
37
38 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI lock_guard(mutex_type& __m, adopt_lock_t)
39 _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
40 : __m_(__m) {}
41 _LIBCPP_HIDE_FROM_ABI ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) { __m_.unlock(); }
42
43private:
44 lock_guard(lock_guard const&) = delete;
45 lock_guard& operator=(lock_guard const&) = delete;
46};
47_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(lock_guard);
48
49_LIBCPP_END_NAMESPACE_STD
50
51#endif // _LIBCPP_HAS_NO_THREADS
52
53#endif // _LIBCPP___MUTEX_LOCK_GUARD_H
lib/libcxx/include/__mutex/mutex.h created+53
......@@ -0,0 +1,53 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___MUTEX_MUTEX_H
10#define _LIBCPP___MUTEX_MUTEX_H
11
12#include <__config>
13#include <__threading_support>
14#include <__type_traits/is_nothrow_default_constructible.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20#ifndef _LIBCPP_HAS_NO_THREADS
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex {
25 __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
26
27public:
28 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR mutex() = default;
29
30 mutex(const mutex&) = delete;
31 mutex& operator=(const mutex&) = delete;
32
33# if defined(_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION)
34 _LIBCPP_HIDE_FROM_ABI ~mutex() = default;
35# else
36 ~mutex() _NOEXCEPT;
37# endif
38
39 void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability());
40 bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
41 void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
42
43 typedef __libcpp_mutex_t* native_handle_type;
44 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
45};
46
47static_assert(is_nothrow_default_constructible<mutex>::value, "the default constructor for std::mutex must be nothrow");
48
49_LIBCPP_END_NAMESPACE_STD
50
51#endif // _LIBCPP_HAS_NO_THREADS
52
53#endif // _LIBCPP___MUTEX_MUTEX_H
lib/libcxx/include/__mutex/tag_types.h created+48
......@@ -0,0 +1,48 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___MUTEX_TAG_TYPES_H
10#define _LIBCPP___MUTEX_TAG_TYPES_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15# pragma GCC system_header
16#endif
17
18#ifndef _LIBCPP_HAS_NO_THREADS
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22struct _LIBCPP_EXPORTED_FROM_ABI defer_lock_t {
23 explicit defer_lock_t() = default;
24};
25
26struct _LIBCPP_EXPORTED_FROM_ABI try_to_lock_t {
27 explicit try_to_lock_t() = default;
28};
29
30struct _LIBCPP_EXPORTED_FROM_ABI adopt_lock_t {
31 explicit adopt_lock_t() = default;
32};
33
34# if _LIBCPP_STD_VER >= 17
35inline constexpr defer_lock_t defer_lock = defer_lock_t();
36inline constexpr try_to_lock_t try_to_lock = try_to_lock_t();
37inline constexpr adopt_lock_t adopt_lock = adopt_lock_t();
38# elif !defined(_LIBCPP_CXX03_LANG)
39constexpr defer_lock_t defer_lock = defer_lock_t();
40constexpr try_to_lock_t try_to_lock = try_to_lock_t();
41constexpr adopt_lock_t adopt_lock = adopt_lock_t();
42# endif
43
44_LIBCPP_END_NAMESPACE_STD
45
46#endif // _LIBCPP_HAS_NO_THREADS
47
48#endif // _LIBCPP___MUTEX_TAG_TYPES_H
lib/libcxx/include/__mutex/unique_lock.h created+173
......@@ -0,0 +1,173 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___MUTEX_UNIQUE_LOCK_H
10#define _LIBCPP___MUTEX_UNIQUE_LOCK_H
11
12#include <__chrono/duration.h>
13#include <__chrono/time_point.h>
14#include <__config>
15#include <__memory/addressof.h>
16#include <__mutex/tag_types.h>
17#include <__system_error/system_error.h>
18#include <__utility/swap.h>
19#include <cerrno>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22# pragma GCC system_header
23#endif
24
25#ifndef _LIBCPP_HAS_NO_THREADS
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29template <class _Mutex>
30class _LIBCPP_TEMPLATE_VIS unique_lock {
31public:
32 typedef _Mutex mutex_type;
33
34private:
35 mutex_type* __m_;
36 bool __owns_;
37
38public:
39 _LIBCPP_HIDE_FROM_ABI unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {}
40 _LIBCPP_HIDE_FROM_ABI explicit unique_lock(mutex_type& __m) : __m_(std::addressof(__m)), __owns_(true) {
41 __m_->lock();
42 }
43
44 _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT
45 : __m_(std::addressof(__m)),
46 __owns_(false) {}
47
48 _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, try_to_lock_t)
49 : __m_(std::addressof(__m)), __owns_(__m.try_lock()) {}
50
51 _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, adopt_lock_t) : __m_(std::addressof(__m)), __owns_(true) {}
52
53 template <class _Clock, class _Duration>
54 _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t)
55 : __m_(std::addressof(__m)), __owns_(__m.try_lock_until(__t)) {}
56
57 template <class _Rep, class _Period>
58 _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d)
59 : __m_(std::addressof(__m)), __owns_(__m.try_lock_for(__d)) {}
60
61 _LIBCPP_HIDE_FROM_ABI ~unique_lock() {
62 if (__owns_)
63 __m_->unlock();
64 }
65
66 unique_lock(unique_lock const&) = delete;
67 unique_lock& operator=(unique_lock const&) = delete;
68
69 _LIBCPP_HIDE_FROM_ABI unique_lock(unique_lock&& __u) _NOEXCEPT : __m_(__u.__m_), __owns_(__u.__owns_) {
70 __u.__m_ = nullptr;
71 __u.__owns_ = false;
72 }
73
74 _LIBCPP_HIDE_FROM_ABI unique_lock& operator=(unique_lock&& __u) _NOEXCEPT {
75 if (__owns_)
76 __m_->unlock();
77
78 __m_ = __u.__m_;
79 __owns_ = __u.__owns_;
80 __u.__m_ = nullptr;
81 __u.__owns_ = false;
82 return *this;
83 }
84
85 void lock();
86 bool try_lock();
87
88 template <class _Rep, class _Period>
89 bool try_lock_for(const chrono::duration<_Rep, _Period>& __d);
90
91 template <class _Clock, class _Duration>
92 bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
93
94 void unlock();
95
96 _LIBCPP_HIDE_FROM_ABI void swap(unique_lock& __u) _NOEXCEPT {
97 std::swap(__m_, __u.__m_);
98 std::swap(__owns_, __u.__owns_);
99 }
100
101 _LIBCPP_HIDE_FROM_ABI mutex_type* release() _NOEXCEPT {
102 mutex_type* __m = __m_;
103 __m_ = nullptr;
104 __owns_ = false;
105 return __m;
106 }
107
108 _LIBCPP_HIDE_FROM_ABI bool owns_lock() const _NOEXCEPT { return __owns_; }
109 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __owns_; }
110 _LIBCPP_HIDE_FROM_ABI mutex_type* mutex() const _NOEXCEPT { return __m_; }
111};
112_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(unique_lock);
113
114template <class _Mutex>
115void unique_lock<_Mutex>::lock() {
116 if (__m_ == nullptr)
117 __throw_system_error(EPERM, "unique_lock::lock: references null mutex");
118 if (__owns_)
119 __throw_system_error(EDEADLK, "unique_lock::lock: already locked");
120 __m_->lock();
121 __owns_ = true;
122}
123
124template <class _Mutex>
125bool unique_lock<_Mutex>::try_lock() {
126 if (__m_ == nullptr)
127 __throw_system_error(EPERM, "unique_lock::try_lock: references null mutex");
128 if (__owns_)
129 __throw_system_error(EDEADLK, "unique_lock::try_lock: already locked");
130 __owns_ = __m_->try_lock();
131 return __owns_;
132}
133
134template <class _Mutex>
135template <class _Rep, class _Period>
136bool unique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
137 if (__m_ == nullptr)
138 __throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex");
139 if (__owns_)
140 __throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked");
141 __owns_ = __m_->try_lock_for(__d);
142 return __owns_;
143}
144
145template <class _Mutex>
146template <class _Clock, class _Duration>
147bool unique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
148 if (__m_ == nullptr)
149 __throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex");
150 if (__owns_)
151 __throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked");
152 __owns_ = __m_->try_lock_until(__t);
153 return __owns_;
154}
155
156template <class _Mutex>
157void unique_lock<_Mutex>::unlock() {
158 if (!__owns_)
159 __throw_system_error(EPERM, "unique_lock::unlock: not locked");
160 __m_->unlock();
161 __owns_ = false;
162}
163
164template <class _Mutex>
165inline _LIBCPP_HIDE_FROM_ABI void swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT {
166 __x.swap(__y);
167}
168
169_LIBCPP_END_NAMESPACE_STD
170
171#endif // _LIBCPP_HAS_NO_THREADS
172
173#endif // _LIBCPP___MUTEX_UNIQUE_LOCK_H
lib/libcxx/include/__mutex_base deleted-523
......@@ -1,523 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MUTEX_BASE
11#define _LIBCPP___MUTEX_BASE
12
13#include <__chrono/duration.h>
14#include <__chrono/steady_clock.h>
15#include <__chrono/system_clock.h>
16#include <__chrono/time_point.h>
17#include <__config>
18#include <__threading_support>
19#include <ratio>
20#include <system_error>
21#include <time.h>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24# pragma GCC system_header
25#endif
26
27_LIBCPP_PUSH_MACROS
28#include <__undef_macros>
29
30
31_LIBCPP_BEGIN_NAMESPACE_STD
32
33#ifndef _LIBCPP_HAS_NO_THREADS
34
35class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex
36{
37 __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
38
39public:
40 _LIBCPP_INLINE_VISIBILITY
41 _LIBCPP_CONSTEXPR mutex() = default;
42
43 mutex(const mutex&) = delete;
44 mutex& operator=(const mutex&) = delete;
45
46#if defined(_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION)
47 ~mutex() = default;
48#else
49 ~mutex() _NOEXCEPT;
50#endif
51
52 void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability());
53 bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
54 void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
55
56 typedef __libcpp_mutex_t* native_handle_type;
57 _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;}
58};
59
60static_assert(is_nothrow_default_constructible<mutex>::value,
61 "the default constructor for std::mutex must be nothrow");
62
63struct _LIBCPP_TYPE_VIS defer_lock_t { explicit defer_lock_t() = default; };
64struct _LIBCPP_TYPE_VIS try_to_lock_t { explicit try_to_lock_t() = default; };
65struct _LIBCPP_TYPE_VIS adopt_lock_t { explicit adopt_lock_t() = default; };
66
67#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
68
69extern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t defer_lock;
70extern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock;
71extern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t adopt_lock;
72
73#else
74
75/* inline */ constexpr defer_lock_t defer_lock = defer_lock_t();
76/* inline */ constexpr try_to_lock_t try_to_lock = try_to_lock_t();
77/* inline */ constexpr adopt_lock_t adopt_lock = adopt_lock_t();
78
79#endif
80
81template <class _Mutex>
82class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable)
83lock_guard
84{
85public:
86 typedef _Mutex mutex_type;
87
88private:
89 mutex_type& __m_;
90public:
91
92 _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY
93 explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
94 : __m_(__m) {__m_.lock();}
95
96 _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY
97 lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
98 : __m_(__m) {}
99 _LIBCPP_INLINE_VISIBILITY
100 ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();}
101
102private:
103 lock_guard(lock_guard const&) = delete;
104 lock_guard& operator=(lock_guard const&) = delete;
105};
106_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(lock_guard);
107
108template <class _Mutex>
109class _LIBCPP_TEMPLATE_VIS unique_lock
110{
111public:
112 typedef _Mutex mutex_type;
113
114private:
115 mutex_type* __m_;
116 bool __owns_;
117
118public:
119 _LIBCPP_INLINE_VISIBILITY
120 unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {}
121 _LIBCPP_INLINE_VISIBILITY
122 explicit unique_lock(mutex_type& __m)
123 : __m_(_VSTD::addressof(__m)), __owns_(true) {__m_->lock();}
124 _LIBCPP_INLINE_VISIBILITY
125 unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT
126 : __m_(_VSTD::addressof(__m)), __owns_(false) {}
127 _LIBCPP_INLINE_VISIBILITY
128 unique_lock(mutex_type& __m, try_to_lock_t)
129 : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock()) {}
130 _LIBCPP_INLINE_VISIBILITY
131 unique_lock(mutex_type& __m, adopt_lock_t)
132 : __m_(_VSTD::addressof(__m)), __owns_(true) {}
133 template <class _Clock, class _Duration>
134 _LIBCPP_INLINE_VISIBILITY
135 unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t)
136 : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_until(__t)) {}
137 template <class _Rep, class _Period>
138 _LIBCPP_INLINE_VISIBILITY
139 unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d)
140 : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_for(__d)) {}
141 _LIBCPP_INLINE_VISIBILITY
142 ~unique_lock()
143 {
144 if (__owns_)
145 __m_->unlock();
146 }
147
148 unique_lock(unique_lock const&) = delete;
149 unique_lock& operator=(unique_lock const&) = delete;
150
151 _LIBCPP_INLINE_VISIBILITY
152 unique_lock(unique_lock&& __u) _NOEXCEPT
153 : __m_(__u.__m_), __owns_(__u.__owns_)
154 {__u.__m_ = nullptr; __u.__owns_ = false;}
155 _LIBCPP_INLINE_VISIBILITY
156 unique_lock& operator=(unique_lock&& __u) _NOEXCEPT
157 {
158 if (__owns_)
159 __m_->unlock();
160 __m_ = __u.__m_;
161 __owns_ = __u.__owns_;
162 __u.__m_ = nullptr;
163 __u.__owns_ = false;
164 return *this;
165 }
166
167 void lock();
168 bool try_lock();
169
170 template <class _Rep, class _Period>
171 bool try_lock_for(const chrono::duration<_Rep, _Period>& __d);
172 template <class _Clock, class _Duration>
173 bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
174
175 void unlock();
176
177 _LIBCPP_INLINE_VISIBILITY
178 void swap(unique_lock& __u) _NOEXCEPT
179 {
180 _VSTD::swap(__m_, __u.__m_);
181 _VSTD::swap(__owns_, __u.__owns_);
182 }
183 _LIBCPP_INLINE_VISIBILITY
184 mutex_type* release() _NOEXCEPT
185 {
186 mutex_type* __m = __m_;
187 __m_ = nullptr;
188 __owns_ = false;
189 return __m;
190 }
191
192 _LIBCPP_INLINE_VISIBILITY
193 bool owns_lock() const _NOEXCEPT {return __owns_;}
194 _LIBCPP_INLINE_VISIBILITY
195 explicit operator bool() const _NOEXCEPT {return __owns_;}
196 _LIBCPP_INLINE_VISIBILITY
197 mutex_type* mutex() const _NOEXCEPT {return __m_;}
198};
199_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(unique_lock);
200
201template <class _Mutex>
202void
203unique_lock<_Mutex>::lock()
204{
205 if (__m_ == nullptr)
206 __throw_system_error(EPERM, "unique_lock::lock: references null mutex");
207 if (__owns_)
208 __throw_system_error(EDEADLK, "unique_lock::lock: already locked");
209 __m_->lock();
210 __owns_ = true;
211}
212
213template <class _Mutex>
214bool
215unique_lock<_Mutex>::try_lock()
216{
217 if (__m_ == nullptr)
218 __throw_system_error(EPERM, "unique_lock::try_lock: references null mutex");
219 if (__owns_)
220 __throw_system_error(EDEADLK, "unique_lock::try_lock: already locked");
221 __owns_ = __m_->try_lock();
222 return __owns_;
223}
224
225template <class _Mutex>
226template <class _Rep, class _Period>
227bool
228unique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d)
229{
230 if (__m_ == nullptr)
231 __throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex");
232 if (__owns_)
233 __throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked");
234 __owns_ = __m_->try_lock_for(__d);
235 return __owns_;
236}
237
238template <class _Mutex>
239template <class _Clock, class _Duration>
240bool
241unique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
242{
243 if (__m_ == nullptr)
244 __throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex");
245 if (__owns_)
246 __throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked");
247 __owns_ = __m_->try_lock_until(__t);
248 return __owns_;
249}
250
251template <class _Mutex>
252void
253unique_lock<_Mutex>::unlock()
254{
255 if (!__owns_)
256 __throw_system_error(EPERM, "unique_lock::unlock: not locked");
257 __m_->unlock();
258 __owns_ = false;
259}
260
261template <class _Mutex>
262inline _LIBCPP_INLINE_VISIBILITY
263void
264swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT
265 {__x.swap(__y);}
266
267//enum class cv_status
268_LIBCPP_DECLARE_STRONG_ENUM(cv_status)
269{
270 no_timeout,
271 timeout
272};
273_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status)
274
275class _LIBCPP_TYPE_VIS condition_variable
276{
277 __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
278public:
279 _LIBCPP_INLINE_VISIBILITY
280 _LIBCPP_CONSTEXPR condition_variable() _NOEXCEPT = default;
281
282#ifdef _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
283 ~condition_variable() = default;
284#else
285 ~condition_variable();
286#endif
287
288 condition_variable(const condition_variable&) = delete;
289 condition_variable& operator=(const condition_variable&) = delete;
290
291 void notify_one() _NOEXCEPT;
292 void notify_all() _NOEXCEPT;
293
294 void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
295 template <class _Predicate>
296 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
297 void wait(unique_lock<mutex>& __lk, _Predicate __pred);
298
299 template <class _Clock, class _Duration>
300 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
301 cv_status
302 wait_until(unique_lock<mutex>& __lk,
303 const chrono::time_point<_Clock, _Duration>& __t);
304
305 template <class _Clock, class _Duration, class _Predicate>
306 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
307 bool
308 wait_until(unique_lock<mutex>& __lk,
309 const chrono::time_point<_Clock, _Duration>& __t,
310 _Predicate __pred);
311
312 template <class _Rep, class _Period>
313 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
314 cv_status
315 wait_for(unique_lock<mutex>& __lk,
316 const chrono::duration<_Rep, _Period>& __d);
317
318 template <class _Rep, class _Period, class _Predicate>
319 bool
320 _LIBCPP_INLINE_VISIBILITY
321 wait_for(unique_lock<mutex>& __lk,
322 const chrono::duration<_Rep, _Period>& __d,
323 _Predicate __pred);
324
325 typedef __libcpp_condvar_t* native_handle_type;
326 _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;}
327
328private:
329 void __do_timed_wait(unique_lock<mutex>& __lk,
330 chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
331#if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
332 void __do_timed_wait(unique_lock<mutex>& __lk,
333 chrono::time_point<chrono::steady_clock, chrono::nanoseconds>) _NOEXCEPT;
334#endif
335 template <class _Clock>
336 void __do_timed_wait(unique_lock<mutex>& __lk,
337 chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT;
338};
339#endif // !_LIBCPP_HAS_NO_THREADS
340
341template <class _Rep, class _Period>
342inline _LIBCPP_INLINE_VISIBILITY
343__enable_if_t<is_floating_point<_Rep>::value, chrono::nanoseconds>
344__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d)
345{
346 using namespace chrono;
347 using __ratio = ratio_divide<_Period, nano>;
348 using __ns_rep = nanoseconds::rep;
349 _Rep __result_float = __d.count() * __ratio::num / __ratio::den;
350
351 _Rep __result_max = numeric_limits<__ns_rep>::max();
352 if (__result_float >= __result_max) {
353 return nanoseconds::max();
354 }
355
356 _Rep __result_min = numeric_limits<__ns_rep>::min();
357 if (__result_float <= __result_min) {
358 return nanoseconds::min();
359 }
360
361 return nanoseconds(static_cast<__ns_rep>(__result_float));
362}
363
364template <class _Rep, class _Period>
365inline _LIBCPP_INLINE_VISIBILITY
366__enable_if_t<!is_floating_point<_Rep>::value, chrono::nanoseconds>
367__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d)
368{
369 using namespace chrono;
370 if (__d.count() == 0) {
371 return nanoseconds(0);
372 }
373
374 using __ratio = ratio_divide<_Period, nano>;
375 using __ns_rep = nanoseconds::rep;
376 __ns_rep __result_max = numeric_limits<__ns_rep>::max();
377 if (__d.count() > 0 && __d.count() > __result_max / __ratio::num) {
378 return nanoseconds::max();
379 }
380
381 __ns_rep __result_min = numeric_limits<__ns_rep>::min();
382 if (__d.count() < 0 && __d.count() < __result_min / __ratio::num) {
383 return nanoseconds::min();
384 }
385
386 __ns_rep __result = __d.count() * __ratio::num / __ratio::den;
387 if (__result == 0) {
388 return nanoseconds(1);
389 }
390
391 return nanoseconds(__result);
392}
393
394#ifndef _LIBCPP_HAS_NO_THREADS
395template <class _Predicate>
396void
397condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred)
398{
399 while (!__pred())
400 wait(__lk);
401}
402
403template <class _Clock, class _Duration>
404cv_status
405condition_variable::wait_until(unique_lock<mutex>& __lk,
406 const chrono::time_point<_Clock, _Duration>& __t)
407{
408 using namespace chrono;
409 using __clock_tp_ns = time_point<_Clock, nanoseconds>;
410
411 typename _Clock::time_point __now = _Clock::now();
412 if (__t <= __now)
413 return cv_status::timeout;
414
415 __clock_tp_ns __t_ns = __clock_tp_ns(_VSTD::__safe_nanosecond_cast(__t.time_since_epoch()));
416
417 __do_timed_wait(__lk, __t_ns);
418 return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
419}
420
421template <class _Clock, class _Duration, class _Predicate>
422bool
423condition_variable::wait_until(unique_lock<mutex>& __lk,
424 const chrono::time_point<_Clock, _Duration>& __t,
425 _Predicate __pred)
426{
427 while (!__pred())
428 {
429 if (wait_until(__lk, __t) == cv_status::timeout)
430 return __pred();
431 }
432 return true;
433}
434
435template <class _Rep, class _Period>
436cv_status
437condition_variable::wait_for(unique_lock<mutex>& __lk,
438 const chrono::duration<_Rep, _Period>& __d)
439{
440 using namespace chrono;
441 if (__d <= __d.zero())
442 return cv_status::timeout;
443 using __ns_rep = nanoseconds::rep;
444 steady_clock::time_point __c_now = steady_clock::now();
445
446#if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
447 using __clock_tp_ns = time_point<steady_clock, nanoseconds>;
448 __ns_rep __now_count_ns = _VSTD::__safe_nanosecond_cast(__c_now.time_since_epoch()).count();
449#else
450 using __clock_tp_ns = time_point<system_clock, nanoseconds>;
451 __ns_rep __now_count_ns = _VSTD::__safe_nanosecond_cast(system_clock::now().time_since_epoch()).count();
452#endif
453
454 __ns_rep __d_ns_count = _VSTD::__safe_nanosecond_cast(__d).count();
455
456 if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) {
457 __do_timed_wait(__lk, __clock_tp_ns::max());
458 } else {
459 __do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count)));
460 }
461
462 return steady_clock::now() - __c_now < __d ? cv_status::no_timeout :
463 cv_status::timeout;
464}
465
466template <class _Rep, class _Period, class _Predicate>
467inline
468bool
469condition_variable::wait_for(unique_lock<mutex>& __lk,
470 const chrono::duration<_Rep, _Period>& __d,
471 _Predicate __pred)
472{
473 return wait_until(__lk, chrono::steady_clock::now() + __d,
474 _VSTD::move(__pred));
475}
476
477#if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
478inline
479void
480condition_variable::__do_timed_wait(unique_lock<mutex>& __lk,
481 chrono::time_point<chrono::steady_clock, chrono::nanoseconds> __tp) _NOEXCEPT
482{
483 using namespace chrono;
484 if (!__lk.owns_lock())
485 __throw_system_error(EPERM,
486 "condition_variable::timed wait: mutex not locked");
487 nanoseconds __d = __tp.time_since_epoch();
488 timespec __ts;
489 seconds __s = duration_cast<seconds>(__d);
490 using __ts_sec = decltype(__ts.tv_sec);
491 const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max();
492 if (__s.count() < __ts_sec_max)
493 {
494 __ts.tv_sec = static_cast<__ts_sec>(__s.count());
495 __ts.tv_nsec = (__d - __s).count();
496 }
497 else
498 {
499 __ts.tv_sec = __ts_sec_max;
500 __ts.tv_nsec = giga::num - 1;
501 }
502 int __ec = pthread_cond_clockwait(&__cv_, __lk.mutex()->native_handle(), CLOCK_MONOTONIC, &__ts);
503 if (__ec != 0 && __ec != ETIMEDOUT)
504 __throw_system_error(__ec, "condition_variable timed_wait failed");
505}
506#endif // _LIBCPP_HAS_COND_CLOCKWAIT
507
508template <class _Clock>
509inline
510void
511condition_variable::__do_timed_wait(unique_lock<mutex>& __lk,
512 chrono::time_point<_Clock, chrono::nanoseconds> __tp) _NOEXCEPT
513{
514 wait_for(__lk, __tp - _Clock::now());
515}
516
517#endif // !_LIBCPP_HAS_NO_THREADS
518
519_LIBCPP_END_NAMESPACE_STD
520
521_LIBCPP_POP_MACROS
522
523#endif // _LIBCPP___MUTEX_BASE
lib/libcxx/include/__node_handle+8-3
......@@ -68,9 +68,12 @@ public:
6868# pragma GCC system_header
6969#endif
7070
71_LIBCPP_PUSH_MACROS
72#include <__undef_macros>
73
7174_LIBCPP_BEGIN_NAMESPACE_STD
7275
73#if _LIBCPP_STD_VER > 14
76#if _LIBCPP_STD_VER >= 17
7477
7578// Specialized in __tree & __hash_table for their _NodeType.
7679template <class _NodeType, class _Alloc>
......@@ -146,7 +149,7 @@ public:
146149 _LIBCPP_INLINE_VISIBILITY
147150 __basic_node_handle& operator=(__basic_node_handle&& __other)
148151 {
149 _LIBCPP_ASSERT(
152 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
150153 __alloc_ == _VSTD::nullopt ||
151154 __alloc_traits::propagate_on_container_move_assignment::value ||
152155 __alloc_ == __other.__alloc_,
......@@ -247,8 +250,10 @@ struct _LIBCPP_TEMPLATE_VIS __insert_return_type
247250 _NodeType node;
248251};
249252
250#endif // _LIBCPP_STD_VER > 14
253#endif // _LIBCPP_STD_VER >= 17
251254
252255_LIBCPP_END_NAMESPACE_STD
253256
257_LIBCPP_POP_MACROS
258
254259#endif // _LIBCPP___NODE_HANDLE
lib/libcxx/include/__numeric/accumulate.h+7-2
......@@ -17,6 +17,9 @@
1717# pragma GCC system_header
1818#endif
1919
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
2023_LIBCPP_BEGIN_NAMESPACE_STD
2124
2225template <class _InputIterator, class _Tp>
......@@ -25,7 +28,7 @@ _Tp
2528accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
2629{
2730 for (; __first != __last; ++__first)
28#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
2932 __init = _VSTD::move(__init) + *__first;
3033#else
3134 __init = __init + *__first;
......@@ -39,7 +42,7 @@ _Tp
3942accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op)
4043{
4144 for (; __first != __last; ++__first)
42#if _LIBCPP_STD_VER > 17
45#if _LIBCPP_STD_VER >= 20
4346 __init = __binary_op(_VSTD::move(__init), *__first);
4447#else
4548 __init = __binary_op(__init, *__first);
......@@ -49,4 +52,6 @@ accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOpe
4952
5053_LIBCPP_END_NAMESPACE_STD
5154
55_LIBCPP_POP_MACROS
56
5257#endif // _LIBCPP___NUMERIC_ACCUMULATE_H
lib/libcxx/include/__numeric/adjacent_difference.h+7-2
......@@ -18,6 +18,9 @@
1818# pragma GCC system_header
1919#endif
2020
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
2124_LIBCPP_BEGIN_NAMESPACE_STD
2225
2326template <class _InputIterator, class _OutputIterator>
......@@ -32,7 +35,7 @@ adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterat
3235 for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
3336 {
3437 typename iterator_traits<_InputIterator>::value_type __val(*__first);
35#if _LIBCPP_STD_VER > 17
38#if _LIBCPP_STD_VER >= 20
3639 *__result = __val - _VSTD::move(__acc);
3740#else
3841 *__result = __val - __acc;
......@@ -56,7 +59,7 @@ adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterat
5659 for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
5760 {
5861 typename iterator_traits<_InputIterator>::value_type __val(*__first);
59#if _LIBCPP_STD_VER > 17
62#if _LIBCPP_STD_VER >= 20
6063 *__result = __binary_op(__val, _VSTD::move(__acc));
6164#else
6265 *__result = __binary_op(__val, __acc);
......@@ -69,4 +72,6 @@ adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterat
6972
7073_LIBCPP_END_NAMESPACE_STD
7174
75_LIBCPP_POP_MACROS
76
7277#endif // _LIBCPP___NUMERIC_ADJACENT_DIFFERENCE_H
lib/libcxx/include/__numeric/exclusive_scan.h+7-2
......@@ -18,9 +18,12 @@
1818# pragma GCC system_header
1919#endif
2020
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
2124_LIBCPP_BEGIN_NAMESPACE_STD
2225
23#if _LIBCPP_STD_VER > 14
26#if _LIBCPP_STD_VER >= 17
2427
2528template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp>
2629_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
......@@ -46,8 +49,10 @@ exclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __
4649 return _VSTD::exclusive_scan(__first, __last, __result, __init, _VSTD::plus<>());
4750}
4851
49#endif // _LIBCPP_STD_VER > 14
52#endif // _LIBCPP_STD_VER >= 17
5053
5154_LIBCPP_END_NAMESPACE_STD
5255
56_LIBCPP_POP_MACROS
57
5358#endif // _LIBCPP___NUMERIC_EXCLUSIVE_SCAN_H
lib/libcxx/include/__numeric/gcd_lcm.h+2-2
......@@ -28,7 +28,7 @@ _LIBCPP_PUSH_MACROS
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
31#if _LIBCPP_STD_VER > 14
31#if _LIBCPP_STD_VER >= 17
3232
3333template <typename _Result, typename _Source, bool _IsSigned = is_signed<_Source>::value> struct __ct_abs;
3434
......@@ -87,7 +87,7 @@ lcm(_Tp __m, _Up __n)
8787 using _Rp = common_type_t<_Tp,_Up>;
8888 _Rp __val1 = __ct_abs<_Rp, _Tp>()(__m) / _VSTD::gcd(__m, __n);
8989 _Rp __val2 = __ct_abs<_Rp, _Up>()(__n);
90 _LIBCPP_ASSERT((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm");
90 _LIBCPP_ASSERT_UNCATEGORIZED((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm");
9191 return __val1 * __val2;
9292}
9393
lib/libcxx/include/__numeric/inclusive_scan.h+2-2
......@@ -21,7 +21,7 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2525
2626template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp>
2727_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
......@@ -53,7 +53,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator inclusiv
5353 return _VSTD::inclusive_scan(__first, __last, __result, _VSTD::plus<>());
5454}
5555
56#endif // _LIBCPP_STD_VER > 14
56#endif // _LIBCPP_STD_VER >= 17
5757
5858_LIBCPP_END_NAMESPACE_STD
5959
lib/libcxx/include/__numeric/inner_product.h+7-2
......@@ -17,6 +17,9 @@
1717# pragma GCC system_header
1818#endif
1919
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
2023_LIBCPP_BEGIN_NAMESPACE_STD
2124
2225template <class _InputIterator1, class _InputIterator2, class _Tp>
......@@ -25,7 +28,7 @@ _Tp
2528inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init)
2629{
2730 for (; __first1 != __last1; ++__first1, (void) ++__first2)
28#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
2932 __init = _VSTD::move(__init) + *__first1 * *__first2;
3033#else
3134 __init = __init + *__first1 * *__first2;
......@@ -40,7 +43,7 @@ inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2
4043 _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
4144{
4245 for (; __first1 != __last1; ++__first1, (void) ++__first2)
43#if _LIBCPP_STD_VER > 17
46#if _LIBCPP_STD_VER >= 20
4447 __init = __binary_op1(_VSTD::move(__init), __binary_op2(*__first1, *__first2));
4548#else
4649 __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
......@@ -50,4 +53,6 @@ inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2
5053
5154_LIBCPP_END_NAMESPACE_STD
5255
56_LIBCPP_POP_MACROS
57
5358#endif // _LIBCPP___NUMERIC_INNER_PRODUCT_H
lib/libcxx/include/__numeric/midpoint.h+2-2
......@@ -33,7 +33,7 @@ _LIBCPP_PUSH_MACROS
3333
3434_LIBCPP_BEGIN_NAMESPACE_STD
3535
36#if _LIBCPP_STD_VER > 17
36#if _LIBCPP_STD_VER >= 20
3737template <class _Tp>
3838_LIBCPP_INLINE_VISIBILITY constexpr
3939enable_if_t<is_integral_v<_Tp> && !is_same_v<bool, _Tp> && !is_null_pointer_v<_Tp>, _Tp>
......@@ -86,7 +86,7 @@ midpoint(_Fp __a, _Fp __b) noexcept
8686 __a/2 + __b/2; // otherwise correctly rounded
8787}
8888
89#endif // _LIBCPP_STD_VER > 17
89#endif // _LIBCPP_STD_VER >= 20
9090
9191_LIBCPP_END_NAMESPACE_STD
9292
lib/libcxx/include/__numeric/partial_sum.h+7-2
......@@ -18,6 +18,9 @@
1818# pragma GCC system_header
1919#endif
2020
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
2124_LIBCPP_BEGIN_NAMESPACE_STD
2225
2326template <class _InputIterator, class _OutputIterator>
......@@ -31,7 +34,7 @@ partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __res
3134 *__result = __t;
3235 for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
3336 {
34#if _LIBCPP_STD_VER > 17
37#if _LIBCPP_STD_VER >= 20
3538 __t = _VSTD::move(__t) + *__first;
3639#else
3740 __t = __t + *__first;
......@@ -54,7 +57,7 @@ partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __res
5457 *__result = __t;
5558 for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
5659 {
57#if _LIBCPP_STD_VER > 17
60#if _LIBCPP_STD_VER >= 20
5861 __t = __binary_op(_VSTD::move(__t), *__first);
5962#else
6063 __t = __binary_op(__t, *__first);
......@@ -67,4 +70,6 @@ partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __res
6770
6871_LIBCPP_END_NAMESPACE_STD
6972
73_LIBCPP_POP_MACROS
74
7075#endif // _LIBCPP___NUMERIC_PARTIAL_SUM_H
lib/libcxx/include/__numeric/pstl_reduce.h created+73
......@@ -0,0 +1,73 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___NUMERIC_PSTL_REDUCE_H
10#define _LIBCPP___NUMERIC_PSTL_REDUCE_H
11
12#include <__algorithm/pstl_frontend_dispatch.h>
13#include <__config>
14#include <__functional/identity.h>
15#include <__iterator/iterator_traits.h>
16#include <__numeric/pstl_transform_reduce.h>
17#include <__type_traits/is_execution_policy.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class>
28void __pstl_reduce();
29
30template <class _ExecutionPolicy,
31 class _ForwardIterator,
32 class _Tp,
33 class _BinaryOperation = plus<>,
34 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
35 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
36_LIBCPP_HIDE_FROM_ABI _Tp
37reduce(_ExecutionPolicy&& __policy,
38 _ForwardIterator __first,
39 _ForwardIterator __last,
40 _Tp __init,
41 _BinaryOperation __op = {}) {
42 return std::__pstl_frontend_dispatch(
43 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_reduce),
44 [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Tp __g_init, _BinaryOperation __g_op) {
45 return std::transform_reduce(
46 __policy, std::move(__g_first), std::move(__g_last), std::move(__g_init), std::move(__g_op), __identity{});
47 },
48 std::move(__first),
49 std::move(__last),
50 std::move(__init),
51 std::move(__op));
52}
53
54template <class _ExecutionPolicy,
55 class _ForwardIterator,
56 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
57 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
58_LIBCPP_HIDE_FROM_ABI __iter_value_type<_ForwardIterator>
59reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last) {
60 return std::__pstl_frontend_dispatch(
61 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_reduce),
62 [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last) {
63 return std::reduce(__policy, __g_first, __g_last, __iter_value_type<_ForwardIterator>());
64 },
65 std::move(__first),
66 std::move(__last));
67}
68
69_LIBCPP_END_NAMESPACE_STD
70
71#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
72
73#endif // _LIBCPP___NUMERIC_PSTL_REDUCE_H
lib/libcxx/include/__numeric/pstl_transform_reduce.h created+100
......@@ -0,0 +1,100 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___NUMERIC_PSTL_TRANSFORM_REDUCE_H
10#define _LIBCPP___NUMERIC_PSTL_TRANSFORM_REDUCE_H
11
12#include <__algorithm/pstl_backend.h>
13#include <__algorithm/pstl_frontend_dispatch.h>
14#include <__config>
15#include <__functional/operations.h>
16#include <__numeric/transform_reduce.h>
17#include <__type_traits/is_execution_policy.h>
18#include <__utility/move.h>
19#include <__utility/terminate_on_exception.h>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22# pragma GCC system_header
23#endif
24
25#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29template <class _ExecutionPolicy,
30 class _ForwardIterator1,
31 class _ForwardIterator2,
32 class _Tp,
33 class _BinaryOperation1,
34 class _BinaryOperation2,
35 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
36 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
37_LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
38 _ExecutionPolicy&&,
39 _ForwardIterator1 __first1,
40 _ForwardIterator1 __last1,
41 _ForwardIterator2 __first2,
42 _Tp __init,
43 _BinaryOperation1 __reduce,
44 _BinaryOperation2 __transform) {
45 using _Backend = typename __select_backend<_RawPolicy>::type;
46 return std::__pstl_transform_reduce<_RawPolicy>(
47 _Backend{},
48 std::move(__first1),
49 std::move(__last1),
50 std::move(__first2),
51 std::move(__init),
52 std::move(__reduce),
53 std::move(__transform));
54}
55
56// This overload doesn't get a customization point because it's trivial to detect (through e.g.
57// __is_trivial_plus_operation) when specializing the more general variant, which should always be preferred
58template <class _ExecutionPolicy,
59 class _ForwardIterator1,
60 class _ForwardIterator2,
61 class _Tp,
62 enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
63_LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
64 _ExecutionPolicy&& __policy,
65 _ForwardIterator1 __first1,
66 _ForwardIterator1 __last1,
67 _ForwardIterator2 __first2,
68 _Tp __init) {
69 return std::transform_reduce(__policy, __first1, __last1, __first2, __init, plus{}, multiplies{});
70}
71
72template <class _ExecutionPolicy,
73 class _ForwardIterator,
74 class _Tp,
75 class _BinaryOperation,
76 class _UnaryOperation,
77 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
78 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
79_LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
80 _ExecutionPolicy&&,
81 _ForwardIterator __first,
82 _ForwardIterator __last,
83 _Tp __init,
84 _BinaryOperation __reduce,
85 _UnaryOperation __transform) {
86 using _Backend = typename __select_backend<_RawPolicy>::type;
87 return std::__pstl_transform_reduce<_RawPolicy>(
88 _Backend{},
89 std::move(__first),
90 std::move(__last),
91 std::move(__init),
92 std::move(__reduce),
93 std::move(__transform));
94}
95
96_LIBCPP_END_NAMESPACE_STD
97
98#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
99
100#endif // _LIBCPP___NUMERIC_PSTL_TRANSFORM_REDUCE_H
lib/libcxx/include/__numeric/reduce.h+3-2
......@@ -13,6 +13,7 @@
1313#include <__config>
1414#include <__functional/operations.h>
1515#include <__iterator/iterator_traits.h>
16#include <__utility/move.h>
1617
1718#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1819# pragma GCC system_header
......@@ -20,12 +21,12 @@
2021
2122_LIBCPP_BEGIN_NAMESPACE_STD
2223
23#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2425template <class _InputIterator, class _Tp, class _BinaryOp>
2526_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp reduce(_InputIterator __first, _InputIterator __last,
2627 _Tp __init, _BinaryOp __b) {
2728 for (; __first != __last; ++__first)
28 __init = __b(__init, *__first);
29 __init = __b(std::move(__init), *__first);
2930 return __init;
3031}
3132
lib/libcxx/include/__numeric/transform_exclusive_scan.h+2-2
......@@ -18,7 +18,7 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21#if _LIBCPP_STD_VER > 14
21#if _LIBCPP_STD_VER >= 17
2222
2323template <class _InputIterator, class _OutputIterator, class _Tp,
2424 class _BinaryOp, class _UnaryOp>
......@@ -42,7 +42,7 @@ transform_exclusive_scan(_InputIterator __first, _InputIterator __last,
4242 return __result;
4343}
4444
45#endif // _LIBCPP_STD_VER > 14
45#endif // _LIBCPP_STD_VER >= 17
4646
4747_LIBCPP_END_NAMESPACE_STD
4848
lib/libcxx/include/__numeric/transform_inclusive_scan.h+2-2
......@@ -19,7 +19,7 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 14
22#if _LIBCPP_STD_VER >= 17
2323
2424template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
2525_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -51,7 +51,7 @@ transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
5151 return __result;
5252}
5353
54#endif // _LIBCPP_STD_VER > 14
54#endif // _LIBCPP_STD_VER >= 17
5555
5656_LIBCPP_END_NAMESPACE_STD
5757
lib/libcxx/include/__numeric/transform_reduce.h+3-3
......@@ -20,13 +20,13 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 14
23#if _LIBCPP_STD_VER >= 17
2424template <class _InputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
2525_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp transform_reduce(_InputIterator __first,
2626 _InputIterator __last, _Tp __init,
2727 _BinaryOp __b, _UnaryOp __u) {
2828 for (; __first != __last; ++__first)
29 __init = __b(__init, __u(*__first));
29 __init = __b(std::move(__init), __u(*__first));
3030 return __init;
3131}
3232
......@@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp transform_reduce(_In
3636 _InputIterator2 __first2, _Tp __init,
3737 _BinaryOp1 __b1, _BinaryOp2 __b2) {
3838 for (; __first1 != __last1; ++__first1, (void)++__first2)
39 __init = __b1(__init, __b2(*__first1, *__first2));
39 __init = __b1(std::move(__init), __b2(*__first1, *__first2));
4040 return __init;
4141}
4242
lib/libcxx/include/__pstl/internal/algorithm_fwd.h created+1768
......@@ -0,0 +1,1768 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_ALGORITHM_FWD_H
11#define _PSTL_ALGORITHM_FWD_H
12
13#include <__config>
14#include <iterator>
15#include <type_traits>
16#include <utility>
17
18namespace __pstl {
19namespace __internal {
20
21//------------------------------------------------------------------------
22// walk1 (pseudo)
23//
24// walk1 evaluates f(x) for each dereferenced value x drawn from [first,last)
25//------------------------------------------------------------------------
26
27template <class _ForwardIterator, class _Function>
28void __brick_walk1(_ForwardIterator,
29 _ForwardIterator,
30 _Function,
31 /*vector=*/std::false_type) noexcept;
32
33template <class _RandomAccessIterator, class _Function>
34void __brick_walk1(_RandomAccessIterator,
35 _RandomAccessIterator,
36 _Function,
37 /*vector=*/std::true_type) noexcept;
38
39template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Function>
40void __pattern_walk1(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function) noexcept;
41
42template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Function>
43void __pattern_walk1(
44 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Function);
45
46template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Brick>
47void __pattern_walk_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Brick) noexcept;
48
49template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Brick>
50void __pattern_walk_brick(
51 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Brick);
52
53//------------------------------------------------------------------------
54// walk1_n
55//------------------------------------------------------------------------
56
57template <class _ForwardIterator, class _Size, class _Function>
58_ForwardIterator __brick_walk1_n(
59 _ForwardIterator,
60 _Size,
61 _Function,
62 /*_IsVectorTag=*/std::false_type);
63
64template <class _RandomAccessIterator, class _DifferenceType, class _Function>
65_RandomAccessIterator __brick_walk1_n(
66 _RandomAccessIterator,
67 _DifferenceType,
68 _Function,
69 /*vectorTag=*/std::true_type) noexcept;
70
71template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function>
72_ForwardIterator __pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Function) noexcept;
73
74template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Function>
75_RandomAccessIterator
76__pattern_walk1_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, _Function);
77
78template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Brick>
79_ForwardIterator __pattern_walk_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Brick) noexcept;
80
81template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Brick>
82_RandomAccessIterator
83__pattern_walk_brick_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, _Brick);
84
85//------------------------------------------------------------------------
86// walk2 (pseudo)
87//
88// walk2 evaluates f(x,y) for deferenced values (x,y) drawn from [first1,last1) and [first2,...)
89//------------------------------------------------------------------------
90
91template <class _ForwardIterator1, class _ForwardIterator2, class _Function>
92_ForwardIterator2 __brick_walk2(
93 _ForwardIterator1,
94 _ForwardIterator1,
95 _ForwardIterator2,
96 _Function,
97 /*vector=*/std::false_type) noexcept;
98
99template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Function>
100_RandomAccessIterator2 __brick_walk2(
101 _RandomAccessIterator1,
102 _RandomAccessIterator1,
103 _RandomAccessIterator2,
104 _Function,
105 /*vector=*/std::true_type) noexcept;
106
107template <class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Function>
108_ForwardIterator2 __brick_walk2_n(
109 _ForwardIterator1,
110 _Size,
111 _ForwardIterator2,
112 _Function,
113 /*vector=*/std::false_type) noexcept;
114
115template <class _RandomAccessIterator1, class _Size, class _RandomAccessIterator2, class _Function>
116_RandomAccessIterator2 __brick_walk2_n(
117 _RandomAccessIterator1,
118 _Size,
119 _RandomAccessIterator2,
120 _Function,
121 /*vector=*/std::true_type) noexcept;
122
123template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Function>
124_ForwardIterator2
125__pattern_walk2(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function) noexcept;
126
127template <class _IsVector,
128 class _ExecutionPolicy,
129 class _RandomAccessIterator1,
130 class _RandomAccessIterator2,
131 class _Function>
132_RandomAccessIterator2 __pattern_walk2(
133 __parallel_tag<_IsVector>,
134 _ExecutionPolicy&&,
135 _RandomAccessIterator1,
136 _RandomAccessIterator1,
137 _RandomAccessIterator2,
138 _Function);
139
140template <class _Tag,
141 class _ExecutionPolicy,
142 class _ForwardIterator1,
143 class _Size,
144 class _ForwardIterator2,
145 class _Function>
146_ForwardIterator2
147__pattern_walk2_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Function) noexcept;
148
149template <class _IsVector,
150 class _ExecutionPolicy,
151 class _RandomAccessIterator1,
152 class _Size,
153 class _RandomAccessIterator2,
154 class _Function>
155_RandomAccessIterator2 __pattern_walk2_n(
156 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Function);
157
158template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Brick>
159_ForwardIterator2 __pattern_walk2_brick(
160 _Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Brick) noexcept;
161
162template <class _IsVector,
163 class _ExecutionPolicy,
164 class _RandomAccessIterator1,
165 class _RandomAccessIterator2,
166 class _Brick>
167_RandomAccessIterator2 __pattern_walk2_brick(
168 __parallel_tag<_IsVector>,
169 _ExecutionPolicy&&,
170 _RandomAccessIterator1,
171 _RandomAccessIterator1,
172 _RandomAccessIterator2,
173 _Brick);
174
175template <class _Tag,
176 class _ExecutionPolicy,
177 class _ForwardIterator1,
178 class _Size,
179 class _ForwardIterator2,
180 class _Brick>
181_ForwardIterator2
182__pattern_walk2_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Brick) noexcept;
183
184template <class _IsVector,
185 class _ExecutionPolicy,
186 class _RandomAccessIterator1,
187 class _Size,
188 class _RandomAccessIterator2,
189 class _Brick>
190_RandomAccessIterator2 __pattern_walk2_brick_n(
191 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Brick);
192
193//------------------------------------------------------------------------
194// walk3 (pseudo)
195//
196// walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...)
197//------------------------------------------------------------------------
198
199template <class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator3, class _Function>
200_ForwardIterator3 __brick_walk3(
201 _ForwardIterator1,
202 _ForwardIterator1,
203 _ForwardIterator2,
204 _ForwardIterator3,
205 _Function,
206 /*vector=*/std::false_type) noexcept;
207
208template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Function>
209_RandomAccessIterator3 __brick_walk3(
210 _RandomAccessIterator1,
211 _RandomAccessIterator1,
212 _RandomAccessIterator2,
213 _RandomAccessIterator3,
214 _Function,
215 /*vector=*/std::true_type) noexcept;
216
217template <class _Tag,
218 class _ExecutionPolicy,
219 class _ForwardIterator1,
220 class _ForwardIterator2,
221 class _ForwardIterator3,
222 class _Function>
223_ForwardIterator3 __pattern_walk3(
224 _Tag,
225 _ExecutionPolicy&&,
226 _ForwardIterator1,
227 _ForwardIterator1,
228 _ForwardIterator2,
229 _ForwardIterator3,
230 _Function) noexcept;
231
232template <class _IsVector,
233 class _ExecutionPolicy,
234 class _RandomAccessIterator1,
235 class _RandomAccessIterator2,
236 class _RandomAccessIterator3,
237 class _Function>
238_RandomAccessIterator3 __pattern_walk3(
239 __parallel_tag<_IsVector>,
240 _ExecutionPolicy&&,
241 _RandomAccessIterator1,
242 _RandomAccessIterator1,
243 _RandomAccessIterator2,
244 _RandomAccessIterator3,
245 _Function);
246
247//------------------------------------------------------------------------
248// equal
249//------------------------------------------------------------------------
250
251template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
252bool __brick_equal(_ForwardIterator1,
253 _ForwardIterator1,
254 _ForwardIterator2,
255 _BinaryPredicate,
256 /* is_vector = */ std::false_type) noexcept;
257
258template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
259bool __brick_equal(_RandomAccessIterator1,
260 _RandomAccessIterator1,
261 _RandomAccessIterator2,
262 _BinaryPredicate,
263 /* is_vector = */ std::true_type) noexcept;
264
265template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
266bool __pattern_equal(
267 _Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _BinaryPredicate) noexcept;
268
269template <class _IsVector,
270 class _ExecutionPolicy,
271 class _RandomAccessIterator1,
272 class _RandomAccessIterator2,
273 class _BinaryPredicate>
274bool __pattern_equal(
275 __parallel_tag<_IsVector>,
276 _ExecutionPolicy&&,
277 _RandomAccessIterator1,
278 _RandomAccessIterator1,
279 _RandomAccessIterator2,
280 _BinaryPredicate);
281
282template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
283bool __brick_equal(_ForwardIterator1,
284 _ForwardIterator1,
285 _ForwardIterator2,
286 _ForwardIterator2,
287 _BinaryPredicate,
288 /* is_vector = */ std::false_type) noexcept;
289
290template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
291bool __brick_equal(_RandomAccessIterator1,
292 _RandomAccessIterator1,
293 _RandomAccessIterator2,
294 _RandomAccessIterator2,
295 _BinaryPredicate,
296 /* is_vector = */ std::true_type) noexcept;
297
298template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
299bool __pattern_equal(
300 _Tag,
301 _ExecutionPolicy&&,
302 _ForwardIterator1,
303 _ForwardIterator1,
304 _ForwardIterator2,
305 _ForwardIterator2,
306 _BinaryPredicate) noexcept;
307
308template <class _IsVector,
309 class _ExecutionPolicy,
310 class _RandomAccessIterator1,
311 class _RandomAccessIterator2,
312 class _BinaryPredicate>
313bool __pattern_equal(
314 __parallel_tag<_IsVector>,
315 _ExecutionPolicy&&,
316 _RandomAccessIterator1,
317 _RandomAccessIterator1,
318 _RandomAccessIterator2,
319 _RandomAccessIterator2,
320 _BinaryPredicate);
321
322//------------------------------------------------------------------------
323// find_end
324//------------------------------------------------------------------------
325
326template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
327_ForwardIterator1 __brick_find_end(
328 _ForwardIterator1,
329 _ForwardIterator1,
330 _ForwardIterator2,
331 _ForwardIterator2,
332 _BinaryPredicate,
333 /*__is_vector=*/std::false_type) noexcept;
334
335template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
336_RandomAccessIterator1 __brick_find_end(
337 _RandomAccessIterator1,
338 _RandomAccessIterator1,
339 _RandomAccessIterator2,
340 _RandomAccessIterator2,
341 _BinaryPredicate,
342 /*__is_vector=*/std::true_type) noexcept;
343
344template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
345_ForwardIterator1 __pattern_find_end(
346 _Tag,
347 _ExecutionPolicy&&,
348 _ForwardIterator1,
349 _ForwardIterator1,
350 _ForwardIterator2,
351 _ForwardIterator2,
352 _BinaryPredicate) noexcept;
353
354template <class _IsVector,
355 class _ExecutionPolicy,
356 class _RandomAccessIterator1,
357 class _RandomAccessIterator2,
358 class _BinaryPredicate>
359_RandomAccessIterator1 __pattern_find_end(
360 __parallel_tag<_IsVector>,
361 _ExecutionPolicy&&,
362 _RandomAccessIterator1,
363 _RandomAccessIterator1,
364 _RandomAccessIterator2,
365 _RandomAccessIterator2,
366 _BinaryPredicate) noexcept;
367
368//------------------------------------------------------------------------
369// find_first_of
370//------------------------------------------------------------------------
371
372template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
373_ForwardIterator1 __brick_find_first_of(
374 _ForwardIterator1,
375 _ForwardIterator1,
376 _ForwardIterator2,
377 _ForwardIterator2,
378 _BinaryPredicate,
379 /*__is_vector=*/std::false_type) noexcept;
380
381template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
382_RandomAccessIterator1 __brick_find_first_of(
383 _RandomAccessIterator1,
384 _RandomAccessIterator1,
385 _RandomAccessIterator2,
386 _RandomAccessIterator2,
387 _BinaryPredicate,
388 /*__is_vector=*/std::true_type) noexcept;
389
390template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
391_ForwardIterator1 __pattern_find_first_of(
392 _Tag,
393 _ExecutionPolicy&&,
394 _ForwardIterator1,
395 _ForwardIterator1,
396 _ForwardIterator2,
397 _ForwardIterator2,
398 _BinaryPredicate) noexcept;
399
400template <class _IsVector,
401 class _ExecutionPolicy,
402 class _RandomAccessIterator1,
403 class _RandomAccessIterator2,
404 class _BinaryPredicate>
405_RandomAccessIterator1 __pattern_find_first_of(
406 __parallel_tag<_IsVector>,
407 _ExecutionPolicy&&,
408 _RandomAccessIterator1,
409 _RandomAccessIterator1,
410 _RandomAccessIterator2,
411 _RandomAccessIterator2,
412 _BinaryPredicate) noexcept;
413
414//------------------------------------------------------------------------
415// search
416//------------------------------------------------------------------------
417
418template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
419_ForwardIterator1 __brick_search(
420 _ForwardIterator1,
421 _ForwardIterator1,
422 _ForwardIterator2,
423 _ForwardIterator2,
424 _BinaryPredicate,
425 /*vector=*/std::false_type) noexcept;
426
427template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
428_RandomAccessIterator1 __brick_search(
429 _RandomAccessIterator1,
430 _RandomAccessIterator1,
431 _RandomAccessIterator2,
432 _RandomAccessIterator2,
433 _BinaryPredicate,
434 /*vector=*/std::true_type) noexcept;
435
436template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
437_ForwardIterator1 __pattern_search(
438 _Tag,
439 _ExecutionPolicy&&,
440 _ForwardIterator1,
441 _ForwardIterator1,
442 _ForwardIterator2,
443 _ForwardIterator2,
444 _BinaryPredicate) noexcept;
445
446template <class _IsVector,
447 class _ExecutionPolicy,
448 class _RandomAccessIterator1,
449 class _RandomAccessIterator2,
450 class _BinaryPredicate>
451_RandomAccessIterator1 __pattern_search(
452 __parallel_tag<_IsVector>,
453 _ExecutionPolicy&&,
454 _RandomAccessIterator1,
455 _RandomAccessIterator1,
456 _RandomAccessIterator2,
457 _RandomAccessIterator2,
458 _BinaryPredicate) noexcept;
459
460//------------------------------------------------------------------------
461// search_n
462//------------------------------------------------------------------------
463
464template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
465_ForwardIterator __brick_search_n(
466 _ForwardIterator,
467 _ForwardIterator,
468 _Size,
469 const _Tp&,
470 _BinaryPredicate,
471 /*vector=*/std::false_type) noexcept;
472
473template <class _RandomAccessIterator, class _Size, class _Tp, class _BinaryPredicate>
474_RandomAccessIterator __brick_search_n(
475 _RandomAccessIterator,
476 _RandomAccessIterator,
477 _Size,
478 const _Tp&,
479 _BinaryPredicate,
480 /*vector=*/std::true_type) noexcept;
481
482template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
483_ForwardIterator __pattern_search_n(
484 _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Size, const _Tp&, _BinaryPredicate) noexcept;
485
486template <class _IsVector,
487 class _ExecutionPolicy,
488 class _RandomAccessIterator,
489 class _Size,
490 class _Tp,
491 class _BinaryPredicate>
492_RandomAccessIterator __pattern_search_n(
493 __parallel_tag<_IsVector>,
494 _ExecutionPolicy&&,
495 _RandomAccessIterator,
496 _RandomAccessIterator,
497 _Size,
498 const _Tp&,
499 _BinaryPredicate) noexcept;
500
501//------------------------------------------------------------------------
502// copy_n
503//------------------------------------------------------------------------
504
505template <class _ForwardIterator, class _Size, class _OutputIterator>
506_OutputIterator __brick_copy_n(_ForwardIterator,
507 _Size,
508 _OutputIterator,
509 /*vector=*/std::false_type) noexcept;
510
511template <class _RandomAccessIterator, class _Size, class _OutputIterator>
512_OutputIterator __brick_copy_n(_RandomAccessIterator,
513 _Size,
514 _OutputIterator,
515 /*vector=*/std::true_type) noexcept;
516
517//------------------------------------------------------------------------
518// copy
519//------------------------------------------------------------------------
520
521template <class _ForwardIterator, class _OutputIterator>
522_OutputIterator __brick_copy(_ForwardIterator,
523 _ForwardIterator,
524 _OutputIterator,
525 /*vector=*/std::false_type) noexcept;
526
527template <class _RandomAccessIterator, class _OutputIterator>
528_OutputIterator __brick_copy(_RandomAccessIterator,
529 _RandomAccessIterator,
530 _OutputIterator,
531 /*vector=*/std::true_type) noexcept;
532
533//------------------------------------------------------------------------
534// move
535//------------------------------------------------------------------------
536
537template <class _ForwardIterator, class _OutputIterator>
538_OutputIterator __brick_move(_ForwardIterator,
539 _ForwardIterator,
540 _OutputIterator,
541 /*vector=*/std::false_type) noexcept;
542
543template <class _RandomAccessIterator, class _OutputIterator>
544_OutputIterator __brick_move(_RandomAccessIterator,
545 _RandomAccessIterator,
546 _OutputIterator,
547 /*vector=*/std::true_type) noexcept;
548
549//------------------------------------------------------------------------
550// swap_ranges
551//------------------------------------------------------------------------
552template <class _ForwardIterator, class _OutputIterator>
553_OutputIterator __brick_swap_ranges(
554 _ForwardIterator,
555 _ForwardIterator,
556 _OutputIterator,
557 /*vector=*/std::false_type) noexcept;
558
559template <class _RandomAccessIterator, class _OutputIterator>
560_OutputIterator __brick_swap_ranges(
561 _RandomAccessIterator,
562 _RandomAccessIterator,
563 _OutputIterator,
564 /*vector=*/std::true_type) noexcept;
565
566//------------------------------------------------------------------------
567// copy_if
568//------------------------------------------------------------------------
569
570template <class _ForwardIterator, class _OutputIterator, class _UnaryPredicate>
571_OutputIterator __brick_copy_if(
572 _ForwardIterator,
573 _ForwardIterator,
574 _OutputIterator,
575 _UnaryPredicate,
576 /*vector=*/std::false_type) noexcept;
577
578template <class _RandomAccessIterator, class _OutputIterator, class _UnaryPredicate>
579_OutputIterator __brick_copy_if(
580 _RandomAccessIterator,
581 _RandomAccessIterator,
582 _OutputIterator,
583 _UnaryPredicate,
584 /*vector=*/std::true_type) noexcept;
585
586template <class _DifferenceType, class _ForwardIterator, class _UnaryPredicate>
587std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1(
588 _ForwardIterator,
589 _ForwardIterator,
590 bool* __restrict,
591 _UnaryPredicate,
592 /*vector=*/std::false_type) noexcept;
593template <class _DifferenceType, class _RandomAccessIterator, class _UnaryPredicate>
594std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1(
595 _RandomAccessIterator,
596 _RandomAccessIterator,
597 bool* __restrict,
598 _UnaryPredicate,
599 /*vector=*/std::true_type) noexcept;
600
601template <class _ForwardIterator, class _OutputIterator>
602void __brick_copy_by_mask(
603 _ForwardIterator,
604 _ForwardIterator,
605 _OutputIterator,
606 bool*,
607 /*vector=*/std::false_type) noexcept;
608
609template <class _RandomAccessIterator, class _OutputIterator>
610void __brick_copy_by_mask(
611 _RandomAccessIterator,
612 _RandomAccessIterator,
613 _OutputIterator,
614 bool* __restrict,
615 /*vector=*/std::true_type) noexcept;
616
617template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2>
618void __brick_partition_by_mask(
619 _ForwardIterator,
620 _ForwardIterator,
621 _OutputIterator1,
622 _OutputIterator2,
623 bool*,
624 /*vector=*/std::false_type) noexcept;
625
626template <class _RandomAccessIterator, class _OutputIterator1, class _OutputIterator2>
627void __brick_partition_by_mask(
628 _RandomAccessIterator,
629 _RandomAccessIterator,
630 _OutputIterator1,
631 _OutputIterator2,
632 bool*,
633 /*vector=*/std::true_type) noexcept;
634
635template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryPredicate>
636_OutputIterator __pattern_copy_if(
637 _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryPredicate) noexcept;
638
639template <class _IsVector,
640 class _ExecutionPolicy,
641 class _RandomAccessIterator,
642 class _OutputIterator,
643 class _UnaryPredicate>
644_OutputIterator __pattern_copy_if(
645 __parallel_tag<_IsVector>,
646 _ExecutionPolicy&&,
647 _RandomAccessIterator,
648 _RandomAccessIterator,
649 _OutputIterator,
650 _UnaryPredicate);
651
652//------------------------------------------------------------------------
653// count
654//------------------------------------------------------------------------
655
656template <class _RandomAccessIterator, class _Predicate>
657typename std::iterator_traits<_RandomAccessIterator>::difference_type __brick_count(
658 _RandomAccessIterator,
659 _RandomAccessIterator,
660 _Predicate,
661 /* is_vector = */ std::true_type) noexcept;
662
663template <class _ForwardIterator, class _Predicate>
664typename std::iterator_traits<_ForwardIterator>::difference_type __brick_count(
665 _ForwardIterator,
666 _ForwardIterator,
667 _Predicate,
668 /* is_vector = */ std::false_type) noexcept;
669
670template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
671typename std::iterator_traits<_ForwardIterator>::difference_type
672__pattern_count(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate) noexcept;
673
674template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Predicate>
675typename std::iterator_traits<_RandomAccessIterator>::difference_type __pattern_count(
676 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Predicate);
677
678//------------------------------------------------------------------------
679// unique
680//------------------------------------------------------------------------
681
682template <class _ForwardIterator, class _BinaryPredicate>
683_ForwardIterator __brick_unique(
684 _ForwardIterator,
685 _ForwardIterator,
686 _BinaryPredicate,
687 /*is_vector=*/std::false_type) noexcept;
688
689template <class _RandomAccessIterator, class _BinaryPredicate>
690_RandomAccessIterator __brick_unique(
691 _RandomAccessIterator,
692 _RandomAccessIterator,
693 _BinaryPredicate,
694 /*is_vector=*/std::true_type) noexcept;
695
696template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
697_ForwardIterator
698__pattern_unique(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate) noexcept;
699
700template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate>
701_RandomAccessIterator __pattern_unique(
702 __parallel_tag<_IsVector>,
703 _ExecutionPolicy&&,
704 _RandomAccessIterator,
705 _RandomAccessIterator,
706 _BinaryPredicate) noexcept;
707
708//------------------------------------------------------------------------
709// unique_copy
710//------------------------------------------------------------------------
711
712template <class _ForwardIterator, class OutputIterator, class _BinaryPredicate>
713OutputIterator __brick_unique_copy(
714 _ForwardIterator,
715 _ForwardIterator,
716 OutputIterator,
717 _BinaryPredicate,
718 /*vector=*/std::false_type) noexcept;
719
720template <class _RandomAccessIterator, class _OutputIterator, class _BinaryPredicate>
721_OutputIterator __brick_unique_copy(
722 _RandomAccessIterator,
723 _RandomAccessIterator,
724 _OutputIterator,
725 _BinaryPredicate,
726 /*vector=*/std::true_type) noexcept;
727
728template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryPredicate>
729_OutputIterator __pattern_unique_copy(
730 _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryPredicate) noexcept;
731
732template <class _ExecutionPolicy, class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate>
733_DifferenceType __brick_calc_mask_2(
734 _RandomAccessIterator,
735 _RandomAccessIterator,
736 bool* __restrict,
737 _BinaryPredicate,
738 /*vector=*/std::false_type) noexcept;
739
740template <class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate>
741_DifferenceType __brick_calc_mask_2(
742 _RandomAccessIterator,
743 _RandomAccessIterator,
744 bool* __restrict,
745 _BinaryPredicate,
746 /*vector=*/std::true_type) noexcept;
747
748template <class _IsVector,
749 class _ExecutionPolicy,
750 class _RandomAccessIterator,
751 class _OutputIterator,
752 class _BinaryPredicate>
753_OutputIterator __pattern_unique_copy(
754 __parallel_tag<_IsVector>,
755 _ExecutionPolicy&&,
756 _RandomAccessIterator,
757 _RandomAccessIterator,
758 _OutputIterator,
759 _BinaryPredicate);
760
761//------------------------------------------------------------------------
762// reverse
763//------------------------------------------------------------------------
764
765template <class _BidirectionalIterator>
766void __brick_reverse(_BidirectionalIterator,
767 _BidirectionalIterator,
768 /*__is_vector=*/std::false_type) noexcept;
769
770template <class _RandomAccessIterator>
771void __brick_reverse(_RandomAccessIterator,
772 _RandomAccessIterator,
773 /*__is_vector=*/std::true_type) noexcept;
774
775template <class _BidirectionalIterator>
776void __brick_reverse(_BidirectionalIterator,
777 _BidirectionalIterator,
778 _BidirectionalIterator,
779 /*is_vector=*/std::false_type) noexcept;
780
781template <class _RandomAccessIterator>
782void __brick_reverse(_RandomAccessIterator,
783 _RandomAccessIterator,
784 _RandomAccessIterator,
785 /*is_vector=*/std::true_type) noexcept;
786
787template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator>
788void __pattern_reverse(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator) noexcept;
789
790template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator>
791void __pattern_reverse(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator);
792
793//------------------------------------------------------------------------
794// reverse_copy
795//------------------------------------------------------------------------
796
797template <class _BidirectionalIterator, class _OutputIterator>
798_OutputIterator __brick_reverse_copy(
799 _BidirectionalIterator,
800 _BidirectionalIterator,
801 _OutputIterator,
802 /*is_vector=*/std::false_type) noexcept;
803
804template <class _RandomAccessIterator, class _OutputIterator>
805_OutputIterator __brick_reverse_copy(
806 _RandomAccessIterator,
807 _RandomAccessIterator,
808 _OutputIterator,
809 /*is_vector=*/std::true_type) noexcept;
810
811template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _OutputIterator>
812_OutputIterator __pattern_reverse_copy(
813 _Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _OutputIterator) noexcept;
814
815template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator>
816_OutputIterator __pattern_reverse_copy(
817 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator);
818
819//------------------------------------------------------------------------
820// rotate
821//------------------------------------------------------------------------
822
823template <class _ForwardIterator>
824_ForwardIterator __brick_rotate(
825 _ForwardIterator,
826 _ForwardIterator,
827 _ForwardIterator,
828 /*is_vector=*/std::false_type) noexcept;
829
830template <class _RandomAccessIterator>
831_RandomAccessIterator __brick_rotate(
832 _RandomAccessIterator,
833 _RandomAccessIterator,
834 _RandomAccessIterator,
835 /*is_vector=*/std::true_type) noexcept;
836
837template <class _Tag, class _ExecutionPolicy, class _ForwardIterator>
838_ForwardIterator
839__pattern_rotate(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator) noexcept;
840
841template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator>
842_RandomAccessIterator __pattern_rotate(
843 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator);
844
845//------------------------------------------------------------------------
846// rotate_copy
847//------------------------------------------------------------------------
848
849template <class _ForwardIterator, class _OutputIterator>
850_OutputIterator __brick_rotate_copy(
851 _ForwardIterator,
852 _ForwardIterator,
853 _ForwardIterator,
854 _OutputIterator,
855 /*__is_vector=*/std::false_type) noexcept;
856
857template <class _RandomAccessIterator, class _OutputIterator>
858_OutputIterator __brick_rotate_copy(
859 _RandomAccessIterator,
860 _RandomAccessIterator,
861 _RandomAccessIterator,
862 _OutputIterator,
863 /*__is_vector=*/std::true_type) noexcept;
864
865template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator>
866_OutputIterator __pattern_rotate_copy(
867 _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator) noexcept;
868
869template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator>
870_OutputIterator __pattern_rotate_copy(
871 __parallel_tag<_IsVector>,
872 _ExecutionPolicy&&,
873 _RandomAccessIterator,
874 _RandomAccessIterator,
875 _RandomAccessIterator,
876 _OutputIterator);
877
878//------------------------------------------------------------------------
879// is_partitioned
880//------------------------------------------------------------------------
881
882template <class _ForwardIterator, class _UnaryPredicate>
883bool __brick_is_partitioned(_ForwardIterator,
884 _ForwardIterator,
885 _UnaryPredicate,
886 /*is_vector=*/std::false_type) noexcept;
887
888template <class _RandomAccessIterator, class _UnaryPredicate>
889bool __brick_is_partitioned(_RandomAccessIterator,
890 _RandomAccessIterator,
891 _UnaryPredicate,
892 /*is_vector=*/std::true_type) noexcept;
893
894template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
895bool __pattern_is_partitioned(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept;
896
897template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
898bool __pattern_is_partitioned(
899 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate);
900
901//------------------------------------------------------------------------
902// partition
903//------------------------------------------------------------------------
904
905template <class _ForwardIterator, class _UnaryPredicate>
906_ForwardIterator __brick_partition(
907 _ForwardIterator,
908 _ForwardIterator,
909 _UnaryPredicate,
910 /*is_vector=*/std::false_type) noexcept;
911
912template <class _RandomAccessIterator, class _UnaryPredicate>
913_RandomAccessIterator __brick_partition(
914 _RandomAccessIterator,
915 _RandomAccessIterator,
916 _UnaryPredicate,
917 /*is_vector=*/std::true_type) noexcept;
918
919template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
920_ForwardIterator
921__pattern_partition(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept;
922
923template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
924_RandomAccessIterator __pattern_partition(
925 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate);
926
927//------------------------------------------------------------------------
928// stable_partition
929//------------------------------------------------------------------------
930
931template <class _BidirectionalIterator, class _UnaryPredicate>
932_BidirectionalIterator __brick_stable_partition(
933 _BidirectionalIterator,
934 _BidirectionalIterator,
935 _UnaryPredicate,
936 /*__is_vector=*/std::false_type) noexcept;
937
938template <class _RandomAccessIterator, class _UnaryPredicate>
939_RandomAccessIterator __brick_stable_partition(
940 _RandomAccessIterator,
941 _RandomAccessIterator,
942 _UnaryPredicate,
943 /*__is_vector=*/std::true_type) noexcept;
944
945template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate>
946_BidirectionalIterator __pattern_stable_partition(
947 _Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate) noexcept;
948
949template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
950_RandomAccessIterator __pattern_stable_partition(
951 __parallel_tag<_IsVector>,
952 _ExecutionPolicy&&,
953 _RandomAccessIterator,
954 _RandomAccessIterator,
955 _UnaryPredicate) noexcept;
956
957//------------------------------------------------------------------------
958// partition_copy
959//------------------------------------------------------------------------
960
961template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2, class _UnaryPredicate>
962std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy(
963 _ForwardIterator,
964 _ForwardIterator,
965 _OutputIterator1,
966 _OutputIterator2,
967 _UnaryPredicate,
968 /*is_vector=*/std::false_type) noexcept;
969
970template <class _RandomAccessIterator, class _OutputIterator1, class _OutputIterator2, class _UnaryPredicate>
971std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy(
972 _RandomAccessIterator,
973 _RandomAccessIterator,
974 _OutputIterator1,
975 _OutputIterator2,
976 _UnaryPredicate,
977 /*is_vector=*/std::true_type) noexcept;
978
979template <class _Tag,
980 class _ExecutionPolicy,
981 class _ForwardIterator,
982 class _OutputIterator1,
983 class _OutputIterator2,
984 class _UnaryPredicate>
985std::pair<_OutputIterator1, _OutputIterator2> __pattern_partition_copy(
986 _Tag,
987 _ExecutionPolicy&&,
988 _ForwardIterator,
989 _ForwardIterator,
990 _OutputIterator1,
991 _OutputIterator2,
992 _UnaryPredicate) noexcept;
993
994template <class _IsVector,
995 class _ExecutionPolicy,
996 class _RandomAccessIterator,
997 class _OutputIterator1,
998 class _OutputIterator2,
999 class _UnaryPredicate>
1000std::pair<_OutputIterator1, _OutputIterator2> __pattern_partition_copy(
1001 __parallel_tag<_IsVector>,
1002 _ExecutionPolicy&&,
1003 _RandomAccessIterator,
1004 _RandomAccessIterator,
1005 _OutputIterator1,
1006 _OutputIterator2,
1007 _UnaryPredicate);
1008
1009//------------------------------------------------------------------------
1010// sort
1011//------------------------------------------------------------------------
1012
1013template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsMoveConstructible>
1014void __pattern_sort(
1015 _Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsMoveConstructible) noexcept;
1016
1017template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1018void __pattern_sort(__parallel_tag<_IsVector>,
1019 _ExecutionPolicy&&,
1020 _RandomAccessIterator,
1021 _RandomAccessIterator,
1022 _Compare,
1023 /*is_move_constructible=*/std::true_type);
1024
1025//------------------------------------------------------------------------
1026// stable_sort
1027//------------------------------------------------------------------------
1028
1029template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1030void __pattern_stable_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept;
1031
1032template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1033void __pattern_stable_sort(
1034 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare);
1035
1036//------------------------------------------------------------------------
1037// partial_sort
1038//------------------------------------------------------------------------
1039
1040template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1041void __pattern_partial_sort(
1042 _Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept;
1043
1044template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1045void __pattern_partial_sort(
1046 __parallel_tag<_IsVector>,
1047 _ExecutionPolicy&&,
1048 _RandomAccessIterator,
1049 _RandomAccessIterator,
1050 _RandomAccessIterator,
1051 _Compare);
1052
1053//------------------------------------------------------------------------
1054// partial_sort_copy
1055//------------------------------------------------------------------------
1056
1057template <class _Tag,
1058 class _ExecutionPolicy,
1059 class _RandomAccessIterator1,
1060 class _RandomAccessIterator2,
1061 class _Compare>
1062_RandomAccessIterator2 __pattern_partial_sort_copy(
1063 _Tag,
1064 _ExecutionPolicy&&,
1065 _RandomAccessIterator1,
1066 _RandomAccessIterator1,
1067 _RandomAccessIterator2,
1068 _RandomAccessIterator2,
1069 _Compare) noexcept;
1070
1071template <class _IsVector,
1072 class _ExecutionPolicy,
1073 class _RandomAccessIterator1,
1074 class _RandomAccessIterator2,
1075 class _Compare>
1076_RandomAccessIterator2 __pattern_partial_sort_copy(
1077 __parallel_tag<_IsVector>,
1078 _ExecutionPolicy&&,
1079 _RandomAccessIterator1,
1080 _RandomAccessIterator1,
1081 _RandomAccessIterator2,
1082 _RandomAccessIterator2,
1083 _Compare);
1084
1085//------------------------------------------------------------------------
1086// adjacent_find
1087//------------------------------------------------------------------------
1088
1089template <class _RandomAccessIterator, class _BinaryPredicate>
1090_RandomAccessIterator __brick_adjacent_find(
1091 _RandomAccessIterator,
1092 _RandomAccessIterator,
1093 _BinaryPredicate,
1094 /* IsVector = */ std::true_type,
1095 bool) noexcept;
1096
1097template <class _ForwardIterator, class _BinaryPredicate>
1098_ForwardIterator __brick_adjacent_find(
1099 _ForwardIterator,
1100 _ForwardIterator,
1101 _BinaryPredicate,
1102 /* IsVector = */ std::false_type,
1103 bool) noexcept;
1104
1105template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
1106_ForwardIterator
1107__pattern_adjacent_find(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate, bool) noexcept;
1108
1109template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate>
1110_RandomAccessIterator __pattern_adjacent_find(
1111 __parallel_tag<_IsVector>,
1112 _ExecutionPolicy&&,
1113 _RandomAccessIterator,
1114 _RandomAccessIterator,
1115 _BinaryPredicate,
1116 bool);
1117
1118//------------------------------------------------------------------------
1119// nth_element
1120//------------------------------------------------------------------------
1121template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1122void __pattern_nth_element(
1123 _Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept;
1124
1125template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1126void __pattern_nth_element(
1127 __parallel_tag<_IsVector>,
1128 _ExecutionPolicy&&,
1129 _RandomAccessIterator,
1130 _RandomAccessIterator,
1131 _RandomAccessIterator,
1132 _Compare) noexcept;
1133
1134//------------------------------------------------------------------------
1135// fill, fill_n
1136//------------------------------------------------------------------------
1137template <class _RandomAccessIterator, class _Tp>
1138void __brick_fill(_RandomAccessIterator,
1139 _RandomAccessIterator,
1140 const _Tp&,
1141 /* __is_vector = */ std::true_type) noexcept;
1142
1143template <class _ForwardIterator, class _Tp>
1144void __brick_fill(_ForwardIterator,
1145 _ForwardIterator,
1146 const _Tp&,
1147 /* __is_vector = */ std::false_type) noexcept;
1148
1149template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Tp>
1150void __pattern_fill(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, const _Tp&) noexcept;
1151
1152template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Tp>
1153_RandomAccessIterator
1154__pattern_fill(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, const _Tp&);
1155
1156template <class _RandomAccessIterator, class _Size, class _Tp>
1157_RandomAccessIterator
1158__brick_fill_n(_RandomAccessIterator,
1159 _Size,
1160 const _Tp&,
1161 /* __is_vector = */ std::true_type) noexcept;
1162
1163template <class _OutputIterator, class _Size, class _Tp>
1164_OutputIterator
1165__brick_fill_n(_OutputIterator,
1166 _Size,
1167 const _Tp&,
1168 /* __is_vector = */ std::false_type) noexcept;
1169
1170template <class _Tag, class _ExecutionPolicy, class _OutputIterator, class _Size, class _Tp>
1171_OutputIterator __pattern_fill_n(_Tag, _ExecutionPolicy&&, _OutputIterator, _Size, const _Tp&) noexcept;
1172
1173template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Tp>
1174_RandomAccessIterator
1175__pattern_fill_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, const _Tp&);
1176
1177//------------------------------------------------------------------------
1178// generate, generate_n
1179//------------------------------------------------------------------------
1180
1181template <class _RandomAccessIterator, class _Generator>
1182void __brick_generate(_RandomAccessIterator,
1183 _RandomAccessIterator,
1184 _Generator,
1185 /* is_vector = */ std::true_type) noexcept;
1186
1187template <class _ForwardIterator, class _Generator>
1188void __brick_generate(_ForwardIterator,
1189 _ForwardIterator,
1190 _Generator,
1191 /* is_vector = */ std::false_type) noexcept;
1192
1193template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Generator>
1194void __pattern_generate(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Generator) noexcept;
1195
1196template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Generator>
1197_RandomAccessIterator __pattern_generate(
1198 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Generator);
1199
1200template <class _RandomAccessIterator, class Size, class _Generator>
1201_RandomAccessIterator __brick_generate_n(
1202 _RandomAccessIterator,
1203 Size,
1204 _Generator,
1205 /* is_vector = */ std::true_type) noexcept;
1206
1207template <class OutputIterator, class Size, class _Generator>
1208OutputIterator __brick_generate_n(
1209 OutputIterator,
1210 Size,
1211 _Generator,
1212 /* is_vector = */ std::false_type) noexcept;
1213
1214template <class _Tag, class _ExecutionPolicy, class OutputIterator, class Size, class _Generator>
1215OutputIterator __pattern_generate_n(_Tag, _ExecutionPolicy&&, OutputIterator, Size, _Generator) noexcept;
1216
1217template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class Size, class _Generator>
1218_RandomAccessIterator
1219__pattern_generate_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, Size, _Generator);
1220
1221//------------------------------------------------------------------------
1222// remove
1223//------------------------------------------------------------------------
1224template <class _ForwardIterator, class _UnaryPredicate>
1225_ForwardIterator __brick_remove_if(
1226 _ForwardIterator,
1227 _ForwardIterator,
1228 _UnaryPredicate,
1229 /* __is_vector = */ std::false_type) noexcept;
1230
1231template <class _RandomAccessIterator, class _UnaryPredicate>
1232_RandomAccessIterator __brick_remove_if(
1233 _RandomAccessIterator,
1234 _RandomAccessIterator,
1235 _UnaryPredicate,
1236 /* __is_vector = */ std::true_type) noexcept;
1237
1238template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
1239_ForwardIterator
1240__pattern_remove_if(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept;
1241
1242template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
1243_RandomAccessIterator __pattern_remove_if(
1244 __parallel_tag<_IsVector>,
1245 _ExecutionPolicy&&,
1246 _RandomAccessIterator,
1247 _RandomAccessIterator,
1248 _UnaryPredicate) noexcept;
1249
1250//------------------------------------------------------------------------
1251// merge
1252//------------------------------------------------------------------------
1253
1254template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
1255_OutputIterator __brick_merge(
1256 _ForwardIterator1,
1257 _ForwardIterator1,
1258 _ForwardIterator2,
1259 _ForwardIterator2,
1260 _OutputIterator,
1261 _Compare,
1262 /* __is_vector = */ std::false_type) noexcept;
1263
1264template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare>
1265_OutputIterator __brick_merge(
1266 _RandomAccessIterator1,
1267 _RandomAccessIterator1,
1268 _RandomAccessIterator2,
1269 _RandomAccessIterator2,
1270 _OutputIterator,
1271 _Compare,
1272 /* __is_vector = */ std::true_type) noexcept;
1273
1274template <class _Tag,
1275 class _ExecutionPolicy,
1276 class _ForwardIterator1,
1277 class _ForwardIterator2,
1278 class _OutputIterator,
1279 class _Compare>
1280_OutputIterator __pattern_merge(
1281 _Tag,
1282 _ExecutionPolicy&&,
1283 _ForwardIterator1,
1284 _ForwardIterator1,
1285 _ForwardIterator2,
1286 _ForwardIterator2,
1287 _OutputIterator,
1288 _Compare) noexcept;
1289
1290template <class _IsVector,
1291 class _ExecutionPolicy,
1292 class _RandomAccessIterator1,
1293 class _RandomAccessIterator2,
1294 class _OutputIterator,
1295 class _Compare>
1296_OutputIterator __pattern_merge(
1297 __parallel_tag<_IsVector>,
1298 _ExecutionPolicy&&,
1299 _RandomAccessIterator1,
1300 _RandomAccessIterator1,
1301 _RandomAccessIterator2,
1302 _RandomAccessIterator2,
1303 _OutputIterator,
1304 _Compare);
1305
1306//------------------------------------------------------------------------
1307// inplace_merge
1308//------------------------------------------------------------------------
1309
1310template <class _BidirectionalIterator, class _Compare>
1311void __brick_inplace_merge(
1312 _BidirectionalIterator,
1313 _BidirectionalIterator,
1314 _BidirectionalIterator,
1315 _Compare,
1316 /* __is_vector = */ std::false_type) noexcept;
1317
1318template <class _RandomAccessIterator, class _Compare>
1319void __brick_inplace_merge(
1320 _RandomAccessIterator,
1321 _RandomAccessIterator,
1322 _RandomAccessIterator,
1323 _Compare,
1324 /* __is_vector = */ std::true_type) noexcept;
1325
1326template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _Compare>
1327void __pattern_inplace_merge(
1328 _Tag,
1329 _ExecutionPolicy&&,
1330 _BidirectionalIterator,
1331 _BidirectionalIterator,
1332 _BidirectionalIterator,
1333 _Compare) noexcept;
1334
1335template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1336void __pattern_inplace_merge(
1337 __parallel_tag<_IsVector>,
1338 _ExecutionPolicy&&,
1339 _RandomAccessIterator,
1340 _RandomAccessIterator,
1341 _RandomAccessIterator,
1342 _Compare);
1343
1344//------------------------------------------------------------------------
1345// includes
1346//------------------------------------------------------------------------
1347
1348template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
1349bool __pattern_includes(
1350 _Tag,
1351 _ExecutionPolicy&&,
1352 _ForwardIterator1,
1353 _ForwardIterator1,
1354 _ForwardIterator2,
1355 _ForwardIterator2,
1356 _Compare) noexcept;
1357
1358template <class _IsVector,
1359 class _ExecutionPolicy,
1360 class _RandomAccessIterator1,
1361 class _RandomAccessIterator2,
1362 class _Compare>
1363bool __pattern_includes(
1364 __parallel_tag<_IsVector>,
1365 _ExecutionPolicy&&,
1366 _RandomAccessIterator1,
1367 _RandomAccessIterator1,
1368 _RandomAccessIterator2,
1369 _RandomAccessIterator2,
1370 _Compare);
1371
1372//------------------------------------------------------------------------
1373// set_union
1374//------------------------------------------------------------------------
1375
1376template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
1377_OutputIterator __brick_set_union(
1378 _ForwardIterator1,
1379 _ForwardIterator1,
1380 _ForwardIterator2,
1381 _ForwardIterator2,
1382 _OutputIterator,
1383 _Compare,
1384 /*__is_vector=*/std::false_type) noexcept;
1385
1386template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare>
1387_OutputIterator __brick_set_union(
1388 _RandomAccessIterator1,
1389 _RandomAccessIterator1,
1390 _RandomAccessIterator2,
1391 _RandomAccessIterator2,
1392 _OutputIterator,
1393 _Compare,
1394 /*__is_vector=*/std::true_type) noexcept;
1395
1396template <class _Tag,
1397 class _ExecutionPolicy,
1398 class _ForwardIterator1,
1399 class _ForwardIterator2,
1400 class _OutputIterator,
1401 class _Compare>
1402_OutputIterator __pattern_set_union(
1403 _Tag,
1404 _ExecutionPolicy&&,
1405 _ForwardIterator1,
1406 _ForwardIterator1,
1407 _ForwardIterator2,
1408 _ForwardIterator2,
1409 _OutputIterator,
1410 _Compare) noexcept;
1411
1412template <class _IsVector,
1413 class _ExecutionPolicy,
1414 class _RandomAccessIterator1,
1415 class _RandomAccessIterator2,
1416 class _OutputIterator,
1417 class _Compare>
1418_OutputIterator __pattern_set_union(
1419 __parallel_tag<_IsVector>,
1420 _ExecutionPolicy&&,
1421 _RandomAccessIterator1,
1422 _RandomAccessIterator1,
1423 _RandomAccessIterator2,
1424 _RandomAccessIterator2,
1425 _OutputIterator,
1426 _Compare);
1427
1428//------------------------------------------------------------------------
1429// set_intersection
1430//------------------------------------------------------------------------
1431
1432template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
1433_OutputIterator __brick_set_intersection(
1434 _ForwardIterator1,
1435 _ForwardIterator1,
1436 _ForwardIterator2,
1437 _ForwardIterator2,
1438 _OutputIterator,
1439 _Compare,
1440 /*__is_vector=*/std::false_type) noexcept;
1441
1442template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare>
1443_OutputIterator __brick_set_intersection(
1444 _RandomAccessIterator1,
1445 _RandomAccessIterator1,
1446 _RandomAccessIterator2,
1447 _RandomAccessIterator2,
1448 _OutputIterator,
1449 _Compare,
1450 /*__is_vector=*/std::true_type) noexcept;
1451
1452template <class _Tag,
1453 class _ExecutionPolicy,
1454 class _ForwardIterator1,
1455 class _ForwardIterator2,
1456 class _OutputIterator,
1457 class _Compare>
1458_OutputIterator __pattern_set_intersection(
1459 _Tag,
1460 _ExecutionPolicy&&,
1461 _ForwardIterator1,
1462 _ForwardIterator1,
1463 _ForwardIterator2,
1464 _ForwardIterator2,
1465 _OutputIterator,
1466 _Compare) noexcept;
1467
1468template <class _IsVector,
1469 class _ExecutionPolicy,
1470 class _RandomAccessIterator1,
1471 class _RandomAccessIterator2,
1472 class _OutputIterator,
1473 class _Compare>
1474_OutputIterator __pattern_set_intersection(
1475 __parallel_tag<_IsVector>,
1476 _ExecutionPolicy&&,
1477 _RandomAccessIterator1,
1478 _RandomAccessIterator1,
1479 _RandomAccessIterator2,
1480 _RandomAccessIterator2,
1481 _OutputIterator,
1482 _Compare);
1483
1484//------------------------------------------------------------------------
1485// set_difference
1486//------------------------------------------------------------------------
1487
1488template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
1489_OutputIterator __brick_set_difference(
1490 _ForwardIterator1,
1491 _ForwardIterator1,
1492 _ForwardIterator2,
1493 _ForwardIterator2,
1494 _OutputIterator,
1495 _Compare,
1496 /*__is_vector=*/std::false_type) noexcept;
1497
1498template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare>
1499_OutputIterator __brick_set_difference(
1500 _RandomAccessIterator1,
1501 _RandomAccessIterator1,
1502 _RandomAccessIterator2,
1503 _RandomAccessIterator2,
1504 _OutputIterator,
1505 _Compare,
1506 /*__is_vector=*/std::true_type) noexcept;
1507
1508template <class _Tag,
1509 class _ExecutionPolicy,
1510 class _ForwardIterator1,
1511 class _ForwardIterator2,
1512 class _OutputIterator,
1513 class _Compare>
1514_OutputIterator __pattern_set_difference(
1515 _Tag,
1516 _ExecutionPolicy&&,
1517 _ForwardIterator1,
1518 _ForwardIterator1,
1519 _ForwardIterator2,
1520 _ForwardIterator2,
1521 _OutputIterator,
1522 _Compare) noexcept;
1523
1524template <class _IsVector,
1525 class _ExecutionPolicy,
1526 class _RandomAccessIterator1,
1527 class _RandomAccessIterator2,
1528 class _OutputIterator,
1529 class _Compare>
1530_OutputIterator __pattern_set_difference(
1531 __parallel_tag<_IsVector>,
1532 _ExecutionPolicy&&,
1533 _RandomAccessIterator1,
1534 _RandomAccessIterator1,
1535 _RandomAccessIterator2,
1536 _RandomAccessIterator2,
1537 _OutputIterator,
1538 _Compare);
1539
1540//------------------------------------------------------------------------
1541// set_symmetric_difference
1542//------------------------------------------------------------------------
1543
1544template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
1545_OutputIterator __brick_set_symmetric_difference(
1546 _ForwardIterator1,
1547 _ForwardIterator1,
1548 _ForwardIterator2,
1549 _ForwardIterator2,
1550 _OutputIterator,
1551 _Compare,
1552 /*__is_vector=*/std::false_type) noexcept;
1553
1554template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare>
1555_OutputIterator __brick_set_symmetric_difference(
1556 _RandomAccessIterator1,
1557 _RandomAccessIterator1,
1558 _RandomAccessIterator2,
1559 _RandomAccessIterator2,
1560 _OutputIterator,
1561 _Compare,
1562 /*__is_vector=*/std::true_type) noexcept;
1563
1564template <class _Tag,
1565 class _ExecutionPolicy,
1566 class _ForwardIterator1,
1567 class _ForwardIterator2,
1568 class _OutputIterator,
1569 class _Compare>
1570_OutputIterator __pattern_set_symmetric_difference(
1571 _Tag,
1572 _ExecutionPolicy&&,
1573 _ForwardIterator1,
1574 _ForwardIterator1,
1575 _ForwardIterator2,
1576 _ForwardIterator2,
1577 _OutputIterator,
1578 _Compare) noexcept;
1579
1580template <class _IsVector,
1581 class _ExecutionPolicy,
1582 class _RandomAccessIterator1,
1583 class _RandomAccessIterator2,
1584 class _OutputIterator,
1585 class _Compare>
1586_OutputIterator __pattern_set_symmetric_difference(
1587 __parallel_tag<_IsVector>,
1588 _ExecutionPolicy&&,
1589 _RandomAccessIterator1,
1590 _RandomAccessIterator1,
1591 _RandomAccessIterator2,
1592 _RandomAccessIterator2,
1593 _OutputIterator,
1594 _Compare);
1595
1596//------------------------------------------------------------------------
1597// is_heap_until
1598//------------------------------------------------------------------------
1599
1600template <class _RandomAccessIterator, class _Compare>
1601_RandomAccessIterator __brick_is_heap_until(
1602 _RandomAccessIterator,
1603 _RandomAccessIterator,
1604 _Compare,
1605 /* __is_vector = */ std::false_type) noexcept;
1606
1607template <class _RandomAccessIterator, class _Compare>
1608_RandomAccessIterator __brick_is_heap_until(
1609 _RandomAccessIterator,
1610 _RandomAccessIterator,
1611 _Compare,
1612 /* __is_vector = */ std::true_type) noexcept;
1613
1614template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1615_RandomAccessIterator
1616__pattern_is_heap_until(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept;
1617
1618template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1619_RandomAccessIterator __pattern_is_heap_until(
1620 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept;
1621
1622//------------------------------------------------------------------------
1623// min_element
1624//------------------------------------------------------------------------
1625
1626template <typename _ForwardIterator, typename _Compare>
1627_ForwardIterator __brick_min_element(
1628 _ForwardIterator,
1629 _ForwardIterator,
1630 _Compare,
1631 /* __is_vector = */ std::false_type) noexcept;
1632
1633template <typename _RandomAccessIterator, typename _Compare>
1634_RandomAccessIterator __brick_min_element(
1635 _RandomAccessIterator,
1636 _RandomAccessIterator,
1637 _Compare,
1638 /* __is_vector = */ std::true_type) noexcept;
1639
1640template <typename _Tag, typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare>
1641_ForwardIterator __pattern_min_element(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare) noexcept;
1642
1643template <typename _IsVector, typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare>
1644_RandomAccessIterator __pattern_min_element(
1645 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare);
1646
1647//------------------------------------------------------------------------
1648// minmax_element
1649//------------------------------------------------------------------------
1650
1651template <typename _ForwardIterator, typename _Compare>
1652std::pair<_ForwardIterator, _ForwardIterator> __brick_minmax_element(
1653 _ForwardIterator,
1654 _ForwardIterator,
1655 _Compare,
1656 /* __is_vector = */ std::false_type) noexcept;
1657
1658template <typename _RandomAccessIterator, typename _Compare>
1659std::pair<_RandomAccessIterator, _RandomAccessIterator> __brick_minmax_element(
1660 _RandomAccessIterator,
1661 _RandomAccessIterator,
1662 _Compare,
1663 /* __is_vector = */ std::true_type) noexcept;
1664
1665template <typename _Tag, typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare>
1666std::pair<_ForwardIterator, _ForwardIterator>
1667__pattern_minmax_element(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare) noexcept;
1668
1669template <typename _IsVector, typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare>
1670std::pair<_RandomAccessIterator, _RandomAccessIterator> __pattern_minmax_element(
1671 __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare);
1672
1673//------------------------------------------------------------------------
1674// mismatch
1675//------------------------------------------------------------------------
1676
1677template <class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
1678std::pair<_ForwardIterator1, _ForwardIterator2> __brick_mismatch(
1679 _ForwardIterator1,
1680 _ForwardIterator1,
1681 _ForwardIterator2,
1682 _ForwardIterator2,
1683 _Predicate,
1684 /* __is_vector = */ std::false_type) noexcept;
1685
1686template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Predicate>
1687std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __brick_mismatch(
1688 _RandomAccessIterator1,
1689 _RandomAccessIterator1,
1690 _RandomAccessIterator2,
1691 _RandomAccessIterator2,
1692 _Predicate,
1693 /* __is_vector = */ std::true_type) noexcept;
1694
1695template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
1696std::pair<_ForwardIterator1, _ForwardIterator2> __pattern_mismatch(
1697 _Tag,
1698 _ExecutionPolicy&&,
1699 _ForwardIterator1,
1700 _ForwardIterator1,
1701 _ForwardIterator2,
1702 _ForwardIterator2,
1703 _Predicate) noexcept;
1704
1705template <class _IsVector,
1706 class _ExecutionPolicy,
1707 class _RandomAccessIterator1,
1708 class _RandomAccessIterator2,
1709 class _Predicate>
1710std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __pattern_mismatch(
1711 __parallel_tag<_IsVector>,
1712 _ExecutionPolicy&&,
1713 _RandomAccessIterator1,
1714 _RandomAccessIterator1,
1715 _RandomAccessIterator2,
1716 _RandomAccessIterator2,
1717 _Predicate) noexcept;
1718
1719//------------------------------------------------------------------------
1720// lexicographical_compare
1721//------------------------------------------------------------------------
1722
1723template <class _ForwardIterator1, class _ForwardIterator2, class _Compare>
1724bool __brick_lexicographical_compare(
1725 _ForwardIterator1,
1726 _ForwardIterator1,
1727 _ForwardIterator2,
1728 _ForwardIterator2,
1729 _Compare,
1730 /* __is_vector = */ std::false_type) noexcept;
1731
1732template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Compare>
1733bool __brick_lexicographical_compare(
1734 _RandomAccessIterator1,
1735 _RandomAccessIterator1,
1736 _RandomAccessIterator2,
1737 _RandomAccessIterator2,
1738 _Compare,
1739 /* __is_vector = */ std::true_type) noexcept;
1740
1741template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
1742bool __pattern_lexicographical_compare(
1743 _Tag,
1744 _ExecutionPolicy&&,
1745 _ForwardIterator1,
1746 _ForwardIterator1,
1747 _ForwardIterator2,
1748 _ForwardIterator2,
1749 _Compare) noexcept;
1750
1751template <class _IsVector,
1752 class _ExecutionPolicy,
1753 class _RandomAccessIterator1,
1754 class _RandomAccessIterator2,
1755 class _Compare>
1756bool __pattern_lexicographical_compare(
1757 __parallel_tag<_IsVector>,
1758 _ExecutionPolicy&&,
1759 _RandomAccessIterator1,
1760 _RandomAccessIterator1,
1761 _RandomAccessIterator2,
1762 _RandomAccessIterator2,
1763 _Compare) noexcept;
1764
1765} // namespace __internal
1766} // namespace __pstl
1767
1768#endif /* _PSTL_ALGORITHM_FWD_H */
lib/libcxx/include/__pstl/internal/algorithm_impl.h created+4174
......@@ -0,0 +1,4174 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_ALGORITHM_IMPL_H
11#define _PSTL_ALGORITHM_IMPL_H
12
13#include <__assert>
14#include <__config>
15#include <algorithm>
16#include <functional>
17#include <iterator>
18#include <type_traits>
19#include <utility>
20
21#include "execution_impl.h"
22#include "memory_impl.h"
23#include "parallel_backend.h"
24#include "parallel_backend_utils.h"
25#include "parallel_impl.h"
26#include "unseq_backend_simd.h"
27
28namespace __pstl {
29namespace __internal {
30
31// [alg.foreach]
32// for_each_n with no policy
33
34template <class _ForwardIterator, class _Size, class _Function>
35_ForwardIterator __for_each_n_it_serial(_ForwardIterator __first, _Size __n, _Function __f) {
36 for (; __n > 0; ++__first, --__n)
37 __f(__first);
38 return __first;
39}
40
41//------------------------------------------------------------------------
42// walk1 (pseudo)
43//
44// walk1 evaluates f(x) for each dereferenced value x drawn from [first,last)
45//------------------------------------------------------------------------
46template <class _ForwardIterator, class _Function>
47void __brick_walk1(
48 _ForwardIterator __first, _ForwardIterator __last, _Function __f, /*vector=*/std::false_type) noexcept {
49 std::for_each(__first, __last, __f);
50}
51
52template <class _RandomAccessIterator, class _Function>
53void __brick_walk1(_RandomAccessIterator __first,
54 _RandomAccessIterator __last,
55 _Function __f,
56 /*vector=*/std::true_type) noexcept {
57 __unseq_backend::__simd_walk_1(__first, __last - __first, __f);
58}
59
60template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Function>
61void __pattern_walk1(
62 _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __f) noexcept {
63 __internal::__brick_walk1(__first, __last, __f, typename _Tag::__is_vector{});
64}
65
66template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Function>
67void __pattern_walk1(__parallel_tag<_IsVector> __tag,
68 _ExecutionPolicy&& __exec,
69 _RandomAccessIterator __first,
70 _RandomAccessIterator __last,
71 _Function __f) {
72 using __backend_tag = typename decltype(__tag)::__backend_tag;
73
74 __internal::__except_handler([&]() {
75 __par_backend::__parallel_for(
76 __backend_tag{},
77 std::forward<_ExecutionPolicy>(__exec),
78 __first,
79 __last,
80 [__f](_RandomAccessIterator __i, _RandomAccessIterator __j) {
81 __internal::__brick_walk1(__i, __j, __f, _IsVector{});
82 });
83 });
84}
85
86template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Brick>
87void __pattern_walk_brick(
88 _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Brick __brick) noexcept {
89 __brick(__first, __last);
90}
91
92template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Brick>
93void __pattern_walk_brick(
94 __parallel_tag<_IsVector> __tag,
95 _ExecutionPolicy&& __exec,
96 _RandomAccessIterator __first,
97 _RandomAccessIterator __last,
98 _Brick __brick) {
99 using __backend_tag = typename decltype(__tag)::__backend_tag;
100
101 __internal::__except_handler([&]() {
102 __par_backend::__parallel_for(
103 __backend_tag{},
104 std::forward<_ExecutionPolicy>(__exec),
105 __first,
106 __last,
107 [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j); });
108 });
109}
110
111//------------------------------------------------------------------------
112// walk1_n
113//------------------------------------------------------------------------
114template <class _ForwardIterator, class _Size, class _Function>
115_ForwardIterator __brick_walk1_n(_ForwardIterator __first, _Size __n, _Function __f, /*_IsVectorTag=*/std::false_type) {
116 return __internal::__for_each_n_it_serial(__first, __n, [&__f](_ForwardIterator __it) {
117 __f(*__it);
118 }); // calling serial version
119}
120
121template <class _RandomAccessIterator, class _DifferenceType, class _Function>
122_RandomAccessIterator
123__brick_walk1_n(_RandomAccessIterator __first,
124 _DifferenceType __n,
125 _Function __f,
126 /*vectorTag=*/std::true_type) noexcept {
127 return __unseq_backend::__simd_walk_1(__first, __n, __f);
128}
129
130template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function>
131_ForwardIterator
132__pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Function __f) noexcept {
133 return __internal::__brick_walk1_n(__first, __n, __f, typename _Tag::__is_vector{});
134}
135
136template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Function>
137_RandomAccessIterator __pattern_walk1_n(
138 __parallel_tag<_IsVector> __tag,
139 _ExecutionPolicy&& __exec,
140 _RandomAccessIterator __first,
141 _Size __n,
142 _Function __f) {
143 __internal::__pattern_walk1(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, __f);
144
145 return __first + __n;
146}
147
148template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Brick>
149_ForwardIterator
150__pattern_walk_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Brick __brick) noexcept {
151 return __brick(__first, __n);
152}
153
154template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Brick>
155_RandomAccessIterator __pattern_walk_brick_n(
156 __parallel_tag<_IsVector> __tag,
157 _ExecutionPolicy&& __exec,
158 _RandomAccessIterator __first,
159 _Size __n,
160 _Brick __brick) {
161 using __backend_tag = typename decltype(__tag)::__backend_tag;
162
163 return __internal::__except_handler([&]() {
164 __par_backend::__parallel_for(
165 __backend_tag{},
166 std::forward<_ExecutionPolicy>(__exec),
167 __first,
168 __first + __n,
169 [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j - __i); });
170 return __first + __n;
171 });
172}
173
174//------------------------------------------------------------------------
175// walk2 (pseudo)
176//
177// walk2 evaluates f(x,y) for deferenced values (x,y) drawn from [first1,last1) and [first2,...)
178//------------------------------------------------------------------------
179template <class _ForwardIterator1, class _ForwardIterator2, class _Function>
180_ForwardIterator2
181__brick_walk2(_ForwardIterator1 __first1,
182 _ForwardIterator1 __last1,
183 _ForwardIterator2 __first2,
184 _Function __f,
185 /*vector=*/std::false_type) noexcept {
186 for (; __first1 != __last1; ++__first1, ++__first2)
187 __f(*__first1, *__first2);
188 return __first2;
189}
190
191template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Function>
192_RandomAccessIterator2
193__brick_walk2(_RandomAccessIterator1 __first1,
194 _RandomAccessIterator1 __last1,
195 _RandomAccessIterator2 __first2,
196 _Function __f,
197 /*vector=*/std::true_type) noexcept {
198 return __unseq_backend::__simd_walk_2(__first1, __last1 - __first1, __first2, __f);
199}
200
201template <class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Function>
202_ForwardIterator2 __brick_walk2_n(
203 _ForwardIterator1 __first1,
204 _Size __n,
205 _ForwardIterator2 __first2,
206 _Function __f,
207 /*vector=*/std::false_type) noexcept {
208 for (; __n > 0; --__n, ++__first1, ++__first2)
209 __f(*__first1, *__first2);
210 return __first2;
211}
212
213template <class _RandomAccessIterator1, class _Size, class _RandomAccessIterator2, class _Function>
214_RandomAccessIterator2 __brick_walk2_n(
215 _RandomAccessIterator1 __first1,
216 _Size __n,
217 _RandomAccessIterator2 __first2,
218 _Function __f,
219 /*vector=*/std::true_type) noexcept {
220 return __unseq_backend::__simd_walk_2(__first1, __n, __first2, __f);
221}
222
223template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Function>
224_ForwardIterator2 __pattern_walk2(
225 _Tag,
226 _ExecutionPolicy&&,
227 _ForwardIterator1 __first1,
228 _ForwardIterator1 __last1,
229 _ForwardIterator2 __first2,
230 _Function __f) noexcept {
231 return __internal::__brick_walk2(__first1, __last1, __first2, __f, typename _Tag::__is_vector{});
232}
233
234template <class _IsVector,
235 class _ExecutionPolicy,
236 class _RandomAccessIterator1,
237 class _RandomAccessIterator2,
238 class _Function>
239_RandomAccessIterator2 __pattern_walk2(
240 __parallel_tag<_IsVector> __tag,
241 _ExecutionPolicy&& __exec,
242 _RandomAccessIterator1 __first1,
243 _RandomAccessIterator1 __last1,
244 _RandomAccessIterator2 __first2,
245 _Function __f) {
246 using __backend_tag = typename decltype(__tag)::__backend_tag;
247
248 return __internal::__except_handler([&]() {
249 __par_backend::__parallel_for(
250 __backend_tag{},
251 std::forward<_ExecutionPolicy>(__exec),
252 __first1,
253 __last1,
254 [__f, __first1, __first2](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
255 __internal::__brick_walk2(__i, __j, __first2 + (__i - __first1), __f, _IsVector{});
256 });
257 return __first2 + (__last1 - __first1);
258 });
259}
260
261template <class _Tag,
262 class _ExecutionPolicy,
263 class _ForwardIterator1,
264 class _Size,
265 class _ForwardIterator2,
266 class _Function>
267_ForwardIterator2 __pattern_walk2_n(
268 _Tag,
269 _ExecutionPolicy&&,
270 _ForwardIterator1 __first1,
271 _Size __n,
272 _ForwardIterator2 __first2,
273 _Function __f) noexcept {
274 return __internal::__brick_walk2_n(__first1, __n, __first2, __f, typename _Tag::__is_vector{});
275}
276
277template <class _IsVector,
278 class _ExecutionPolicy,
279 class _RandomAccessIterator1,
280 class _Size,
281 class _RandomAccessIterator2,
282 class _Function>
283_RandomAccessIterator2 __pattern_walk2_n(
284 __parallel_tag<_IsVector> __tag,
285 _ExecutionPolicy&& __exec,
286 _RandomAccessIterator1 __first1,
287 _Size __n,
288 _RandomAccessIterator2 __first2,
289 _Function __f) {
290 return __internal::__pattern_walk2(
291 __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, __first2, __f);
292}
293
294template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Brick>
295_ForwardIterator2 __pattern_walk2_brick(
296 _Tag,
297 _ExecutionPolicy&&,
298 _ForwardIterator1 __first1,
299 _ForwardIterator1 __last1,
300 _ForwardIterator2 __first2,
301 _Brick __brick) noexcept {
302 return __brick(__first1, __last1, __first2);
303}
304
305template <class _IsVector,
306 class _ExecutionPolicy,
307 class _RandomAccessIterator1,
308 class _RandomAccessIterator2,
309 class _Brick>
310_RandomAccessIterator2 __pattern_walk2_brick(
311 __parallel_tag<_IsVector> __tag,
312 _ExecutionPolicy&& __exec,
313 _RandomAccessIterator1 __first1,
314 _RandomAccessIterator1 __last1,
315 _RandomAccessIterator2 __first2,
316 _Brick __brick) {
317 using __backend_tag = typename decltype(__tag)::__backend_tag;
318
319 return __internal::__except_handler([&]() {
320 __par_backend::__parallel_for(
321 __backend_tag{},
322 std::forward<_ExecutionPolicy>(__exec),
323 __first1,
324 __last1,
325 [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
326 __brick(__i, __j, __first2 + (__i - __first1));
327 });
328 return __first2 + (__last1 - __first1);
329 });
330}
331
332template <class _Tag,
333 class _ExecutionPolicy,
334 class _ForwardIterator1,
335 class _Size,
336 class _ForwardIterator2,
337 class _Brick>
338_ForwardIterator2 __pattern_walk2_brick_n(
339 _Tag,
340 _ExecutionPolicy&&,
341 _ForwardIterator1 __first1,
342 _Size __n,
343 _ForwardIterator2 __first2,
344 _Brick __brick) noexcept {
345 return __brick(__first1, __n, __first2);
346}
347
348template <class _IsVector,
349 class _ExecutionPolicy,
350 class _RandomAccessIterator1,
351 class _Size,
352 class _RandomAccessIterator2,
353 class _Brick>
354_RandomAccessIterator2 __pattern_walk2_brick_n(
355 __parallel_tag<_IsVector> __tag,
356 _ExecutionPolicy&& __exec,
357 _RandomAccessIterator1 __first1,
358 _Size __n,
359 _RandomAccessIterator2 __first2,
360 _Brick __brick) {
361 using __backend_tag = typename decltype(__tag)::__backend_tag;
362
363 return __internal::__except_handler([&]() {
364 __par_backend::__parallel_for(
365 __backend_tag{},
366 std::forward<_ExecutionPolicy>(__exec),
367 __first1,
368 __first1 + __n,
369 [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
370 __brick(__i, __j - __i, __first2 + (__i - __first1));
371 });
372 return __first2 + __n;
373 });
374}
375
376//------------------------------------------------------------------------
377// walk3 (pseudo)
378//
379// walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...)
380//------------------------------------------------------------------------
381template <class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator3, class _Function>
382_ForwardIterator3 __brick_walk3(
383 _ForwardIterator1 __first1,
384 _ForwardIterator1 __last1,
385 _ForwardIterator2 __first2,
386 _ForwardIterator3 __first3,
387 _Function __f,
388 /*vector=*/std::false_type) noexcept {
389 for (; __first1 != __last1; ++__first1, ++__first2, ++__first3)
390 __f(*__first1, *__first2, *__first3);
391 return __first3;
392}
393
394template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Function>
395_RandomAccessIterator3 __brick_walk3(
396 _RandomAccessIterator1 __first1,
397 _RandomAccessIterator1 __last1,
398 _RandomAccessIterator2 __first2,
399 _RandomAccessIterator3 __first3,
400 _Function __f,
401 /*vector=*/std::true_type) noexcept {
402 return __unseq_backend::__simd_walk_3(__first1, __last1 - __first1, __first2, __first3, __f);
403}
404
405template <class _Tag,
406 class _ExecutionPolicy,
407 class _ForwardIterator1,
408 class _ForwardIterator2,
409 class _ForwardIterator3,
410 class _Function>
411_ForwardIterator3 __pattern_walk3(
412 _Tag,
413 _ExecutionPolicy&&,
414 _ForwardIterator1 __first1,
415 _ForwardIterator1 __last1,
416 _ForwardIterator2 __first2,
417 _ForwardIterator3 __first3,
418 _Function __f) noexcept {
419 return __internal::__brick_walk3(__first1, __last1, __first2, __first3, __f, typename _Tag::__is_vector{});
420}
421
422template <class _IsVector,
423 class _ExecutionPolicy,
424 class _RandomAccessIterator1,
425 class _RandomAccessIterator2,
426 class _RandomAccessIterator3,
427 class _Function>
428_RandomAccessIterator3 __pattern_walk3(
429 __parallel_tag<_IsVector> __tag,
430 _ExecutionPolicy&& __exec,
431 _RandomAccessIterator1 __first1,
432 _RandomAccessIterator1 __last1,
433 _RandomAccessIterator2 __first2,
434 _RandomAccessIterator3 __first3,
435 _Function __f) {
436 using __backend_tag = typename decltype(__tag)::__backend_tag;
437
438 return __internal::__except_handler([&]() {
439 __par_backend::__parallel_for(
440 __backend_tag{},
441 std::forward<_ExecutionPolicy>(__exec),
442 __first1,
443 __last1,
444 [__f, __first1, __first2, __first3](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
445 __internal::__brick_walk3(
446 __i, __j, __first2 + (__i - __first1), __first3 + (__i - __first1), __f, _IsVector{});
447 });
448 return __first3 + (__last1 - __first1);
449 });
450}
451
452//------------------------------------------------------------------------
453// equal
454//------------------------------------------------------------------------
455
456template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
457bool __brick_equal(_ForwardIterator1 __first1,
458 _ForwardIterator1 __last1,
459 _ForwardIterator2 __first2,
460 _ForwardIterator2 __last2,
461 _BinaryPredicate __p,
462 /* IsVector = */ std::false_type) noexcept {
463 return std::equal(__first1, __last1, __first2, __last2, __p);
464}
465
466template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
467bool __brick_equal(_RandomAccessIterator1 __first1,
468 _RandomAccessIterator1 __last1,
469 _RandomAccessIterator2 __first2,
470 _RandomAccessIterator2 __last2,
471 _BinaryPredicate __p,
472 /* is_vector = */ std::true_type) noexcept {
473 if (__last1 - __first1 != __last2 - __first2)
474 return false;
475
476 return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1;
477}
478
479template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
480bool __pattern_equal(
481 _Tag,
482 _ExecutionPolicy&&,
483 _ForwardIterator1 __first1,
484 _ForwardIterator1 __last1,
485 _ForwardIterator2 __first2,
486 _ForwardIterator2 __last2,
487 _BinaryPredicate __p) noexcept {
488 return __internal::__brick_equal(__first1, __last1, __first2, __last2, __p, typename _Tag::__is_vector{});
489}
490
491template <class _IsVector,
492 class _ExecutionPolicy,
493 class _RandomAccessIterator1,
494 class _RandomAccessIterator2,
495 class _BinaryPredicate>
496bool __pattern_equal(
497 __parallel_tag<_IsVector> __tag,
498 _ExecutionPolicy&& __exec,
499 _RandomAccessIterator1 __first1,
500 _RandomAccessIterator1 __last1,
501 _RandomAccessIterator2 __first2,
502 _RandomAccessIterator2 __last2,
503 _BinaryPredicate __p) {
504 using __backend_tag = typename decltype(__tag)::__backend_tag;
505
506 if (__last1 - __first1 != __last2 - __first2)
507 return false;
508
509 return __internal::__except_handler([&]() {
510 return !__internal::__parallel_or(
511 __backend_tag{},
512 std::forward<_ExecutionPolicy>(__exec),
513 __first1,
514 __last1,
515 [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
516 return !__internal::__brick_equal(
517 __i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), __p, _IsVector{});
518 });
519 });
520}
521
522//------------------------------------------------------------------------
523// equal version for sequences with equal length
524//------------------------------------------------------------------------
525
526template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
527bool __brick_equal(_ForwardIterator1 __first1,
528 _ForwardIterator1 __last1,
529 _ForwardIterator2 __first2,
530 _BinaryPredicate __p,
531 /* IsVector = */ std::false_type) noexcept {
532 return std::equal(__first1, __last1, __first2, __p);
533}
534
535template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
536bool __brick_equal(_RandomAccessIterator1 __first1,
537 _RandomAccessIterator1 __last1,
538 _RandomAccessIterator2 __first2,
539 _BinaryPredicate __p,
540 /* is_vector = */ std::true_type) noexcept {
541 return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1;
542}
543
544template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
545bool __pattern_equal(
546 _Tag,
547 _ExecutionPolicy&&,
548 _ForwardIterator1 __first1,
549 _ForwardIterator1 __last1,
550 _ForwardIterator2 __first2,
551 _BinaryPredicate __p) noexcept {
552 return __internal::__brick_equal(__first1, __last1, __first2, __p, typename _Tag::__is_vector{});
553}
554
555template <class _IsVector,
556 class _ExecutionPolicy,
557 class _RandomAccessIterator1,
558 class _RandomAccessIterator2,
559 class _BinaryPredicate>
560bool __pattern_equal(
561 __parallel_tag<_IsVector> __tag,
562 _ExecutionPolicy&& __exec,
563 _RandomAccessIterator1 __first1,
564 _RandomAccessIterator1 __last1,
565 _RandomAccessIterator2 __first2,
566 _BinaryPredicate __p) {
567 using __backend_tag = typename decltype(__tag)::__backend_tag;
568
569 return __internal::__except_handler([&]() {
570 return !__internal::__parallel_or(
571 __backend_tag{},
572 std::forward<_ExecutionPolicy>(__exec),
573 __first1,
574 __last1,
575 [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
576 return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __p, _IsVector{});
577 });
578 });
579}
580
581//------------------------------------------------------------------------
582// find_end
583//------------------------------------------------------------------------
584
585// find the first occurrence of the subsequence [s_first, s_last)
586// or the last occurrence of the subsequence in the range [first, last)
587// b_first determines what occurrence we want to find (first or last)
588template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate, class _IsVector>
589_RandomAccessIterator1 __find_subrange(
590 _RandomAccessIterator1 __first,
591 _RandomAccessIterator1 __last,
592 _RandomAccessIterator1 __global_last,
593 _RandomAccessIterator2 __s_first,
594 _RandomAccessIterator2 __s_last,
595 _BinaryPredicate __pred,
596 bool __b_first,
597 _IsVector __is_vector) noexcept {
598 typedef typename std::iterator_traits<_RandomAccessIterator2>::value_type _ValueType;
599 auto __n2 = __s_last - __s_first;
600 if (__n2 < 1) {
601 return __b_first ? __first : __last;
602 }
603
604 auto __n1 = __global_last - __first;
605 if (__n1 < __n2) {
606 return __last;
607 }
608
609 auto __cur = __last;
610 while (__first != __last && (__global_last - __first >= __n2)) {
611 // find position of *s_first in [first, last) (it can be start of subsequence)
612 __first = __internal::__brick_find_if(
613 __first, __last, __equal_value_by_pred<_ValueType, _BinaryPredicate>(*__s_first, __pred), __is_vector);
614
615 // if position that was found previously is the start of subsequence
616 // then we can exit the loop (b_first == true) or keep the position
617 // (b_first == false)
618 if (__first != __last && (__global_last - __first >= __n2) &&
619 __internal::__brick_equal(__s_first + 1, __s_last, __first + 1, __pred, __is_vector)) {
620 if (__b_first) {
621 return __first;
622 } else {
623 __cur = __first;
624 }
625 } else if (__first == __last) {
626 break;
627 } else {
628 }
629
630 // in case of b_first == false we try to find new start position
631 // for the next subsequence
632 ++__first;
633 }
634 return __cur;
635}
636
637template <class _RandomAccessIterator, class _Size, class _Tp, class _BinaryPredicate, class _IsVector>
638_RandomAccessIterator __find_subrange(
639 _RandomAccessIterator __first,
640 _RandomAccessIterator __last,
641 _RandomAccessIterator __global_last,
642 _Size __count,
643 const _Tp& __value,
644 _BinaryPredicate __pred,
645 _IsVector __is_vector) noexcept {
646 if (static_cast<_Size>(__global_last - __first) < __count || __count < 1) {
647 return __last; // According to the standard last shall be returned when count < 1
648 }
649
650 auto __unary_pred = __equal_value_by_pred<_Tp, _BinaryPredicate>(__value, __pred);
651 while (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count)) {
652 __first = __internal::__brick_find_if(__first, __last, __unary_pred, __is_vector);
653
654 // check that all of elements in [first+1, first+count) equal to value
655 if (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count) &&
656 !__internal::__brick_any_of(__first + 1, __first + __count, std::not_fn(__unary_pred), __is_vector)) {
657 return __first;
658 } else if (__first == __last) {
659 break;
660 } else {
661 ++__first;
662 }
663 }
664 return __last;
665}
666
667template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
668_ForwardIterator1 __brick_find_end(
669 _ForwardIterator1 __first,
670 _ForwardIterator1 __last,
671 _ForwardIterator2 __s_first,
672 _ForwardIterator2 __s_last,
673 _BinaryPredicate __pred,
674 /*__is_vector=*/std::false_type) noexcept {
675 return std::find_end(__first, __last, __s_first, __s_last, __pred);
676}
677
678template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
679_RandomAccessIterator1 __brick_find_end(
680 _RandomAccessIterator1 __first,
681 _RandomAccessIterator1 __last,
682 _RandomAccessIterator2 __s_first,
683 _RandomAccessIterator2 __s_last,
684 _BinaryPredicate __pred,
685 /*__is_vector=*/std::true_type) noexcept {
686 return __find_subrange(__first, __last, __last, __s_first, __s_last, __pred, false, std::true_type());
687}
688
689template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
690_ForwardIterator1 __pattern_find_end(
691 _Tag,
692 _ExecutionPolicy&&,
693 _ForwardIterator1 __first,
694 _ForwardIterator1 __last,
695 _ForwardIterator2 __s_first,
696 _ForwardIterator2 __s_last,
697 _BinaryPredicate __pred) noexcept {
698 return __internal::__brick_find_end(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{});
699}
700
701template <class _IsVector,
702 class _ExecutionPolicy,
703 class _RandomAccessIterator1,
704 class _RandomAccessIterator2,
705 class _BinaryPredicate>
706_RandomAccessIterator1 __pattern_find_end(
707 __parallel_tag<_IsVector> __tag,
708 _ExecutionPolicy&& __exec,
709 _RandomAccessIterator1 __first,
710 _RandomAccessIterator1 __last,
711 _RandomAccessIterator2 __s_first,
712 _RandomAccessIterator2 __s_last,
713 _BinaryPredicate __pred) noexcept {
714 using __backend_tag = typename decltype(__tag)::__backend_tag;
715
716 if (__last - __first == __s_last - __s_first) {
717 const bool __res =
718 __internal::__pattern_equal(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __pred);
719 return __res ? __first : __last;
720 } else {
721 return __internal::__except_handler([&]() {
722 return __internal::__parallel_find(
723 __backend_tag{},
724 std::forward<_ExecutionPolicy>(__exec),
725 __first,
726 __last,
727 [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
728 return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, false, _IsVector{});
729 },
730 std::greater<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(),
731 /*is_first=*/false);
732 });
733 }
734}
735
736//------------------------------------------------------------------------
737// find_first_of
738//------------------------------------------------------------------------
739template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
740_ForwardIterator1 __brick_find_first_of(
741 _ForwardIterator1 __first,
742 _ForwardIterator1 __last,
743 _ForwardIterator2 __s_first,
744 _ForwardIterator2 __s_last,
745 _BinaryPredicate __pred,
746 /*__is_vector=*/std::false_type) noexcept {
747 return std::find_first_of(__first, __last, __s_first, __s_last, __pred);
748}
749
750template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
751_RandomAccessIterator1 __brick_find_first_of(
752 _RandomAccessIterator1 __first,
753 _RandomAccessIterator1 __last,
754 _RandomAccessIterator2 __s_first,
755 _RandomAccessIterator2 __s_last,
756 _BinaryPredicate __pred,
757 /*__is_vector=*/std::true_type) noexcept {
758 return __unseq_backend::__simd_find_first_of(__first, __last, __s_first, __s_last, __pred);
759}
760
761template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
762_ForwardIterator1 __pattern_find_first_of(
763 _Tag,
764 _ExecutionPolicy&&,
765 _ForwardIterator1 __first,
766 _ForwardIterator1 __last,
767 _ForwardIterator2 __s_first,
768 _ForwardIterator2 __s_last,
769 _BinaryPredicate __pred) noexcept {
770 return __internal::__brick_find_first_of(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{});
771}
772
773template <class _IsVector,
774 class _ExecutionPolicy,
775 class _RandomAccessIterator1,
776 class _RandomAccessIterator2,
777 class _BinaryPredicate>
778_RandomAccessIterator1 __pattern_find_first_of(
779 __parallel_tag<_IsVector> __tag,
780 _ExecutionPolicy&& __exec,
781 _RandomAccessIterator1 __first,
782 _RandomAccessIterator1 __last,
783 _RandomAccessIterator2 __s_first,
784 _RandomAccessIterator2 __s_last,
785 _BinaryPredicate __pred) noexcept {
786 using __backend_tag = typename decltype(__tag)::__backend_tag;
787
788 return __internal::__except_handler([&]() {
789 return __internal::__parallel_find(
790 __backend_tag{},
791 std::forward<_ExecutionPolicy>(__exec),
792 __first,
793 __last,
794 [__s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
795 return __internal::__brick_find_first_of(__i, __j, __s_first, __s_last, __pred, _IsVector{});
796 },
797 std::less<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(),
798 /*is_first=*/true);
799 });
800}
801
802//------------------------------------------------------------------------
803// search
804//------------------------------------------------------------------------
805template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
806_RandomAccessIterator1 __brick_search(
807 _RandomAccessIterator1 __first,
808 _RandomAccessIterator1 __last,
809 _RandomAccessIterator2 __s_first,
810 _RandomAccessIterator2 __s_last,
811 _BinaryPredicate __pred,
812 /*vector=*/std::false_type) noexcept {
813 return std::search(__first, __last, __s_first, __s_last, __pred);
814}
815
816template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
817_RandomAccessIterator1 __brick_search(
818 _RandomAccessIterator1 __first,
819 _RandomAccessIterator1 __last,
820 _RandomAccessIterator2 __s_first,
821 _RandomAccessIterator2 __s_last,
822 _BinaryPredicate __pred,
823 /*vector=*/std::true_type) noexcept {
824 return __internal::__find_subrange(__first, __last, __last, __s_first, __s_last, __pred, true, std::true_type());
825}
826
827template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
828_ForwardIterator1 __pattern_search(
829 _Tag,
830 _ExecutionPolicy&&,
831 _ForwardIterator1 __first,
832 _ForwardIterator1 __last,
833 _ForwardIterator2 __s_first,
834 _ForwardIterator2 __s_last,
835 _BinaryPredicate __pred) noexcept {
836 return __internal::__brick_search(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{});
837}
838
839template <class _IsVector,
840 class _ExecutionPolicy,
841 class _RandomAccessIterator1,
842 class _RandomAccessIterator2,
843 class _BinaryPredicate>
844_RandomAccessIterator1 __pattern_search(
845 __parallel_tag<_IsVector> __tag,
846 _ExecutionPolicy&& __exec,
847 _RandomAccessIterator1 __first,
848 _RandomAccessIterator1 __last,
849 _RandomAccessIterator2 __s_first,
850 _RandomAccessIterator2 __s_last,
851 _BinaryPredicate __pred) noexcept {
852 using __backend_tag = typename decltype(__tag)::__backend_tag;
853
854 if (__last - __first == __s_last - __s_first) {
855 const bool __res =
856 __internal::__pattern_equal(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __pred);
857 return __res ? __first : __last;
858 } else {
859 return __internal::__except_handler([&]() {
860 return __internal::__parallel_find(
861 __backend_tag{},
862 std::forward<_ExecutionPolicy>(__exec),
863 __first,
864 __last,
865 [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
866 return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, true, _IsVector{});
867 },
868 std::less<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(),
869 /*is_first=*/true);
870 });
871 }
872}
873
874//------------------------------------------------------------------------
875// search_n
876//------------------------------------------------------------------------
877template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
878_ForwardIterator __brick_search_n(
879 _ForwardIterator __first,
880 _ForwardIterator __last,
881 _Size __count,
882 const _Tp& __value,
883 _BinaryPredicate __pred,
884 /*vector=*/std::false_type) noexcept {
885 return std::search_n(__first, __last, __count, __value, __pred);
886}
887
888template <class _RandomAccessIterator, class _Size, class _Tp, class _BinaryPredicate>
889_RandomAccessIterator __brick_search_n(
890 _RandomAccessIterator __first,
891 _RandomAccessIterator __last,
892 _Size __count,
893 const _Tp& __value,
894 _BinaryPredicate __pred,
895 /*vector=*/std::true_type) noexcept {
896 return __internal::__find_subrange(__first, __last, __last, __count, __value, __pred, std::true_type());
897}
898
899template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
900_ForwardIterator __pattern_search_n(
901 _Tag,
902 _ExecutionPolicy&&,
903 _ForwardIterator __first,
904 _ForwardIterator __last,
905 _Size __count,
906 const _Tp& __value,
907 _BinaryPredicate __pred) noexcept {
908 return __internal::__brick_search_n(__first, __last, __count, __value, __pred, typename _Tag::__is_vector{});
909}
910
911template <class _IsVector,
912 class _ExecutionPolicy,
913 class _RandomAccessIterator,
914 class _Size,
915 class _Tp,
916 class _BinaryPredicate>
917_RandomAccessIterator __pattern_search_n(
918 __parallel_tag<_IsVector> __tag,
919 _ExecutionPolicy&& __exec,
920 _RandomAccessIterator __first,
921 _RandomAccessIterator __last,
922 _Size __count,
923 const _Tp& __value,
924 _BinaryPredicate __pred) noexcept {
925 using __backend_tag = typename decltype(__tag)::__backend_tag;
926
927 if (static_cast<_Size>(__last - __first) == __count) {
928 const bool __result = !__internal::__pattern_any_of(
929 __tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [&__value, &__pred](const _Tp& __val) {
930 return !__pred(__val, __value);
931 });
932 return __result ? __first : __last;
933 } else {
934 return __internal::__except_handler([&__exec, __first, __last, __count, &__value, __pred]() {
935 return __internal::__parallel_find(
936 __backend_tag{},
937 std::forward<_ExecutionPolicy>(__exec),
938 __first,
939 __last,
940 [__last, __count, &__value, __pred](_RandomAccessIterator __i, _RandomAccessIterator __j) {
941 return __internal::__find_subrange(__i, __j, __last, __count, __value, __pred, _IsVector{});
942 },
943 std::less<typename std::iterator_traits<_RandomAccessIterator>::difference_type>(),
944 /*is_first=*/true);
945 });
946 }
947}
948
949//------------------------------------------------------------------------
950// copy_n
951//------------------------------------------------------------------------
952
953template <class _ForwardIterator, class _Size, class _OutputIterator>
954_OutputIterator
955__brick_copy_n(_ForwardIterator __first, _Size __n, _OutputIterator __result, /*vector=*/std::false_type) noexcept {
956 return std::copy_n(__first, __n, __result);
957}
958
959template <class _RandomAccessIterator1, class _Size, class _RandomAccessIterator2>
960_RandomAccessIterator2
961__brick_copy_n(_RandomAccessIterator1 __first,
962 _Size __n,
963 _RandomAccessIterator2 __result,
964 /*vector=*/std::true_type) noexcept {
965 return __unseq_backend::__simd_assign(
966 __first, __n, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) {
967 *__result = *__first;
968 });
969}
970
971//------------------------------------------------------------------------
972// copy
973//------------------------------------------------------------------------
974template <class _ForwardIterator, class _OutputIterator>
975_OutputIterator
976__brick_copy(_ForwardIterator __first,
977 _ForwardIterator __last,
978 _OutputIterator __result,
979 /*vector=*/std::false_type) noexcept {
980 return std::copy(__first, __last, __result);
981}
982
983template <class _RandomAccessIterator1, class _RandomAccessIterator2>
984_RandomAccessIterator2
985__brick_copy(_RandomAccessIterator1 __first,
986 _RandomAccessIterator1 __last,
987 _RandomAccessIterator2 __result,
988 /*vector=*/std::true_type) noexcept {
989 return __unseq_backend::__simd_assign(
990 __first, __last - __first, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) {
991 *__result = *__first;
992 });
993}
994
995//------------------------------------------------------------------------
996// move
997//------------------------------------------------------------------------
998template <class _ForwardIterator, class _OutputIterator>
999_OutputIterator
1000__brick_move(_ForwardIterator __first,
1001 _ForwardIterator __last,
1002 _OutputIterator __result,
1003 /*vector=*/std::false_type) noexcept {
1004 return std::move(__first, __last, __result);
1005}
1006
1007template <class _RandomAccessIterator1, class _RandomAccessIterator2>
1008_RandomAccessIterator2
1009__brick_move(_RandomAccessIterator1 __first,
1010 _RandomAccessIterator1 __last,
1011 _RandomAccessIterator2 __result,
1012 /*vector=*/std::true_type) noexcept {
1013 return __unseq_backend::__simd_assign(
1014 __first, __last - __first, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) {
1015 *__result = std::move(*__first);
1016 });
1017}
1018
1019struct __brick_move_destroy {
1020 template <typename _RandomAccessIterator1, typename _RandomAccessIterator2>
1021 _RandomAccessIterator2
1022 operator()(_RandomAccessIterator1 __first,
1023 _RandomAccessIterator1 __last,
1024 _RandomAccessIterator2 __result,
1025 /*vec*/ std::true_type) const {
1026 using _IteratorValueType = typename std::iterator_traits<_RandomAccessIterator1>::value_type;
1027
1028 return __unseq_backend::__simd_assign(
1029 __first, __last - __first, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) {
1030 *__result = std::move(*__first);
1031 (*__first).~_IteratorValueType();
1032 });
1033 }
1034
1035 template <typename _RandomAccessIterator1, typename _RandomAccessIterator2>
1036 _RandomAccessIterator2
1037 operator()(_RandomAccessIterator1 __first,
1038 _RandomAccessIterator1 __last,
1039 _RandomAccessIterator2 __result,
1040 /*vec*/ std::false_type) const {
1041 using _IteratorValueType = typename std::iterator_traits<_RandomAccessIterator1>::value_type;
1042
1043 for (; __first != __last; ++__first, ++__result) {
1044 *__result = std::move(*__first);
1045 (*__first).~_IteratorValueType();
1046 }
1047 return __result;
1048 }
1049};
1050
1051//------------------------------------------------------------------------
1052// swap_ranges
1053//------------------------------------------------------------------------
1054template <class _ForwardIterator, class _OutputIterator>
1055_OutputIterator __brick_swap_ranges(
1056 _ForwardIterator __first,
1057 _ForwardIterator __last,
1058 _OutputIterator __result,
1059 /*vector=*/std::false_type) noexcept {
1060 return std::swap_ranges(__first, __last, __result);
1061}
1062
1063template <class _RandomAccessIterator1, class _RandomAccessIterator2>
1064_RandomAccessIterator2 __brick_swap_ranges(
1065 _RandomAccessIterator1 __first,
1066 _RandomAccessIterator1 __last,
1067 _RandomAccessIterator2 __result,
1068 /*vector=*/std::true_type) noexcept {
1069 using std::iter_swap;
1070 return __unseq_backend::__simd_assign(
1071 __first, __last - __first, __result, iter_swap<_RandomAccessIterator1, _RandomAccessIterator2>);
1072}
1073
1074//------------------------------------------------------------------------
1075// copy_if
1076//------------------------------------------------------------------------
1077template <class _ForwardIterator, class _OutputIterator, class _UnaryPredicate>
1078_OutputIterator __brick_copy_if(
1079 _ForwardIterator __first,
1080 _ForwardIterator __last,
1081 _OutputIterator __result,
1082 _UnaryPredicate __pred,
1083 /*vector=*/std::false_type) noexcept {
1084 return std::copy_if(__first, __last, __result, __pred);
1085}
1086
1087template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _UnaryPredicate>
1088_RandomAccessIterator2 __brick_copy_if(
1089 _RandomAccessIterator1 __first,
1090 _RandomAccessIterator1 __last,
1091 _RandomAccessIterator2 __result,
1092 _UnaryPredicate __pred,
1093 /*vector=*/std::true_type) noexcept {
1094#if defined(_PSTL_MONOTONIC_PRESENT)
1095 return __unseq_backend::__simd_copy_if(__first, __last - __first, __result, __pred);
1096#else
1097 return std::copy_if(__first, __last, __result, __pred);
1098#endif
1099}
1100
1101// TODO: Try to use transform_reduce for combining __brick_copy_if_phase1 on IsVector.
1102template <class _DifferenceType, class _ForwardIterator, class _UnaryPredicate>
1103std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1(
1104 _ForwardIterator __first,
1105 _ForwardIterator __last,
1106 bool* __restrict __mask,
1107 _UnaryPredicate __pred,
1108 /*vector=*/std::false_type) noexcept {
1109 auto __count_true = _DifferenceType(0);
1110 auto __size = __last - __first;
1111
1112 static_assert(__are_random_access_iterators<_ForwardIterator>::value,
1113 "Pattern-brick error. Should be a random access iterator.");
1114
1115 for (; __first != __last; ++__first, ++__mask) {
1116 *__mask = __pred(*__first);
1117 if (*__mask) {
1118 ++__count_true;
1119 }
1120 }
1121 return std::make_pair(__count_true, __size - __count_true);
1122}
1123
1124template <class _DifferenceType, class _RandomAccessIterator, class _UnaryPredicate>
1125std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1(
1126 _RandomAccessIterator __first,
1127 _RandomAccessIterator __last,
1128 bool* __mask,
1129 _UnaryPredicate __pred,
1130 /*vector=*/std::true_type) noexcept {
1131 auto __result = __unseq_backend::__simd_calc_mask_1(__first, __last - __first, __mask, __pred);
1132 return std::make_pair(__result, (__last - __first) - __result);
1133}
1134
1135template <class _ForwardIterator, class _OutputIterator, class _Assigner>
1136void __brick_copy_by_mask(
1137 _ForwardIterator __first,
1138 _ForwardIterator __last,
1139 _OutputIterator __result,
1140 bool* __mask,
1141 _Assigner __assigner,
1142 /*vector=*/std::false_type) noexcept {
1143 for (; __first != __last; ++__first, ++__mask) {
1144 if (*__mask) {
1145 __assigner(__first, __result);
1146 ++__result;
1147 }
1148 }
1149}
1150
1151template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Assigner>
1152void __brick_copy_by_mask(
1153 _RandomAccessIterator1 __first,
1154 _RandomAccessIterator1 __last,
1155 _RandomAccessIterator2 __result,
1156 bool* __restrict __mask,
1157 _Assigner __assigner,
1158 /*vector=*/std::true_type) noexcept {
1159#if defined(_PSTL_MONOTONIC_PRESENT)
1160 __unseq_backend::__simd_copy_by_mask(__first, __last - __first, __result, __mask, __assigner);
1161#else
1162 __internal::__brick_copy_by_mask(__first, __last, __result, __mask, __assigner, std::false_type());
1163#endif
1164}
1165
1166template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2>
1167void __brick_partition_by_mask(
1168 _ForwardIterator __first,
1169 _ForwardIterator __last,
1170 _OutputIterator1 __out_true,
1171 _OutputIterator2 __out_false,
1172 bool* __mask,
1173 /*vector=*/std::false_type) noexcept {
1174 for (; __first != __last; ++__first, ++__mask) {
1175 if (*__mask) {
1176 *__out_true = *__first;
1177 ++__out_true;
1178 } else {
1179 *__out_false = *__first;
1180 ++__out_false;
1181 }
1182 }
1183}
1184
1185template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3>
1186void __brick_partition_by_mask(
1187 _RandomAccessIterator1 __first,
1188 _RandomAccessIterator1 __last,
1189 _RandomAccessIterator2 __out_true,
1190 _RandomAccessIterator3 __out_false,
1191 bool* __mask,
1192 /*vector=*/std::true_type) noexcept {
1193#if defined(_PSTL_MONOTONIC_PRESENT)
1194 __unseq_backend::__simd_partition_by_mask(__first, __last - __first, __out_true, __out_false, __mask);
1195#else
1196 __internal::__brick_partition_by_mask(__first, __last, __out_true, __out_false, __mask, std::false_type());
1197#endif
1198}
1199
1200template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryPredicate>
1201_OutputIterator __pattern_copy_if(
1202 _Tag,
1203 _ExecutionPolicy&&,
1204 _ForwardIterator __first,
1205 _ForwardIterator __last,
1206 _OutputIterator __result,
1207 _UnaryPredicate __pred) noexcept {
1208 return __internal::__brick_copy_if(__first, __last, __result, __pred, typename _Tag::__is_vector{});
1209}
1210
1211template <class _IsVector,
1212 class _ExecutionPolicy,
1213 class _RandomAccessIterator1,
1214 class _RandomAccessIterator2,
1215 class _UnaryPredicate>
1216_RandomAccessIterator2 __pattern_copy_if(
1217 __parallel_tag<_IsVector> __tag,
1218 _ExecutionPolicy&& __exec,
1219 _RandomAccessIterator1 __first,
1220 _RandomAccessIterator1 __last,
1221 _RandomAccessIterator2 __result,
1222 _UnaryPredicate __pred) {
1223 using __backend_tag = typename decltype(__tag)::__backend_tag;
1224
1225 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType;
1226 const _DifferenceType __n = __last - __first;
1227 if (_DifferenceType(1) < __n) {
1228 __par_backend::__buffer<bool> __mask_buf(__n);
1229 return __internal::__except_handler([&__exec, __n, __first, __result, __pred, &__mask_buf]() {
1230 bool* __mask = __mask_buf.get();
1231 _DifferenceType __m{};
1232 __par_backend::__parallel_strict_scan(
1233 __backend_tag{},
1234 std::forward<_ExecutionPolicy>(__exec),
1235 __n,
1236 _DifferenceType(0),
1237 [=](_DifferenceType __i, _DifferenceType __len) { // Reduce
1238 return __internal::__brick_calc_mask_1<_DifferenceType>(
1239 __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{})
1240 .first;
1241 },
1242 std::plus<_DifferenceType>(), // Combine
1243 [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan
1244 __internal::__brick_copy_by_mask(
1245 __first + __i,
1246 __first + (__i + __len),
1247 __result + __initial,
1248 __mask + __i,
1249 [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; },
1250 _IsVector{});
1251 },
1252 [&__m](_DifferenceType __total) { __m = __total; });
1253 return __result + __m;
1254 });
1255 }
1256 // trivial sequence - use serial algorithm
1257 return __internal::__brick_copy_if(__first, __last, __result, __pred, _IsVector{});
1258}
1259
1260//------------------------------------------------------------------------
1261// count
1262//------------------------------------------------------------------------
1263template <class _RandomAccessIterator, class _Predicate>
1264typename std::iterator_traits<_RandomAccessIterator>::difference_type
1265__brick_count(_RandomAccessIterator __first,
1266 _RandomAccessIterator __last,
1267 _Predicate __pred,
1268 /* is_vector = */ std::true_type) noexcept {
1269 return __unseq_backend::__simd_count(__first, __last - __first, __pred);
1270}
1271
1272template <class _ForwardIterator, class _Predicate>
1273typename std::iterator_traits<_ForwardIterator>::difference_type
1274__brick_count(_ForwardIterator __first,
1275 _ForwardIterator __last,
1276 _Predicate __pred,
1277 /* is_vector = */ std::false_type) noexcept {
1278 return std::count_if(__first, __last, __pred);
1279}
1280
1281template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
1282typename std::iterator_traits<_ForwardIterator>::difference_type __pattern_count(
1283 _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) noexcept {
1284 return __internal::__brick_count(__first, __last, __pred, typename _Tag::__is_vector{});
1285}
1286
1287template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Predicate>
1288typename std::iterator_traits<_RandomAccessIterator>::difference_type __pattern_count(
1289 __parallel_tag<_IsVector> __tag,
1290 _ExecutionPolicy&& __exec,
1291 _RandomAccessIterator __first,
1292 _RandomAccessIterator __last,
1293 _Predicate __pred) {
1294 using __backend_tag = typename decltype(__tag)::__backend_tag;
1295
1296 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType;
1297 return __internal::__except_handler([&]() {
1298 return __par_backend::__parallel_reduce(
1299 __backend_tag{},
1300 std::forward<_ExecutionPolicy>(__exec),
1301 __first,
1302 __last,
1303 _SizeType(0),
1304 [__pred](_RandomAccessIterator __begin, _RandomAccessIterator __end, _SizeType __value) -> _SizeType {
1305 return __value + __internal::__brick_count(__begin, __end, __pred, _IsVector{});
1306 },
1307 std::plus<_SizeType>());
1308 });
1309}
1310
1311//------------------------------------------------------------------------
1312// unique
1313//------------------------------------------------------------------------
1314
1315template <class _RandomAccessIterator, class _BinaryPredicate>
1316_RandomAccessIterator
1317__brick_unique(_RandomAccessIterator __first,
1318 _RandomAccessIterator __last,
1319 _BinaryPredicate __pred,
1320 /*is_vector=*/std::false_type) noexcept {
1321 return std::unique(__first, __last, __pred);
1322}
1323
1324template <class _RandomAccessIterator, class _BinaryPredicate>
1325_RandomAccessIterator
1326__brick_unique(_RandomAccessIterator __first,
1327 _RandomAccessIterator __last,
1328 _BinaryPredicate __pred,
1329 /*is_vector=*/std::true_type) noexcept {
1330 // TODO: vectorize
1331 return std::unique(__first, __last, __pred);
1332}
1333
1334template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
1335_ForwardIterator __pattern_unique(
1336 _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) noexcept {
1337 return __internal::__brick_unique(__first, __last, __pred, typename _Tag::__is_vector{});
1338}
1339
1340// That function is shared between two algorithms - remove_if (__pattern_remove_if) and unique (pattern unique). But a
1341// mask calculation is different. So, a caller passes _CalcMask brick into remove_elements.
1342template <class _IsVector, class _ExecutionPolicy, class _ForwardIterator, class _CalcMask>
1343_ForwardIterator __remove_elements(
1344 __parallel_tag<_IsVector> __tag,
1345 _ExecutionPolicy&& __exec,
1346 _ForwardIterator __first,
1347 _ForwardIterator __last,
1348 _CalcMask __calc_mask) {
1349 using __backend_tag = typename decltype(__tag)::__backend_tag;
1350
1351 typedef typename std::iterator_traits<_ForwardIterator>::difference_type _DifferenceType;
1352 typedef typename std::iterator_traits<_ForwardIterator>::value_type _Tp;
1353 _DifferenceType __n = __last - __first;
1354 __par_backend::__buffer<bool> __mask_buf(__n);
1355 // 1. find a first iterator that should be removed
1356 return __internal::__except_handler([&]() {
1357 bool* __mask = __mask_buf.get();
1358 _DifferenceType __min = __par_backend::__parallel_reduce(
1359 __backend_tag{},
1360 std::forward<_ExecutionPolicy>(__exec),
1361 _DifferenceType(0),
1362 __n,
1363 __n,
1364 [__first, __mask, &__calc_mask](
1365 _DifferenceType __i, _DifferenceType __j, _DifferenceType __local_min) -> _DifferenceType {
1366 // Create mask
1367 __calc_mask(__mask + __i, __mask + __j, __first + __i);
1368
1369 // if minimum was found in a previous range we shouldn't do anymore
1370 if (__local_min < __i) {
1371 return __local_min;
1372 }
1373 // find first iterator that should be removed
1374 bool* __result = __internal::__brick_find_if(
1375 __mask + __i, __mask + __j, [](bool __val) { return !__val; }, _IsVector{});
1376 if (__result - __mask == __j) {
1377 return __local_min;
1378 }
1379 return std::min(__local_min, _DifferenceType(__result - __mask));
1380 },
1381 [](_DifferenceType __local_min1, _DifferenceType __local_min2) -> _DifferenceType {
1382 return std::min(__local_min1, __local_min2);
1383 });
1384
1385 // No elements to remove - exit
1386 if (__min == __n) {
1387 return __last;
1388 }
1389 __n -= __min;
1390 __first += __min;
1391
1392 __par_backend::__buffer<_Tp> __buf(__n);
1393 _Tp* __result = __buf.get();
1394 __mask += __min;
1395 _DifferenceType __m{};
1396 // 2. Elements that doesn't satisfy pred are moved to result
1397 __par_backend::__parallel_strict_scan(
1398 __backend_tag{},
1399 std::forward<_ExecutionPolicy>(__exec),
1400 __n,
1401 _DifferenceType(0),
1402 [__mask](_DifferenceType __i, _DifferenceType __len) {
1403 return __internal::__brick_count(
1404 __mask + __i, __mask + __i + __len, [](bool __val) { return __val; }, _IsVector{});
1405 },
1406 std::plus<_DifferenceType>(),
1407 [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) {
1408 __internal::__brick_copy_by_mask(
1409 __first + __i,
1410 __first + __i + __len,
1411 __result + __initial,
1412 __mask + __i,
1413 [](_ForwardIterator __x, _Tp* __z) {
1414 __internal::__invoke_if_else(
1415 std::is_trivial<_Tp>(),
1416 [&]() { *__z = std::move(*__x); },
1417 [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); });
1418 },
1419 _IsVector{});
1420 },
1421 [&__m](_DifferenceType __total) { __m = __total; });
1422
1423 // 3. Elements from result are moved to [first, last)
1424 __par_backend::__parallel_for(
1425 __backend_tag{},
1426 std::forward<_ExecutionPolicy>(__exec),
1427 __result,
1428 __result + __m,
1429 [__result, __first](_Tp* __i, _Tp* __j) {
1430 __invoke_if_else(
1431 std::is_trivial<_Tp>(),
1432 [&]() { __brick_move(__i, __j, __first + (__i - __result), _IsVector{}); },
1433 [&]() { __brick_move_destroy()(__i, __j, __first + (__i - __result), _IsVector{}); });
1434 });
1435 return __first + __m;
1436 });
1437}
1438
1439template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate>
1440_RandomAccessIterator __pattern_unique(
1441 __parallel_tag<_IsVector> __tag,
1442 _ExecutionPolicy&& __exec,
1443 _RandomAccessIterator __first,
1444 _RandomAccessIterator __last,
1445 _BinaryPredicate __pred) noexcept {
1446 typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType;
1447
1448 if (__first == __last) {
1449 return __last;
1450 }
1451 if (__first + 1 == __last || __first + 2 == __last) {
1452 // Trivial sequence - use serial algorithm
1453 return __internal::__brick_unique(__first, __last, __pred, _IsVector{});
1454 }
1455 return __internal::__remove_elements(
1456 __tag,
1457 std::forward<_ExecutionPolicy>(__exec),
1458 ++__first,
1459 __last,
1460 [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) {
1461 __internal::__brick_walk3(
1462 __b,
1463 __e,
1464 __it - 1,
1465 __it,
1466 [&__pred](bool& __x, _ReferenceType __y, _ReferenceType __z) { __x = !__pred(__y, __z); },
1467 _IsVector{});
1468 });
1469}
1470
1471//------------------------------------------------------------------------
1472// unique_copy
1473//------------------------------------------------------------------------
1474
1475template <class _ForwardIterator, class OutputIterator, class _BinaryPredicate>
1476OutputIterator __brick_unique_copy(
1477 _ForwardIterator __first,
1478 _ForwardIterator __last,
1479 OutputIterator __result,
1480 _BinaryPredicate __pred,
1481 /*vector=*/std::false_type) noexcept {
1482 return std::unique_copy(__first, __last, __result, __pred);
1483}
1484
1485template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
1486_RandomAccessIterator2 __brick_unique_copy(
1487 _RandomAccessIterator1 __first,
1488 _RandomAccessIterator1 __last,
1489 _RandomAccessIterator2 __result,
1490 _BinaryPredicate __pred,
1491 /*vector=*/std::true_type) noexcept {
1492#if defined(_PSTL_MONOTONIC_PRESENT)
1493 return __unseq_backend::__simd_unique_copy(__first, __last - __first, __result, __pred);
1494#else
1495 return std::unique_copy(__first, __last, __result, __pred);
1496#endif
1497}
1498
1499template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryPredicate>
1500_OutputIterator __pattern_unique_copy(
1501 _Tag,
1502 _ExecutionPolicy&&,
1503 _ForwardIterator __first,
1504 _ForwardIterator __last,
1505 _OutputIterator __result,
1506 _BinaryPredicate __pred) noexcept {
1507 return __internal::__brick_unique_copy(__first, __last, __result, __pred, typename _Tag::__is_vector{});
1508}
1509
1510template <class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate>
1511_DifferenceType __brick_calc_mask_2(
1512 _RandomAccessIterator __first,
1513 _RandomAccessIterator __last,
1514 bool* __restrict __mask,
1515 _BinaryPredicate __pred,
1516 /*vector=*/std::false_type) noexcept {
1517 _DifferenceType __count = 0;
1518 for (; __first != __last; ++__first, ++__mask) {
1519 *__mask = !__pred(*__first, *(__first - 1));
1520 __count += *__mask;
1521 }
1522 return __count;
1523}
1524
1525template <class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate>
1526_DifferenceType __brick_calc_mask_2(
1527 _RandomAccessIterator __first,
1528 _RandomAccessIterator __last,
1529 bool* __restrict __mask,
1530 _BinaryPredicate __pred,
1531 /*vector=*/std::true_type) noexcept {
1532 return __unseq_backend::__simd_calc_mask_2(__first, __last - __first, __mask, __pred);
1533}
1534
1535template <class _IsVector,
1536 class _ExecutionPolicy,
1537 class _RandomAccessIterator1,
1538 class _RandomAccessIterator2,
1539 class _BinaryPredicate>
1540_RandomAccessIterator2 __pattern_unique_copy(
1541 __parallel_tag<_IsVector> __tag,
1542 _ExecutionPolicy&& __exec,
1543 _RandomAccessIterator1 __first,
1544 _RandomAccessIterator1 __last,
1545 _RandomAccessIterator2 __result,
1546 _BinaryPredicate __pred) {
1547 using __backend_tag = typename decltype(__tag)::__backend_tag;
1548
1549 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType;
1550 const _DifferenceType __n = __last - __first;
1551 if (_DifferenceType(2) < __n) {
1552 __par_backend::__buffer<bool> __mask_buf(__n);
1553 if (_DifferenceType(2) < __n) {
1554 return __internal::__except_handler([&__exec, __n, __first, __result, __pred, &__mask_buf]() {
1555 bool* __mask = __mask_buf.get();
1556 _DifferenceType __m{};
1557 __par_backend::__parallel_strict_scan(
1558 __backend_tag{},
1559 std::forward<_ExecutionPolicy>(__exec),
1560 __n,
1561 _DifferenceType(0),
1562 [=](_DifferenceType __i, _DifferenceType __len) -> _DifferenceType { // Reduce
1563 _DifferenceType __extra = 0;
1564 if (__i == 0) {
1565 // Special boundary case
1566 __mask[__i] = true;
1567 if (--__len == 0)
1568 return 1;
1569 ++__i;
1570 ++__extra;
1571 }
1572 return __internal::__brick_calc_mask_2<_DifferenceType>(
1573 __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{}) +
1574 __extra;
1575 },
1576 std::plus<_DifferenceType>(), // Combine
1577 [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan
1578 // Phase 2 is same as for __pattern_copy_if
1579 __internal::__brick_copy_by_mask(
1580 __first + __i,
1581 __first + (__i + __len),
1582 __result + __initial,
1583 __mask + __i,
1584 [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; },
1585 _IsVector{});
1586 },
1587 [&__m](_DifferenceType __total) { __m = __total; });
1588 return __result + __m;
1589 });
1590 }
1591 }
1592 // trivial sequence - use serial algorithm
1593 return __internal::__brick_unique_copy(__first, __last, __result, __pred, _IsVector{});
1594}
1595
1596//------------------------------------------------------------------------
1597// reverse
1598//------------------------------------------------------------------------
1599template <class _BidirectionalIterator>
1600void __brick_reverse(
1601 _BidirectionalIterator __first, _BidirectionalIterator __last, /*__is_vector=*/std::false_type) noexcept {
1602 std::reverse(__first, __last);
1603}
1604
1605template <class _RandomAccessIterator>
1606void __brick_reverse(
1607 _RandomAccessIterator __first, _RandomAccessIterator __last, /*__is_vector=*/std::true_type) noexcept {
1608 typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType;
1609
1610 const auto __n = (__last - __first) / 2;
1611 __unseq_backend::__simd_walk_2(
1612 __first, __n, std::reverse_iterator<_RandomAccessIterator>(__last), [](_ReferenceType __x, _ReferenceType __y) {
1613 using std::swap;
1614 swap(__x, __y);
1615 });
1616}
1617
1618// this brick is called in parallel version, so we can use iterator arithmetic
1619template <class _BidirectionalIterator>
1620void __brick_reverse(_BidirectionalIterator __first,
1621 _BidirectionalIterator __last,
1622 _BidirectionalIterator __d_last,
1623 /*is_vector=*/std::false_type) noexcept {
1624 for (--__d_last; __first != __last; ++__first, --__d_last) {
1625 using std::iter_swap;
1626 iter_swap(__first, __d_last);
1627 }
1628}
1629
1630// this brick is called in parallel version, so we can use iterator arithmetic
1631template <class _RandomAccessIterator>
1632void __brick_reverse(_RandomAccessIterator __first,
1633 _RandomAccessIterator __last,
1634 _RandomAccessIterator __d_last,
1635 /*is_vector=*/std::true_type) noexcept {
1636 typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType;
1637
1638 __unseq_backend::__simd_walk_2(
1639 __first,
1640 __last - __first,
1641 std::reverse_iterator<_RandomAccessIterator>(__d_last),
1642 [](_ReferenceType __x, _ReferenceType __y) {
1643 using std::swap;
1644 swap(__x, __y);
1645 });
1646}
1647
1648template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator>
1649void __pattern_reverse(
1650 _Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last) noexcept {
1651 __internal::__brick_reverse(__first, __last, typename _Tag::__is_vector{});
1652}
1653
1654template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator>
1655void __pattern_reverse(__parallel_tag<_IsVector> __tag,
1656 _ExecutionPolicy&& __exec,
1657 _RandomAccessIterator __first,
1658 _RandomAccessIterator __last) {
1659 using __backend_tag = typename decltype(__tag)::__backend_tag;
1660
1661 __par_backend::__parallel_for(
1662 __backend_tag{},
1663 std::forward<_ExecutionPolicy>(__exec),
1664 __first,
1665 __first + (__last - __first) / 2,
1666 [__first, __last](_RandomAccessIterator __inner_first, _RandomAccessIterator __inner_last) {
1667 __internal::__brick_reverse(__inner_first, __inner_last, __last - (__inner_first - __first), _IsVector{});
1668 });
1669}
1670
1671//------------------------------------------------------------------------
1672// reverse_copy
1673//------------------------------------------------------------------------
1674
1675template <class _BidirectionalIterator, class _OutputIterator>
1676_OutputIterator __brick_reverse_copy(
1677 _BidirectionalIterator __first,
1678 _BidirectionalIterator __last,
1679 _OutputIterator __d_first,
1680 /*is_vector=*/std::false_type) noexcept {
1681 return std::reverse_copy(__first, __last, __d_first);
1682}
1683
1684template <class _RandomAccessIterator1, class _RandomAccessIterator2>
1685_RandomAccessIterator2 __brick_reverse_copy(
1686 _RandomAccessIterator1 __first,
1687 _RandomAccessIterator1 __last,
1688 _RandomAccessIterator2 __d_first,
1689 /*is_vector=*/std::true_type) noexcept {
1690 typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1;
1691 typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2;
1692
1693 return __unseq_backend::__simd_walk_2(
1694 std::reverse_iterator<_RandomAccessIterator1>(__last),
1695 __last - __first,
1696 __d_first,
1697 [](_ReferenceType1 __x, _ReferenceType2 __y) { __y = __x; });
1698}
1699
1700template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _OutputIterator>
1701_OutputIterator __pattern_reverse_copy(
1702 _Tag,
1703 _ExecutionPolicy&&,
1704 _BidirectionalIterator __first,
1705 _BidirectionalIterator __last,
1706 _OutputIterator __d_first) noexcept {
1707 return __internal::__brick_reverse_copy(__first, __last, __d_first, typename _Tag::__is_vector{});
1708}
1709
1710template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2>
1711_RandomAccessIterator2 __pattern_reverse_copy(
1712 __parallel_tag<_IsVector> __tag,
1713 _ExecutionPolicy&& __exec,
1714 _RandomAccessIterator1 __first,
1715 _RandomAccessIterator1 __last,
1716 _RandomAccessIterator2 __d_first) {
1717 using __backend_tag = typename decltype(__tag)::__backend_tag;
1718
1719 auto __len = __last - __first;
1720 __par_backend::__parallel_for(
1721 __backend_tag{},
1722 std::forward<_ExecutionPolicy>(__exec),
1723 __first,
1724 __last,
1725 [__first, __len, __d_first](_RandomAccessIterator1 __inner_first, _RandomAccessIterator1 __inner_last) {
1726 __internal::__brick_reverse_copy(
1727 __inner_first, __inner_last, __d_first + (__len - (__inner_last - __first)), _IsVector{});
1728 });
1729 return __d_first + __len;
1730}
1731
1732//------------------------------------------------------------------------
1733// rotate
1734//------------------------------------------------------------------------
1735template <class _ForwardIterator>
1736_ForwardIterator
1737__brick_rotate(_ForwardIterator __first,
1738 _ForwardIterator __middle,
1739 _ForwardIterator __last,
1740 /*is_vector=*/std::false_type) noexcept {
1741#if defined(_PSTL_CPP11_STD_ROTATE_BROKEN)
1742 std::rotate(__first, __middle, __last);
1743 return std::next(__first, std::distance(__middle, __last));
1744#else
1745 return std::rotate(__first, __middle, __last);
1746#endif
1747}
1748
1749template <class _RandomAccessIterator>
1750_RandomAccessIterator
1751__brick_rotate(_RandomAccessIterator __first,
1752 _RandomAccessIterator __middle,
1753 _RandomAccessIterator __last,
1754 /*is_vector=*/std::true_type) noexcept {
1755 auto __n = __last - __first;
1756 auto __m = __middle - __first;
1757 const _RandomAccessIterator __ret = __first + (__last - __middle);
1758
1759 bool __is_left = (__m <= __n / 2);
1760 if (!__is_left)
1761 __m = __n - __m;
1762
1763 while (__n > 1 && __m > 0) {
1764 using std::iter_swap;
1765 const auto __m_2 = __m * 2;
1766 if (__is_left) {
1767 for (; __last - __first >= __m_2; __first += __m) {
1768 __unseq_backend::__simd_assign(
1769 __first, __m, __first + __m, iter_swap<_RandomAccessIterator, _RandomAccessIterator>);
1770 }
1771 } else {
1772 for (; __last - __first >= __m_2; __last -= __m) {
1773 __unseq_backend::__simd_assign(
1774 __last - __m, __m, __last - __m_2, iter_swap<_RandomAccessIterator, _RandomAccessIterator>);
1775 }
1776 }
1777 __is_left = !__is_left;
1778 __m = __n % __m;
1779 __n = __last - __first;
1780 }
1781
1782 return __ret;
1783}
1784
1785template <class _Tag, class _ExecutionPolicy, class _ForwardIterator>
1786_ForwardIterator __pattern_rotate(
1787 _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) noexcept {
1788 return __internal::__brick_rotate(__first, __middle, __last, typename _Tag::__is_vector{});
1789}
1790
1791template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator>
1792_RandomAccessIterator __pattern_rotate(
1793 __parallel_tag<_IsVector> __tag,
1794 _ExecutionPolicy&& __exec,
1795 _RandomAccessIterator __first,
1796 _RandomAccessIterator __middle,
1797 _RandomAccessIterator __last) {
1798 using __backend_tag = typename decltype(__tag)::__backend_tag;
1799
1800 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp;
1801 auto __n = __last - __first;
1802 auto __m = __middle - __first;
1803 if (__m <= __n / 2) {
1804 __par_backend::__buffer<_Tp> __buf(__n - __m);
1805 return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, &__buf]() {
1806 _Tp* __result = __buf.get();
1807 __par_backend::__parallel_for(
1808 __backend_tag{},
1809 std::forward<_ExecutionPolicy>(__exec),
1810 __middle,
1811 __last,
1812 [__middle, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) {
1813 __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __middle), _IsVector{});
1814 });
1815
1816 __par_backend::__parallel_for(
1817 __backend_tag{},
1818 std::forward<_ExecutionPolicy>(__exec),
1819 __first,
1820 __middle,
1821 [__last, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) {
1822 __internal::__brick_move(__b, __e, __b + (__last - __middle), _IsVector{});
1823 });
1824
1825 __par_backend::__parallel_for(
1826 __backend_tag{},
1827 std::forward<_ExecutionPolicy>(__exec),
1828 __result,
1829 __result + (__n - __m),
1830 [__first, __result](_Tp* __b, _Tp* __e) {
1831 __brick_move_destroy()(__b, __e, __first + (__b - __result), _IsVector{});
1832 });
1833
1834 return __first + (__last - __middle);
1835 });
1836 } else {
1837 __par_backend::__buffer<_Tp> __buf(__m);
1838 return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, &__buf]() {
1839 _Tp* __result = __buf.get();
1840 __par_backend::__parallel_for(
1841 __backend_tag{},
1842 std::forward<_ExecutionPolicy>(__exec),
1843 __first,
1844 __middle,
1845 [__first, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) {
1846 __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __first), _IsVector{});
1847 });
1848
1849 __par_backend::__parallel_for(
1850 __backend_tag{},
1851 std::forward<_ExecutionPolicy>(__exec),
1852 __middle,
1853 __last,
1854 [__first, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) {
1855 __internal::__brick_move(__b, __e, __first + (__b - __middle), _IsVector{});
1856 });
1857
1858 __par_backend::__parallel_for(
1859 __backend_tag{},
1860 std::forward<_ExecutionPolicy>(__exec),
1861 __result,
1862 __result + __m,
1863 [__n, __m, __first, __result](_Tp* __b, _Tp* __e) {
1864 __brick_move_destroy()(__b, __e, __first + ((__n - __m) + (__b - __result)), _IsVector{});
1865 });
1866
1867 return __first + (__last - __middle);
1868 });
1869 }
1870}
1871
1872//------------------------------------------------------------------------
1873// rotate_copy
1874//------------------------------------------------------------------------
1875
1876template <class _ForwardIterator, class _OutputIterator>
1877_OutputIterator __brick_rotate_copy(
1878 _ForwardIterator __first,
1879 _ForwardIterator __middle,
1880 _ForwardIterator __last,
1881 _OutputIterator __result,
1882 /*__is_vector=*/std::false_type) noexcept {
1883 return std::rotate_copy(__first, __middle, __last, __result);
1884}
1885
1886template <class _RandomAccessIterator1, class _RandomAccessIterator2>
1887_RandomAccessIterator2 __brick_rotate_copy(
1888 _RandomAccessIterator1 __first,
1889 _RandomAccessIterator1 __middle,
1890 _RandomAccessIterator1 __last,
1891 _RandomAccessIterator2 __result,
1892 /*__is_vector=*/std::true_type) noexcept {
1893 _RandomAccessIterator2 __res = __internal::__brick_copy(__middle, __last, __result, std::true_type());
1894 return __internal::__brick_copy(__first, __middle, __res, std::true_type());
1895}
1896
1897template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator>
1898_OutputIterator __pattern_rotate_copy(
1899 _Tag,
1900 _ExecutionPolicy&&,
1901 _ForwardIterator __first,
1902 _ForwardIterator __middle,
1903 _ForwardIterator __last,
1904 _OutputIterator __result) noexcept {
1905 return __internal::__brick_rotate_copy(__first, __middle, __last, __result, typename _Tag::__is_vector{});
1906}
1907
1908template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2>
1909_RandomAccessIterator2 __pattern_rotate_copy(
1910 __parallel_tag<_IsVector> __tag,
1911 _ExecutionPolicy&& __exec,
1912 _RandomAccessIterator1 __first,
1913 _RandomAccessIterator1 __middle,
1914 _RandomAccessIterator1 __last,
1915 _RandomAccessIterator2 __result) {
1916 using __backend_tag = typename decltype(__tag)::__backend_tag;
1917
1918 __par_backend::__parallel_for(
1919 __backend_tag{},
1920 std::forward<_ExecutionPolicy>(__exec),
1921 __first,
1922 __last,
1923 [__first, __last, __middle, __result](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) {
1924 if (__b > __middle) {
1925 __internal::__brick_copy(__b, __e, __result + (__b - __middle), _IsVector{});
1926 } else {
1927 _RandomAccessIterator2 __new_result = __result + ((__last - __middle) + (__b - __first));
1928 if (__e < __middle) {
1929 __internal::__brick_copy(__b, __e, __new_result, _IsVector{});
1930 } else {
1931 __internal::__brick_copy(__b, __middle, __new_result, _IsVector{});
1932 __internal::__brick_copy(__middle, __e, __result, _IsVector{});
1933 }
1934 }
1935 });
1936 return __result + (__last - __first);
1937}
1938
1939//------------------------------------------------------------------------
1940// is_partitioned
1941//------------------------------------------------------------------------
1942
1943template <class _ForwardIterator, class _UnaryPredicate>
1944bool __brick_is_partitioned(_ForwardIterator __first,
1945 _ForwardIterator __last,
1946 _UnaryPredicate __pred,
1947 /*is_vector=*/std::false_type) noexcept {
1948 return std::is_partitioned(__first, __last, __pred);
1949}
1950
1951template <class _RandomAccessIterator, class _UnaryPredicate>
1952bool __brick_is_partitioned(_RandomAccessIterator __first,
1953 _RandomAccessIterator __last,
1954 _UnaryPredicate __pred,
1955 /*is_vector=*/std::true_type) noexcept {
1956 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType;
1957 if (__first == __last) {
1958 return true;
1959 } else {
1960 _RandomAccessIterator __result = __unseq_backend::__simd_first(
1961 __first, _SizeType(0), __last - __first, [&__pred](_RandomAccessIterator __it, _SizeType __i) {
1962 return !__pred(__it[__i]);
1963 });
1964 if (__result == __last) {
1965 return true;
1966 } else {
1967 ++__result;
1968 return !__unseq_backend::__simd_or(__result, __last - __result, __pred);
1969 }
1970 }
1971}
1972
1973template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
1974bool __pattern_is_partitioned(
1975 _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) noexcept {
1976 return __internal::__brick_is_partitioned(__first, __last, __pred, typename _Tag::__is_vector{});
1977}
1978
1979template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
1980bool __pattern_is_partitioned(
1981 __parallel_tag<_IsVector> __tag,
1982 _ExecutionPolicy&& __exec,
1983 _RandomAccessIterator __first,
1984 _RandomAccessIterator __last,
1985 _UnaryPredicate __pred) {
1986 if (__first == __last) {
1987 return true;
1988 } else {
1989 using __backend_tag = typename decltype(__tag)::__backend_tag;
1990
1991 return __internal::__except_handler([&]() {
1992 // State of current range:
1993 // broken - current range is not partitioned by pred
1994 // all_true - all elements in current range satisfy pred
1995 // all_false - all elements in current range don't satisfy pred
1996 // true_false - elements satisfy pred are placed before elements that don't satisfy pred
1997 enum _ReduceType { __not_init = -1, __broken, __all_true, __all_false, __true_false };
1998 _ReduceType __init = __not_init;
1999
2000 // Array with states that we'll have when state from the left branch is merged with state from the right branch.
2001 // State is calculated by formula: new_state = table[left_state * 4 + right_state]
2002 _ReduceType __table[] = {
2003 __broken,
2004 __broken,
2005 __broken,
2006 __broken,
2007 __broken,
2008 __all_true,
2009 __true_false,
2010 __true_false,
2011 __broken,
2012 __broken,
2013 __all_false,
2014 __broken,
2015 __broken,
2016 __broken,
2017 __true_false,
2018 __broken};
2019
2020 __init = __par_backend::__parallel_reduce(
2021 __backend_tag{},
2022 std::forward<_ExecutionPolicy>(__exec),
2023 __first,
2024 __last,
2025 __init,
2026 [&__pred,
2027 &__table](_RandomAccessIterator __i, _RandomAccessIterator __j, _ReduceType __value) -> _ReduceType {
2028 if (__value == __broken) {
2029 return __broken;
2030 }
2031 _ReduceType __res = __not_init;
2032 // if first element satisfy pred
2033 if (__pred(*__i)) {
2034 // find first element that don't satisfy pred
2035 _RandomAccessIterator __x = __internal::__brick_find_if(__i + 1, __j, std::not_fn(__pred), _IsVector{});
2036 if (__x != __j) {
2037 // find first element after "x" that satisfy pred
2038 _RandomAccessIterator __y = __internal::__brick_find_if(__x + 1, __j, __pred, _IsVector{});
2039 // if it was found then range isn't partitioned by pred
2040 if (__y != __j) {
2041 return __broken;
2042 } else {
2043 __res = __true_false;
2044 }
2045 } else {
2046 __res = __all_true;
2047 }
2048 } else { // if first element doesn't satisfy pred
2049 // then we should find the first element that satisfy pred.
2050 // If we found it then range isn't partitioned by pred
2051 if (__internal::__brick_find_if(__i + 1, __j, __pred, _IsVector{}) != __j) {
2052 return __broken;
2053 } else {
2054 __res = __all_false;
2055 }
2056 }
2057 // if we have value from left range then we should calculate the result
2058 return (__value == -1) ? __res : __table[__value * 4 + __res];
2059 },
2060
2061 [&__table](_ReduceType __val1, _ReduceType __val2) -> _ReduceType {
2062 if (__val1 == __broken || __val2 == __broken) {
2063 return __broken;
2064 }
2065 // calculate the result for new big range
2066 return __table[__val1 * 4 + __val2];
2067 });
2068 return __init != __broken;
2069 });
2070 }
2071}
2072
2073//------------------------------------------------------------------------
2074// partition
2075//------------------------------------------------------------------------
2076
2077template <class _ForwardIterator, class _UnaryPredicate>
2078_ForwardIterator __brick_partition(
2079 _ForwardIterator __first,
2080 _ForwardIterator __last,
2081 _UnaryPredicate __pred,
2082 /*is_vector=*/std::false_type) noexcept {
2083 return std::partition(__first, __last, __pred);
2084}
2085
2086template <class _RandomAccessIterator, class _UnaryPredicate>
2087_RandomAccessIterator __brick_partition(
2088 _RandomAccessIterator __first,
2089 _RandomAccessIterator __last,
2090 _UnaryPredicate __pred,
2091 /*is_vector=*/std::true_type) noexcept {
2092 // TODO: vectorize
2093 return std::partition(__first, __last, __pred);
2094}
2095
2096template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
2097_ForwardIterator __pattern_partition(
2098 _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) noexcept {
2099 return __internal::__brick_partition(__first, __last, __pred, typename _Tag::__is_vector{});
2100}
2101
2102template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
2103_RandomAccessIterator __pattern_partition(
2104 __parallel_tag<_IsVector> __tag,
2105 _ExecutionPolicy&& __exec,
2106 _RandomAccessIterator __first,
2107 _RandomAccessIterator __last,
2108 _UnaryPredicate __pred) {
2109 using __backend_tag = typename decltype(__tag)::__backend_tag;
2110
2111 // partitioned range: elements before pivot satisfy pred (true part),
2112 // elements after pivot don't satisfy pred (false part)
2113 struct _PartitionRange {
2114 _RandomAccessIterator __begin;
2115 _RandomAccessIterator __pivot;
2116 _RandomAccessIterator __end;
2117 };
2118
2119 return __internal::__except_handler([&]() {
2120 _PartitionRange __init{__last, __last, __last};
2121
2122 // lambda for merging two partitioned ranges to one partitioned range
2123 auto __reductor = [&__exec](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange {
2124 auto __size1 = __val1.__end - __val1.__pivot;
2125 auto __size2 = __val2.__pivot - __val2.__begin;
2126 auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin);
2127
2128 // if all elements in left range satisfy pred then we can move new pivot to pivot of right range
2129 if (__val1.__end == __val1.__pivot) {
2130 return {__new_begin, __val2.__pivot, __val2.__end};
2131 }
2132 // if true part of right range greater than false part of left range
2133 // then we should swap the false part of left range and last part of true part of right range
2134 else if (__size2 > __size1) {
2135 __par_backend::__parallel_for(
2136 __backend_tag{},
2137 std::forward<_ExecutionPolicy>(__exec),
2138 __val1.__pivot,
2139 __val1.__pivot + __size1,
2140 [__val1, __val2, __size1](_RandomAccessIterator __i, _RandomAccessIterator __j) {
2141 __internal::__brick_swap_ranges(
2142 __i, __j, (__val2.__pivot - __size1) + (__i - __val1.__pivot), _IsVector{});
2143 });
2144 return {__new_begin, __val2.__pivot - __size1, __val2.__end};
2145 }
2146 // else we should swap the first part of false part of left range and true part of right range
2147 else {
2148 __par_backend::__parallel_for(
2149 __backend_tag{},
2150 std::forward<_ExecutionPolicy>(__exec),
2151 __val1.__pivot,
2152 __val1.__pivot + __size2,
2153 [__val1, __val2](_RandomAccessIterator __i, _RandomAccessIterator __j) {
2154 __internal::__brick_swap_ranges(__i, __j, __val2.__begin + (__i - __val1.__pivot), _IsVector{});
2155 });
2156 return {__new_begin, __val1.__pivot + __size2, __val2.__end};
2157 }
2158 };
2159
2160 _PartitionRange __result = __par_backend::__parallel_reduce(
2161 __backend_tag{},
2162 std::forward<_ExecutionPolicy>(__exec),
2163 __first,
2164 __last,
2165 __init,
2166 [__pred,
2167 __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, _PartitionRange __value) -> _PartitionRange {
2168 // 1. serial partition
2169 _RandomAccessIterator __pivot = __internal::__brick_partition(__i, __j, __pred, _IsVector{});
2170
2171 // 2. merging of two ranges (left and right respectively)
2172 return __reductor(__value, {__i, __pivot, __j});
2173 },
2174 __reductor);
2175 return __result.__pivot;
2176 });
2177}
2178
2179//------------------------------------------------------------------------
2180// stable_partition
2181//------------------------------------------------------------------------
2182
2183template <class _BidirectionalIterator, class _UnaryPredicate>
2184_BidirectionalIterator __brick_stable_partition(
2185 _BidirectionalIterator __first,
2186 _BidirectionalIterator __last,
2187 _UnaryPredicate __pred,
2188 /*__is_vector=*/std::false_type) noexcept {
2189 return std::stable_partition(__first, __last, __pred);
2190}
2191
2192template <class _RandomAccessIterator, class _UnaryPredicate>
2193_RandomAccessIterator __brick_stable_partition(
2194 _RandomAccessIterator __first,
2195 _RandomAccessIterator __last,
2196 _UnaryPredicate __pred,
2197 /*__is_vector=*/std::true_type) noexcept {
2198 // TODO: vectorize
2199 return std::stable_partition(__first, __last, __pred);
2200}
2201
2202template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate>
2203_BidirectionalIterator __pattern_stable_partition(
2204 _Tag,
2205 _ExecutionPolicy&&,
2206 _BidirectionalIterator __first,
2207 _BidirectionalIterator __last,
2208 _UnaryPredicate __pred) noexcept {
2209 return __internal::__brick_stable_partition(__first, __last, __pred, typename _Tag::__is_vector{});
2210}
2211
2212template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
2213_RandomAccessIterator __pattern_stable_partition(
2214 __parallel_tag<_IsVector> __tag,
2215 _ExecutionPolicy&& __exec,
2216 _RandomAccessIterator __first,
2217 _RandomAccessIterator __last,
2218 _UnaryPredicate __pred) noexcept {
2219 using __backend_tag = typename decltype(__tag)::__backend_tag;
2220
2221 // partitioned range: elements before pivot satisfy pred (true part),
2222 // elements after pivot don't satisfy pred (false part)
2223 struct _PartitionRange {
2224 _RandomAccessIterator __begin;
2225 _RandomAccessIterator __pivot;
2226 _RandomAccessIterator __end;
2227 };
2228
2229 return __internal::__except_handler([&]() {
2230 _PartitionRange __init{__last, __last, __last};
2231
2232 // lambda for merging two partitioned ranges to one partitioned range
2233 auto __reductor = [](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange {
2234 auto __size1 = __val1.__end - __val1.__pivot;
2235 auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin);
2236
2237 // if all elements in left range satisfy pred then we can move new pivot to pivot of right range
2238 if (__val1.__end == __val1.__pivot) {
2239 return {__new_begin, __val2.__pivot, __val2.__end};
2240 }
2241 // if true part of right range greater than false part of left range
2242 // then we should swap the false part of left range and last part of true part of right range
2243 else {
2244 __internal::__brick_rotate(__val1.__pivot, __val2.__begin, __val2.__pivot, _IsVector{});
2245 return {__new_begin, __val2.__pivot - __size1, __val2.__end};
2246 }
2247 };
2248
2249 _PartitionRange __result = __par_backend::__parallel_reduce(
2250 __backend_tag{},
2251 std::forward<_ExecutionPolicy>(__exec),
2252 __first,
2253 __last,
2254 __init,
2255 [&__pred,
2256 __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, _PartitionRange __value) -> _PartitionRange {
2257 // 1. serial stable_partition
2258 _RandomAccessIterator __pivot = __internal::__brick_stable_partition(__i, __j, __pred, _IsVector{});
2259
2260 // 2. merging of two ranges (left and right respectively)
2261 return __reductor(__value, {__i, __pivot, __j});
2262 },
2263 __reductor);
2264 return __result.__pivot;
2265 });
2266}
2267
2268//------------------------------------------------------------------------
2269// partition_copy
2270//------------------------------------------------------------------------
2271
2272template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2, class _UnaryPredicate>
2273std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy(
2274 _ForwardIterator __first,
2275 _ForwardIterator __last,
2276 _OutputIterator1 __out_true,
2277 _OutputIterator2 __out_false,
2278 _UnaryPredicate __pred,
2279 /*is_vector=*/std::false_type) noexcept {
2280 return std::partition_copy(__first, __last, __out_true, __out_false, __pred);
2281}
2282
2283template <class _RandomAccessIterator1,
2284 class _RandomAccessIterator2,
2285 class _RandomAccessIterator3,
2286 class _UnaryPredicate>
2287std::pair<_RandomAccessIterator2, _RandomAccessIterator3> __brick_partition_copy(
2288 _RandomAccessIterator1 __first,
2289 _RandomAccessIterator1 __last,
2290 _RandomAccessIterator2 __out_true,
2291 _RandomAccessIterator3 __out_false,
2292 _UnaryPredicate __pred,
2293 /*is_vector=*/std::true_type) noexcept {
2294#if defined(_PSTL_MONOTONIC_PRESENT)
2295 return __unseq_backend::__simd_partition_copy(__first, __last - __first, __out_true, __out_false, __pred);
2296#else
2297 return std::partition_copy(__first, __last, __out_true, __out_false, __pred);
2298#endif
2299}
2300
2301template <class _Tag,
2302 class _ExecutionPolicy,
2303 class _ForwardIterator,
2304 class _OutputIterator1,
2305 class _OutputIterator2,
2306 class _UnaryPredicate>
2307std::pair<_OutputIterator1, _OutputIterator2> __pattern_partition_copy(
2308 _Tag,
2309 _ExecutionPolicy&&,
2310 _ForwardIterator __first,
2311 _ForwardIterator __last,
2312 _OutputIterator1 __out_true,
2313 _OutputIterator2 __out_false,
2314 _UnaryPredicate __pred) noexcept {
2315 return __internal::__brick_partition_copy(
2316 __first, __last, __out_true, __out_false, __pred, typename _Tag::__is_vector{});
2317}
2318
2319template <class _IsVector,
2320 class _ExecutionPolicy,
2321 class _RandomAccessIterator1,
2322 class _RandomAccessIterator2,
2323 class _RandomAccessIterator3,
2324 class _UnaryPredicate>
2325std::pair<_RandomAccessIterator2, _RandomAccessIterator3> __pattern_partition_copy(
2326 __parallel_tag<_IsVector> __tag,
2327 _ExecutionPolicy&& __exec,
2328 _RandomAccessIterator1 __first,
2329 _RandomAccessIterator1 __last,
2330 _RandomAccessIterator2 __out_true,
2331 _RandomAccessIterator3 __out_false,
2332 _UnaryPredicate __pred) {
2333 using __backend_tag = typename decltype(__tag)::__backend_tag;
2334
2335 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType;
2336 typedef std::pair<_DifferenceType, _DifferenceType> _ReturnType;
2337 const _DifferenceType __n = __last - __first;
2338 if (_DifferenceType(1) < __n) {
2339 __par_backend::__buffer<bool> __mask_buf(__n);
2340 return __internal::__except_handler([&__exec, __n, __first, __out_true, __out_false, __pred, &__mask_buf]() {
2341 bool* __mask = __mask_buf.get();
2342 _ReturnType __m{};
2343 __par_backend::__parallel_strict_scan(
2344 __backend_tag{},
2345 std::forward<_ExecutionPolicy>(__exec),
2346 __n,
2347 std::make_pair(_DifferenceType(0), _DifferenceType(0)),
2348 [=](_DifferenceType __i, _DifferenceType __len) { // Reduce
2349 return __internal::__brick_calc_mask_1<_DifferenceType>(
2350 __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{});
2351 },
2352 [](const _ReturnType& __x, const _ReturnType& __y) -> _ReturnType {
2353 return std::make_pair(__x.first + __y.first, __x.second + __y.second);
2354 }, // Combine
2355 [=](_DifferenceType __i, _DifferenceType __len, _ReturnType __initial) { // Scan
2356 __internal::__brick_partition_by_mask(
2357 __first + __i,
2358 __first + (__i + __len),
2359 __out_true + __initial.first,
2360 __out_false + __initial.second,
2361 __mask + __i,
2362 _IsVector{});
2363 },
2364 [&__m](_ReturnType __total) { __m = __total; });
2365 return std::make_pair(__out_true + __m.first, __out_false + __m.second);
2366 });
2367 }
2368 // trivial sequence - use serial algorithm
2369 return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, _IsVector{});
2370}
2371
2372//------------------------------------------------------------------------
2373// sort
2374//------------------------------------------------------------------------
2375
2376template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsMoveConstructible>
2377void __pattern_sort(_Tag,
2378 _ExecutionPolicy&&,
2379 _RandomAccessIterator __first,
2380 _RandomAccessIterator __last,
2381 _Compare __comp,
2382 _IsMoveConstructible) noexcept {
2383 std::sort(__first, __last, __comp);
2384}
2385
2386template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
2387void __pattern_sort(__parallel_tag<_IsVector> __tag,
2388 _ExecutionPolicy&& __exec,
2389 _RandomAccessIterator __first,
2390 _RandomAccessIterator __last,
2391 _Compare __comp,
2392 /*is_move_constructible=*/std::true_type) {
2393 using __backend_tag = typename decltype(__tag)::__backend_tag;
2394
2395 __internal::__except_handler([&]() {
2396 __par_backend::__parallel_stable_sort(
2397 __backend_tag{},
2398 std::forward<_ExecutionPolicy>(__exec),
2399 __first,
2400 __last,
2401 __comp,
2402 [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
2403 std::sort(__first, __last, __comp);
2404 });
2405 });
2406}
2407
2408//------------------------------------------------------------------------
2409// stable_sort
2410//------------------------------------------------------------------------
2411
2412template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
2413void __pattern_stable_sort(
2414 _Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) noexcept {
2415 std::stable_sort(__first, __last, __comp);
2416}
2417
2418template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
2419void __pattern_stable_sort(
2420 __parallel_tag<_IsVector> __tag,
2421 _ExecutionPolicy&& __exec,
2422 _RandomAccessIterator __first,
2423 _RandomAccessIterator __last,
2424 _Compare __comp) {
2425 using __backend_tag = typename decltype(__tag)::__backend_tag;
2426
2427 __internal::__except_handler([&]() {
2428 __par_backend::__parallel_stable_sort(
2429 __backend_tag{},
2430 std::forward<_ExecutionPolicy>(__exec),
2431 __first,
2432 __last,
2433 __comp,
2434 [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
2435 std::stable_sort(__first, __last, __comp);
2436 });
2437 });
2438}
2439
2440//------------------------------------------------------------------------
2441// partial_sort
2442//------------------------------------------------------------------------
2443
2444template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
2445void __pattern_partial_sort(
2446 _Tag,
2447 _ExecutionPolicy&&,
2448 _RandomAccessIterator __first,
2449 _RandomAccessIterator __middle,
2450 _RandomAccessIterator __last,
2451 _Compare __comp) noexcept {
2452 std::partial_sort(__first, __middle, __last, __comp);
2453}
2454
2455template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
2456void __pattern_partial_sort(
2457 __parallel_tag<_IsVector> __tag,
2458 _ExecutionPolicy&& __exec,
2459 _RandomAccessIterator __first,
2460 _RandomAccessIterator __middle,
2461 _RandomAccessIterator __last,
2462 _Compare __comp) {
2463 using __backend_tag = typename decltype(__tag)::__backend_tag;
2464
2465 const auto __n = __middle - __first;
2466 if (__n == 0)
2467 return;
2468
2469 __internal::__except_handler([&]() {
2470 __par_backend::__parallel_stable_sort(
2471 __backend_tag{},
2472 std::forward<_ExecutionPolicy>(__exec),
2473 __first,
2474 __last,
2475 __comp,
2476 [__n](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Compare __comp) {
2477 if (__n < __end - __begin)
2478 std::partial_sort(__begin, __begin + __n, __end, __comp);
2479 else
2480 std::sort(__begin, __end, __comp);
2481 },
2482 __n);
2483 });
2484}
2485
2486//------------------------------------------------------------------------
2487// partial_sort_copy
2488//------------------------------------------------------------------------
2489
2490template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare>
2491_RandomAccessIterator __pattern_partial_sort_copy(
2492 _Tag,
2493 _ExecutionPolicy&&,
2494 _ForwardIterator __first,
2495 _ForwardIterator __last,
2496 _RandomAccessIterator __d_first,
2497 _RandomAccessIterator __d_last,
2498 _Compare __comp) noexcept {
2499 return std::partial_sort_copy(__first, __last, __d_first, __d_last, __comp);
2500}
2501
2502template <class _IsVector,
2503 class _ExecutionPolicy,
2504 class _RandomAccessIterator1,
2505 class _RandomAccessIterator2,
2506 class _Compare>
2507_RandomAccessIterator2 __pattern_partial_sort_copy(
2508 __parallel_tag<_IsVector> __tag,
2509 _ExecutionPolicy&& __exec,
2510 _RandomAccessIterator1 __first,
2511 _RandomAccessIterator1 __last,
2512 _RandomAccessIterator2 __d_first,
2513 _RandomAccessIterator2 __d_last,
2514 _Compare __comp) {
2515 using __backend_tag = typename decltype(__tag)::__backend_tag;
2516
2517 if (__last == __first || __d_last == __d_first) {
2518 return __d_first;
2519 }
2520 auto __n1 = __last - __first;
2521 auto __n2 = __d_last - __d_first;
2522 return __internal::__except_handler([&]() {
2523 if (__n2 >= __n1) {
2524 __par_backend::__parallel_stable_sort(
2525 __backend_tag{},
2526 std::forward<_ExecutionPolicy>(__exec),
2527 __d_first,
2528 __d_first + __n1,
2529 __comp,
2530 [__first, __d_first](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j, _Compare __comp) {
2531 _RandomAccessIterator1 __i1 = __first + (__i - __d_first);
2532 _RandomAccessIterator1 __j1 = __first + (__j - __d_first);
2533
2534 // 1. Copy elements from input to output
2535#if !defined(_PSTL_ICC_18_OMP_SIMD_BROKEN)
2536 __internal::__brick_copy(__i1, __j1, __i, _IsVector{});
2537#else
2538 std::copy(__i1, __j1, __i);
2539#endif
2540 // 2. Sort elements in output sequence
2541 std::sort(__i, __j, __comp);
2542 },
2543 __n1);
2544 return __d_first + __n1;
2545 } else {
2546 typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type _T1;
2547 typedef typename std::iterator_traits<_RandomAccessIterator2>::value_type _T2;
2548 __par_backend::__buffer<_T1> __buf(__n1);
2549 _T1* __r = __buf.get();
2550
2551 __par_backend::__parallel_stable_sort(
2552 __backend_tag{},
2553 std::forward<_ExecutionPolicy>(__exec),
2554 __r,
2555 __r + __n1,
2556 __comp,
2557 [__n2, __first, __r](_T1* __i, _T1* __j, _Compare __comp) {
2558 _RandomAccessIterator1 __it = __first + (__i - __r);
2559
2560 // 1. Copy elements from input to raw memory
2561 for (_T1* __k = __i; __k != __j; ++__k, ++__it) {
2562 ::new (__k) _T2(*__it);
2563 }
2564
2565 // 2. Sort elements in temporary __buffer
2566 if (__n2 < __j - __i)
2567 std::partial_sort(__i, __i + __n2, __j, __comp);
2568 else
2569 std::sort(__i, __j, __comp);
2570 },
2571 __n2);
2572
2573 // 3. Move elements from temporary __buffer to output
2574 __par_backend::__parallel_for(
2575 __backend_tag{},
2576 std::forward<_ExecutionPolicy>(__exec),
2577 __r,
2578 __r + __n2,
2579 [__r, __d_first](_T1* __i, _T1* __j) {
2580 __brick_move_destroy()(__i, __j, __d_first + (__i - __r), _IsVector{});
2581 });
2582 __par_backend::__parallel_for(
2583 __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r + __n2, __r + __n1, [](_T1* __i, _T1* __j) {
2584 __brick_destroy(__i, __j, _IsVector{});
2585 });
2586
2587 return __d_first + __n2;
2588 }
2589 });
2590}
2591
2592//------------------------------------------------------------------------
2593// adjacent_find
2594//------------------------------------------------------------------------
2595template <class _RandomAccessIterator, class _BinaryPredicate>
2596_RandomAccessIterator __brick_adjacent_find(
2597 _RandomAccessIterator __first,
2598 _RandomAccessIterator __last,
2599 _BinaryPredicate __pred,
2600 /* IsVector = */ std::true_type,
2601 bool __or_semantic) noexcept {
2602 return __unseq_backend::__simd_adjacent_find(__first, __last, __pred, __or_semantic);
2603}
2604
2605template <class _ForwardIterator, class _BinaryPredicate>
2606_ForwardIterator __brick_adjacent_find(
2607 _ForwardIterator __first,
2608 _ForwardIterator __last,
2609 _BinaryPredicate __pred,
2610 /* IsVector = */ std::false_type,
2611 bool) noexcept {
2612 return std::adjacent_find(__first, __last, __pred);
2613}
2614
2615template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
2616_ForwardIterator __pattern_adjacent_find(
2617 _Tag,
2618 _ExecutionPolicy&&,
2619 _ForwardIterator __first,
2620 _ForwardIterator __last,
2621 _BinaryPredicate __pred,
2622 bool __or_semantic) noexcept {
2623 return __internal::__brick_adjacent_find(__first, __last, __pred, typename _Tag::__is_vector{}, __or_semantic);
2624}
2625
2626template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate>
2627_RandomAccessIterator __pattern_adjacent_find(
2628 __parallel_tag<_IsVector> __tag,
2629 _ExecutionPolicy&& __exec,
2630 _RandomAccessIterator __first,
2631 _RandomAccessIterator __last,
2632 _BinaryPredicate __pred,
2633 bool __or_semantic) {
2634 if (__last - __first < 2)
2635 return __last;
2636
2637 using __backend_tag = typename decltype(__tag)::__backend_tag;
2638
2639 return __internal::__except_handler([&]() {
2640 return __par_backend::__parallel_reduce(
2641 __backend_tag{},
2642 std::forward<_ExecutionPolicy>(__exec),
2643 __first,
2644 __last,
2645 __last,
2646 [__last, __pred, __or_semantic](
2647 _RandomAccessIterator __begin, _RandomAccessIterator __end, _RandomAccessIterator __value)
2648 -> _RandomAccessIterator {
2649 // TODO: investigate performance benefits from the use of shared variable for the result,
2650 // checking (compare_and_swap idiom) its __value at __first.
2651 if (__or_semantic && __value < __last) { // found
2652 __par_backend::__cancel_execution();
2653 return __value;
2654 }
2655
2656 if (__value > __begin) {
2657 // modify __end to check the predicate on the boundary __values;
2658 // TODO: to use a custom range with boundaries overlapping
2659 // TODO: investigate what if we remove "if" below and run algorithm on range [__first, __last-1)
2660 // then check the pair [__last-1, __last)
2661 if (__end != __last)
2662 ++__end;
2663
2664 // correct the global result iterator if the "brick" returns a local "__last"
2665 const _RandomAccessIterator __res =
2666 __internal::__brick_adjacent_find(__begin, __end, __pred, _IsVector{}, __or_semantic);
2667 if (__res < __end)
2668 __value = __res;
2669 }
2670 return __value;
2671 },
2672 [](_RandomAccessIterator __x, _RandomAccessIterator __y) -> _RandomAccessIterator {
2673 return __x < __y ? __x : __y;
2674 } // reduce a __value
2675 );
2676 });
2677}
2678
2679//------------------------------------------------------------------------
2680// nth_element
2681//------------------------------------------------------------------------
2682
2683template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
2684void __pattern_nth_element(
2685 _Tag,
2686 _ExecutionPolicy&&,
2687 _RandomAccessIterator __first,
2688 _RandomAccessIterator __nth,
2689 _RandomAccessIterator __last,
2690 _Compare __comp) noexcept {
2691 std::nth_element(__first, __nth, __last, __comp);
2692}
2693
2694template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
2695void __pattern_nth_element(
2696 __parallel_tag<_IsVector> __tag,
2697 _ExecutionPolicy&& __exec,
2698 _RandomAccessIterator __first,
2699 _RandomAccessIterator __nth,
2700 _RandomAccessIterator __last,
2701 _Compare __comp) noexcept {
2702 if (__first == __last || __nth == __last) {
2703 return;
2704 }
2705
2706 using std::iter_swap;
2707 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp;
2708 _RandomAccessIterator __x;
2709 do {
2710 __x = __internal::__pattern_partition(
2711 __tag, std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, [&__comp, __first](const _Tp& __x) {
2712 return __comp(__x, *__first);
2713 });
2714 --__x;
2715 if (__x != __first) {
2716 iter_swap(__first, __x);
2717 }
2718 // if x > nth then our new range for partition is [first, x)
2719 if (__x - __nth > 0) {
2720 __last = __x;
2721 }
2722 // if x < nth then our new range for partition is [x, last)
2723 else if (__x - __nth < 0) {
2724 // if *x == *nth then we can start new partition with x+1
2725 if (!__comp(*__nth, *__x) && !__comp(*__x, *__nth)) {
2726 ++__x;
2727 } else {
2728 iter_swap(__nth, __x);
2729 }
2730 __first = __x;
2731 }
2732 } while (__x != __nth);
2733}
2734
2735//------------------------------------------------------------------------
2736// generate, generate_n
2737//------------------------------------------------------------------------
2738template <class _RandomAccessIterator, class _Generator>
2739void __brick_generate(_RandomAccessIterator __first,
2740 _RandomAccessIterator __last,
2741 _Generator __g,
2742 /* is_vector = */ std::true_type) noexcept {
2743 __unseq_backend::__simd_generate_n(__first, __last - __first, __g);
2744}
2745
2746template <class _ForwardIterator, class _Generator>
2747void __brick_generate(_ForwardIterator __first,
2748 _ForwardIterator __last,
2749 _Generator __g,
2750 /* is_vector = */ std::false_type) noexcept {
2751 std::generate(__first, __last, __g);
2752}
2753
2754template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Generator>
2755void __pattern_generate(
2756 _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) noexcept {
2757 __internal::__brick_generate(__first, __last, __g, typename _Tag::__is_vector{});
2758}
2759
2760template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Generator>
2761_RandomAccessIterator __pattern_generate(
2762 __parallel_tag<_IsVector> __tag,
2763 _ExecutionPolicy&& __exec,
2764 _RandomAccessIterator __first,
2765 _RandomAccessIterator __last,
2766 _Generator __g) {
2767 using __backend_tag = typename decltype(__tag)::__backend_tag;
2768
2769 return __internal::__except_handler([&]() {
2770 __par_backend::__parallel_for(
2771 __backend_tag{},
2772 std::forward<_ExecutionPolicy>(__exec),
2773 __first,
2774 __last,
2775 [__g](_RandomAccessIterator __begin, _RandomAccessIterator __end) {
2776 __internal::__brick_generate(__begin, __end, __g, _IsVector{});
2777 });
2778 return __last;
2779 });
2780}
2781
2782template <class _RandomAccessIterator, class Size, class _Generator>
2783_RandomAccessIterator __brick_generate_n(
2784 _RandomAccessIterator __first,
2785 Size __count,
2786 _Generator __g,
2787 /* is_vector = */ std::true_type) noexcept {
2788 return __unseq_backend::__simd_generate_n(__first, __count, __g);
2789}
2790
2791template <class OutputIterator, class Size, class _Generator>
2792OutputIterator
2793__brick_generate_n(OutputIterator __first, Size __count, _Generator __g, /* is_vector = */ std::false_type) noexcept {
2794 return std::generate_n(__first, __count, __g);
2795}
2796
2797template <class _Tag, class _ExecutionPolicy, class _OutputIterator, class _Size, class _Generator>
2798_OutputIterator
2799__pattern_generate_n(_Tag, _ExecutionPolicy&&, _OutputIterator __first, _Size __count, _Generator __g) noexcept {
2800 return __internal::__brick_generate_n(__first, __count, __g, typename _Tag::__is_vector{});
2801}
2802
2803template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Generator>
2804_RandomAccessIterator __pattern_generate_n(
2805 __parallel_tag<_IsVector> __tag,
2806 _ExecutionPolicy&& __exec,
2807 _RandomAccessIterator __first,
2808 _Size __count,
2809 _Generator __g) {
2810 static_assert(__are_random_access_iterators<_RandomAccessIterator>::value,
2811 "Pattern-brick error. Should be a random access iterator.");
2812 return __internal::__pattern_generate(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, __g);
2813}
2814
2815//------------------------------------------------------------------------
2816// remove
2817//------------------------------------------------------------------------
2818
2819template <class _ForwardIterator, class _UnaryPredicate>
2820_ForwardIterator __brick_remove_if(
2821 _ForwardIterator __first,
2822 _ForwardIterator __last,
2823 _UnaryPredicate __pred,
2824 /* __is_vector = */ std::false_type) noexcept {
2825 return std::remove_if(__first, __last, __pred);
2826}
2827
2828template <class _RandomAccessIterator, class _UnaryPredicate>
2829_RandomAccessIterator __brick_remove_if(
2830 _RandomAccessIterator __first,
2831 _RandomAccessIterator __last,
2832 _UnaryPredicate __pred,
2833 /* __is_vector = */ std::true_type) noexcept {
2834#if defined(_PSTL_MONOTONIC_PRESENT)
2835 return __unseq_backend::__simd_remove_if(__first, __last - __first, __pred);
2836#else
2837 return std::remove_if(__first, __last, __pred);
2838#endif
2839}
2840
2841template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
2842_ForwardIterator __pattern_remove_if(
2843 _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) noexcept {
2844 return __internal::__brick_remove_if(__first, __last, __pred, typename _Tag::__is_vector{});
2845}
2846
2847template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate>
2848_RandomAccessIterator __pattern_remove_if(
2849 __parallel_tag<_IsVector> __tag,
2850 _ExecutionPolicy&& __exec,
2851 _RandomAccessIterator __first,
2852 _RandomAccessIterator __last,
2853 _UnaryPredicate __pred) noexcept {
2854 typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType;
2855
2856 if (__first == __last || __first + 1 == __last) {
2857 // Trivial sequence - use serial algorithm
2858 return __internal::__brick_remove_if(__first, __last, __pred, _IsVector{});
2859 }
2860
2861 return __internal::__remove_elements(
2862 __tag,
2863 std::forward<_ExecutionPolicy>(__exec),
2864 __first,
2865 __last,
2866 [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) {
2867 __internal::__brick_walk2(
2868 __b, __e, __it, [&__pred](bool& __x, _ReferenceType __y) { __x = !__pred(__y); }, _IsVector{});
2869 });
2870}
2871
2872//------------------------------------------------------------------------
2873// inplace_merge
2874//------------------------------------------------------------------------
2875template <class _BidirectionalIterator, class _Compare>
2876void __brick_inplace_merge(
2877 _BidirectionalIterator __first,
2878 _BidirectionalIterator __middle,
2879 _BidirectionalIterator __last,
2880 _Compare __comp,
2881 /* __is_vector = */ std::false_type) noexcept {
2882 std::inplace_merge(__first, __middle, __last, __comp);
2883}
2884
2885template <class _RandomAccessIterator, class _Compare>
2886void __brick_inplace_merge(
2887 _RandomAccessIterator __first,
2888 _RandomAccessIterator __middle,
2889 _RandomAccessIterator __last,
2890 _Compare __comp,
2891 /* __is_vector = */ std::true_type) noexcept {
2892 // TODO: vectorize
2893 std::inplace_merge(__first, __middle, __last, __comp);
2894}
2895
2896template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _Compare>
2897void __pattern_inplace_merge(
2898 _Tag,
2899 _ExecutionPolicy&&,
2900 _BidirectionalIterator __first,
2901 _BidirectionalIterator __middle,
2902 _BidirectionalIterator __last,
2903 _Compare __comp) noexcept {
2904 __internal::__brick_inplace_merge(__first, __middle, __last, __comp, typename _Tag::__is_vector{});
2905}
2906
2907template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
2908void __pattern_inplace_merge(
2909 __parallel_tag<_IsVector> __tag,
2910 _ExecutionPolicy&& __exec,
2911 _RandomAccessIterator __first,
2912 _RandomAccessIterator __middle,
2913 _RandomAccessIterator __last,
2914 _Compare __comp) {
2915 using __backend_tag = typename decltype(__tag)::__backend_tag;
2916
2917 if (__first == __last || __first == __middle || __middle == __last) {
2918 return;
2919 }
2920 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp;
2921 auto __n = __last - __first;
2922 __par_backend::__buffer<_Tp> __buf(__n);
2923 _Tp* __r = __buf.get();
2924 __internal::__except_handler([&]() {
2925 auto __move_values = [](_RandomAccessIterator __x, _Tp* __z) {
2926 __internal::__invoke_if_else(
2927 std::is_trivial<_Tp>(),
2928 [&]() { *__z = std::move(*__x); },
2929 [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); });
2930 };
2931
2932 auto __move_sequences = [](_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Tp* __first2) {
2933 return __internal::__brick_uninitialized_move(__first1, __last1, __first2, _IsVector());
2934 };
2935
2936 __par_backend::__parallel_merge(
2937 __backend_tag{},
2938 std::forward<_ExecutionPolicy>(__exec),
2939 __first,
2940 __middle,
2941 __middle,
2942 __last,
2943 __r,
2944 __comp,
2945 [__n, __move_values, __move_sequences](
2946 _RandomAccessIterator __f1,
2947 _RandomAccessIterator __l1,
2948 _RandomAccessIterator __f2,
2949 _RandomAccessIterator __l2,
2950 _Tp* __f3,
2951 _Compare __comp) {
2952 (__utils::__serial_move_merge(__n))(
2953 __f1, __l1, __f2, __l2, __f3, __comp, __move_values, __move_values, __move_sequences, __move_sequences);
2954 return __f3 + (__l1 - __f1) + (__l2 - __f2);
2955 });
2956 __par_backend::__parallel_for(
2957 __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r, __r + __n, [__r, __first](_Tp* __i, _Tp* __j) {
2958 __brick_move_destroy()(__i, __j, __first + (__i - __r), _IsVector{});
2959 });
2960 });
2961}
2962
2963//------------------------------------------------------------------------
2964// includes
2965//------------------------------------------------------------------------
2966
2967template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
2968bool __pattern_includes(
2969 _Tag,
2970 _ExecutionPolicy&&,
2971 _ForwardIterator1 __first1,
2972 _ForwardIterator1 __last1,
2973 _ForwardIterator2 __first2,
2974 _ForwardIterator2 __last2,
2975 _Compare __comp) noexcept {
2976 return std::includes(__first1, __last1, __first2, __last2, __comp);
2977}
2978
2979template <class _IsVector,
2980 class _ExecutionPolicy,
2981 class _RandomAccessIterator1,
2982 class _RandomAccessIterator2,
2983 class _Compare>
2984bool __pattern_includes(
2985 __parallel_tag<_IsVector> __tag,
2986 _ExecutionPolicy&& __exec,
2987 _RandomAccessIterator1 __first1,
2988 _RandomAccessIterator1 __last1,
2989 _RandomAccessIterator2 __first2,
2990 _RandomAccessIterator2 __last2,
2991 _Compare __comp) {
2992 using __backend_tag = typename decltype(__tag)::__backend_tag;
2993
2994 if (__first2 >= __last2)
2995 return true;
2996
2997 if (__first1 >= __last1 || __comp(*__first2, *__first1) || __comp(*(__last1 - 1), *(__last2 - 1)))
2998 return false;
2999
3000 __first1 = std::lower_bound(__first1, __last1, *__first2, __comp);
3001 if (__first1 == __last1)
3002 return false;
3003
3004 if (__last2 - __first2 == 1)
3005 return !__comp(*__first1, *__first2) && !__comp(*__first2, *__first1);
3006
3007 return __internal::__except_handler([&]() {
3008 return !__internal::__parallel_or(
3009 __backend_tag{},
3010 std::forward<_ExecutionPolicy>(__exec),
3011 __first2,
3012 __last2,
3013 [__first1, __last1, __first2, __last2, &__comp](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j) {
3014 _LIBCPP_ASSERT_UNCATEGORIZED(__j > __i, "");
3015 //_LIBCPP_ASSERT_UNCATEGORIZED(__j - __i > 1, "");
3016
3017 // 1. moving boundaries to "consume" subsequence of equal elements
3018 auto __is_equal = [&__comp](_RandomAccessIterator2 __a, _RandomAccessIterator2 __b) -> bool {
3019 return !__comp(*__a, *__b) && !__comp(*__b, *__a);
3020 };
3021
3022 // 1.1 left bound, case "aaa[aaaxyz...]" - searching "x"
3023 if (__i > __first2 && __is_equal(__i, __i - 1)) {
3024 // whole subrange continues to content equal elements - return "no op"
3025 if (__is_equal(__i, __j - 1))
3026 return false;
3027
3028 __i = std::upper_bound(__i, __last2, *__i, __comp);
3029 }
3030
3031 // 1.2 right bound, case "[...aaa]aaaxyz" - searching "x"
3032 if (__j < __last2 && __is_equal(__j - 1, __j))
3033 __j = std::upper_bound(__j, __last2, *__j, __comp);
3034
3035 // 2. testing is __a subsequence of the second range included into the first range
3036 auto __b = std::lower_bound(__first1, __last1, *__i, __comp);
3037
3038 _LIBCPP_ASSERT_UNCATEGORIZED(!__comp(*(__last1 - 1), *__b), "");
3039 _LIBCPP_ASSERT_UNCATEGORIZED(!__comp(*(__j - 1), *__i), "");
3040 return !std::includes(__b, __last1, __i, __j, __comp);
3041 });
3042 });
3043}
3044
3045constexpr auto __set_algo_cut_off = 1000;
3046
3047template <class _IsVector,
3048 class _ExecutionPolicy,
3049 class _ForwardIterator1,
3050 class _ForwardIterator2,
3051 class _OutputIterator,
3052 class _Compare,
3053 class _SizeFunction,
3054 class _SetOP>
3055_OutputIterator __parallel_set_op(
3056 __parallel_tag<_IsVector> __tag,
3057 _ExecutionPolicy&& __exec,
3058 _ForwardIterator1 __first1,
3059 _ForwardIterator1 __last1,
3060 _ForwardIterator2 __first2,
3061 _ForwardIterator2 __last2,
3062 _OutputIterator __result,
3063 _Compare __comp,
3064 _SizeFunction __size_func,
3065 _SetOP __set_op) {
3066 using __backend_tag = typename decltype(__tag)::__backend_tag;
3067
3068 typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;
3069 typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
3070
3071 struct _SetRange {
3072 _DifferenceType __pos, __len, __buf_pos;
3073 bool empty() const { return __len == 0; }
3074 };
3075
3076 const _DifferenceType __n1 = __last1 - __first1;
3077 const _DifferenceType __n2 = __last2 - __first2;
3078
3079 __par_backend::__buffer<_Tp> __buf(__size_func(__n1, __n2));
3080
3081 return __internal::__except_handler(
3082 [&__exec, __n1, __first1, __last1, __first2, __last2, __result, __comp, __size_func, __set_op, &__buf]() {
3083 auto __buffer = __buf.get();
3084 _DifferenceType __m{};
3085 auto __scan = [=](_DifferenceType, _DifferenceType, const _SetRange& __s) { // Scan
3086 if (!__s.empty())
3087 __brick_move_destroy()(
3088 __buffer + __s.__buf_pos, __buffer + (__s.__buf_pos + __s.__len), __result + __s.__pos, _IsVector{});
3089 };
3090 __par_backend::__parallel_strict_scan(
3091 __backend_tag{},
3092 std::forward<_ExecutionPolicy>(__exec),
3093 __n1,
3094 _SetRange{0, 0, 0}, //-1, 0},
3095 [=](_DifferenceType __i, _DifferenceType __len) { // Reduce
3096 //[__b; __e) - a subrange of the first sequence, to reduce
3097 _ForwardIterator1 __b = __first1 + __i, __e = __first1 + (__i + __len);
3098
3099 // try searching for the first element which not equal to *__b
3100 if (__b != __first1)
3101 __b = std::upper_bound(__b, __last1, *__b, __comp);
3102
3103 // try searching for the first element which not equal to *__e
3104 if (__e != __last1)
3105 __e = std::upper_bound(__e, __last1, *__e, __comp);
3106
3107 // check is [__b; __e) empty
3108 if (__e - __b < 1) {
3109 _ForwardIterator2 __bb = __last2;
3110 if (__b != __last1)
3111 __bb = std::lower_bound(__first2, __last2, *__b, __comp);
3112
3113 const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2));
3114 return _SetRange{0, 0, __buf_pos};
3115 }
3116
3117 // try searching for "corresponding" subrange [__bb; __ee) in the second sequence
3118 _ForwardIterator2 __bb = __first2;
3119 if (__b != __first1)
3120 __bb = std::lower_bound(__first2, __last2, *__b, __comp);
3121
3122 _ForwardIterator2 __ee = __last2;
3123 if (__e != __last1)
3124 __ee = std::lower_bound(__bb, __last2, *__e, __comp);
3125
3126 const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2));
3127 auto __buffer_b = __buffer + __buf_pos;
3128 auto __res = __set_op(__b, __e, __bb, __ee, __buffer_b, __comp);
3129
3130 return _SetRange{0, __res - __buffer_b, __buf_pos};
3131 },
3132 [](const _SetRange& __a, const _SetRange& __b) { // Combine
3133 if (__b.__buf_pos > __a.__buf_pos || ((__b.__buf_pos == __a.__buf_pos) && !__b.empty()))
3134 return _SetRange{__a.__pos + __a.__len + __b.__pos, __b.__len, __b.__buf_pos};
3135 return _SetRange{__b.__pos + __b.__len + __a.__pos, __a.__len, __a.__buf_pos};
3136 },
3137 __scan, // Scan
3138 [&__m, &__scan](const _SetRange& __total) { // Apex
3139 // final scan
3140 __scan(0, 0, __total);
3141 __m = __total.__pos + __total.__len;
3142 });
3143 return __result + __m;
3144 });
3145}
3146
3147// a shared parallel pattern for '__pattern_set_union' and '__pattern_set_symmetric_difference'
3148template <class _Tag,
3149 class _ExecutionPolicy,
3150 class _ForwardIterator1,
3151 class _ForwardIterator2,
3152 class _OutputIterator,
3153 class _Compare,
3154 class _SetUnionOp>
3155_OutputIterator __parallel_set_union_op(
3156 _Tag __tag,
3157 _ExecutionPolicy&& __exec,
3158 _ForwardIterator1 __first1,
3159 _ForwardIterator1 __last1,
3160 _ForwardIterator2 __first2,
3161 _ForwardIterator2 __last2,
3162 _OutputIterator __result,
3163 _Compare __comp,
3164 _SetUnionOp __set_union_op) {
3165 using __backend_tag = typename decltype(__tag)::__backend_tag;
3166
3167 typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;
3168
3169 const auto __n1 = __last1 - __first1;
3170 const auto __n2 = __last2 - __first2;
3171
3172 auto copy_range1 = [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) {
3173 return __internal::__brick_copy(__begin, __end, __res, typename _Tag::__is_vector{});
3174 };
3175 auto copy_range2 = [](_ForwardIterator2 __begin, _ForwardIterator2 __end, _OutputIterator __res) {
3176 return __internal::__brick_copy(__begin, __end, __res, typename _Tag::__is_vector{});
3177 };
3178
3179 // {1} {}: parallel copying just first sequence
3180 if (__n2 == 0)
3181 return __internal::__pattern_walk2_brick(
3182 __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, copy_range1);
3183
3184 // {} {2}: parallel copying justmake second sequence
3185 if (__n1 == 0)
3186 return __internal::__pattern_walk2_brick(
3187 __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result, copy_range2);
3188
3189 // testing whether the sequences are intersected
3190 _ForwardIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp);
3191
3192 if (__left_bound_seq_1 == __last1) {
3193 //{1} < {2}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2
3194 __par_backend::__parallel_invoke(
3195 __backend_tag{},
3196 std::forward<_ExecutionPolicy>(__exec),
3197 [=] {
3198 __internal::__pattern_walk2_brick(
3199 __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, copy_range1);
3200 },
3201 [=] {
3202 __internal::__pattern_walk2_brick(
3203 __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result + __n1, copy_range2);
3204 });
3205 return __result + __n1 + __n2;
3206 }
3207
3208 // testing whether the sequences are intersected
3209 _ForwardIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp);
3210
3211 if (__left_bound_seq_2 == __last2) {
3212 //{2} < {1}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2
3213 __par_backend::__parallel_invoke(
3214 __backend_tag{},
3215 std::forward<_ExecutionPolicy>(__exec),
3216 [=] {
3217 __internal::__pattern_walk2_brick(
3218 __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result, copy_range2);
3219 },
3220 [=] {
3221 __internal::__pattern_walk2_brick(
3222 __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result + __n2, copy_range1);
3223 });
3224 return __result + __n1 + __n2;
3225 }
3226
3227 const auto __m1 = __left_bound_seq_1 - __first1;
3228 if (__m1 > __set_algo_cut_off) {
3229 auto __res_or = __result;
3230 __result += __m1; // we know proper offset due to [first1; left_bound_seq_1) < [first2; last2)
3231 __par_backend::__parallel_invoke(
3232 __backend_tag{},
3233 std::forward<_ExecutionPolicy>(__exec),
3234 // do parallel copying of [first1; left_bound_seq_1)
3235 [=] {
3236 __internal::__pattern_walk2_brick(
3237 __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __left_bound_seq_1, __res_or, copy_range1);
3238 },
3239 [=, &__result] {
3240 __result = __internal::__parallel_set_op(
3241 __tag,
3242 std::forward<_ExecutionPolicy>(__exec),
3243 __left_bound_seq_1,
3244 __last1,
3245 __first2,
3246 __last2,
3247 __result,
3248 __comp,
3249 [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; },
3250 __set_union_op);
3251 });
3252 return __result;
3253 }
3254
3255 const auto __m2 = __left_bound_seq_2 - __first2;
3256 _LIBCPP_ASSERT_UNCATEGORIZED(__m1 == 0 || __m2 == 0, "");
3257 if (__m2 > __set_algo_cut_off) {
3258 auto __res_or = __result;
3259 __result += __m2; // we know proper offset due to [first2; left_bound_seq_2) < [first1; last1)
3260 __par_backend::__parallel_invoke(
3261 __backend_tag{},
3262 std::forward<_ExecutionPolicy>(__exec),
3263 // do parallel copying of [first2; left_bound_seq_2)
3264 [=] {
3265 __internal::__pattern_walk2_brick(
3266 __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __left_bound_seq_2, __res_or, copy_range2);
3267 },
3268 [=, &__result] {
3269 __result = __internal::__parallel_set_op(
3270 __tag,
3271 std::forward<_ExecutionPolicy>(__exec),
3272 __first1,
3273 __last1,
3274 __left_bound_seq_2,
3275 __last2,
3276 __result,
3277 __comp,
3278 [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; },
3279 __set_union_op);
3280 });
3281 return __result;
3282 }
3283
3284 return __internal::__parallel_set_op(
3285 __tag,
3286 std::forward<_ExecutionPolicy>(__exec),
3287 __first1,
3288 __last1,
3289 __first2,
3290 __last2,
3291 __result,
3292 __comp,
3293 [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; },
3294 __set_union_op);
3295}
3296
3297//------------------------------------------------------------------------
3298// set_union
3299//------------------------------------------------------------------------
3300
3301template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
3302_OutputIterator __brick_set_union(
3303 _ForwardIterator1 __first1,
3304 _ForwardIterator1 __last1,
3305 _ForwardIterator2 __first2,
3306 _ForwardIterator2 __last2,
3307 _OutputIterator __result,
3308 _Compare __comp,
3309 /*__is_vector=*/std::false_type) noexcept {
3310 return std::set_union(__first1, __last1, __first2, __last2, __result, __comp);
3311}
3312
3313template <typename _IsVector>
3314struct __BrickCopyConstruct {
3315 template <typename _ForwardIterator, typename _OutputIterator>
3316 _OutputIterator operator()(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result) {
3317 return __brick_uninitialized_copy(__first, __last, __result, _IsVector());
3318 }
3319};
3320
3321template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare>
3322_OutputIterator __brick_set_union(
3323 _RandomAccessIterator1 __first1,
3324 _RandomAccessIterator1 __last1,
3325 _RandomAccessIterator2 __first2,
3326 _RandomAccessIterator2 __last2,
3327 _OutputIterator __result,
3328 _Compare __comp,
3329 /*__is_vector=*/std::true_type) noexcept {
3330 // TODO: vectorize
3331 return std::set_union(__first1, __last1, __first2, __last2, __result, __comp);
3332}
3333
3334template <class _Tag,
3335 class _ExecutionPolicy,
3336 class _ForwardIterator1,
3337 class _ForwardIterator2,
3338 class _OutputIterator,
3339 class _Compare>
3340_OutputIterator __pattern_set_union(
3341 _Tag,
3342 _ExecutionPolicy&&,
3343 _ForwardIterator1 __first1,
3344 _ForwardIterator1 __last1,
3345 _ForwardIterator2 __first2,
3346 _ForwardIterator2 __last2,
3347 _OutputIterator __result,
3348 _Compare __comp) noexcept {
3349 return __internal::__brick_set_union(
3350 __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{});
3351}
3352
3353template <class _IsVector,
3354 class _ExecutionPolicy,
3355 class _RandomAccessIterator1,
3356 class _RandomAccessIterator2,
3357 class _OutputIterator,
3358 class _Compare>
3359_OutputIterator __pattern_set_union(
3360 __parallel_tag<_IsVector> __tag,
3361 _ExecutionPolicy&& __exec,
3362 _RandomAccessIterator1 __first1,
3363 _RandomAccessIterator1 __last1,
3364 _RandomAccessIterator2 __first2,
3365 _RandomAccessIterator2 __last2,
3366 _OutputIterator __result,
3367 _Compare __comp) {
3368 const auto __n1 = __last1 - __first1;
3369 const auto __n2 = __last2 - __first2;
3370
3371 // use serial algorithm
3372 if (__n1 + __n2 <= __set_algo_cut_off)
3373 return std::set_union(__first1, __last1, __first2, __last2, __result, __comp);
3374
3375 typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
3376 return __parallel_set_union_op(
3377 __tag,
3378 std::forward<_ExecutionPolicy>(__exec),
3379 __first1,
3380 __last1,
3381 __first2,
3382 __last2,
3383 __result,
3384 __comp,
3385 [](_RandomAccessIterator1 __first1,
3386 _RandomAccessIterator1 __last1,
3387 _RandomAccessIterator2 __first2,
3388 _RandomAccessIterator2 __last2,
3389 _Tp* __result,
3390 _Compare __comp) {
3391 return __pstl::__utils::__set_union_construct(
3392 __first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>());
3393 });
3394}
3395
3396//------------------------------------------------------------------------
3397// set_intersection
3398//------------------------------------------------------------------------
3399
3400template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
3401_OutputIterator __brick_set_intersection(
3402 _ForwardIterator1 __first1,
3403 _ForwardIterator1 __last1,
3404 _ForwardIterator2 __first2,
3405 _ForwardIterator2 __last2,
3406 _OutputIterator __result,
3407 _Compare __comp,
3408 /*__is_vector=*/std::false_type) noexcept {
3409 return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp);
3410}
3411
3412template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare>
3413_RandomAccessIterator3 __brick_set_intersection(
3414 _RandomAccessIterator1 __first1,
3415 _RandomAccessIterator1 __last1,
3416 _RandomAccessIterator2 __first2,
3417 _RandomAccessIterator2 __last2,
3418 _RandomAccessIterator3 __result,
3419 _Compare __comp,
3420 /*__is_vector=*/std::true_type) noexcept {
3421 // TODO: vectorize
3422 return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp);
3423}
3424
3425template <class _Tag,
3426 class _ExecutionPolicy,
3427 class _ForwardIterator1,
3428 class _ForwardIterator2,
3429 class _OutputIterator,
3430 class _Compare>
3431_OutputIterator __pattern_set_intersection(
3432 _Tag,
3433 _ExecutionPolicy&&,
3434 _ForwardIterator1 __first1,
3435 _ForwardIterator1 __last1,
3436 _ForwardIterator2 __first2,
3437 _ForwardIterator2 __last2,
3438 _OutputIterator __result,
3439 _Compare __comp) noexcept {
3440 return __internal::__brick_set_intersection(
3441 __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{});
3442}
3443
3444template <class _IsVector,
3445 class _ExecutionPolicy,
3446 class _RandomAccessIterator1,
3447 class _RandomAccessIterator2,
3448 class _RandomAccessIterator3,
3449 class _Compare>
3450_RandomAccessIterator3 __pattern_set_intersection(
3451 __parallel_tag<_IsVector> __tag,
3452 _ExecutionPolicy&& __exec,
3453 _RandomAccessIterator1 __first1,
3454 _RandomAccessIterator1 __last1,
3455 _RandomAccessIterator2 __first2,
3456 _RandomAccessIterator2 __last2,
3457 _RandomAccessIterator3 __result,
3458 _Compare __comp) {
3459 typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp;
3460 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType;
3461
3462 const auto __n1 = __last1 - __first1;
3463 const auto __n2 = __last2 - __first2;
3464
3465 // intersection is empty
3466 if (__n1 == 0 || __n2 == 0)
3467 return __result;
3468
3469 // testing whether the sequences are intersected
3470 _RandomAccessIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp);
3471 //{1} < {2}: seq 2 is wholly greater than seq 1, so, the intersection is empty
3472 if (__left_bound_seq_1 == __last1)
3473 return __result;
3474
3475 // testing whether the sequences are intersected
3476 _RandomAccessIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp);
3477 //{2} < {1}: seq 1 is wholly greater than seq 2, so, the intersection is empty
3478 if (__left_bound_seq_2 == __last2)
3479 return __result;
3480
3481 const auto __m1 = __last1 - __left_bound_seq_1 + __n2;
3482 if (__m1 > __set_algo_cut_off) {
3483 // we know proper offset due to [first1; left_bound_seq_1) < [first2; last2)
3484 return __internal::__parallel_set_op(
3485 __tag,
3486 std::forward<_ExecutionPolicy>(__exec),
3487 __left_bound_seq_1,
3488 __last1,
3489 __first2,
3490 __last2,
3491 __result,
3492 __comp,
3493 [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); },
3494 [](_RandomAccessIterator1 __first1,
3495 _RandomAccessIterator1 __last1,
3496 _RandomAccessIterator2 __first2,
3497 _RandomAccessIterator2 __last2,
3498 _Tp* __result,
3499 _Compare __comp) {
3500 return __pstl::__utils::__set_intersection_construct(__first1, __last1, __first2, __last2, __result, __comp);
3501 });
3502 }
3503
3504 const auto __m2 = __last2 - __left_bound_seq_2 + __n1;
3505 if (__m2 > __set_algo_cut_off) {
3506 // we know proper offset due to [first2; left_bound_seq_2) < [first1; last1)
3507 __result = __internal::__parallel_set_op(
3508 __tag,
3509 std::forward<_ExecutionPolicy>(__exec),
3510 __first1,
3511 __last1,
3512 __left_bound_seq_2,
3513 __last2,
3514 __result,
3515 __comp,
3516 [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); },
3517 [](_RandomAccessIterator1 __first1,
3518 _RandomAccessIterator1 __last1,
3519 _RandomAccessIterator2 __first2,
3520 _RandomAccessIterator2 __last2,
3521 _Tp* __result,
3522 _Compare __comp) {
3523 return __pstl::__utils::__set_intersection_construct(__first2, __last2, __first1, __last1, __result, __comp);
3524 });
3525 return __result;
3526 }
3527
3528 // [left_bound_seq_1; last1) and [left_bound_seq_2; last2) - use serial algorithm
3529 return std::set_intersection(__left_bound_seq_1, __last1, __left_bound_seq_2, __last2, __result, __comp);
3530}
3531
3532//------------------------------------------------------------------------
3533// set_difference
3534//------------------------------------------------------------------------
3535
3536template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
3537_OutputIterator __brick_set_difference(
3538 _ForwardIterator1 __first1,
3539 _ForwardIterator1 __last1,
3540 _ForwardIterator2 __first2,
3541 _ForwardIterator2 __last2,
3542 _OutputIterator __result,
3543 _Compare __comp,
3544 /*__is_vector=*/std::false_type) noexcept {
3545 return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp);
3546}
3547
3548template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare>
3549_RandomAccessIterator3 __brick_set_difference(
3550 _RandomAccessIterator1 __first1,
3551 _RandomAccessIterator1 __last1,
3552 _RandomAccessIterator2 __first2,
3553 _RandomAccessIterator2 __last2,
3554 _RandomAccessIterator3 __result,
3555 _Compare __comp,
3556 /*__is_vector=*/std::true_type) noexcept {
3557 // TODO: vectorize
3558 return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp);
3559}
3560
3561template <class _Tag,
3562 class _ExecutionPolicy,
3563 class _ForwardIterator1,
3564 class _ForwardIterator2,
3565 class _OutputIterator,
3566 class _Compare>
3567_OutputIterator __pattern_set_difference(
3568 _Tag,
3569 _ExecutionPolicy&&,
3570 _ForwardIterator1 __first1,
3571 _ForwardIterator1 __last1,
3572 _ForwardIterator2 __first2,
3573 _ForwardIterator2 __last2,
3574 _OutputIterator __result,
3575 _Compare __comp) noexcept {
3576 return __internal::__brick_set_difference(
3577 __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{});
3578}
3579
3580template <class _IsVector,
3581 class _ExecutionPolicy,
3582 class _RandomAccessIterator1,
3583 class _RandomAccessIterator2,
3584 class _RandomAccessIterator3,
3585 class _Compare>
3586_RandomAccessIterator3 __pattern_set_difference(
3587 __parallel_tag<_IsVector> __tag,
3588 _ExecutionPolicy&& __exec,
3589 _RandomAccessIterator1 __first1,
3590 _RandomAccessIterator1 __last1,
3591 _RandomAccessIterator2 __first2,
3592 _RandomAccessIterator2 __last2,
3593 _RandomAccessIterator3 __result,
3594 _Compare __comp) {
3595 typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp;
3596 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType;
3597
3598 const auto __n1 = __last1 - __first1;
3599 const auto __n2 = __last2 - __first2;
3600
3601 // {} \ {2}: the difference is empty
3602 if (__n1 == 0)
3603 return __result;
3604
3605 // {1} \ {}: parallel copying just first sequence
3606 if (__n2 == 0)
3607 return __internal::__pattern_walk2_brick(
3608 __tag,
3609 std::forward<_ExecutionPolicy>(__exec),
3610 __first1,
3611 __last1,
3612 __result,
3613 [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) {
3614 return __internal::__brick_copy(__begin, __end, __res, _IsVector{});
3615 });
3616
3617 // testing whether the sequences are intersected
3618 _RandomAccessIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp);
3619 //{1} < {2}: seq 2 is wholly greater than seq 1, so, parallel copying just first sequence
3620 if (__left_bound_seq_1 == __last1)
3621 return __internal::__pattern_walk2_brick(
3622 __tag,
3623 std::forward<_ExecutionPolicy>(__exec),
3624 __first1,
3625 __last1,
3626 __result,
3627 [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) {
3628 return __internal::__brick_copy(__begin, __end, __res, _IsVector{});
3629 });
3630
3631 // testing whether the sequences are intersected
3632 _RandomAccessIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp);
3633 //{2} < {1}: seq 1 is wholly greater than seq 2, so, parallel copying just first sequence
3634 if (__left_bound_seq_2 == __last2)
3635 return __internal::__pattern_walk2_brick(
3636 __tag,
3637 std::forward<_ExecutionPolicy>(__exec),
3638 __first1,
3639 __last1,
3640 __result,
3641 [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) {
3642 return __internal::__brick_copy(__begin, __end, __res, _IsVector{});
3643 });
3644
3645 if (__n1 + __n2 > __set_algo_cut_off)
3646 return __parallel_set_op(
3647 __tag,
3648 std::forward<_ExecutionPolicy>(__exec),
3649 __first1,
3650 __last1,
3651 __first2,
3652 __last2,
3653 __result,
3654 __comp,
3655 [](_DifferenceType __n, _DifferenceType) { return __n; },
3656 [](_RandomAccessIterator1 __first1,
3657 _RandomAccessIterator1 __last1,
3658 _RandomAccessIterator2 __first2,
3659 _RandomAccessIterator2 __last2,
3660 _Tp* __result,
3661 _Compare __comp) {
3662 return __pstl::__utils::__set_difference_construct(
3663 __first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>());
3664 });
3665
3666 // use serial algorithm
3667 return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp);
3668}
3669
3670//------------------------------------------------------------------------
3671// set_symmetric_difference
3672//------------------------------------------------------------------------
3673
3674template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
3675_OutputIterator __brick_set_symmetric_difference(
3676 _ForwardIterator1 __first1,
3677 _ForwardIterator1 __last1,
3678 _ForwardIterator2 __first2,
3679 _ForwardIterator2 __last2,
3680 _OutputIterator __result,
3681 _Compare __comp,
3682 /*__is_vector=*/std::false_type) noexcept {
3683 return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
3684}
3685
3686template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare>
3687_RandomAccessIterator3 __brick_set_symmetric_difference(
3688 _RandomAccessIterator1 __first1,
3689 _RandomAccessIterator1 __last1,
3690 _RandomAccessIterator2 __first2,
3691 _RandomAccessIterator2 __last2,
3692 _RandomAccessIterator3 __result,
3693 _Compare __comp,
3694 /*__is_vector=*/std::true_type) noexcept {
3695 // TODO: vectorize
3696 return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
3697}
3698
3699template <class _Tag,
3700 class _ExecutionPolicy,
3701 class _ForwardIterator1,
3702 class _ForwardIterator2,
3703 class _OutputIterator,
3704 class _Compare>
3705_OutputIterator __pattern_set_symmetric_difference(
3706 _Tag,
3707 _ExecutionPolicy&&,
3708 _ForwardIterator1 __first1,
3709 _ForwardIterator1 __last1,
3710 _ForwardIterator2 __first2,
3711 _ForwardIterator2 __last2,
3712 _OutputIterator __result,
3713 _Compare __comp) noexcept {
3714 return __internal::__brick_set_symmetric_difference(
3715 __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{});
3716}
3717
3718template <class _IsVector,
3719 class _ExecutionPolicy,
3720 class _RandomAccessIterator1,
3721 class _RandomAccessIterator2,
3722 class _RandomAccessIterator3,
3723 class _Compare>
3724_RandomAccessIterator3 __pattern_set_symmetric_difference(
3725 __parallel_tag<_IsVector> __tag,
3726 _ExecutionPolicy&& __exec,
3727 _RandomAccessIterator1 __first1,
3728 _RandomAccessIterator1 __last1,
3729 _RandomAccessIterator2 __first2,
3730 _RandomAccessIterator2 __last2,
3731 _RandomAccessIterator3 __result,
3732 _Compare __comp) {
3733 const auto __n1 = __last1 - __first1;
3734 const auto __n2 = __last2 - __first2;
3735
3736 // use serial algorithm
3737 if (__n1 + __n2 <= __set_algo_cut_off)
3738 return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
3739
3740 typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp;
3741 return __internal::__parallel_set_union_op(
3742 __tag,
3743 std::forward<_ExecutionPolicy>(__exec),
3744 __first1,
3745 __last1,
3746 __first2,
3747 __last2,
3748 __result,
3749 __comp,
3750 [](_RandomAccessIterator1 __first1,
3751 _RandomAccessIterator1 __last1,
3752 _RandomAccessIterator2 __first2,
3753 _RandomAccessIterator2 __last2,
3754 _Tp* __result,
3755 _Compare __comp) {
3756 return __pstl::__utils::__set_symmetric_difference_construct(
3757 __first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>());
3758 });
3759}
3760
3761//------------------------------------------------------------------------
3762// is_heap_until
3763//------------------------------------------------------------------------
3764
3765template <class _RandomAccessIterator, class _Compare>
3766_RandomAccessIterator __brick_is_heap_until(
3767 _RandomAccessIterator __first,
3768 _RandomAccessIterator __last,
3769 _Compare __comp,
3770 /* __is_vector = */ std::false_type) noexcept {
3771 return std::is_heap_until(__first, __last, __comp);
3772}
3773
3774template <class _RandomAccessIterator, class _Compare>
3775_RandomAccessIterator __brick_is_heap_until(
3776 _RandomAccessIterator __first,
3777 _RandomAccessIterator __last,
3778 _Compare __comp,
3779 /* __is_vector = */ std::true_type) noexcept {
3780 if (__last - __first < 2)
3781 return __last;
3782 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType;
3783 return __unseq_backend::__simd_first(
3784 __first, _SizeType(0), __last - __first, [&__comp](_RandomAccessIterator __it, _SizeType __i) {
3785 return __comp(__it[(__i - 1) / 2], __it[__i]);
3786 });
3787}
3788
3789template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
3790_RandomAccessIterator __pattern_is_heap_until(
3791 _Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) noexcept {
3792 return __internal::__brick_is_heap_until(__first, __last, __comp, typename _Tag::__is_vector{});
3793}
3794
3795template <class _RandomAccessIterator, class _DifferenceType, class _Compare>
3796_RandomAccessIterator __is_heap_until_local(
3797 _RandomAccessIterator __first,
3798 _DifferenceType __begin,
3799 _DifferenceType __end,
3800 _Compare __comp,
3801 /* __is_vector = */ std::false_type) noexcept {
3802 _DifferenceType __i = __begin;
3803 for (; __i < __end; ++__i) {
3804 if (__comp(__first[(__i - 1) / 2], __first[__i])) {
3805 break;
3806 }
3807 }
3808 return __first + __i;
3809}
3810
3811template <class _RandomAccessIterator, class _DifferenceType, class _Compare>
3812_RandomAccessIterator __is_heap_until_local(
3813 _RandomAccessIterator __first,
3814 _DifferenceType __begin,
3815 _DifferenceType __end,
3816 _Compare __comp,
3817 /* __is_vector = */ std::true_type) noexcept {
3818 return __unseq_backend::__simd_first(
3819 __first, __begin, __end, [&__comp](_RandomAccessIterator __it, _DifferenceType __i) {
3820 return __comp(__it[(__i - 1) / 2], __it[__i]);
3821 });
3822}
3823
3824template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
3825_RandomAccessIterator __pattern_is_heap_until(
3826 __parallel_tag<_IsVector> __tag,
3827 _ExecutionPolicy&& __exec,
3828 _RandomAccessIterator __first,
3829 _RandomAccessIterator __last,
3830 _Compare __comp) noexcept {
3831 using __backend_tag = typename decltype(__tag)::__backend_tag;
3832
3833 if (__last - __first < 2)
3834 return __last;
3835
3836 return __internal::__except_handler([&]() {
3837 return __parallel_find(
3838 __backend_tag{},
3839 std::forward<_ExecutionPolicy>(__exec),
3840 __first,
3841 __last,
3842 [__first, __comp](_RandomAccessIterator __i, _RandomAccessIterator __j) {
3843 return __internal::__is_heap_until_local(__first, __i - __first, __j - __first, __comp, _IsVector{});
3844 },
3845 std::less<typename std::iterator_traits<_RandomAccessIterator>::difference_type>(),
3846 /*is_first=*/true);
3847 });
3848}
3849
3850//------------------------------------------------------------------------
3851// min_element
3852//------------------------------------------------------------------------
3853
3854template <typename _ForwardIterator, typename _Compare>
3855_ForwardIterator __brick_min_element(
3856 _ForwardIterator __first,
3857 _ForwardIterator __last,
3858 _Compare __comp,
3859 /* __is_vector = */ std::false_type) noexcept {
3860 return std::min_element(__first, __last, __comp);
3861}
3862
3863template <typename _RandomAccessIterator, typename _Compare>
3864_RandomAccessIterator __brick_min_element(
3865 _RandomAccessIterator __first,
3866 _RandomAccessIterator __last,
3867 _Compare __comp,
3868 /* __is_vector = */ std::true_type) noexcept {
3869#if defined(_PSTL_UDR_PRESENT)
3870 return __unseq_backend::__simd_min_element(__first, __last - __first, __comp);
3871#else
3872 return std::min_element(__first, __last, __comp);
3873#endif
3874}
3875
3876template <typename _Tag, typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare>
3877_ForwardIterator __pattern_min_element(
3878 _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) noexcept {
3879 return __internal::__brick_min_element(__first, __last, __comp, typename _Tag::__is_vector{});
3880}
3881
3882template <typename _IsVector, typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare>
3883_RandomAccessIterator __pattern_min_element(
3884 __parallel_tag<_IsVector> __tag,
3885 _ExecutionPolicy&& __exec,
3886 _RandomAccessIterator __first,
3887 _RandomAccessIterator __last,
3888 _Compare __comp) {
3889 if (__first == __last)
3890 return __last;
3891
3892 using __backend_tag = typename decltype(__tag)::__backend_tag;
3893
3894 return __internal::__except_handler([&]() {
3895 return __par_backend::__parallel_reduce(
3896 __backend_tag{},
3897 std::forward<_ExecutionPolicy>(__exec),
3898 __first + 1,
3899 __last,
3900 __first,
3901 [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, _RandomAccessIterator __init)
3902 -> _RandomAccessIterator {
3903 const _RandomAccessIterator subresult = __internal::__brick_min_element(__begin, __end, __comp, _IsVector{});
3904 return __internal::__cmp_iterators_by_values(__init, subresult, __comp);
3905 },
3906 [=](_RandomAccessIterator __it1, _RandomAccessIterator __it2) -> _RandomAccessIterator {
3907 return __internal::__cmp_iterators_by_values(__it1, __it2, __comp);
3908 });
3909 });
3910}
3911
3912//------------------------------------------------------------------------
3913// minmax_element
3914//------------------------------------------------------------------------
3915
3916template <typename _ForwardIterator, typename _Compare>
3917std::pair<_ForwardIterator, _ForwardIterator> __brick_minmax_element(
3918 _ForwardIterator __first,
3919 _ForwardIterator __last,
3920 _Compare __comp,
3921 /* __is_vector = */ std::false_type) noexcept {
3922 return std::minmax_element(__first, __last, __comp);
3923}
3924
3925template <typename _RandomAccessIterator, typename _Compare>
3926std::pair<_RandomAccessIterator, _RandomAccessIterator> __brick_minmax_element(
3927 _RandomAccessIterator __first,
3928 _RandomAccessIterator __last,
3929 _Compare __comp,
3930 /* __is_vector = */ std::true_type) noexcept {
3931#if defined(_PSTL_UDR_PRESENT)
3932 return __unseq_backend::__simd_minmax_element(__first, __last - __first, __comp);
3933#else
3934 return std::minmax_element(__first, __last, __comp);
3935#endif
3936}
3937
3938template <typename _Tag, typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare>
3939std::pair<_ForwardIterator, _ForwardIterator> __pattern_minmax_element(
3940 _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) noexcept {
3941 return __internal::__brick_minmax_element(__first, __last, __comp, typename _Tag::__is_vector{});
3942}
3943
3944template <typename _IsVector, typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare>
3945std::pair<_RandomAccessIterator, _RandomAccessIterator> __pattern_minmax_element(
3946 __parallel_tag<_IsVector> __tag,
3947 _ExecutionPolicy&& __exec,
3948 _RandomAccessIterator __first,
3949 _RandomAccessIterator __last,
3950 _Compare __comp) {
3951 if (__first == __last)
3952 return std::make_pair(__first, __first);
3953
3954 using __backend_tag = typename decltype(__tag)::__backend_tag;
3955
3956 return __internal::__except_handler([&]() {
3957 typedef std::pair<_RandomAccessIterator, _RandomAccessIterator> _Result;
3958
3959 return __par_backend::__parallel_reduce(
3960 __backend_tag{},
3961 std::forward<_ExecutionPolicy>(__exec),
3962 __first + 1,
3963 __last,
3964 std::make_pair(__first, __first),
3965 [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Result __init) -> _Result {
3966 const _Result __subresult = __internal::__brick_minmax_element(__begin, __end, __comp, _IsVector{});
3967 return std::make_pair(
3968 __internal::__cmp_iterators_by_values(__subresult.first, __init.first, __comp),
3969 __internal::__cmp_iterators_by_values(__init.second, __subresult.second, std::not_fn(__comp)));
3970 },
3971 [=](_Result __p1, _Result __p2) -> _Result {
3972 return std::make_pair(__internal::__cmp_iterators_by_values(__p1.first, __p2.first, __comp),
3973 __internal::__cmp_iterators_by_values(__p2.second, __p1.second, std::not_fn(__comp)));
3974 });
3975 });
3976}
3977
3978//------------------------------------------------------------------------
3979// mismatch
3980//------------------------------------------------------------------------
3981template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
3982std::pair<_ForwardIterator1, _ForwardIterator2> __mismatch_serial(
3983 _ForwardIterator1 __first1,
3984 _ForwardIterator1 __last1,
3985 _ForwardIterator2 __first2,
3986 _ForwardIterator2 __last2,
3987 _BinaryPredicate __pred) {
3988 return std::mismatch(__first1, __last1, __first2, __last2, __pred);
3989}
3990
3991template <class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
3992std::pair<_ForwardIterator1, _ForwardIterator2> __brick_mismatch(
3993 _ForwardIterator1 __first1,
3994 _ForwardIterator1 __last1,
3995 _ForwardIterator2 __first2,
3996 _ForwardIterator2 __last2,
3997 _Predicate __pred,
3998 /* __is_vector = */ std::false_type) noexcept {
3999 return __mismatch_serial(__first1, __last1, __first2, __last2, __pred);
4000}
4001
4002template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Predicate>
4003std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __brick_mismatch(
4004 _RandomAccessIterator1 __first1,
4005 _RandomAccessIterator1 __last1,
4006 _RandomAccessIterator2 __first2,
4007 _RandomAccessIterator2 __last2,
4008 _Predicate __pred,
4009 /* __is_vector = */ std::true_type) noexcept {
4010 auto __n = std::min(__last1 - __first1, __last2 - __first2);
4011 return __unseq_backend::__simd_first(__first1, __n, __first2, std::not_fn(__pred));
4012}
4013
4014template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
4015std::pair<_ForwardIterator1, _ForwardIterator2> __pattern_mismatch(
4016 _Tag,
4017 _ExecutionPolicy&&,
4018 _ForwardIterator1 __first1,
4019 _ForwardIterator1 __last1,
4020 _ForwardIterator2 __first2,
4021 _ForwardIterator2 __last2,
4022 _Predicate __pred) noexcept {
4023 return __internal::__brick_mismatch(__first1, __last1, __first2, __last2, __pred, typename _Tag::__is_vector{});
4024}
4025
4026template <class _IsVector,
4027 class _ExecutionPolicy,
4028 class _RandomAccessIterator1,
4029 class _RandomAccessIterator2,
4030 class _Predicate>
4031std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __pattern_mismatch(
4032 __parallel_tag<_IsVector> __tag,
4033 _ExecutionPolicy&& __exec,
4034 _RandomAccessIterator1 __first1,
4035 _RandomAccessIterator1 __last1,
4036 _RandomAccessIterator2 __first2,
4037 _RandomAccessIterator2 __last2,
4038 _Predicate __pred) noexcept {
4039 using __backend_tag = typename decltype(__tag)::__backend_tag;
4040
4041 return __internal::__except_handler([&]() {
4042 auto __n = std::min(__last1 - __first1, __last2 - __first2);
4043 auto __result = __internal::__parallel_find(
4044 __backend_tag{},
4045 std::forward<_ExecutionPolicy>(__exec),
4046 __first1,
4047 __first1 + __n,
4048 [__first1, __first2, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
4049 return __internal::__brick_mismatch(
4050 __i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), __pred, _IsVector{})
4051 .first;
4052 },
4053 std::less<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(),
4054 /*is_first=*/true);
4055 return std::make_pair(__result, __first2 + (__result - __first1));
4056 });
4057}
4058
4059//------------------------------------------------------------------------
4060// lexicographical_compare
4061//------------------------------------------------------------------------
4062
4063template <class _ForwardIterator1, class _ForwardIterator2, class _Compare>
4064bool __brick_lexicographical_compare(
4065 _ForwardIterator1 __first1,
4066 _ForwardIterator1 __last1,
4067 _ForwardIterator2 __first2,
4068 _ForwardIterator2 __last2,
4069 _Compare __comp,
4070 /* __is_vector = */ std::false_type) noexcept {
4071 return std::lexicographical_compare(__first1, __last1, __first2, __last2, __comp);
4072}
4073
4074template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Compare>
4075bool __brick_lexicographical_compare(
4076 _RandomAccessIterator1 __first1,
4077 _RandomAccessIterator1 __last1,
4078 _RandomAccessIterator2 __first2,
4079 _RandomAccessIterator2 __last2,
4080 _Compare __comp,
4081 /* __is_vector = */ std::true_type) noexcept {
4082 if (__first2 == __last2) { // if second sequence is empty
4083 return false;
4084 } else if (__first1 == __last1) { // if first sequence is empty
4085 return true;
4086 } else {
4087 typedef typename std::iterator_traits<_RandomAccessIterator1>::reference ref_type1;
4088 typedef typename std::iterator_traits<_RandomAccessIterator2>::reference ref_type2;
4089 --__last1;
4090 --__last2;
4091 auto __n = std::min(__last1 - __first1, __last2 - __first2);
4092 std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __result = __unseq_backend::__simd_first(
4093 __first1, __n, __first2, [__comp](const ref_type1 __x, const ref_type2 __y) mutable {
4094 return __comp(__x, __y) || __comp(__y, __x);
4095 });
4096
4097 if (__result.first == __last1 && __result.second != __last2) { // if first sequence shorter than second
4098 return !__comp(*__result.second, *__result.first);
4099 } else { // if second sequence shorter than first or both have the same number of elements
4100 return __comp(*__result.first, *__result.second);
4101 }
4102 }
4103}
4104
4105template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
4106bool __pattern_lexicographical_compare(
4107 _Tag,
4108 _ExecutionPolicy&&,
4109 _ForwardIterator1 __first1,
4110 _ForwardIterator1 __last1,
4111 _ForwardIterator2 __first2,
4112 _ForwardIterator2 __last2,
4113 _Compare __comp) noexcept {
4114 return __internal::__brick_lexicographical_compare(
4115 __first1, __last1, __first2, __last2, __comp, typename _Tag::__is_vector{});
4116}
4117
4118template <class _IsVector,
4119 class _ExecutionPolicy,
4120 class _RandomAccessIterator1,
4121 class _RandomAccessIterator2,
4122 class _Compare>
4123bool __pattern_lexicographical_compare(
4124 __parallel_tag<_IsVector> __tag,
4125 _ExecutionPolicy&& __exec,
4126 _RandomAccessIterator1 __first1,
4127 _RandomAccessIterator1 __last1,
4128 _RandomAccessIterator2 __first2,
4129 _RandomAccessIterator2 __last2,
4130 _Compare __comp) noexcept {
4131 using __backend_tag = typename decltype(__tag)::__backend_tag;
4132
4133 if (__first2 == __last2) { // if second sequence is empty
4134 return false;
4135 } else if (__first1 == __last1) { // if first sequence is empty
4136 return true;
4137 } else {
4138 typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _RefType1;
4139 typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _RefType2;
4140 --__last1;
4141 --__last2;
4142 auto __n = std::min(__last1 - __first1, __last2 - __first2);
4143 auto __result = __internal::__parallel_find(
4144 __backend_tag{},
4145 std::forward<_ExecutionPolicy>(__exec),
4146 __first1,
4147 __first1 + __n,
4148 [__first1, __first2, &__comp](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
4149 return __internal::__brick_mismatch(
4150 __i,
4151 __j,
4152 __first2 + (__i - __first1),
4153 __first2 + (__j - __first1),
4154 [&__comp](const _RefType1 __x, const _RefType2 __y) {
4155 return !__comp(__x, __y) && !__comp(__y, __x);
4156 },
4157 _IsVector{})
4158 .first;
4159 },
4160 std::less<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(),
4161 /*is_first=*/true);
4162
4163 if (__result == __last1 && __first2 + (__result - __first1) != __last2) { // if first sequence shorter than second
4164 return !__comp(*(__first2 + (__result - __first1)), *__result);
4165 } else { // if second sequence shorter than first or both have the same number of elements
4166 return __comp(*__result, *(__first2 + (__result - __first1)));
4167 }
4168 }
4169}
4170
4171} // namespace __internal
4172} // namespace __pstl
4173
4174#endif /* _PSTL_ALGORITHM_IMPL_H */
lib/libcxx/include/__pstl/internal/execution_defs.h created+76
......@@ -0,0 +1,76 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_EXECUTION_POLICY_DEFS_H
11#define _PSTL_EXECUTION_POLICY_DEFS_H
12
13#include <__config>
14#include <__type_traits/decay.h>
15#include <__type_traits/enable_if.h>
16#include <__type_traits/integral_constant.h>
17
18#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
19
20namespace __pstl {
21namespace execution {
22inline namespace v1 {
23
24// 2.4, Sequential execution policy
25class sequenced_policy {};
26
27// 2.5, Parallel execution policy
28class parallel_policy {};
29
30// 2.6, Parallel+Vector execution policy
31class parallel_unsequenced_policy {};
32
33class unsequenced_policy {};
34
35// 2.8, Execution policy objects
36constexpr sequenced_policy seq{};
37constexpr parallel_policy par{};
38constexpr parallel_unsequenced_policy par_unseq{};
39constexpr unsequenced_policy unseq{};
40
41// 2.3, Execution policy type trait
42template <class>
43struct is_execution_policy : std::false_type {};
44
45template <>
46struct is_execution_policy<__pstl::execution::sequenced_policy> : std::true_type {};
47template <>
48struct is_execution_policy<__pstl::execution::parallel_policy> : std::true_type {};
49template <>
50struct is_execution_policy<__pstl::execution::parallel_unsequenced_policy> : std::true_type {};
51template <>
52struct is_execution_policy<__pstl::execution::unsequenced_policy> : std::true_type {};
53
54template <class _Tp>
55constexpr bool is_execution_policy_v = __pstl::execution::is_execution_policy<_Tp>::value;
56} // namespace v1
57} // namespace execution
58
59namespace __internal {
60template <class _ExecPolicy, class _Tp>
61using __enable_if_execution_policy =
62 typename std::enable_if<__pstl::execution::is_execution_policy<typename std::decay<_ExecPolicy>::type>::value,
63 _Tp>::type;
64
65template <class _IsVector>
66struct __serial_tag;
67template <class _IsVector>
68struct __parallel_tag;
69
70} // namespace __internal
71
72} // namespace __pstl
73
74#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
75
76#endif /* _PSTL_EXECUTION_POLICY_DEFS_H */
lib/libcxx/include/__pstl/internal/execution_impl.h created+97
......@@ -0,0 +1,97 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_EXECUTION_IMPL_H
11#define _PSTL_EXECUTION_IMPL_H
12
13#include <__config>
14#include <__iterator/iterator_traits.h>
15#include <__type_traits/conditional.h>
16#include <__type_traits/conjunction.h>
17#include <__type_traits/decay.h>
18#include <__type_traits/integral_constant.h>
19#include <__type_traits/is_base_of.h>
20
21#include <__pstl/internal/execution_defs.h>
22
23#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
24
25namespace __pstl {
26namespace __internal {
27
28template <typename _IteratorTag, typename... _IteratorTypes>
29using __are_iterators_of = std::conjunction<
30 std::is_base_of<_IteratorTag, typename std::iterator_traits<std::decay_t<_IteratorTypes>>::iterator_category>...>;
31
32template <typename... _IteratorTypes>
33using __are_random_access_iterators = __are_iterators_of<std::random_access_iterator_tag, _IteratorTypes...>;
34
35struct __serial_backend_tag {};
36struct __tbb_backend_tag {};
37struct __openmp_backend_tag {};
38
39# if defined(_PSTL_PAR_BACKEND_TBB)
40using __par_backend_tag = __tbb_backend_tag;
41# elif defined(_PSTL_PAR_BACKEND_OPENMP)
42using __par_backend_tag = __openmp_backend_tag;
43# elif defined(_PSTL_PAR_BACKEND_SERIAL)
44using __par_backend_tag = __serial_backend_tag;
45# else
46# error "A parallel backend must be specified";
47# endif
48
49template <class _IsVector>
50struct __serial_tag {
51 using __is_vector = _IsVector;
52};
53
54template <class _IsVector>
55struct __parallel_tag {
56 using __is_vector = _IsVector;
57 // backend tag can be change depending on
58 // TBB availability in the environment
59 using __backend_tag = __par_backend_tag;
60};
61
62template <class _IsVector, class... _IteratorTypes>
63using __tag_type =
64 typename std::conditional<__internal::__are_random_access_iterators<_IteratorTypes...>::value,
65 __parallel_tag<_IsVector>,
66 __serial_tag<_IsVector>>::type;
67
68template <class... _IteratorTypes>
69_LIBCPP_HIDE_FROM_ABI __serial_tag</*_IsVector = */ std::false_type>
70__select_backend(__pstl::execution::sequenced_policy, _IteratorTypes&&...) {
71 return {};
72}
73
74template <class... _IteratorTypes>
75_LIBCPP_HIDE_FROM_ABI __serial_tag<__internal::__are_random_access_iterators<_IteratorTypes...>>
76__select_backend(__pstl::execution::unsequenced_policy, _IteratorTypes&&...) {
77 return {};
78}
79
80template <class... _IteratorTypes>
81_LIBCPP_HIDE_FROM_ABI __tag_type</*_IsVector = */ std::false_type, _IteratorTypes...>
82__select_backend(__pstl::execution::parallel_policy, _IteratorTypes&&...) {
83 return {};
84}
85
86template <class... _IteratorTypes>
87_LIBCPP_HIDE_FROM_ABI __tag_type<__internal::__are_random_access_iterators<_IteratorTypes...>, _IteratorTypes...>
88__select_backend(__pstl::execution::parallel_unsequenced_policy, _IteratorTypes&&...) {
89 return {};
90}
91
92} // namespace __internal
93} // namespace __pstl
94
95#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
96
97#endif /* _PSTL_EXECUTION_IMPL_H */
lib/libcxx/include/__pstl/internal/glue_algorithm_defs.h created+655
......@@ -0,0 +1,655 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_GLUE_ALGORITHM_DEFS_H
11#define _PSTL_GLUE_ALGORITHM_DEFS_H
12
13#include <__config>
14#include <functional>
15#include <iterator>
16
17#include "execution_defs.h"
18
19namespace std {
20
21// [alg.find.end]
22
23template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
24__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
25find_end(_ExecutionPolicy&& __exec,
26 _ForwardIterator1 __first,
27 _ForwardIterator1 __last,
28 _ForwardIterator2 __s_first,
29 _ForwardIterator2 __s_last,
30 _BinaryPredicate __pred);
31
32template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
33__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
34find_end(_ExecutionPolicy&& __exec,
35 _ForwardIterator1 __first,
36 _ForwardIterator1 __last,
37 _ForwardIterator2 __s_first,
38 _ForwardIterator2 __s_last);
39
40// [alg.find_first_of]
41
42template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
43__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> find_first_of(
44 _ExecutionPolicy&& __exec,
45 _ForwardIterator1 __first,
46 _ForwardIterator1 __last,
47 _ForwardIterator2 __s_first,
48 _ForwardIterator2 __s_last,
49 _BinaryPredicate __pred);
50
51template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
52__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
53find_first_of(_ExecutionPolicy&& __exec,
54 _ForwardIterator1 __first,
55 _ForwardIterator1 __last,
56 _ForwardIterator2 __s_first,
57 _ForwardIterator2 __s_last);
58
59// [alg.adjacent_find]
60
61template <class _ExecutionPolicy, class _ForwardIterator>
62__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
63adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
64
65template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
66__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
67adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred);
68
69// [alg.count]
70
71template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
72__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
73 typename iterator_traits<_ForwardIterator>::difference_type>
74count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value);
75
76template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
77__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
78 typename iterator_traits<_ForwardIterator>::difference_type>
79count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred);
80
81// [alg.search]
82
83template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
84__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
85search(_ExecutionPolicy&& __exec,
86 _ForwardIterator1 __first,
87 _ForwardIterator1 __last,
88 _ForwardIterator2 __s_first,
89 _ForwardIterator2 __s_last,
90 _BinaryPredicate __pred);
91
92template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
93__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
94search(_ExecutionPolicy&& __exec,
95 _ForwardIterator1 __first,
96 _ForwardIterator1 __last,
97 _ForwardIterator2 __s_first,
98 _ForwardIterator2 __s_last);
99
100template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
101__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
102search_n(_ExecutionPolicy&& __exec,
103 _ForwardIterator __first,
104 _ForwardIterator __last,
105 _Size __count,
106 const _Tp& __value,
107 _BinaryPredicate __pred);
108
109template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
110__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> search_n(
111 _ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value);
112
113// [alg.copy]
114
115template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
116__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
117copy_if(_ExecutionPolicy&& __exec,
118 _ForwardIterator1 __first,
119 _ForwardIterator1 __last,
120 _ForwardIterator2 result,
121 _Predicate __pred);
122
123// [alg.swap]
124
125template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
126__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> swap_ranges(
127 _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2);
128
129// [alg.replace]
130
131template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _Tp>
132__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
133replace_if(_ExecutionPolicy&& __exec,
134 _ForwardIterator __first,
135 _ForwardIterator __last,
136 _UnaryPredicate __pred,
137 const _Tp& __new_value);
138
139template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
140__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
141replace(_ExecutionPolicy&& __exec,
142 _ForwardIterator __first,
143 _ForwardIterator __last,
144 const _Tp& __old_value,
145 const _Tp& __new_value);
146
147template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryPredicate, class _Tp>
148__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> replace_copy_if(
149 _ExecutionPolicy&& __exec,
150 _ForwardIterator1 __first,
151 _ForwardIterator1 __last,
152 _ForwardIterator2 __result,
153 _UnaryPredicate __pred,
154 const _Tp& __new_value);
155
156template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
157__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> replace_copy(
158 _ExecutionPolicy&& __exec,
159 _ForwardIterator1 __first,
160 _ForwardIterator1 __last,
161 _ForwardIterator2 __result,
162 const _Tp& __old_value,
163 const _Tp& __new_value);
164
165// [alg.generate]
166template <class _ExecutionPolicy, class _ForwardIterator, class _Generator>
167__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
168generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g);
169
170template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Generator>
171__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
172generate_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size count, _Generator __g);
173
174// [alg.remove]
175
176template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
177__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> remove_copy_if(
178 _ExecutionPolicy&& __exec,
179 _ForwardIterator1 __first,
180 _ForwardIterator1 __last,
181 _ForwardIterator2 __result,
182 _Predicate __pred);
183
184template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
185__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
186remove_copy(_ExecutionPolicy&& __exec,
187 _ForwardIterator1 __first,
188 _ForwardIterator1 __last,
189 _ForwardIterator2 __result,
190 const _Tp& __value);
191
192template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
193__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
194remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred);
195
196template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
197__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
198remove(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value);
199
200// [alg.unique]
201
202template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
203__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
204unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred);
205
206template <class _ExecutionPolicy, class _ForwardIterator>
207__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
208unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
209
210template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
211__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
212unique_copy(_ExecutionPolicy&& __exec,
213 _ForwardIterator1 __first,
214 _ForwardIterator1 __last,
215 _ForwardIterator2 __result,
216 _BinaryPredicate __pred);
217
218template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
219__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
220unique_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result);
221
222// [alg.reverse]
223
224template <class _ExecutionPolicy, class _BidirectionalIterator>
225__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
226reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last);
227
228template <class _ExecutionPolicy, class _BidirectionalIterator, class _ForwardIterator>
229__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
230reverse_copy(_ExecutionPolicy&& __exec,
231 _BidirectionalIterator __first,
232 _BidirectionalIterator __last,
233 _ForwardIterator __d_first);
234
235// [alg.rotate]
236
237template <class _ExecutionPolicy, class _ForwardIterator>
238__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
239rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last);
240
241template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
242__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
243rotate_copy(_ExecutionPolicy&& __exec,
244 _ForwardIterator1 __first,
245 _ForwardIterator1 __middle,
246 _ForwardIterator1 __last,
247 _ForwardIterator2 __result);
248
249// [alg.partitions]
250
251template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
252__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
253is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred);
254
255template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
256__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
257partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred);
258
259template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate>
260__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _BidirectionalIterator> stable_partition(
261 _ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, _UnaryPredicate __pred);
262
263template <class _ExecutionPolicy,
264 class _ForwardIterator,
265 class _ForwardIterator1,
266 class _ForwardIterator2,
267 class _UnaryPredicate>
268__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
269partition_copy(_ExecutionPolicy&& __exec,
270 _ForwardIterator __first,
271 _ForwardIterator __last,
272 _ForwardIterator1 __out_true,
273 _ForwardIterator2 __out_false,
274 _UnaryPredicate __pred);
275
276// [alg.sort]
277
278template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
279__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
280sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp);
281
282template <class _ExecutionPolicy, class _RandomAccessIterator>
283__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
284sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last);
285
286// [stable.sort]
287
288template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
289__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
290stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp);
291
292template <class _ExecutionPolicy, class _RandomAccessIterator>
293__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
294stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last);
295
296// [mismatch]
297
298template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
299__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
300mismatch(_ExecutionPolicy&& __exec,
301 _ForwardIterator1 __first1,
302 _ForwardIterator1 __last1,
303 _ForwardIterator2 __first2,
304 _ForwardIterator2 __last2,
305 _BinaryPredicate __pred);
306
307template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
308__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
309mismatch(_ExecutionPolicy&& __exec,
310 _ForwardIterator1 __first1,
311 _ForwardIterator1 __last1,
312 _ForwardIterator2 __first2,
313 _BinaryPredicate __pred);
314
315template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
316__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
317mismatch(_ExecutionPolicy&& __exec,
318 _ForwardIterator1 __first1,
319 _ForwardIterator1 __last1,
320 _ForwardIterator2 __first2,
321 _ForwardIterator2 __last2);
322
323template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
324__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
325mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2);
326
327// [alg.equal]
328
329template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
330__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
331equal(_ExecutionPolicy&& __exec,
332 _ForwardIterator1 __first1,
333 _ForwardIterator1 __last1,
334 _ForwardIterator2 __first2,
335 _BinaryPredicate __p);
336
337template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
338__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
339equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2);
340
341template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
342__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
343equal(_ExecutionPolicy&& __exec,
344 _ForwardIterator1 __first1,
345 _ForwardIterator1 __last1,
346 _ForwardIterator2 __first2,
347 _ForwardIterator2 __last2,
348 _BinaryPredicate __p);
349
350template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
351__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
352equal(_ExecutionPolicy&& __exec,
353 _ForwardIterator1 __first1,
354 _ForwardIterator1 __last1,
355 _ForwardIterator2 __first2,
356 _ForwardIterator2 __last2);
357
358// [alg.move]
359template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
360__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
361move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first);
362
363// [partial.sort]
364
365template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
366__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
367partial_sort(_ExecutionPolicy&& __exec,
368 _RandomAccessIterator __first,
369 _RandomAccessIterator __middle,
370 _RandomAccessIterator __last,
371 _Compare __comp);
372
373template <class _ExecutionPolicy, class _RandomAccessIterator>
374__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
375partial_sort(_ExecutionPolicy&& __exec,
376 _RandomAccessIterator __first,
377 _RandomAccessIterator __middle,
378 _RandomAccessIterator __last);
379
380// [partial.sort.copy]
381
382template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare>
383__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy(
384 _ExecutionPolicy&& __exec,
385 _ForwardIterator __first,
386 _ForwardIterator __last,
387 _RandomAccessIterator __d_first,
388 _RandomAccessIterator __d_last,
389 _Compare __comp);
390
391template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator>
392__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy(
393 _ExecutionPolicy&& __exec,
394 _ForwardIterator __first,
395 _ForwardIterator __last,
396 _RandomAccessIterator __d_first,
397 _RandomAccessIterator __d_last);
398
399// [is.sorted]
400template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
401__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
402is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp);
403
404template <class _ExecutionPolicy, class _ForwardIterator>
405__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
406is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
407
408template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
409__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
410is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp);
411
412template <class _ExecutionPolicy, class _ForwardIterator>
413__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
414is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
415
416// [alg.nth.element]
417
418template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
419__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
420nth_element(_ExecutionPolicy&& __exec,
421 _RandomAccessIterator __first,
422 _RandomAccessIterator __nth,
423 _RandomAccessIterator __last,
424 _Compare __comp);
425
426template <class _ExecutionPolicy, class _RandomAccessIterator>
427__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
428nth_element(_ExecutionPolicy&& __exec,
429 _RandomAccessIterator __first,
430 _RandomAccessIterator __nth,
431 _RandomAccessIterator __last);
432
433// [alg.merge]
434template <class _ExecutionPolicy,
435 class _ForwardIterator1,
436 class _ForwardIterator2,
437 class _ForwardIterator,
438 class _Compare>
439__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
440merge(_ExecutionPolicy&& __exec,
441 _ForwardIterator1 __first1,
442 _ForwardIterator1 __last1,
443 _ForwardIterator2 __first2,
444 _ForwardIterator2 __last2,
445 _ForwardIterator __d_first,
446 _Compare __comp);
447
448template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
449__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
450merge(_ExecutionPolicy&& __exec,
451 _ForwardIterator1 __first1,
452 _ForwardIterator1 __last1,
453 _ForwardIterator2 __first2,
454 _ForwardIterator2 __last2,
455 _ForwardIterator __d_first);
456
457template <class _ExecutionPolicy, class _BidirectionalIterator, class _Compare>
458__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
459inplace_merge(_ExecutionPolicy&& __exec,
460 _BidirectionalIterator __first,
461 _BidirectionalIterator __middle,
462 _BidirectionalIterator __last,
463 _Compare __comp);
464
465template <class _ExecutionPolicy, class _BidirectionalIterator>
466__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
467inplace_merge(_ExecutionPolicy&& __exec,
468 _BidirectionalIterator __first,
469 _BidirectionalIterator __middle,
470 _BidirectionalIterator __last);
471
472// [includes]
473
474template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
475__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
476includes(_ExecutionPolicy&& __exec,
477 _ForwardIterator1 __first1,
478 _ForwardIterator1 __last1,
479 _ForwardIterator2 __first2,
480 _ForwardIterator2 __last2,
481 _Compare __comp);
482
483template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
484__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
485includes(_ExecutionPolicy&& __exec,
486 _ForwardIterator1 __first1,
487 _ForwardIterator1 __last1,
488 _ForwardIterator2 __first2,
489 _ForwardIterator2 __last2);
490
491// [set.union]
492
493template <class _ExecutionPolicy,
494 class _ForwardIterator1,
495 class _ForwardIterator2,
496 class _ForwardIterator,
497 class _Compare>
498__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
499set_union(_ExecutionPolicy&& __exec,
500 _ForwardIterator1 __first1,
501 _ForwardIterator1 __last1,
502 _ForwardIterator2 __first2,
503 _ForwardIterator2 __last2,
504 _ForwardIterator __result,
505 _Compare __comp);
506
507template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
508__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
509set_union(_ExecutionPolicy&& __exec,
510 _ForwardIterator1 __first1,
511 _ForwardIterator1 __last1,
512 _ForwardIterator2 __first2,
513 _ForwardIterator2 __last2,
514 _ForwardIterator __result);
515
516// [set.intersection]
517
518template <class _ExecutionPolicy,
519 class _ForwardIterator1,
520 class _ForwardIterator2,
521 class _ForwardIterator,
522 class _Compare>
523__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection(
524 _ExecutionPolicy&& __exec,
525 _ForwardIterator1 __first1,
526 _ForwardIterator1 __last1,
527 _ForwardIterator2 __first2,
528 _ForwardIterator2 __last2,
529 _ForwardIterator __result,
530 _Compare __comp);
531
532template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
533__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection(
534 _ExecutionPolicy&& __exec,
535 _ForwardIterator1 __first1,
536 _ForwardIterator1 __last1,
537 _ForwardIterator2 __first2,
538 _ForwardIterator2 __last2,
539 _ForwardIterator __result);
540
541// [set.difference]
542
543template <class _ExecutionPolicy,
544 class _ForwardIterator1,
545 class _ForwardIterator2,
546 class _ForwardIterator,
547 class _Compare>
548__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference(
549 _ExecutionPolicy&& __exec,
550 _ForwardIterator1 __first1,
551 _ForwardIterator1 __last1,
552 _ForwardIterator2 __first2,
553 _ForwardIterator2 __last2,
554 _ForwardIterator __result,
555 _Compare __comp);
556
557template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
558__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference(
559 _ExecutionPolicy&& __exec,
560 _ForwardIterator1 __first1,
561 _ForwardIterator1 __last1,
562 _ForwardIterator2 __first2,
563 _ForwardIterator2 __last2,
564 _ForwardIterator __result);
565
566// [set.symmetric.difference]
567
568template <class _ExecutionPolicy,
569 class _ForwardIterator1,
570 class _ForwardIterator2,
571 class _ForwardIterator,
572 class _Compare>
573__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference(
574 _ExecutionPolicy&& __exec,
575 _ForwardIterator1 __first1,
576 _ForwardIterator1 __last1,
577 _ForwardIterator2 __first2,
578 _ForwardIterator2 __last2,
579 _ForwardIterator result,
580 _Compare __comp);
581
582template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
583__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference(
584 _ExecutionPolicy&& __exec,
585 _ForwardIterator1 __first1,
586 _ForwardIterator1 __last1,
587 _ForwardIterator2 __first2,
588 _ForwardIterator2 __last2,
589 _ForwardIterator __result);
590
591// [is.heap]
592template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
593__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
594is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp);
595
596template <class _ExecutionPolicy, class _RandomAccessIterator>
597__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
598is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last);
599
600template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
601__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
602is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp);
603
604template <class _ExecutionPolicy, class _RandomAccessIterator>
605__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
606is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last);
607
608// [alg.min.max]
609
610template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
611__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
612min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp);
613
614template <class _ExecutionPolicy, class _ForwardIterator>
615__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
616min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
617
618template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
619__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
620max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp);
621
622template <class _ExecutionPolicy, class _ForwardIterator>
623__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
624max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
625
626template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
627__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>>
628minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp);
629
630template <class _ExecutionPolicy, class _ForwardIterator>
631__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>>
632minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
633
634// [alg.lex.comparison]
635
636template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
637__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare(
638 _ExecutionPolicy&& __exec,
639 _ForwardIterator1 __first1,
640 _ForwardIterator1 __last1,
641 _ForwardIterator2 __first2,
642 _ForwardIterator2 __last2,
643 _Compare __comp);
644
645template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
646__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare(
647 _ExecutionPolicy&& __exec,
648 _ForwardIterator1 __first1,
649 _ForwardIterator1 __last1,
650 _ForwardIterator2 __first2,
651 _ForwardIterator2 __last2);
652
653} // namespace std
654
655#endif /* _PSTL_GLUE_ALGORITHM_DEFS_H */
lib/libcxx/include/__pstl/internal/glue_algorithm_impl.h created+972
......@@ -0,0 +1,972 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_GLUE_ALGORITHM_IMPL_H
11#define _PSTL_GLUE_ALGORITHM_IMPL_H
12
13#include <__config>
14#include <functional>
15
16#include "algorithm_fwd.h"
17#include "execution_defs.h"
18#include "numeric_fwd.h" /* count and count_if use __pattern_transform_reduce */
19#include "utils.h"
20
21#include "execution_impl.h"
22
23namespace std {
24
25// [alg.find.end]
26template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
27__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
28find_end(_ExecutionPolicy&& __exec,
29 _ForwardIterator1 __first,
30 _ForwardIterator1 __last,
31 _ForwardIterator2 __s_first,
32 _ForwardIterator2 __s_last,
33 _BinaryPredicate __pred) {
34 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first);
35
36 return __pstl::__internal::__pattern_find_end(
37 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred);
38}
39
40template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
41__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
42find_end(_ExecutionPolicy&& __exec,
43 _ForwardIterator1 __first,
44 _ForwardIterator1 __last,
45 _ForwardIterator2 __s_first,
46 _ForwardIterator2 __s_last) {
47 return std::find_end(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>());
48}
49
50// [alg.find_first_of]
51template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
52__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> find_first_of(
53 _ExecutionPolicy&& __exec,
54 _ForwardIterator1 __first,
55 _ForwardIterator1 __last,
56 _ForwardIterator2 __s_first,
57 _ForwardIterator2 __s_last,
58 _BinaryPredicate __pred) {
59 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first);
60
61 return __pstl::__internal::__pattern_find_first_of(
62 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred);
63}
64
65template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
66__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
67find_first_of(_ExecutionPolicy&& __exec,
68 _ForwardIterator1 __first,
69 _ForwardIterator1 __last,
70 _ForwardIterator2 __s_first,
71 _ForwardIterator2 __s_last) {
72 return std::find_first_of(
73 std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>());
74}
75
76// [alg.adjacent_find]
77template <class _ExecutionPolicy, class _ForwardIterator>
78__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
79adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
80 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
81
82 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
83 return __pstl::__internal::__pattern_adjacent_find(
84 __dispatch_tag,
85 std::forward<_ExecutionPolicy>(__exec),
86 __first,
87 __last,
88 std::equal_to<_ValueType>(),
89 /*first_semantic*/ false);
90}
91
92template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
93__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
94adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) {
95 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
96 return __pstl::__internal::__pattern_adjacent_find(
97 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, /*first_semantic*/ false);
98}
99
100// [alg.count]
101
102// Implementation note: count and count_if call the pattern directly instead of calling std::transform_reduce
103// so that we do not have to include <numeric>.
104
105template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
106__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
107 typename iterator_traits<_ForwardIterator>::difference_type>
108count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
109 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
110
111 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
112 return __pstl::__internal::__pattern_count(
113 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [&__value](const _ValueType& __x) {
114 return __value == __x;
115 });
116}
117
118template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
119__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
120 typename iterator_traits<_ForwardIterator>::difference_type>
121count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
122 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
123 return __pstl::__internal::__pattern_count(
124 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
125}
126
127// [alg.search]
128
129template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
130__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
131search(_ExecutionPolicy&& __exec,
132 _ForwardIterator1 __first,
133 _ForwardIterator1 __last,
134 _ForwardIterator2 __s_first,
135 _ForwardIterator2 __s_last,
136 _BinaryPredicate __pred) {
137 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first);
138
139 return __pstl::__internal::__pattern_search(
140 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred);
141}
142
143template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
144__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
145search(_ExecutionPolicy&& __exec,
146 _ForwardIterator1 __first,
147 _ForwardIterator1 __last,
148 _ForwardIterator2 __s_first,
149 _ForwardIterator2 __s_last) {
150 return std::search(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>());
151}
152
153template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
154__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
155search_n(_ExecutionPolicy&& __exec,
156 _ForwardIterator __first,
157 _ForwardIterator __last,
158 _Size __count,
159 const _Tp& __value,
160 _BinaryPredicate __pred) {
161 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
162
163 return __pstl::__internal::__pattern_search_n(
164 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __count, __value, __pred);
165}
166
167template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
168__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> search_n(
169 _ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) {
170 return std::search_n(
171 std::forward<_ExecutionPolicy>(__exec),
172 __first,
173 __last,
174 __count,
175 __value,
176 std::equal_to<typename iterator_traits<_ForwardIterator>::value_type>());
177}
178
179// [alg.copy]
180
181template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
182__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
183copy_if(_ExecutionPolicy&& __exec,
184 _ForwardIterator1 __first,
185 _ForwardIterator1 __last,
186 _ForwardIterator2 __result,
187 _Predicate __pred) {
188 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
189
190 return __pstl::__internal::__pattern_copy_if(
191 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred);
192}
193
194// [alg.swap]
195
196template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
197__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> swap_ranges(
198 _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
199 typedef typename iterator_traits<_ForwardIterator1>::reference _ReferenceType1;
200 typedef typename iterator_traits<_ForwardIterator2>::reference _ReferenceType2;
201
202 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
203
204 return __pstl::__internal::__pattern_walk2(
205 __dispatch_tag,
206 std::forward<_ExecutionPolicy>(__exec),
207 __first1,
208 __last1,
209 __first2,
210 [](_ReferenceType1 __x, _ReferenceType2 __y) {
211 using std::swap;
212 swap(__x, __y);
213 });
214}
215
216// [alg.generate]
217template <class _ExecutionPolicy, class _ForwardIterator, class _Generator>
218__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
219generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) {
220 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
221
222 __pstl::__internal::__pattern_generate(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __g);
223}
224
225template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Generator>
226__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
227generate_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, _Generator __g) {
228 if (__count <= 0)
229 return __first;
230
231 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
232
233 return __pstl::__internal::__pattern_generate_n(
234 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __count, __g);
235}
236
237// [alg.remove]
238
239template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
240__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> remove_copy_if(
241 _ExecutionPolicy&& __exec,
242 _ForwardIterator1 __first,
243 _ForwardIterator1 __last,
244 _ForwardIterator2 __result,
245 _Predicate __pred) {
246 return std::copy_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, std::not_fn(__pred));
247}
248
249template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
250__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
251remove_copy(_ExecutionPolicy&& __exec,
252 _ForwardIterator1 __first,
253 _ForwardIterator1 __last,
254 _ForwardIterator2 __result,
255 const _Tp& __value) {
256 return std::copy_if(
257 std::forward<_ExecutionPolicy>(__exec),
258 __first,
259 __last,
260 __result,
261 __pstl::__internal::__not_equal_value<_Tp>(__value));
262}
263
264template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
265__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
266remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) {
267 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
268
269 return __pstl::__internal::__pattern_remove_if(
270 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
271}
272
273template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
274__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
275remove(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
276 return std::remove_if(
277 std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__equal_value<_Tp>(__value));
278}
279
280// [alg.unique]
281
282template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
283__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
284unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) {
285 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
286
287 return __pstl::__internal::__pattern_unique(
288 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
289}
290
291template <class _ExecutionPolicy, class _ForwardIterator>
292__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
293unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
294 return std::unique(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::equal_to<>());
295}
296
297template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
298__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
299unique_copy(_ExecutionPolicy&& __exec,
300 _ForwardIterator1 __first,
301 _ForwardIterator1 __last,
302 _ForwardIterator2 __result,
303 _BinaryPredicate __pred) {
304 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
305
306 return __pstl::__internal::__pattern_unique_copy(
307 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred);
308}
309
310template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
311__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> unique_copy(
312 _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) {
313 return std::unique_copy(__exec, __first, __last, __result, std::equal_to<>());
314}
315
316// [alg.reverse]
317
318template <class _ExecutionPolicy, class _BidirectionalIterator>
319__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
320reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last) {
321 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
322
323 __pstl::__internal::__pattern_reverse(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last);
324}
325
326template <class _ExecutionPolicy, class _BidirectionalIterator, class _ForwardIterator>
327__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
328reverse_copy(_ExecutionPolicy&& __exec,
329 _BidirectionalIterator __first,
330 _BidirectionalIterator __last,
331 _ForwardIterator __d_first) {
332 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
333
334 return __pstl::__internal::__pattern_reverse_copy(
335 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first);
336}
337
338// [alg.rotate]
339
340template <class _ExecutionPolicy, class _ForwardIterator>
341__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
342rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) {
343 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
344
345 return __pstl::__internal::__pattern_rotate(
346 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last);
347}
348
349template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
350__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
351rotate_copy(_ExecutionPolicy&& __exec,
352 _ForwardIterator1 __first,
353 _ForwardIterator1 __middle,
354 _ForwardIterator1 __last,
355 _ForwardIterator2 __result) {
356 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
357
358 return __pstl::__internal::__pattern_rotate_copy(
359 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __result);
360}
361
362// [alg.partitions]
363
364template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
365__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
366is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) {
367 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
368 return __pstl::__internal::__pattern_is_partitioned(
369 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
370}
371
372template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
373__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
374partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) {
375 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
376
377 return __pstl::__internal::__pattern_partition(
378 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
379}
380
381template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate>
382__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _BidirectionalIterator> stable_partition(
383 _ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, _UnaryPredicate __pred) {
384 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
385 return __pstl::__internal::__pattern_stable_partition(
386 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
387}
388
389template <class _ExecutionPolicy,
390 class _ForwardIterator,
391 class _ForwardIterator1,
392 class _ForwardIterator2,
393 class _UnaryPredicate>
394__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
395partition_copy(_ExecutionPolicy&& __exec,
396 _ForwardIterator __first,
397 _ForwardIterator __last,
398 _ForwardIterator1 __out_true,
399 _ForwardIterator2 __out_false,
400 _UnaryPredicate __pred) {
401 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __out_true, __out_false);
402
403 return __pstl::__internal::__pattern_partition_copy(
404 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __out_true, __out_false, __pred);
405}
406
407// [alg.sort]
408
409template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
410__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
411sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
412 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
413
414 typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType;
415 return __pstl::__internal::__pattern_sort(
416 __dispatch_tag,
417 std::forward<_ExecutionPolicy>(__exec),
418 __first,
419 __last,
420 __comp,
421 typename std::is_move_constructible<_InputType>::type());
422}
423
424template <class _ExecutionPolicy, class _RandomAccessIterator>
425__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
426sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) {
427 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType;
428 std::sort(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
429}
430
431// [stable.sort]
432
433template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
434__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
435stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
436 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
437
438 return __pstl::__internal::__pattern_stable_sort(
439 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp);
440}
441
442template <class _ExecutionPolicy, class _RandomAccessIterator>
443__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
444stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) {
445 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType;
446 std::stable_sort(__exec, __first, __last, std::less<_InputType>());
447}
448
449// [mismatch]
450
451template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
452__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
453mismatch(_ExecutionPolicy&& __exec,
454 _ForwardIterator1 __first1,
455 _ForwardIterator1 __last1,
456 _ForwardIterator2 __first2,
457 _ForwardIterator2 __last2,
458 _BinaryPredicate __pred) {
459 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
460
461 return __pstl::__internal::__pattern_mismatch(
462 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __pred);
463}
464
465template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
466__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
467mismatch(_ExecutionPolicy&& __exec,
468 _ForwardIterator1 __first1,
469 _ForwardIterator1 __last1,
470 _ForwardIterator2 __first2,
471 _BinaryPredicate __pred) {
472 return std::mismatch(
473 __exec, __first1, __last1, __first2, std::next(__first2, std::distance(__first1, __last1)), __pred);
474}
475
476template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
477__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
478mismatch(_ExecutionPolicy&& __exec,
479 _ForwardIterator1 __first1,
480 _ForwardIterator1 __last1,
481 _ForwardIterator2 __first2,
482 _ForwardIterator2 __last2) {
483 return std::mismatch(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::equal_to<>());
484}
485
486template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
487__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
488mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
489 // TODO: to get rid of "distance"
490 return std::mismatch(
491 std::forward<_ExecutionPolicy>(__exec),
492 __first1,
493 __last1,
494 __first2,
495 std::next(__first2, std::distance(__first1, __last1)));
496}
497
498// [alg.equal]
499
500template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
501__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
502equal(_ExecutionPolicy&& __exec,
503 _ForwardIterator1 __first1,
504 _ForwardIterator1 __last1,
505 _ForwardIterator2 __first2,
506 _BinaryPredicate __p) {
507 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
508
509 return __pstl::__internal::__pattern_equal(
510 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __p);
511}
512
513template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
514__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
515equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
516 return std::equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, std::equal_to<>());
517}
518
519template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
520__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
521equal(_ExecutionPolicy&& __exec,
522 _ForwardIterator1 __first1,
523 _ForwardIterator1 __last1,
524 _ForwardIterator2 __first2,
525 _ForwardIterator2 __last2,
526 _BinaryPredicate __p) {
527 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
528
529 return __pstl::__internal::__pattern_equal(
530 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __p);
531}
532
533template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
534__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
535equal(_ExecutionPolicy&& __exec,
536 _ForwardIterator1 __first1,
537 _ForwardIterator1 __last1,
538 _ForwardIterator2 __first2,
539 _ForwardIterator2 __last2) {
540 return equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::equal_to<>());
541}
542
543// [alg.move]
544template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
545__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
546move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first) {
547 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
548
549 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
550
551 return __pstl::__internal::__pattern_walk2_brick(
552 __dispatch_tag,
553 std::forward<_ExecutionPolicy>(__exec),
554 __first,
555 __last,
556 __d_first,
557 [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) {
558 return __pstl::__internal::__brick_move(__begin, __end, __res, __is_vector{});
559 });
560}
561
562// [partial.sort]
563
564template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
565__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
566partial_sort(_ExecutionPolicy&& __exec,
567 _RandomAccessIterator __first,
568 _RandomAccessIterator __middle,
569 _RandomAccessIterator __last,
570 _Compare __comp) {
571 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
572
573 __pstl::__internal::__pattern_partial_sort(
574 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp);
575}
576
577template <class _ExecutionPolicy, class _RandomAccessIterator>
578__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
579partial_sort(_ExecutionPolicy&& __exec,
580 _RandomAccessIterator __first,
581 _RandomAccessIterator __middle,
582 _RandomAccessIterator __last) {
583 typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType;
584 std::partial_sort(__exec, __first, __middle, __last, std::less<_InputType>());
585}
586
587// [partial.sort.copy]
588
589template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare>
590__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy(
591 _ExecutionPolicy&& __exec,
592 _ForwardIterator __first,
593 _ForwardIterator __last,
594 _RandomAccessIterator __d_first,
595 _RandomAccessIterator __d_last,
596 _Compare __comp) {
597 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
598
599 return __pstl::__internal::__pattern_partial_sort_copy(
600 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, __comp);
601}
602
603template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator>
604__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy(
605 _ExecutionPolicy&& __exec,
606 _ForwardIterator __first,
607 _ForwardIterator __last,
608 _RandomAccessIterator __d_first,
609 _RandomAccessIterator __d_last) {
610 return std::partial_sort_copy(
611 std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, std::less<>());
612}
613
614// [is.sorted]
615template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
616__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
617is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
618 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
619 const _ForwardIterator __res = __pstl::__internal::__pattern_adjacent_find(
620 __dispatch_tag,
621 std::forward<_ExecutionPolicy>(__exec),
622 __first,
623 __last,
624 __pstl::__internal::__reorder_pred<_Compare>(__comp),
625 /*first_semantic*/ false);
626 return __res == __last ? __last : std::next(__res);
627}
628
629template <class _ExecutionPolicy, class _ForwardIterator>
630__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
631is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
632 typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType;
633 return is_sorted_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
634}
635
636template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
637__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
638is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
639 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
640 return __pstl::__internal::__pattern_adjacent_find(
641 __dispatch_tag,
642 std::forward<_ExecutionPolicy>(__exec),
643 __first,
644 __last,
645 __pstl::__internal::__reorder_pred<_Compare>(__comp),
646 /*or_semantic*/ true) == __last;
647}
648
649template <class _ExecutionPolicy, class _ForwardIterator>
650__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
651is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
652 typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType;
653 return std::is_sorted(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
654}
655
656// [alg.merge]
657template <class _ExecutionPolicy, class _BidirectionalIterator, class _Compare>
658__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
659inplace_merge(_ExecutionPolicy&& __exec,
660 _BidirectionalIterator __first,
661 _BidirectionalIterator __middle,
662 _BidirectionalIterator __last,
663 _Compare __comp) {
664 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
665
666 __pstl::__internal::__pattern_inplace_merge(
667 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp);
668}
669
670template <class _ExecutionPolicy, class _BidirectionalIterator>
671__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
672inplace_merge(_ExecutionPolicy&& __exec,
673 _BidirectionalIterator __first,
674 _BidirectionalIterator __middle,
675 _BidirectionalIterator __last) {
676 typedef typename std::iterator_traits<_BidirectionalIterator>::value_type _InputType;
677 std::inplace_merge(__exec, __first, __middle, __last, std::less<_InputType>());
678}
679
680// [includes]
681
682template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
683__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
684includes(_ExecutionPolicy&& __exec,
685 _ForwardIterator1 __first1,
686 _ForwardIterator1 __last1,
687 _ForwardIterator2 __first2,
688 _ForwardIterator2 __last2,
689 _Compare __comp) {
690 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
691
692 return __pstl::__internal::__pattern_includes(
693 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp);
694}
695
696template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
697__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
698includes(_ExecutionPolicy&& __exec,
699 _ForwardIterator1 __first1,
700 _ForwardIterator1 __last1,
701 _ForwardIterator2 __first2,
702 _ForwardIterator2 __last2) {
703 return std::includes(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::less<>());
704}
705
706// [set.union]
707
708template <class _ExecutionPolicy,
709 class _ForwardIterator1,
710 class _ForwardIterator2,
711 class _ForwardIterator,
712 class _Compare>
713__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
714set_union(_ExecutionPolicy&& __exec,
715 _ForwardIterator1 __first1,
716 _ForwardIterator1 __last1,
717 _ForwardIterator2 __first2,
718 _ForwardIterator2 __last2,
719 _ForwardIterator __result,
720 _Compare __comp) {
721 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
722
723 return __pstl::__internal::__pattern_set_union(
724 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp);
725}
726
727template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
728__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
729set_union(_ExecutionPolicy&& __exec,
730 _ForwardIterator1 __first1,
731 _ForwardIterator1 __last1,
732 _ForwardIterator2 __first2,
733 _ForwardIterator2 __last2,
734 _ForwardIterator __result) {
735 return std::set_union(
736 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>());
737}
738
739// [set.intersection]
740
741template <class _ExecutionPolicy,
742 class _ForwardIterator1,
743 class _ForwardIterator2,
744 class _ForwardIterator,
745 class _Compare>
746__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection(
747 _ExecutionPolicy&& __exec,
748 _ForwardIterator1 __first1,
749 _ForwardIterator1 __last1,
750 _ForwardIterator2 __first2,
751 _ForwardIterator2 __last2,
752 _ForwardIterator __result,
753 _Compare __comp) {
754 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
755
756 return __pstl::__internal::__pattern_set_intersection(
757 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp);
758}
759
760template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
761__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection(
762 _ExecutionPolicy&& __exec,
763 _ForwardIterator1 __first1,
764 _ForwardIterator1 __last1,
765 _ForwardIterator2 __first2,
766 _ForwardIterator2 __last2,
767 _ForwardIterator __result) {
768 return std::set_intersection(
769 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>());
770}
771
772// [set.difference]
773
774template <class _ExecutionPolicy,
775 class _ForwardIterator1,
776 class _ForwardIterator2,
777 class _ForwardIterator,
778 class _Compare>
779__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference(
780 _ExecutionPolicy&& __exec,
781 _ForwardIterator1 __first1,
782 _ForwardIterator1 __last1,
783 _ForwardIterator2 __first2,
784 _ForwardIterator2 __last2,
785 _ForwardIterator __result,
786 _Compare __comp) {
787 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
788
789 return __pstl::__internal::__pattern_set_difference(
790 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp);
791}
792
793template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
794__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference(
795 _ExecutionPolicy&& __exec,
796 _ForwardIterator1 __first1,
797 _ForwardIterator1 __last1,
798 _ForwardIterator2 __first2,
799 _ForwardIterator2 __last2,
800 _ForwardIterator __result) {
801 return std::set_difference(
802 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>());
803}
804
805// [set.symmetric.difference]
806
807template <class _ExecutionPolicy,
808 class _ForwardIterator1,
809 class _ForwardIterator2,
810 class _ForwardIterator,
811 class _Compare>
812__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference(
813 _ExecutionPolicy&& __exec,
814 _ForwardIterator1 __first1,
815 _ForwardIterator1 __last1,
816 _ForwardIterator2 __first2,
817 _ForwardIterator2 __last2,
818 _ForwardIterator __result,
819 _Compare __comp) {
820 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
821
822 return __pstl::__internal::__pattern_set_symmetric_difference(
823 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp);
824}
825
826template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
827__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference(
828 _ExecutionPolicy&& __exec,
829 _ForwardIterator1 __first1,
830 _ForwardIterator1 __last1,
831 _ForwardIterator2 __first2,
832 _ForwardIterator2 __last2,
833 _ForwardIterator __result) {
834 return std::set_symmetric_difference(
835 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>());
836}
837
838// [is.heap]
839template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
840__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
841is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
842 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
843
844 return __pstl::__internal::__pattern_is_heap_until(
845 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp);
846}
847
848template <class _ExecutionPolicy, class _RandomAccessIterator>
849__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
850is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) {
851 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType;
852 return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
853}
854
855template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
856__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
857is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
858 return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp) == __last;
859}
860
861template <class _ExecutionPolicy, class _RandomAccessIterator>
862__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
863is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) {
864 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType;
865 return std::is_heap(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
866}
867
868// [alg.min.max]
869
870template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
871__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
872min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
873 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
874 return __pstl::__internal::__pattern_min_element(
875 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp);
876}
877
878template <class _ExecutionPolicy, class _ForwardIterator>
879__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
880min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
881 typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType;
882 return std::min_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
883}
884
885template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
886__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
887max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
888 return min_element(
889 std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__reorder_pred<_Compare>(__comp));
890}
891
892template <class _ExecutionPolicy, class _ForwardIterator>
893__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
894max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
895 typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType;
896 return std::min_element(
897 std::forward<_ExecutionPolicy>(__exec),
898 __first,
899 __last,
900 __pstl::__internal::__reorder_pred<std::less<_InputType>>(std::less<_InputType>()));
901}
902
903template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
904__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>>
905minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
906 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
907 return __pstl::__internal::__pattern_minmax_element(
908 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp);
909}
910
911template <class _ExecutionPolicy, class _ForwardIterator>
912__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>>
913minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
914 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
915 return std::minmax_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_ValueType>());
916}
917
918// [alg.nth.element]
919
920template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
921__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
922nth_element(_ExecutionPolicy&& __exec,
923 _RandomAccessIterator __first,
924 _RandomAccessIterator __nth,
925 _RandomAccessIterator __last,
926 _Compare __comp) {
927 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
928
929 __pstl::__internal::__pattern_nth_element(
930 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, __comp);
931}
932
933template <class _ExecutionPolicy, class _RandomAccessIterator>
934__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
935nth_element(_ExecutionPolicy&& __exec,
936 _RandomAccessIterator __first,
937 _RandomAccessIterator __nth,
938 _RandomAccessIterator __last) {
939 typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType;
940 std::nth_element(std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, std::less<_InputType>());
941}
942
943// [alg.lex.comparison]
944
945template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
946__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare(
947 _ExecutionPolicy&& __exec,
948 _ForwardIterator1 __first1,
949 _ForwardIterator1 __last1,
950 _ForwardIterator2 __first2,
951 _ForwardIterator2 __last2,
952 _Compare __comp) {
953 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
954
955 return __pstl::__internal::__pattern_lexicographical_compare(
956 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp);
957}
958
959template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
960__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare(
961 _ExecutionPolicy&& __exec,
962 _ForwardIterator1 __first1,
963 _ForwardIterator1 __last1,
964 _ForwardIterator2 __first2,
965 _ForwardIterator2 __last2) {
966 return std::lexicographical_compare(
967 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::less<>());
968}
969
970} // namespace std
971
972#endif /* _PSTL_GLUE_ALGORITHM_IMPL_H */
lib/libcxx/include/__pstl/internal/glue_memory_defs.h created+81
......@@ -0,0 +1,81 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_GLUE_MEMORY_DEFS_H
11#define _PSTL_GLUE_MEMORY_DEFS_H
12
13#include <__config>
14
15#include "execution_defs.h"
16
17namespace std {
18
19// [uninitialized.copy]
20
21template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
22__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
23uninitialized_copy(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result);
24
25template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
26__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
27uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result);
28
29// [uninitialized.move]
30
31template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
32__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
33uninitialized_move(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result);
34
35template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
36__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
37uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result);
38
39// [uninitialized.fill]
40
41template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
42__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
43uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value);
44
45template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
46__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
47uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, const _Tp& __value);
48
49// [specialized.destroy]
50
51template <class _ExecutionPolicy, class _ForwardIterator>
52__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
53destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
54
55template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
56__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
57destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n);
58
59// [uninitialized.construct.default]
60
61template <class _ExecutionPolicy, class _ForwardIterator>
62__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
63uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
64
65template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
66__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
67uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n);
68
69// [uninitialized.construct.value]
70
71template <class _ExecutionPolicy, class _ForwardIterator>
72__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
73uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
74
75template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
76__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
77uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n);
78
79} // namespace std
80
81#endif /* _PSTL_GLUE_MEMORY_DEFS_H */
lib/libcxx/include/__pstl/internal/glue_memory_impl.h created+379
......@@ -0,0 +1,379 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_GLUE_MEMORY_IMPL_H
11#define _PSTL_GLUE_MEMORY_IMPL_H
12
13#include <__config>
14
15#include "algorithm_fwd.h"
16#include "execution_defs.h"
17#include "utils.h"
18
19#include "execution_impl.h"
20
21namespace std {
22
23// [uninitialized.copy]
24
25template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
26__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> uninitialized_copy(
27 _ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result) {
28 typedef typename iterator_traits<_InputIterator>::value_type _ValueType1;
29 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
30 typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
31 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
32
33 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
34
35 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
36
37 return __pstl::__internal::__invoke_if_else(
38 std::integral_constant < bool,
39 std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
40 [&]() {
41 return __pstl::__internal::__pattern_walk2_brick(
42 __dispatch_tag,
43 std::forward<_ExecutionPolicy>(__exec),
44 __first,
45 __last,
46 __result,
47 [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) {
48 return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{});
49 });
50 },
51 [&]() {
52 return __pstl::__internal::__pattern_walk2(
53 __dispatch_tag,
54 std::forward<_ExecutionPolicy>(__exec),
55 __first,
56 __last,
57 __result,
58 [](_ReferenceType1 __val1, _ReferenceType2 __val2) { ::new (std::addressof(__val2)) _ValueType2(__val1); });
59 });
60}
61
62template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
63__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
64uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result) {
65 typedef typename iterator_traits<_InputIterator>::value_type _ValueType1;
66 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
67 typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
68 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
69
70 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
71
72 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
73
74 return __pstl::__internal::__invoke_if_else(
75 std::integral_constant < bool,
76 std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
77 [&]() {
78 return __pstl::__internal::__pattern_walk2_brick_n(
79 __dispatch_tag,
80 std::forward<_ExecutionPolicy>(__exec),
81 __first,
82 __n,
83 __result,
84 [](_InputIterator __begin, _Size __sz, _ForwardIterator __res) {
85 return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{});
86 });
87 },
88 [&]() {
89 return __pstl::__internal::__pattern_walk2_n(
90 __dispatch_tag,
91 std::forward<_ExecutionPolicy>(__exec),
92 __first,
93 __n,
94 __result,
95 [](_ReferenceType1 __val1, _ReferenceType2 __val2) { ::new (std::addressof(__val2)) _ValueType2(__val1); });
96 });
97}
98
99// [uninitialized.move]
100
101template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
102__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> uninitialized_move(
103 _ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result) {
104 typedef typename iterator_traits<_InputIterator>::value_type _ValueType1;
105 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
106 typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
107 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
108
109 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
110
111 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
112
113 return __pstl::__internal::__invoke_if_else(
114 std::integral_constant < bool,
115 std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
116 [&]() {
117 return __pstl::__internal::__pattern_walk2_brick(
118 __dispatch_tag,
119 std::forward<_ExecutionPolicy>(__exec),
120 __first,
121 __last,
122 __result,
123 [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) {
124 return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{});
125 });
126 },
127 [&]() {
128 return __pstl::__internal::__pattern_walk2(
129 __dispatch_tag,
130 std::forward<_ExecutionPolicy>(__exec),
131 __first,
132 __last,
133 __result,
134 [](_ReferenceType1 __val1, _ReferenceType2 __val2) {
135 ::new (std::addressof(__val2)) _ValueType2(std::move(__val1));
136 });
137 });
138}
139
140template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
141__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
142uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result) {
143 typedef typename iterator_traits<_InputIterator>::value_type _ValueType1;
144 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
145 typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
146 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
147
148 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
149
150 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
151
152 return __pstl::__internal::__invoke_if_else(
153 std::integral_constant < bool,
154 std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
155 [&]() {
156 return __pstl::__internal::__pattern_walk2_brick_n(
157 __dispatch_tag,
158 std::forward<_ExecutionPolicy>(__exec),
159 __first,
160 __n,
161 __result,
162 [](_InputIterator __begin, _Size __sz, _ForwardIterator __res) {
163 return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{});
164 });
165 },
166 [&]() {
167 return __pstl::__internal::__pattern_walk2_n(
168 __dispatch_tag,
169 std::forward<_ExecutionPolicy>(__exec),
170 __first,
171 __n,
172 __result,
173 [](_ReferenceType1 __val1, _ReferenceType2 __val2) {
174 ::new (std::addressof(__val2)) _ValueType2(std::move(__val1));
175 });
176 });
177}
178
179// [uninitialized.fill]
180
181template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
182__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
183uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
184 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
185 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
186
187 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
188
189 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
190
191 __pstl::__internal::__invoke_if_else(
192 std::is_arithmetic<_ValueType>(),
193 [&]() {
194 __pstl::__internal::__pattern_walk_brick(
195 __dispatch_tag,
196 std::forward<_ExecutionPolicy>(__exec),
197 __first,
198 __last,
199 [&__value](_ForwardIterator __begin, _ForwardIterator __end) {
200 __pstl::__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector{});
201 });
202 },
203 [&]() {
204 __pstl::__internal::__pattern_walk1(
205 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [&__value](_ReferenceType __val) {
206 ::new (std::addressof(__val)) _ValueType(__value);
207 });
208 });
209}
210
211template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
212__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
213uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, const _Tp& __value) {
214 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
215 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
216
217 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
218
219 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
220
221 return __pstl::__internal::__invoke_if_else(
222 std::is_arithmetic<_ValueType>(),
223 [&]() {
224 return __pstl::__internal::__pattern_walk_brick_n(
225 __dispatch_tag,
226 std::forward<_ExecutionPolicy>(__exec),
227 __first,
228 __n,
229 [&__value](_ForwardIterator __begin, _Size __count) {
230 return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(__value), __is_vector{});
231 });
232 },
233 [&]() {
234 return __pstl::__internal::__pattern_walk1_n(
235 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [&__value](_ReferenceType __val) {
236 ::new (std::addressof(__val)) _ValueType(__value);
237 });
238 });
239}
240
241// [specialized.destroy]
242
243template <class _ExecutionPolicy, class _ForwardIterator>
244__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
245destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
246 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
247 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
248
249 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
250
251 __pstl::__internal::__invoke_if_not(std::is_trivially_destructible<_ValueType>(), [&]() {
252 __pstl::__internal::__pattern_walk1(
253 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [](_ReferenceType __val) {
254 __val.~_ValueType();
255 });
256 });
257}
258
259template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
260__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
261destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) {
262 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
263 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
264
265 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
266
267 return __pstl::__internal::__invoke_if_else(
268 std::is_trivially_destructible<_ValueType>(),
269 [&]() { return std::next(__first, __n); },
270 [&]() {
271 return __pstl::__internal::__pattern_walk1_n(
272 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [](_ReferenceType __val) {
273 __val.~_ValueType();
274 });
275 });
276}
277
278// [uninitialized.construct.default]
279
280template <class _ExecutionPolicy, class _ForwardIterator>
281__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
282uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
283 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
284 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
285
286 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
287
288 __pstl::__internal::__invoke_if_not(std::is_trivial<_ValueType>(), [&]() {
289 __pstl::__internal::__pattern_walk1(
290 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [](_ReferenceType __val) {
291 ::new (std::addressof(__val)) _ValueType;
292 });
293 });
294}
295
296template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
297__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
298uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) {
299 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
300 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
301
302 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
303
304 return __pstl::__internal::__invoke_if_else(
305 std::is_trivial<_ValueType>(),
306 [&]() { return std::next(__first, __n); },
307 [&]() {
308 return __pstl::__internal::__pattern_walk1_n(
309 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [](_ReferenceType __val) {
310 ::new (std::addressof(__val)) _ValueType;
311 });
312 });
313}
314
315// [uninitialized.construct.value]
316
317template <class _ExecutionPolicy, class _ForwardIterator>
318__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
319uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) {
320 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
321 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
322
323 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
324
325 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
326
327 __pstl::__internal::__invoke_if_else(
328 std::is_trivial<_ValueType>(),
329 [&]() {
330 __pstl::__internal::__pattern_walk_brick(
331 __dispatch_tag,
332 std::forward<_ExecutionPolicy>(__exec),
333 __first,
334 __last,
335 [](_ForwardIterator __begin, _ForwardIterator __end) {
336 __pstl::__internal::__brick_fill(__begin, __end, _ValueType(), __is_vector{});
337 });
338 },
339 [&]() {
340 __pstl::__internal::__pattern_walk1(
341 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [](_ReferenceType __val) {
342 ::new (std::addressof(__val)) _ValueType();
343 });
344 });
345}
346
347template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
348__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
349uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) {
350 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
351 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
352
353 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
354
355 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
356
357 return __pstl::__internal::__invoke_if_else(
358 std::is_trivial<_ValueType>(),
359 [&]() {
360 return __pstl::__internal::__pattern_walk_brick_n(
361 __dispatch_tag,
362 std::forward<_ExecutionPolicy>(__exec),
363 __first,
364 __n,
365 [](_ForwardIterator __begin, _Size __count) {
366 return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(), __is_vector{});
367 });
368 },
369 [&]() {
370 return __pstl::__internal::__pattern_walk1_n(
371 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [](_ReferenceType __val) {
372 ::new (std::addressof(__val)) _ValueType();
373 });
374 });
375}
376
377} // namespace std
378
379#endif /* _PSTL_GLUE_MEMORY_IMPL_H */
lib/libcxx/include/__pstl/internal/glue_numeric_defs.h created+124
......@@ -0,0 +1,124 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_GLUE_NUMERIC_DEFS_H
11#define _PSTL_GLUE_NUMERIC_DEFS_H
12
13#include <__config>
14#include <iterator>
15
16#include "execution_defs.h"
17
18namespace std {
19// [exclusive.scan]
20
21template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
22__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan(
23 _ExecutionPolicy&& __exec,
24 _ForwardIterator1 __first,
25 _ForwardIterator1 __last,
26 _ForwardIterator2 __result,
27 _Tp __init);
28
29template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
30__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan(
31 _ExecutionPolicy&& __exec,
32 _ForwardIterator1 __first,
33 _ForwardIterator1 __last,
34 _ForwardIterator2 __result,
35 _Tp __init,
36 _BinaryOperation __binary_op);
37
38// [inclusive.scan]
39
40template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
41__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
42 _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result);
43
44template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
45__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
46 _ExecutionPolicy&& __exec,
47 _ForwardIterator1 __first,
48 _ForwardIterator1 __last,
49 _ForwardIterator2 __result,
50 _BinaryOperation __binary_op);
51
52template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
53__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
54 _ExecutionPolicy&& __exec,
55 _ForwardIterator1 __first,
56 _ForwardIterator1 __last,
57 _ForwardIterator2 __result,
58 _BinaryOperation __binary_op,
59 _Tp __init);
60
61// [transform.exclusive.scan]
62
63template <class _ExecutionPolicy,
64 class _ForwardIterator1,
65 class _ForwardIterator2,
66 class _Tp,
67 class _BinaryOperation,
68 class _UnaryOperation>
69__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_exclusive_scan(
70 _ExecutionPolicy&& __exec,
71 _ForwardIterator1 __first,
72 _ForwardIterator1 __last,
73 _ForwardIterator2 __result,
74 _Tp __init,
75 _BinaryOperation __binary_op,
76 _UnaryOperation __unary_op);
77
78// [transform.inclusive.scan]
79
80template <class _ExecutionPolicy,
81 class _ForwardIterator1,
82 class _ForwardIterator2,
83 class _BinaryOperation,
84 class _UnaryOperation,
85 class _Tp>
86__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan(
87 _ExecutionPolicy&& __exec,
88 _ForwardIterator1 __first,
89 _ForwardIterator1 __last,
90 _ForwardIterator2 __result,
91 _BinaryOperation __binary_op,
92 _UnaryOperation __unary_op,
93 _Tp __init);
94
95template <class _ExecutionPolicy,
96 class _ForwardIterator1,
97 class _ForwardIterator2,
98 class _UnaryOperation,
99 class _BinaryOperation>
100__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan(
101 _ExecutionPolicy&& __exec,
102 _ForwardIterator1 __first,
103 _ForwardIterator1 __last,
104 _ForwardIterator2 __result,
105 _BinaryOperation __binary_op,
106 _UnaryOperation __unary_op);
107
108// [adjacent.difference]
109
110template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
111__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference(
112 _ExecutionPolicy&& __exec,
113 _ForwardIterator1 __first,
114 _ForwardIterator1 __last,
115 _ForwardIterator2 __d_first,
116 _BinaryOperation op);
117
118template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
119__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference(
120 _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first);
121
122} // namespace std
123
124#endif /* _PSTL_GLUE_NUMERIC_DEFS_H */
lib/libcxx/include/__pstl/internal/glue_numeric_impl.h created+223
......@@ -0,0 +1,223 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_GLUE_NUMERIC_IMPL_H
11#define _PSTL_GLUE_NUMERIC_IMPL_H
12
13#include <__config>
14#include <functional>
15
16#include "execution_impl.h"
17#include "numeric_fwd.h"
18#include "utils.h"
19
20namespace std {
21
22// [exclusive.scan]
23
24template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
25__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan(
26 _ExecutionPolicy&& __exec,
27 _ForwardIterator1 __first,
28 _ForwardIterator1 __last,
29 _ForwardIterator2 __result,
30 _Tp __init) {
31 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
32
33 using namespace __pstl;
34 return __internal::__pattern_transform_scan(
35 __dispatch_tag,
36 std::forward<_ExecutionPolicy>(__exec),
37 __first,
38 __last,
39 __result,
40 __pstl::__internal::__no_op(),
41 __init,
42 std::plus<_Tp>(),
43 /*inclusive=*/std::false_type());
44}
45
46template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
47__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan(
48 _ExecutionPolicy&& __exec,
49 _ForwardIterator1 __first,
50 _ForwardIterator1 __last,
51 _ForwardIterator2 __result,
52 _Tp __init,
53 _BinaryOperation __binary_op) {
54 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
55
56 using namespace __pstl;
57 return __internal::__pattern_transform_scan(
58 __dispatch_tag,
59 std::forward<_ExecutionPolicy>(__exec),
60 __first,
61 __last,
62 __result,
63 __pstl::__internal::__no_op(),
64 __init,
65 __binary_op,
66 /*inclusive=*/std::false_type());
67}
68
69// [inclusive.scan]
70
71template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
72__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
73 _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) {
74 typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType;
75 return transform_inclusive_scan(
76 std::forward<_ExecutionPolicy>(__exec),
77 __first,
78 __last,
79 __result,
80 std::plus<_InputType>(),
81 __pstl::__internal::__no_op());
82}
83
84template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
85__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
86 _ExecutionPolicy&& __exec,
87 _ForwardIterator1 __first,
88 _ForwardIterator1 __last,
89 _ForwardIterator2 __result,
90 _BinaryOperation __binary_op) {
91 return transform_inclusive_scan(
92 std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __binary_op, __pstl::__internal::__no_op());
93}
94
95template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
96__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
97 _ExecutionPolicy&& __exec,
98 _ForwardIterator1 __first,
99 _ForwardIterator1 __last,
100 _ForwardIterator2 __result,
101 _BinaryOperation __binary_op,
102 _Tp __init) {
103 return transform_inclusive_scan(
104 std::forward<_ExecutionPolicy>(__exec),
105 __first,
106 __last,
107 __result,
108 __binary_op,
109 __pstl::__internal::__no_op(),
110 __init);
111}
112
113// [transform.exclusive.scan]
114
115template <class _ExecutionPolicy,
116 class _ForwardIterator1,
117 class _ForwardIterator2,
118 class _Tp,
119 class _BinaryOperation,
120 class _UnaryOperation>
121__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_exclusive_scan(
122 _ExecutionPolicy&& __exec,
123 _ForwardIterator1 __first,
124 _ForwardIterator1 __last,
125 _ForwardIterator2 __result,
126 _Tp __init,
127 _BinaryOperation __binary_op,
128 _UnaryOperation __unary_op) {
129 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
130
131 return __pstl::__internal::__pattern_transform_scan(
132 __dispatch_tag,
133 std::forward<_ExecutionPolicy>(__exec),
134 __first,
135 __last,
136 __result,
137 __unary_op,
138 __init,
139 __binary_op,
140 /*inclusive=*/std::false_type());
141}
142
143// [transform.inclusive.scan]
144
145template <class _ExecutionPolicy,
146 class _ForwardIterator1,
147 class _ForwardIterator2,
148 class _BinaryOperation,
149 class _UnaryOperation,
150 class _Tp>
151__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan(
152 _ExecutionPolicy&& __exec,
153 _ForwardIterator1 __first,
154 _ForwardIterator1 __last,
155 _ForwardIterator2 __result,
156 _BinaryOperation __binary_op,
157 _UnaryOperation __unary_op,
158 _Tp __init) {
159 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
160
161 return __pstl::__internal::__pattern_transform_scan(
162 __dispatch_tag,
163 std::forward<_ExecutionPolicy>(__exec),
164 __first,
165 __last,
166 __result,
167 __unary_op,
168 __init,
169 __binary_op,
170 /*inclusive=*/std::true_type());
171}
172
173template <class _ExecutionPolicy,
174 class _ForwardIterator1,
175 class _ForwardIterator2,
176 class _UnaryOperation,
177 class _BinaryOperation>
178__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan(
179 _ExecutionPolicy&& __exec,
180 _ForwardIterator1 __first,
181 _ForwardIterator1 __last,
182 _ForwardIterator2 __result,
183 _BinaryOperation __binary_op,
184 _UnaryOperation __unary_op) {
185 if (__first != __last) {
186 auto __tmp = __unary_op(*__first);
187 *__result = __tmp;
188 return transform_inclusive_scan(
189 std::forward<_ExecutionPolicy>(__exec), ++__first, __last, ++__result, __binary_op, __unary_op, __tmp);
190 } else {
191 return __result;
192 }
193}
194
195// [adjacent.difference]
196
197template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
198__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference(
199 _ExecutionPolicy&& __exec,
200 _ForwardIterator1 __first,
201 _ForwardIterator1 __last,
202 _ForwardIterator2 __d_first,
203 _BinaryOperation __op) {
204 if (__first == __last)
205 return __d_first;
206
207 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
208
209 return __pstl::__internal::__pattern_adjacent_difference(
210 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __op);
211}
212
213template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
214__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference(
215 _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first) {
216 typedef typename iterator_traits<_ForwardIterator1>::value_type _ValueType;
217 return adjacent_difference(
218 std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, std::minus<_ValueType>());
219}
220
221} // namespace std
222
223#endif /* _PSTL_GLUE_NUMERIC_IMPL_H_ */
lib/libcxx/include/__pstl/internal/memory_impl.h created+106
......@@ -0,0 +1,106 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_MEMORY_IMPL_H
11#define _PSTL_MEMORY_IMPL_H
12
13#include <__config>
14#include <iterator>
15
16#include "unseq_backend_simd.h"
17
18namespace __pstl {
19namespace __internal {
20
21//------------------------------------------------------------------------
22// uninitialized_move
23//------------------------------------------------------------------------
24
25template <typename _ForwardIterator, typename _OutputIterator>
26_OutputIterator __brick_uninitialized_move(
27 _ForwardIterator __first,
28 _ForwardIterator __last,
29 _OutputIterator __result,
30 /*vector=*/std::false_type) noexcept {
31 using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
32 for (; __first != __last; ++__first, ++__result) {
33 ::new (std::addressof(*__result)) _ValueType(std::move(*__first));
34 }
35 return __result;
36}
37
38template <typename _RandomAccessIterator, typename _OutputIterator>
39_OutputIterator __brick_uninitialized_move(
40 _RandomAccessIterator __first,
41 _RandomAccessIterator __last,
42 _OutputIterator __result,
43 /*vector=*/std::true_type) noexcept {
44 using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
45 using _ReferenceType1 = typename std::iterator_traits<_RandomAccessIterator>::reference;
46 using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference;
47
48 return __unseq_backend::__simd_walk_2(
49 __first, __last - __first, __result, [](_ReferenceType1 __x, _ReferenceType2 __y) {
50 ::new (std::addressof(__y)) __ValueType(std::move(__x));
51 });
52}
53
54template <typename _Iterator>
55void __brick_destroy(_Iterator __first, _Iterator __last, /*vector*/ std::false_type) noexcept {
56 using _ValueType = typename std::iterator_traits<_Iterator>::value_type;
57
58 for (; __first != __last; ++__first)
59 __first->~_ValueType();
60}
61
62template <typename _RandomAccessIterator>
63void __brick_destroy(_RandomAccessIterator __first, _RandomAccessIterator __last, /*vector*/ std::true_type) noexcept {
64 using _ValueType = typename std::iterator_traits<_RandomAccessIterator>::value_type;
65 using _ReferenceType = typename std::iterator_traits<_RandomAccessIterator>::reference;
66
67 __unseq_backend::__simd_walk_1(__first, __last - __first, [](_ReferenceType __x) { __x.~_ValueType(); });
68}
69
70//------------------------------------------------------------------------
71// uninitialized copy
72//------------------------------------------------------------------------
73
74template <typename _ForwardIterator, typename _OutputIterator>
75_OutputIterator __brick_uninitialized_copy(
76 _ForwardIterator __first,
77 _ForwardIterator __last,
78 _OutputIterator __result,
79 /*vector=*/std::false_type) noexcept {
80 using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
81 for (; __first != __last; ++__first, ++__result) {
82 ::new (std::addressof(*__result)) _ValueType(*__first);
83 }
84 return __result;
85}
86
87template <typename _RandomAccessIterator, typename _OutputIterator>
88_OutputIterator __brick_uninitialized_copy(
89 _RandomAccessIterator __first,
90 _RandomAccessIterator __last,
91 _OutputIterator __result,
92 /*vector=*/std::true_type) noexcept {
93 using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
94 using _ReferenceType1 = typename std::iterator_traits<_RandomAccessIterator>::reference;
95 using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference;
96
97 return __unseq_backend::__simd_walk_2(
98 __first, __last - __first, __result, [](_ReferenceType1 __x, _ReferenceType2 __y) {
99 ::new (std::addressof(__y)) __ValueType(__x);
100 });
101}
102
103} // namespace __internal
104} // namespace __pstl
105
106#endif /* _PSTL_MEMORY_IMPL_H */
lib/libcxx/include/__pstl/internal/numeric_fwd.h created+143
......@@ -0,0 +1,143 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_NUMERIC_FWD_H
11#define _PSTL_NUMERIC_FWD_H
12
13#include <__config>
14#include <type_traits>
15#include <utility>
16
17namespace __pstl {
18namespace __internal {
19
20//------------------------------------------------------------------------
21// transform_exclusive_scan
22//
23// walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...)
24//------------------------------------------------------------------------
25
26template <class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
27std::pair<_OutputIterator, _Tp> __brick_transform_scan(
28 _ForwardIterator,
29 _ForwardIterator,
30 _OutputIterator,
31 _UnaryOperation,
32 _Tp,
33 _BinaryOperation,
34 /*Inclusive*/ std::false_type) noexcept;
35
36template <class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
37std::pair<_OutputIterator, _Tp> __brick_transform_scan(
38 _RandomAccessIterator,
39 _RandomAccessIterator,
40 _OutputIterator,
41 _UnaryOperation,
42 _Tp,
43 _BinaryOperation,
44 /*Inclusive*/ std::true_type) noexcept;
45
46template <class _Tag,
47 class _ExecutionPolicy,
48 class _ForwardIterator,
49 class _OutputIterator,
50 class _UnaryOperation,
51 class _Tp,
52 class _BinaryOperation,
53 class _Inclusive>
54_OutputIterator __pattern_transform_scan(
55 _Tag,
56 _ExecutionPolicy&&,
57 _ForwardIterator,
58 _ForwardIterator,
59 _OutputIterator,
60 _UnaryOperation,
61 _Tp,
62 _BinaryOperation,
63 _Inclusive) noexcept;
64
65template <class _IsVector,
66 class _ExecutionPolicy,
67 class _RandomAccessIterator,
68 class _OutputIterator,
69 class _UnaryOperation,
70 class _Tp,
71 class _BinaryOperation,
72 class _Inclusive>
73typename std::enable_if<!std::is_floating_point<_Tp>::value, _OutputIterator>::type __pattern_transform_scan(
74 __parallel_tag<_IsVector> __tag,
75 _ExecutionPolicy&&,
76 _RandomAccessIterator,
77 _RandomAccessIterator,
78 _OutputIterator,
79 _UnaryOperation,
80 _Tp,
81 _BinaryOperation,
82 _Inclusive);
83
84template <class _IsVector,
85 class _ExecutionPolicy,
86 class _RandomAccessIterator,
87 class _OutputIterator,
88 class _UnaryOperation,
89 class _Tp,
90 class _BinaryOperation,
91 class _Inclusive>
92typename std::enable_if<std::is_floating_point<_Tp>::value, _OutputIterator>::type __pattern_transform_scan(
93 __parallel_tag<_IsVector>,
94 _ExecutionPolicy&&,
95 _RandomAccessIterator,
96 _RandomAccessIterator,
97 _OutputIterator,
98 _UnaryOperation,
99 _Tp,
100 _BinaryOperation,
101 _Inclusive);
102
103//------------------------------------------------------------------------
104// adjacent_difference
105//------------------------------------------------------------------------
106
107template <class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
108_OutputIterator __brick_adjacent_difference(
109 _ForwardIterator,
110 _ForwardIterator,
111 _OutputIterator,
112 _BinaryOperation,
113 /*is_vector*/ std::false_type) noexcept;
114
115template <class _RandomAccessIterator, class _OutputIterator, class _BinaryOperation>
116_OutputIterator __brick_adjacent_difference(
117 _RandomAccessIterator,
118 _RandomAccessIterator,
119 _OutputIterator,
120 _BinaryOperation,
121 /*is_vector*/ std::true_type) noexcept;
122
123template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
124_OutputIterator __pattern_adjacent_difference(
125 _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation) noexcept;
126
127template <class _IsVector,
128 class _ExecutionPolicy,
129 class _RandomAccessIterator,
130 class _OutputIterator,
131 class _BinaryOperation>
132_OutputIterator __pattern_adjacent_difference(
133 __parallel_tag<_IsVector>,
134 _ExecutionPolicy&&,
135 _RandomAccessIterator,
136 _RandomAccessIterator,
137 _OutputIterator,
138 _BinaryOperation);
139
140} // namespace __internal
141} // namespace __pstl
142
143#endif /* _PSTL_NUMERIC_FWD_H */
lib/libcxx/include/__pstl/internal/numeric_impl.h created+364
......@@ -0,0 +1,364 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_NUMERIC_IMPL_H
11#define _PSTL_NUMERIC_IMPL_H
12
13#include <__assert>
14#include <__config>
15#include <iterator>
16#include <type_traits>
17#include <numeric>
18
19#include "parallel_backend.h"
20#include "execution_impl.h"
21#include "unseq_backend_simd.h"
22#include "algorithm_fwd.h"
23
24namespace __pstl {
25namespace __internal {
26
27//------------------------------------------------------------------------
28// transform_exclusive_scan
29//
30// walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...)
31//------------------------------------------------------------------------
32
33// Exclusive form
34template <class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
35std::pair<_OutputIterator, _Tp> __brick_transform_scan(
36 _ForwardIterator __first,
37 _ForwardIterator __last,
38 _OutputIterator __result,
39 _UnaryOperation __unary_op,
40 _Tp __init,
41 _BinaryOperation __binary_op,
42 /*Inclusive*/ std::false_type,
43 /*is_vector=*/std::false_type) noexcept {
44 for (; __first != __last; ++__first, ++__result) {
45 *__result = __init;
46 __init = __binary_op(__init, __unary_op(*__first));
47 }
48 return std::make_pair(__result, __init);
49}
50
51// Inclusive form
52template <class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
53std::pair<_OutputIterator, _Tp> __brick_transform_scan(
54 _RandomAccessIterator __first,
55 _RandomAccessIterator __last,
56 _OutputIterator __result,
57 _UnaryOperation __unary_op,
58 _Tp __init,
59 _BinaryOperation __binary_op,
60 /*Inclusive*/ std::true_type,
61 /*is_vector=*/std::false_type) noexcept {
62 for (; __first != __last; ++__first, ++__result) {
63 __init = __binary_op(__init, __unary_op(*__first));
64 *__result = __init;
65 }
66 return std::make_pair(__result, __init);
67}
68
69// type is arithmetic and binary operation is a user defined operation.
70template <typename _Tp, typename _BinaryOperation>
71using is_arithmetic_udop =
72 std::integral_constant<bool,
73 std::is_arithmetic<_Tp>::value && !std::is_same<_BinaryOperation, std::plus<_Tp>>::value>;
74
75// [restriction] - T shall be DefaultConstructible.
76// [violation] - default ctor of T shall set the identity value for binary_op.
77template <class _RandomAccessIterator,
78 class _OutputIterator,
79 class _UnaryOperation,
80 class _Tp,
81 class _BinaryOperation,
82 class _Inclusive>
83typename std::enable_if<!is_arithmetic_udop<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
84__brick_transform_scan(
85 _RandomAccessIterator __first,
86 _RandomAccessIterator __last,
87 _OutputIterator __result,
88 _UnaryOperation __unary_op,
89 _Tp __init,
90 _BinaryOperation __binary_op,
91 _Inclusive,
92 /*is_vector=*/std::true_type) noexcept {
93#if defined(_PSTL_UDS_PRESENT)
94 return __unseq_backend::__simd_scan(
95 __first, __last - __first, __result, __unary_op, __init, __binary_op, _Inclusive());
96#else
97 // We need to call serial brick here to call function for inclusive and exclusive scan that depends on _Inclusive()
98 // value
99 return __internal::__brick_transform_scan(
100 __first,
101 __last,
102 __result,
103 __unary_op,
104 __init,
105 __binary_op,
106 _Inclusive(),
107 /*is_vector=*/std::false_type());
108#endif
109}
110
111template <class _RandomAccessIterator,
112 class _OutputIterator,
113 class _UnaryOperation,
114 class _Tp,
115 class _BinaryOperation,
116 class _Inclusive>
117typename std::enable_if<is_arithmetic_udop<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
118__brick_transform_scan(
119 _RandomAccessIterator __first,
120 _RandomAccessIterator __last,
121 _OutputIterator __result,
122 _UnaryOperation __unary_op,
123 _Tp __init,
124 _BinaryOperation __binary_op,
125 _Inclusive,
126 /*is_vector=*/std::true_type) noexcept {
127 return __internal::__brick_transform_scan(
128 __first,
129 __last,
130 __result,
131 __unary_op,
132 __init,
133 __binary_op,
134 _Inclusive(),
135 /*is_vector=*/std::false_type());
136}
137
138template <class _Tag,
139 class _ExecutionPolicy,
140 class _ForwardIterator,
141 class _OutputIterator,
142 class _UnaryOperation,
143 class _Tp,
144 class _BinaryOperation,
145 class _Inclusive>
146_OutputIterator __pattern_transform_scan(
147 _Tag,
148 _ExecutionPolicy&&,
149 _ForwardIterator __first,
150 _ForwardIterator __last,
151 _OutputIterator __result,
152 _UnaryOperation __unary_op,
153 _Tp __init,
154 _BinaryOperation __binary_op,
155 _Inclusive) noexcept {
156 return __internal::__brick_transform_scan(
157 __first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(), typename _Tag::__is_vector{})
158 .first;
159}
160
161template <class _IsVector,
162 class _ExecutionPolicy,
163 class _RandomAccessIterator,
164 class _OutputIterator,
165 class _UnaryOperation,
166 class _Tp,
167 class _BinaryOperation,
168 class _Inclusive>
169typename std::enable_if<!std::is_floating_point<_Tp>::value, _OutputIterator>::type __pattern_transform_scan(
170 __parallel_tag<_IsVector> __tag,
171 _ExecutionPolicy&& __exec,
172 _RandomAccessIterator __first,
173 _RandomAccessIterator __last,
174 _OutputIterator __result,
175 _UnaryOperation __unary_op,
176 _Tp __init,
177 _BinaryOperation __binary_op,
178 _Inclusive) {
179 using __backend_tag = typename decltype(__tag)::__backend_tag;
180
181 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
182
183 return __internal::__except_handler([&]() {
184 __par_backend::__parallel_transform_scan(
185 __backend_tag{},
186 std::forward<_ExecutionPolicy>(__exec),
187 __last - __first,
188 [__first, __unary_op](_DifferenceType __i) mutable { return __unary_op(__first[__i]); },
189 __init,
190 __binary_op,
191 [__first, __unary_op, __binary_op](_DifferenceType __i, _DifferenceType __j, _Tp __init) {
192 // Execute serial __brick_transform_reduce, due to the explicit SIMD vectorization (reduction) requires a
193 // commutative operation for the guarantee of correct scan.
194 return __internal::__brick_transform_reduce(
195 __first + __i,
196 __first + __j,
197 __init,
198 __binary_op,
199 __unary_op,
200 /*__is_vector*/ std::false_type());
201 },
202 [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __j, _Tp __init) {
203 return __internal::__brick_transform_scan(
204 __first + __i,
205 __first + __j,
206 __result + __i,
207 __unary_op,
208 __init,
209 __binary_op,
210 _Inclusive(),
211 _IsVector{})
212 .second;
213 });
214 return __result + (__last - __first);
215 });
216}
217
218template <class _IsVector,
219 class _ExecutionPolicy,
220 class _RandomAccessIterator,
221 class _OutputIterator,
222 class _UnaryOperation,
223 class _Tp,
224 class _BinaryOperation,
225 class _Inclusive>
226typename std::enable_if<std::is_floating_point<_Tp>::value, _OutputIterator>::type __pattern_transform_scan(
227 __parallel_tag<_IsVector> __tag,
228 _ExecutionPolicy&& __exec,
229 _RandomAccessIterator __first,
230 _RandomAccessIterator __last,
231 _OutputIterator __result,
232 _UnaryOperation __unary_op,
233 _Tp __init,
234 _BinaryOperation __binary_op,
235 _Inclusive) {
236 using __backend_tag = typename decltype(__tag)::__backend_tag;
237
238 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
239 _DifferenceType __n = __last - __first;
240
241 if (__n <= 0) {
242 return __result;
243 }
244 return __internal::__except_handler([&]() {
245 __par_backend::__parallel_strict_scan(
246 __backend_tag{},
247 std::forward<_ExecutionPolicy>(__exec),
248 __n,
249 __init,
250 [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __len) {
251 return __internal::__brick_transform_scan(
252 __first + __i,
253 __first + (__i + __len),
254 __result + __i,
255 __unary_op,
256 _Tp{},
257 __binary_op,
258 _Inclusive(),
259 _IsVector{})
260 .second;
261 },
262 __binary_op,
263 [__result, &__binary_op](_DifferenceType __i, _DifferenceType __len, _Tp __initial) {
264 return *(std::transform(__result + __i,
265 __result + __i + __len,
266 __result + __i,
267 [&__initial, &__binary_op](const _Tp& __x) {
268 return __binary_op(__initial, __x);
269 }) -
270 1);
271 },
272 [](_Tp) {});
273 return __result + (__last - __first);
274 });
275}
276
277//------------------------------------------------------------------------
278// adjacent_difference
279//------------------------------------------------------------------------
280
281template <class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
282_OutputIterator __brick_adjacent_difference(
283 _ForwardIterator __first,
284 _ForwardIterator __last,
285 _OutputIterator __d_first,
286 _BinaryOperation __op,
287 /*is_vector*/ std::false_type) noexcept {
288 return std::adjacent_difference(__first, __last, __d_first, __op);
289}
290
291template <class _RandomAccessIterator1, class _RandomAccessIterator2, class BinaryOperation>
292_RandomAccessIterator2 __brick_adjacent_difference(
293 _RandomAccessIterator1 __first,
294 _RandomAccessIterator1 __last,
295 _RandomAccessIterator2 __d_first,
296 BinaryOperation __op,
297 /*is_vector=*/std::true_type) noexcept {
298 _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "Range cannot be empty");
299
300 typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1;
301 typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2;
302
303 auto __n = __last - __first;
304 *__d_first = *__first;
305 return __unseq_backend::__simd_walk_3(
306 __first + 1,
307 __n - 1,
308 __first,
309 __d_first + 1,
310 [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__x, __y); });
311}
312
313template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
314_OutputIterator __pattern_adjacent_difference(
315 _Tag,
316 _ExecutionPolicy&&,
317 _ForwardIterator __first,
318 _ForwardIterator __last,
319 _OutputIterator __d_first,
320 _BinaryOperation __op) noexcept {
321 return __internal::__brick_adjacent_difference(__first, __last, __d_first, __op, typename _Tag::__is_vector{});
322}
323
324template <class _IsVector,
325 class _ExecutionPolicy,
326 class _RandomAccessIterator1,
327 class _RandomAccessIterator2,
328 class _BinaryOperation>
329_RandomAccessIterator2 __pattern_adjacent_difference(
330 __parallel_tag<_IsVector> __tag,
331 _ExecutionPolicy&& __exec,
332 _RandomAccessIterator1 __first,
333 _RandomAccessIterator1 __last,
334 _RandomAccessIterator2 __d_first,
335 _BinaryOperation __op) {
336 _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "range cannot be empty");
337 typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1;
338 typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2;
339
340 using __backend_tag = typename decltype(__tag)::__backend_tag;
341
342 *__d_first = *__first;
343 __par_backend::__parallel_for(
344 __backend_tag{},
345 std::forward<_ExecutionPolicy>(__exec),
346 __first,
347 __last - 1,
348 [&__op, __d_first, __first](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) {
349 _RandomAccessIterator2 __d_b = __d_first + (__b - __first);
350 __internal::__brick_walk3(
351 __b,
352 __e,
353 __b + 1,
354 __d_b + 1,
355 [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__y, __x); },
356 _IsVector{});
357 });
358 return __d_first + (__last - __first);
359}
360
361} // namespace __internal
362} // namespace __pstl
363
364#endif /* _PSTL_NUMERIC_IMPL_H */
lib/libcxx/include/__pstl/internal/omp/parallel_for.h created+64
......@@ -0,0 +1,64 @@
1// -*- C++ -*-
2// -*-===----------------------------------------------------------------------===//
3//
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7// See https://llvm.org/LICENSE.txt for license information.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _PSTL_INTERNAL_OMP_PARALLEL_FOR_H
12#define _PSTL_INTERNAL_OMP_PARALLEL_FOR_H
13
14#include <cstddef>
15
16#include "util.h"
17
18namespace __pstl
19{
20namespace __omp_backend
21{
22
23template <class _Index, class _Fp>
24void
25__parallel_for_body(_Index __first, _Index __last, _Fp __f)
26{
27 // initial partition of the iteration space into chunks
28 auto __policy = __omp_backend::__chunk_partitioner(__first, __last);
29
30 // To avoid over-subscription we use taskloop for the nested parallelism
31 _PSTL_PRAGMA(omp taskloop untied mergeable)
32 for (std::size_t __chunk = 0; __chunk < __policy.__n_chunks; ++__chunk)
33 {
34 __pstl::__omp_backend::__process_chunk(__policy, __first, __chunk, __f);
35 }
36}
37
38//------------------------------------------------------------------------
39// Notation:
40// Evaluation of brick f[i,j) for each subrange [i,j) of [first, last)
41//------------------------------------------------------------------------
42
43template <class _ExecutionPolicy, class _Index, class _Fp>
44void
45__parallel_for(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f)
46{
47 if (omp_in_parallel())
48 {
49 // we don't create a nested parallel region in an existing parallel
50 // region: just create tasks
51 __pstl::__omp_backend::__parallel_for_body(__first, __last, __f);
52 }
53 else
54 {
55 // in any case (nested or non-nested) one parallel region is created and
56 // only one thread creates a set of tasks
57 _PSTL_PRAGMA(omp parallel)
58 _PSTL_PRAGMA(omp single nowait) { __pstl::__omp_backend::__parallel_for_body(__first, __last, __f); }
59 }
60}
61
62} // namespace __omp_backend
63} // namespace __pstl
64#endif // _PSTL_INTERNAL_OMP_PARALLEL_FOR_H
lib/libcxx/include/__pstl/internal/omp/parallel_for_each.h created+59
......@@ -0,0 +1,59 @@
1// -*- C++ -*-
2// -*-===----------------------------------------------------------------------===//
3//
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7// See https://llvm.org/LICENSE.txt for license information.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _PSTL_INTERNAL_OMP_PARALLEL_FOR_EACH_H
12#define _PSTL_INTERNAL_OMP_PARALLEL_FOR_EACH_H
13
14#include "util.h"
15
16namespace __pstl
17{
18namespace __omp_backend
19{
20
21template <class _ForwardIterator, class _Fp>
22void
23__parallel_for_each_body(_ForwardIterator __first, _ForwardIterator __last, _Fp __f)
24{
25 using DifferenceType = typename std::iterator_traits<_ForwardIterator>::difference_type;
26 // TODO: Think of an approach to remove the std::distance call
27 auto __size = std::distance(__first, __last);
28
29 _PSTL_PRAGMA(omp taskloop untied mergeable)
30 for (DifferenceType __index = 0; __index < __size; ++__index)
31 {
32 // TODO: Think of an approach to remove the increment here each time.
33 auto __iter = std::next(__first, __index);
34 __f(*__iter);
35 }
36}
37
38template <class _ExecutionPolicy, class _ForwardIterator, class _Fp>
39void
40__parallel_for_each(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Fp __f)
41{
42 if (omp_in_parallel())
43 {
44 // we don't create a nested parallel region in an existing parallel
45 // region: just create tasks
46 __pstl::__omp_backend::__parallel_for_each_body(__first, __last, __f);
47 }
48 else
49 {
50 // in any case (nested or non-nested) one parallel region is created and
51 // only one thread creates a set of tasks
52 _PSTL_PRAGMA(omp parallel)
53 _PSTL_PRAGMA(omp single nowait) { __pstl::__omp_backend::__parallel_for_each_body(__first, __last, __f); }
54 }
55}
56
57} // namespace __omp_backend
58} // namespace __pstl
59#endif // _PSTL_INTERNAL_OMP_PARALLEL_FOR_EACH_H
lib/libcxx/include/__pstl/internal/omp/parallel_invoke.h created+50
......@@ -0,0 +1,50 @@
1// -*- C++ -*-
2// -*-===----------------------------------------------------------------------===//
3//
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7// See https://llvm.org/LICENSE.txt for license information.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _PSTL_INTERNAL_OMP_PARALLEL_INVOKE_H
12#define _PSTL_INTERNAL_OMP_PARALLEL_INVOKE_H
13
14#include "util.h"
15
16namespace __pstl
17{
18namespace __omp_backend
19{
20
21template <typename _F1, typename _F2>
22void
23__parallel_invoke_body(_F1&& __f1, _F2&& __f2)
24{
25 _PSTL_PRAGMA(omp taskgroup)
26 {
27 _PSTL_PRAGMA(omp task untied mergeable) { std::forward<_F1>(__f1)(); }
28 _PSTL_PRAGMA(omp task untied mergeable) { std::forward<_F2>(__f2)(); }
29 }
30}
31
32template <class _ExecutionPolicy, typename _F1, typename _F2>
33void
34__parallel_invoke(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
35{
36 if (omp_in_parallel())
37 {
38 __pstl::__omp_backend::__parallel_invoke_body(std::forward<_F1>(__f1), std::forward<_F2>(__f2));
39 }
40 else
41 {
42 _PSTL_PRAGMA(omp parallel)
43 _PSTL_PRAGMA(omp single nowait)
44 __pstl::__omp_backend::__parallel_invoke_body(std::forward<_F1>(__f1), std::forward<_F2>(__f2));
45 }
46}
47
48} // namespace __omp_backend
49} // namespace __pstl
50#endif // _PSTL_INTERNAL_OMP_PARALLEL_INVOKE_H
lib/libcxx/include/__pstl/internal/omp/parallel_merge.h created+98
......@@ -0,0 +1,98 @@
1// -*- C++ -*-
2// -*-===----------------------------------------------------------------------===//
3//
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7// See https://llvm.org/LICENSE.txt for license information.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _PSTL_INTERNAL_OMP_PARALLEL_MERGE_H
12#define _PSTL_INTERNAL_OMP_PARALLEL_MERGE_H
13
14#include "util.h"
15
16namespace __pstl
17{
18namespace __omp_backend
19{
20
21template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _RandomAccessIterator3,
22 typename _Compare, typename _LeafMerge>
23void
24__parallel_merge_body(std::size_t __size_x, std::size_t __size_y, _RandomAccessIterator1 __xs,
25 _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye,
26 _RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge)
27{
28
29 if (__size_x + __size_y <= __omp_backend::__default_chunk_size)
30 {
31 __leaf_merge(__xs, __xe, __ys, __ye, __zs, __comp);
32 return;
33 }
34
35 _RandomAccessIterator1 __xm;
36 _RandomAccessIterator2 __ym;
37
38 if (__size_x < __size_y)
39 {
40 __ym = __ys + (__size_y / 2);
41 __xm = std::upper_bound(__xs, __xe, *__ym, __comp);
42 }
43 else
44 {
45 __xm = __xs + (__size_x / 2);
46 __ym = std::lower_bound(__ys, __ye, *__xm, __comp);
47 }
48
49 auto __zm = __zs + (__xm - __xs) + (__ym - __ys);
50
51 _PSTL_PRAGMA(omp task untied mergeable default(none)
52 firstprivate(__xs, __xm, __ys, __ym, __zs, __comp, __leaf_merge))
53 __pstl::__omp_backend::__parallel_merge_body(__xm - __xs, __ym - __ys, __xs, __xm, __ys, __ym, __zs, __comp,
54 __leaf_merge);
55
56 _PSTL_PRAGMA(omp task untied mergeable default(none)
57 firstprivate(__xm, __xe, __ym, __ye, __zm, __comp, __leaf_merge))
58 __pstl::__omp_backend::__parallel_merge_body(__xe - __xm, __ye - __ym, __xm, __xe, __ym, __ye, __zm, __comp,
59 __leaf_merge);
60
61 _PSTL_PRAGMA(omp taskwait)
62}
63
64template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2,
65 typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
66void
67__parallel_merge(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&& /*__exec*/, _RandomAccessIterator1 __xs,
68 _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye,
69 _RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge)
70
71{
72 std::size_t __size_x = __xe - __xs;
73 std::size_t __size_y = __ye - __ys;
74
75 /*
76 * Run the merge in parallel by chunking it up. Use the smaller range (if any) as the iteration range, and the
77 * larger range as the search range.
78 */
79
80 if (omp_in_parallel())
81 {
82 __pstl::__omp_backend::__parallel_merge_body(__size_x, __size_y, __xs, __xe, __ys, __ye, __zs, __comp,
83 __leaf_merge);
84 }
85 else
86 {
87 _PSTL_PRAGMA(omp parallel)
88 {
89 _PSTL_PRAGMA(omp single nowait)
90 __pstl::__omp_backend::__parallel_merge_body(__size_x, __size_y, __xs, __xe, __ys, __ye, __zs, __comp,
91 __leaf_merge);
92 }
93 }
94}
95
96} // namespace __omp_backend
97} // namespace __pstl
98#endif // _PSTL_INTERNAL_OMP_PARALLEL_MERGE_H
lib/libcxx/include/__pstl/internal/omp/parallel_reduce.h created+73
......@@ -0,0 +1,73 @@
1// -*- C++ -*-
2// -*-===----------------------------------------------------------------------===//
3//
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7// See https://llvm.org/LICENSE.txt for license information.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _PSTL_INTERNAL_OMP_PARALLEL_REDUCE_H
12#define _PSTL_INTERNAL_OMP_PARALLEL_REDUCE_H
13
14#include "util.h"
15
16namespace __pstl
17{
18namespace __omp_backend
19{
20
21template <class _RandomAccessIterator, class _Value, typename _RealBody, typename _Reduction>
22_Value
23__parallel_reduce_body(_RandomAccessIterator __first, _RandomAccessIterator __last, _Value __identity,
24 _RealBody __real_body, _Reduction __reduce)
25{
26 if (__should_run_serial(__first, __last))
27 {
28 return __real_body(__first, __last, __identity);
29 }
30
31 auto __middle = __first + ((__last - __first) / 2);
32 _Value __v1(__identity), __v2(__identity);
33 __parallel_invoke_body(
34 [&]() { __v1 = __parallel_reduce_body(__first, __middle, __identity, __real_body, __reduce); },
35 [&]() { __v2 = __parallel_reduce_body(__middle, __last, __identity, __real_body, __reduce); });
36
37 return __reduce(__v1, __v2);
38}
39
40//------------------------------------------------------------------------
41// Notation:
42// r(i,j,init) returns reduction of init with reduction over [i,j)
43// c(x,y) combines values x and y that were the result of r
44//------------------------------------------------------------------------
45
46template <class _ExecutionPolicy, class _RandomAccessIterator, class _Value, typename _RealBody, typename _Reduction>
47_Value
48__parallel_reduce(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first,
49 _RandomAccessIterator __last, _Value __identity, _RealBody __real_body, _Reduction __reduction)
50{
51 // We don't create a nested parallel region in an existing parallel region:
52 // just create tasks.
53 if (omp_in_parallel())
54 {
55 return __pstl::__omp_backend::__parallel_reduce_body(__first, __last, __identity, __real_body, __reduction);
56 }
57
58 // In any case (nested or non-nested) one parallel region is created and only
59 // one thread creates a set of tasks.
60 _Value __res = __identity;
61
62 _PSTL_PRAGMA(omp parallel)
63 _PSTL_PRAGMA(omp single nowait)
64 {
65 __res = __pstl::__omp_backend::__parallel_reduce_body(__first, __last, __identity, __real_body, __reduction);
66 }
67
68 return __res;
69}
70
71} // namespace __omp_backend
72} // namespace __pstl
73#endif // _PSTL_INTERNAL_OMP_PARALLEL_REDUCE_H
lib/libcxx/include/__pstl/internal/omp/parallel_scan.h created+136
......@@ -0,0 +1,136 @@
1// -*- C++ -*-
2// -*-===----------------------------------------------------------------------===//
3//
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7// See https://llvm.org/LICENSE.txt for license information.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _PSTL_INTERNAL_OMP_PARALLEL_SCAN_H
12#define _PSTL_INTERNAL_OMP_PARALLEL_SCAN_H
13
14#include "parallel_invoke.h"
15
16namespace __pstl
17{
18namespace __omp_backend
19{
20
21template <typename _Index>
22_Index
23__split(_Index __m)
24{
25 _Index __k = 1;
26 while (2 * __k < __m)
27 __k *= 2;
28 return __k;
29}
30
31template <typename _Index, typename _Tp, typename _Rp, typename _Cp>
32void
33__upsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsize, _Rp __reduce, _Cp __combine)
34{
35 if (__m == 1)
36 __r[0] = __reduce(__i * __tilesize, __lastsize);
37 else
38 {
39 _Index __k = __split(__m);
40 __omp_backend::__parallel_invoke_body(
41 [=] { __omp_backend::__upsweep(__i, __k, __tilesize, __r, __tilesize, __reduce, __combine); },
42 [=] {
43 __omp_backend::__upsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize, __reduce, __combine);
44 });
45 if (__m == 2 * __k)
46 __r[__m - 1] = __combine(__r[__k - 1], __r[__m - 1]);
47 }
48}
49
50template <typename _Index, typename _Tp, typename _Cp, typename _Sp>
51void
52__downsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsize, _Tp __initial, _Cp __combine,
53 _Sp __scan)
54{
55 if (__m == 1)
56 __scan(__i * __tilesize, __lastsize, __initial);
57 else
58 {
59 const _Index __k = __split(__m);
60 __omp_backend::__parallel_invoke_body(
61 [=] { __omp_backend::__downsweep(__i, __k, __tilesize, __r, __tilesize, __initial, __combine, __scan); },
62 // Assumes that __combine never throws.
63 // TODO: Consider adding a requirement for user functors to be constant.
64 [=, &__combine]
65 {
66 __omp_backend::__downsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize,
67 __combine(__initial, __r[__k - 1]), __combine, __scan);
68 });
69 }
70}
71
72template <typename _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp,
73 typename _Ap>
74void
75__parallel_strict_scan_body(_Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
76{
77 _Index __p = omp_get_num_threads();
78 const _Index __slack = 4;
79 _Index __tilesize = (__n - 1) / (__slack * __p) + 1;
80 _Index __m = (__n - 1) / __tilesize;
81 __buffer<_Tp> __buf(__m + 1);
82 _Tp* __r = __buf.get();
83
84 __omp_backend::__upsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __reduce, __combine);
85
86 std::size_t __k = __m + 1;
87 _Tp __t = __r[__k - 1];
88 while ((__k &= __k - 1))
89 {
90 __t = __combine(__r[__k - 1], __t);
91 }
92
93 __apex(__combine(__initial, __t));
94 __omp_backend::__downsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __initial,
95 __combine, __scan);
96}
97
98template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap>
99void
100__parallel_strict_scan(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial,
101 _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
102{
103 if (__n <= __default_chunk_size)
104 {
105 _Tp __sum = __initial;
106 if (__n)
107 {
108 __sum = __combine(__sum, __reduce(_Index(0), __n));
109 }
110 __apex(__sum);
111 if (__n)
112 {
113 __scan(_Index(0), __n, __initial);
114 }
115 return;
116 }
117
118 if (omp_in_parallel())
119 {
120 __pstl::__omp_backend::__parallel_strict_scan_body<_ExecutionPolicy>(__n, __initial, __reduce, __combine,
121 __scan, __apex);
122 }
123 else
124 {
125 _PSTL_PRAGMA(omp parallel)
126 _PSTL_PRAGMA(omp single nowait)
127 {
128 __pstl::__omp_backend::__parallel_strict_scan_body<_ExecutionPolicy>(__n, __initial, __reduce, __combine,
129 __scan, __apex);
130 }
131 }
132}
133
134} // namespace __omp_backend
135} // namespace __pstl
136#endif // _PSTL_INTERNAL_OMP_PARALLEL_SCAN_H
lib/libcxx/include/__pstl/internal/omp/parallel_stable_partial_sort.h created+33
......@@ -0,0 +1,33 @@
1// -*- C++ -*-
2// -*-===----------------------------------------------------------------------===//
3//
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7// See https://llvm.org/LICENSE.txt for license information.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _PSTL_INTERNAL_OMP_PARALLEL_STABLE_PARTIAL_SORT_H
12#define _PSTL_INTERNAL_OMP_PARALLEL_STABLE_PARTIAL_SORT_H
13
14#include "util.h"
15
16namespace __pstl
17{
18namespace __omp_backend
19{
20
21template <typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
22void
23__parallel_stable_partial_sort(__pstl::__internal::__openmp_backend_tag, _RandomAccessIterator __xs,
24 _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort,
25 std::size_t /* __nsort */)
26{
27 // TODO: "Parallel partial sort needs to be implemented.");
28 __leaf_sort(__xs, __xe, __comp);
29}
30
31} // namespace __omp_backend
32} // namespace __pstl
33#endif // _PSTL_INTERNAL_OMP_PARALLEL_STABLE_PARTIAL_SORT_H
lib/libcxx/include/__pstl/internal/omp/parallel_stable_sort.h created+160
......@@ -0,0 +1,160 @@
1// -*- C++ -*-
2// -*-===----------------------------------------------------------------------===//
3//
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7// See https://llvm.org/LICENSE.txt for license information.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _PSTL_INTERNAL_OMP_PARALLEL_STABLE_SORT_H
12#define _PSTL_INTERNAL_OMP_PARALLEL_STABLE_SORT_H
13
14#include "util.h"
15#include "parallel_merge.h"
16
17namespace __pstl
18{
19namespace __omp_backend
20{
21
22namespace __sort_details
23{
24struct __move_value
25{
26 template <typename _Iterator, typename _OutputIterator>
27 void
28 operator()(_Iterator __x, _OutputIterator __z) const
29 {
30 *__z = std::move(*__x);
31 }
32};
33
34template <typename _RandomAccessIterator, typename _OutputIterator>
35_OutputIterator
36__parallel_move_range(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _OutputIterator __d_first)
37{
38 std::size_t __size = __last1 - __first1;
39
40 // Perform serial moving of small chunks
41
42 if (__size <= __default_chunk_size)
43 {
44 return std::move(__first1, __last1, __d_first);
45 }
46
47 // Perform parallel moving of larger chunks
48 auto __policy = __pstl::__omp_backend::__chunk_partitioner(__first1, __last1);
49
50 _PSTL_PRAGMA(omp taskloop)
51 for (std::size_t __chunk = 0; __chunk < __policy.__n_chunks; ++__chunk)
52 {
53 __pstl::__omp_backend::__process_chunk(__policy, __first1, __chunk,
54 [&](auto __chunk_first, auto __chunk_last)
55 {
56 auto __chunk_offset = __chunk_first - __first1;
57 auto __output_it = __d_first + __chunk_offset;
58 std::move(__chunk_first, __chunk_last, __output_it);
59 });
60 }
61
62 return __d_first + __size;
63}
64
65struct __move_range
66{
67 template <typename _RandomAccessIterator, typename _OutputIterator>
68 _OutputIterator
69 operator()(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _OutputIterator __d_first) const
70 {
71 return __pstl::__omp_backend::__sort_details::__parallel_move_range(__first1, __last1, __d_first);
72 }
73};
74} // namespace __sort_details
75
76template <typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
77void
78__parallel_stable_sort_body(_RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp,
79 _LeafSort __leaf_sort)
80{
81 using _ValueType = typename std::iterator_traits<_RandomAccessIterator>::value_type;
82 using _VecType = typename std::vector<_ValueType>;
83 using _OutputIterator = typename _VecType::iterator;
84 using _MoveValue = typename __omp_backend::__sort_details::__move_value;
85 using _MoveRange = __omp_backend::__sort_details::__move_range;
86
87 if (__should_run_serial(__xs, __xe))
88 {
89 __leaf_sort(__xs, __xe, __comp);
90 }
91 else
92 {
93 std::size_t __size = __xe - __xs;
94 auto __mid = __xs + (__size / 2);
95 __pstl::__omp_backend::__parallel_invoke_body(
96 [&]() { __parallel_stable_sort_body(__xs, __mid, __comp, __leaf_sort); },
97 [&]() { __parallel_stable_sort_body(__mid, __xe, __comp, __leaf_sort); });
98
99 // Perform a parallel merge of the sorted ranges into __output_data.
100 _VecType __output_data(__size);
101 _MoveValue __move_value;
102 _MoveRange __move_range;
103 __utils::__serial_move_merge __merge(__size);
104 __pstl::__omp_backend::__parallel_merge_body(
105 __mid - __xs, __xe - __mid, __xs, __mid, __mid, __xe, __output_data.begin(), __comp,
106 [&__merge, &__move_value, &__move_range](_RandomAccessIterator __as, _RandomAccessIterator __ae,
107 _RandomAccessIterator __bs, _RandomAccessIterator __be,
108 _OutputIterator __cs, _Compare __comp)
109 { __merge(__as, __ae, __bs, __be, __cs, __comp, __move_value, __move_value, __move_range, __move_range); });
110
111 // Move the values from __output_data back in the original source range.
112 __pstl::__omp_backend::__sort_details::__parallel_move_range(__output_data.begin(), __output_data.end(), __xs);
113 }
114}
115
116template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
117void
118__parallel_stable_sort(__pstl::__internal::__openmp_backend_tag __tag, _ExecutionPolicy&& /*__exec*/,
119 _RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort,
120 std::size_t __nsort = 0)
121{
122 auto __count = static_cast<std::size_t>(__xe - __xs);
123 if (__count <= __default_chunk_size || __nsort < __count)
124 {
125 __leaf_sort(__xs, __xe, __comp);
126 return;
127 }
128
129 // TODO: the partial sort implementation should
130 // be shared with the other backends.
131
132 if (omp_in_parallel())
133 {
134 if (__count <= __nsort)
135 {
136 __pstl::__omp_backend::__parallel_stable_sort_body(__xs, __xe, __comp, __leaf_sort);
137 }
138 else
139 {
140 __pstl::__omp_backend::__parallel_stable_partial_sort(__tag, __xs, __xe, __comp, __leaf_sort, __nsort);
141 }
142 }
143 else
144 {
145 _PSTL_PRAGMA(omp parallel)
146 _PSTL_PRAGMA(omp single nowait)
147 if (__count <= __nsort)
148 {
149 __pstl::__omp_backend::__parallel_stable_sort_body(__xs, __xe, __comp, __leaf_sort);
150 }
151 else
152 {
153 __pstl::__omp_backend::__parallel_stable_partial_sort(__tag, __xs, __xe, __comp, __leaf_sort, __nsort);
154 }
155 }
156}
157
158} // namespace __omp_backend
159} // namespace __pstl
160#endif // _PSTL_INTERNAL_OMP_PARALLEL_STABLE_SORT_H
lib/libcxx/include/__pstl/internal/omp/parallel_transform_reduce.h created+113
......@@ -0,0 +1,113 @@
1// -*- C++ -*-
2// -*-===----------------------------------------------------------------------===//
3//
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7// See https://llvm.org/LICENSE.txt for license information.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_REDUCE_H
12#define _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_REDUCE_H
13
14#include "util.h"
15
16namespace __pstl
17{
18namespace __omp_backend
19{
20
21//------------------------------------------------------------------------
22// parallel_transform_reduce
23//
24// Notation:
25// r(i,j,init) returns reduction of init with reduction over [i,j)
26// u(i) returns f(i,i+1,identity) for a hypothetical left identity element
27// of r c(x,y) combines values x and y that were the result of r or u
28//------------------------------------------------------------------------
29
30template <class _RandomAccessIterator, class _UnaryOp, class _Value, class _Combiner, class _Reduction>
31auto
32__transform_reduce_body(_RandomAccessIterator __first, _RandomAccessIterator __last, _UnaryOp __unary_op, _Value __init,
33 _Combiner __combiner, _Reduction __reduction)
34{
35 const std::size_t __num_threads = omp_get_num_threads();
36 const std::size_t __size = __last - __first;
37
38 // Initial partition of the iteration space into chunks. If the range is too small,
39 // this will result in a nonsense policy, so we check on the size as well below.
40 auto __policy = __omp_backend::__chunk_partitioner(__first + __num_threads, __last);
41
42 if (__size <= __num_threads || __policy.__n_chunks < 2)
43 {
44 return __reduction(__first, __last, __init);
45 }
46
47 // Here, we cannot use OpenMP UDR because we must store the init value in
48 // the combiner and it will be used several times. Although there should be
49 // the only one; we manually generate the identity elements for each thread.
50 std::vector<_Value> __accums;
51 __accums.reserve(__num_threads);
52
53 // initialize accumulators for all threads
54 for (std::size_t __i = 0; __i < __num_threads; ++__i)
55 {
56 __accums.emplace_back(__unary_op(__first + __i));
57 }
58
59 // main loop
60 _PSTL_PRAGMA(omp taskloop shared(__accums))
61 for (std::size_t __chunk = 0; __chunk < __policy.__n_chunks; ++__chunk)
62 {
63 __pstl::__omp_backend::__process_chunk(__policy, __first + __num_threads, __chunk,
64 [&](auto __chunk_first, auto __chunk_last)
65 {
66 auto __thread_num = omp_get_thread_num();
67 __accums[__thread_num] =
68 __reduction(__chunk_first, __chunk_last, __accums[__thread_num]);
69 });
70 }
71
72 // combine by accumulators
73 for (std::size_t __i = 0; __i < __num_threads; ++__i)
74 {
75 __init = __combiner(__init, __accums[__i]);
76 }
77
78 return __init;
79}
80
81template <class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryOp, class _Value, class _Combiner,
82 class _Reduction>
83_Value
84__parallel_transform_reduce(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first,
85 _RandomAccessIterator __last, _UnaryOp __unary_op, _Value __init, _Combiner __combiner,
86 _Reduction __reduction)
87{
88 _Value __result = __init;
89 if (omp_in_parallel())
90 {
91 // We don't create a nested parallel region in an existing parallel
92 // region: just create tasks
93 __result = __pstl::__omp_backend::__transform_reduce_body(__first, __last, __unary_op, __init, __combiner,
94 __reduction);
95 }
96 else
97 {
98 // Create a parallel region, and a single thread will create tasks
99 // for the region.
100 _PSTL_PRAGMA(omp parallel)
101 _PSTL_PRAGMA(omp single nowait)
102 {
103 __result = __pstl::__omp_backend::__transform_reduce_body(__first, __last, __unary_op, __init, __combiner,
104 __reduction);
105 }
106 }
107
108 return __result;
109}
110
111} // namespace __omp_backend
112} // namespace __pstl
113#endif // _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_REDUCE_H
lib/libcxx/include/__pstl/internal/omp/parallel_transform_scan.h created+32
......@@ -0,0 +1,32 @@
1// -*- C++ -*-
2// -*-===----------------------------------------------------------------------===//
3//
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7// See https://llvm.org/LICENSE.txt for license information.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_SCAN_H
12#define _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_SCAN_H
13
14#include "util.h"
15
16namespace __pstl
17{
18namespace __omp_backend
19{
20
21template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp>
22_Tp
23__parallel_transform_scan(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __n, _Up /* __u */,
24 _Tp __init, _Cp /* __combine */, _Rp /* __brick_reduce */, _Sp __scan)
25{
26 // TODO: parallelize this function.
27 return __scan(_Index(0), __n, __init);
28}
29
30} // namespace __omp_backend
31} // namespace __pstl
32#endif // _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_SCAN_H
lib/libcxx/include/__pstl/internal/omp/util.h created+171
......@@ -0,0 +1,171 @@
1// -*- C++ -*-
2// -*-===----------------------------------------------------------------------===//
3//
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7// See https://llvm.org/LICENSE.txt for license information.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _PSTL_INTERNAL_OMP_UTIL_H
12#define _PSTL_INTERNAL_OMP_UTIL_H
13
14#include <algorithm>
15#include <atomic>
16#include <iterator>
17#include <cstddef>
18#include <cstdio>
19#include <memory>
20#include <vector>
21#include <omp.h>
22
23#include "../parallel_backend_utils.h"
24#include "../unseq_backend_simd.h"
25#include "../utils.h"
26
27// Portability "#pragma" definition
28#ifdef _MSC_VER
29# define _PSTL_PRAGMA(x) __pragma(x)
30#else
31# define _PSTL_PRAGMA(x) _Pragma(# x)
32#endif
33
34namespace __pstl
35{
36namespace __omp_backend
37{
38
39//------------------------------------------------------------------------
40// use to cancel execution
41//------------------------------------------------------------------------
42inline void
43__cancel_execution()
44{
45 // TODO: Figure out how to make cancelation work.
46}
47
48//------------------------------------------------------------------------
49// raw buffer
50//------------------------------------------------------------------------
51
52template <typename _Tp>
53class __buffer
54{
55 std::allocator<_Tp> __allocator_;
56 _Tp* __ptr_;
57 const std::size_t __buf_size_;
58 __buffer(const __buffer&) = delete;
59 void
60 operator=(const __buffer&) = delete;
61
62 public:
63 __buffer(std::size_t __n) : __allocator_(), __ptr_(__allocator_.allocate(__n)), __buf_size_(__n) {}
64
65 operator bool() const { return __ptr_ != nullptr; }
66
67 _Tp*
68 get() const
69 {
70 return __ptr_;
71 }
72 ~__buffer() { __allocator_.deallocate(__ptr_, __buf_size_); }
73};
74
75// Preliminary size of each chunk: requires further discussion
76inline constexpr std::size_t __default_chunk_size = 2048;
77
78// Convenience function to determine when we should run serial.
79template <typename _Iterator, std::enable_if_t<!std::is_integral<_Iterator>::value, bool> = true>
80constexpr auto
81__should_run_serial(_Iterator __first, _Iterator __last) -> bool
82{
83 using _difference_type = typename std::iterator_traits<_Iterator>::difference_type;
84 auto __size = std::distance(__first, __last);
85 return __size <= static_cast<_difference_type>(__default_chunk_size);
86}
87
88template <typename _Index, std::enable_if_t<std::is_integral<_Index>::value, bool> = true>
89constexpr auto
90__should_run_serial(_Index __first, _Index __last) -> bool
91{
92 using _difference_type = _Index;
93 auto __size = __last - __first;
94 return __size <= static_cast<_difference_type>(__default_chunk_size);
95}
96
97struct __chunk_metrics
98{
99 std::size_t __n_chunks;
100 std::size_t __chunk_size;
101 std::size_t __first_chunk_size;
102};
103
104// The iteration space partitioner according to __requested_chunk_size
105template <class _RandomAccessIterator, class _Size = std::size_t>
106auto
107__chunk_partitioner(_RandomAccessIterator __first, _RandomAccessIterator __last,
108 _Size __requested_chunk_size = __default_chunk_size) -> __chunk_metrics
109{
110 /*
111 * This algorithm improves distribution of elements in chunks by avoiding
112 * small tail chunks. The leftover elements that do not fit neatly into
113 * the chunk size are redistributed to early chunks. This improves
114 * utilization of the processor's prefetch and reduces the number of
115 * tasks needed by 1.
116 */
117
118 const _Size __n = __last - __first;
119 _Size __n_chunks = 0;
120 _Size __chunk_size = 0;
121 _Size __first_chunk_size = 0;
122 if (__n < __requested_chunk_size)
123 {
124 __chunk_size = __n;
125 __first_chunk_size = __n;
126 __n_chunks = 1;
127 return __chunk_metrics{__n_chunks, __chunk_size, __first_chunk_size};
128 }
129
130 __n_chunks = (__n / __requested_chunk_size) + 1;
131 __chunk_size = __n / __n_chunks;
132 __first_chunk_size = __chunk_size;
133 const _Size __n_leftover_items = __n - (__n_chunks * __chunk_size);
134
135 if (__n_leftover_items == __chunk_size)
136 {
137 __n_chunks += 1;
138 return __chunk_metrics{__n_chunks, __chunk_size, __first_chunk_size};
139 }
140 else if (__n_leftover_items == 0)
141 {
142 __first_chunk_size = __chunk_size;
143 return __chunk_metrics{__n_chunks, __chunk_size, __first_chunk_size};
144 }
145
146 const _Size __n_extra_items_per_chunk = __n_leftover_items / __n_chunks;
147 const _Size __n_final_leftover_items = __n_leftover_items - (__n_extra_items_per_chunk * __n_chunks);
148
149 __chunk_size += __n_extra_items_per_chunk;
150 __first_chunk_size = __chunk_size + __n_final_leftover_items;
151
152 return __chunk_metrics{__n_chunks, __chunk_size, __first_chunk_size};
153}
154
155template <typename _Iterator, typename _Index, typename _Func>
156void
157__process_chunk(const __chunk_metrics& __metrics, _Iterator __base, _Index __chunk_index, _Func __f)
158{
159 auto __this_chunk_size = __chunk_index == 0 ? __metrics.__first_chunk_size : __metrics.__chunk_size;
160 auto __index = __chunk_index == 0 ? 0
161 : (__chunk_index * __metrics.__chunk_size) +
162 (__metrics.__first_chunk_size - __metrics.__chunk_size);
163 auto __first = __base + __index;
164 auto __last = __first + __this_chunk_size;
165 __f(__first, __last);
166}
167
168} // namespace __omp_backend
169} // namespace __pstl
170
171#endif // _PSTL_INTERNAL_OMP_UTIL_H
lib/libcxx/include/__pstl/internal/parallel_backend.h created+39
......@@ -0,0 +1,39 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_PARALLEL_BACKEND_H
11#define _PSTL_PARALLEL_BACKEND_H
12
13#include <__config>
14
15#if defined(_PSTL_PAR_BACKEND_SERIAL)
16# include "parallel_backend_serial.h"
17# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
18namespace __pstl
19{
20namespace __par_backend = __serial_backend;
21} // namespace __pstl
22# endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
23#elif defined(_PSTL_PAR_BACKEND_TBB)
24# include "parallel_backend_tbb.h"
25namespace __pstl
26{
27namespace __par_backend = __tbb_backend;
28}
29#elif defined(_PSTL_PAR_BACKEND_OPENMP)
30# include "parallel_backend_omp.h"
31namespace __pstl
32{
33namespace __par_backend = __omp_backend;
34}
35#else
36# error "No backend set"
37#endif
38
39#endif /* _PSTL_PARALLEL_BACKEND_H */
lib/libcxx/include/__pstl/internal/parallel_backend_omp.h created+58
......@@ -0,0 +1,58 @@
1// -*- C++ -*-
2// -*-===----------------------------------------------------------------------===//
3//
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7// See https://llvm.org/LICENSE.txt for license information.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _PSTL_PARALLEL_BACKEND_OMP_H
12#define _PSTL_PARALLEL_BACKEND_OMP_H
13
14//------------------------------------------------------------------------
15// parallel_invoke
16//------------------------------------------------------------------------
17
18#include "./omp/parallel_invoke.h"
19
20//------------------------------------------------------------------------
21// parallel_for
22//------------------------------------------------------------------------
23
24#include "./omp/parallel_for.h"
25
26//------------------------------------------------------------------------
27// parallel_for_each
28//------------------------------------------------------------------------
29
30#include "./omp/parallel_for_each.h"
31
32//------------------------------------------------------------------------
33// parallel_reduce
34//------------------------------------------------------------------------
35
36#include "./omp/parallel_reduce.h"
37#include "./omp/parallel_transform_reduce.h"
38
39//------------------------------------------------------------------------
40// parallel_scan
41//------------------------------------------------------------------------
42
43#include "./omp/parallel_scan.h"
44#include "./omp/parallel_transform_scan.h"
45
46//------------------------------------------------------------------------
47// parallel_stable_sort
48//------------------------------------------------------------------------
49
50#include "./omp/parallel_stable_partial_sort.h"
51#include "./omp/parallel_stable_sort.h"
52
53//------------------------------------------------------------------------
54// parallel_merge
55//------------------------------------------------------------------------
56#include "./omp/parallel_merge.h"
57
58#endif //_PSTL_PARALLEL_BACKEND_OMP_H
lib/libcxx/include/__pstl/internal/parallel_backend_serial.h created+106
......@@ -0,0 +1,106 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_PARALLEL_BACKEND_SERIAL_H
11#define _PSTL_PARALLEL_BACKEND_SERIAL_H
12
13#include <__config>
14#include <__memory/allocator.h>
15#include <__pstl/internal/execution_impl.h>
16#include <__utility/forward.h>
17#include <cstddef>
18
19#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
20
21namespace __pstl
22{
23namespace __serial_backend
24{
25
26template <typename _Tp>
27class __buffer
28{
29 std::allocator<_Tp> __allocator_;
30 _Tp* __ptr_;
31 const std::size_t __buf_size_;
32 __buffer(const __buffer&) = delete;
33 void
34 operator=(const __buffer&) = delete;
35
36 public:
37 _LIBCPP_HIDE_FROM_ABI
38 __buffer(std::size_t __n) : __allocator_(), __ptr_(__allocator_.allocate(__n)), __buf_size_(__n) {}
39
40 _LIBCPP_HIDE_FROM_ABI operator bool() const { return __ptr_ != nullptr; }
41 _LIBCPP_HIDE_FROM_ABI _Tp*
42 get() const
43 {
44 return __ptr_;
45 }
46 _LIBCPP_HIDE_FROM_ABI ~__buffer() { __allocator_.deallocate(__ptr_, __buf_size_); }
47};
48
49template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction>
50_LIBCPP_HIDE_FROM_ABI _Value
51__parallel_reduce(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
52 const _Value& __identity, const _RealBody& __real_body, const _Reduction&)
53{
54 if (__first == __last)
55 {
56 return __identity;
57 }
58 else
59 {
60 return __real_body(__first, __last, __identity);
61 }
62}
63
64template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap>
65_LIBCPP_HIDE_FROM_ABI void
66__parallel_strict_scan(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial,
67 _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
68{
69 _Tp __sum = __initial;
70 if (__n)
71 __sum = __combine(__sum, __reduce(_Index(0), __n));
72 __apex(__sum);
73 if (__n)
74 __scan(_Index(0), __n, __initial);
75}
76
77template <class _ExecutionPolicy, class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce, class _Scan>
78_LIBCPP_HIDE_FROM_ABI _Tp
79__parallel_transform_scan(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __n, _UnaryOp,
80 _Tp __init, _BinaryOp, _Reduce, _Scan __scan)
81{
82 return __scan(_Index(0), __n, __init);
83}
84
85template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
86_LIBCPP_HIDE_FROM_ABI void
87__parallel_stable_sort(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first,
88 _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort, std::size_t = 0)
89{
90 __leaf_sort(__first, __last, __comp);
91}
92
93template <class _ExecutionPolicy, typename _F1, typename _F2>
94_LIBCPP_HIDE_FROM_ABI void
95__parallel_invoke(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
96{
97 std::forward<_F1>(__f1)();
98 std::forward<_F2>(__f2)();
99}
100
101} // namespace __serial_backend
102} // namespace __pstl
103
104#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
105
106#endif /* _PSTL_PARALLEL_BACKEND_SERIAL_H */
lib/libcxx/include/__pstl/internal/parallel_backend_tbb.h created+1295
......@@ -0,0 +1,1295 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_PARALLEL_BACKEND_TBB_H
11#define _PSTL_PARALLEL_BACKEND_TBB_H
12
13#include <__assert>
14#include <__config>
15#include <algorithm>
16#include <type_traits>
17
18#include "parallel_backend_utils.h"
19
20// Bring in minimal required subset of Intel TBB
21#include <tbb/blocked_range.h>
22#include <tbb/parallel_for.h>
23#include <tbb/parallel_reduce.h>
24#include <tbb/parallel_scan.h>
25#include <tbb/parallel_invoke.h>
26#include <tbb/task_arena.h>
27#include <tbb/tbb_allocator.h>
28#include <tbb/task.h>
29
30#if TBB_INTERFACE_VERSION < 10000
31# error Intel(R) Threading Building Blocks 2018 is required; older versions are not supported.
32#endif
33
34namespace __pstl
35{
36namespace __tbb_backend
37{
38
39//! Raw memory buffer with automatic freeing and no exceptions.
40/** Some of our algorithms need to start with raw memory buffer,
41not an initialize array, because initialization/destruction
42would make the span be at least O(N). */
43// tbb::allocator can improve performance in some cases.
44template <typename _Tp>
45class __buffer
46{
47 tbb::tbb_allocator<_Tp> _M_allocator;
48 _Tp* _M_ptr;
49 const std::size_t _M_buf_size;
50 __buffer(const __buffer&) = delete;
51 void
52 operator=(const __buffer&) = delete;
53
54 public:
55 //! Try to obtain buffer of given size to store objects of _Tp type
56 __buffer(std::size_t n) : _M_allocator(), _M_ptr(_M_allocator.allocate(n)), _M_buf_size(n) {}
57 //! True if buffer was successfully obtained, zero otherwise.
58 operator bool() const { return _M_ptr != NULL; }
59 //! Return pointer to buffer, or NULL if buffer could not be obtained.
60 _Tp*
61 get() const
62 {
63 return _M_ptr;
64 }
65 //! Destroy buffer
66 ~__buffer() { _M_allocator.deallocate(_M_ptr, _M_buf_size); }
67};
68
69// Wrapper for tbb::task
70inline void
71__cancel_execution()
72{
73#if TBB_INTERFACE_VERSION <= 12000
74 tbb::task::self().group()->cancel_group_execution();
75#else
76 tbb::task::current_context()->cancel_group_execution();
77#endif
78}
79
80//------------------------------------------------------------------------
81// parallel_for
82//------------------------------------------------------------------------
83
84template <class _Index, class _RealBody>
85class __parallel_for_body
86{
87 public:
88 __parallel_for_body(const _RealBody& __body) : _M_body(__body) {}
89 __parallel_for_body(const __parallel_for_body& __body) : _M_body(__body._M_body) {}
90 void
91 operator()(const tbb::blocked_range<_Index>& __range) const
92 {
93 _M_body(__range.begin(), __range.end());
94 }
95
96 private:
97 _RealBody _M_body;
98};
99
100//! Evaluation of brick f[i,j) for each subrange [i,j) of [first,last)
101// wrapper over tbb::parallel_for
102template <class _ExecutionPolicy, class _Index, class _Fp>
103void
104__parallel_for(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f)
105{
106 tbb::this_task_arena::isolate([=]() {
107 tbb::parallel_for(tbb::blocked_range<_Index>(__first, __last), __parallel_for_body<_Index, _Fp>(__f));
108 });
109}
110
111//! Evaluation of brick f[i,j) for each subrange [i,j) of [first,last)
112// wrapper over tbb::parallel_reduce
113template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction>
114_Value
115__parallel_reduce(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
116 const _Value& __identity, const _RealBody& __real_body, const _Reduction& __reduction)
117{
118 return tbb::this_task_arena::isolate([__first, __last, &__identity, &__real_body, &__reduction]() -> _Value {
119 return tbb::parallel_reduce(
120 tbb::blocked_range<_Index>(__first, __last), __identity,
121 [__real_body](const tbb::blocked_range<_Index>& __r, const _Value& __value) -> _Value {
122 return __real_body(__r.begin(), __r.end(), __value);
123 },
124 __reduction);
125 });
126}
127
128//------------------------------------------------------------------------
129// parallel_transform_reduce
130//
131// Notation:
132// r(i,j,init) returns reduction of init with reduction over [i,j)
133// u(i) returns f(i,i+1,identity) for a hypothetical left identity element of r
134// c(x,y) combines values x and y that were the result of r or u
135//------------------------------------------------------------------------
136
137template <class _Index, class _Up, class _Tp, class _Cp, class _Rp>
138struct __par_trans_red_body
139{
140 alignas(_Tp) char _M_sum_storage[sizeof(_Tp)]; // Holds generalized non-commutative sum when has_sum==true
141 _Rp _M_brick_reduce; // Most likely to have non-empty layout
142 _Up _M_u;
143 _Cp _M_combine;
144 bool _M_has_sum; // Put last to minimize size of class
145 _Tp&
146 sum()
147 {
148 __TBB_ASSERT(_M_has_sum, "sum expected");
149 return *(_Tp*)_M_sum_storage;
150 }
151 __par_trans_red_body(_Up __u, _Tp __init, _Cp __c, _Rp __r)
152 : _M_brick_reduce(__r), _M_u(__u), _M_combine(__c), _M_has_sum(true)
153 {
154 new (_M_sum_storage) _Tp(__init);
155 }
156
157 __par_trans_red_body(__par_trans_red_body& __left, tbb::split)
158 : _M_brick_reduce(__left._M_brick_reduce), _M_u(__left._M_u), _M_combine(__left._M_combine), _M_has_sum(false)
159 {
160 }
161
162 ~__par_trans_red_body()
163 {
164 // 17.6.5.12 tells us to not worry about catching exceptions from destructors.
165 if (_M_has_sum)
166 sum().~_Tp();
167 }
168
169 void
170 join(__par_trans_red_body& __rhs)
171 {
172 sum() = _M_combine(sum(), __rhs.sum());
173 }
174
175 void
176 operator()(const tbb::blocked_range<_Index>& __range)
177 {
178 _Index __i = __range.begin();
179 _Index __j = __range.end();
180 if (!_M_has_sum)
181 {
182 __TBB_ASSERT(__range.size() > 1, "there should be at least 2 elements");
183 new (&_M_sum_storage)
184 _Tp(_M_combine(_M_u(__i), _M_u(__i + 1))); // The condition i+1 < j is provided by the grain size of 3
185 _M_has_sum = true;
186 std::advance(__i, 2);
187 if (__i == __j)
188 return;
189 }
190 sum() = _M_brick_reduce(__i, __j, sum());
191 }
192};
193
194template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp>
195_Tp
196__parallel_transform_reduce(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
197 _Up __u, _Tp __init, _Cp __combine, _Rp __brick_reduce)
198{
199 __tbb_backend::__par_trans_red_body<_Index, _Up, _Tp, _Cp, _Rp> __body(__u, __init, __combine, __brick_reduce);
200 // The grain size of 3 is used in order to provide mininum 2 elements for each body
201 tbb::this_task_arena::isolate(
202 [__first, __last, &__body]() { tbb::parallel_reduce(tbb::blocked_range<_Index>(__first, __last, 3), __body); });
203 return __body.sum();
204}
205
206//------------------------------------------------------------------------
207// parallel_scan
208//------------------------------------------------------------------------
209
210template <class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp>
211class __trans_scan_body
212{
213 alignas(_Tp) char _M_sum_storage[sizeof(_Tp)]; // Holds generalized non-commutative sum when has_sum==true
214 _Rp _M_brick_reduce; // Most likely to have non-empty layout
215 _Up _M_u;
216 _Cp _M_combine;
217 _Sp _M_scan;
218 bool _M_has_sum; // Put last to minimize size of class
219 public:
220 __trans_scan_body(_Up __u, _Tp __init, _Cp __combine, _Rp __reduce, _Sp __scan)
221 : _M_brick_reduce(__reduce), _M_u(__u), _M_combine(__combine), _M_scan(__scan), _M_has_sum(true)
222 {
223 new (_M_sum_storage) _Tp(__init);
224 }
225
226 __trans_scan_body(__trans_scan_body& __b, tbb::split)
227 : _M_brick_reduce(__b._M_brick_reduce), _M_u(__b._M_u), _M_combine(__b._M_combine), _M_scan(__b._M_scan),
228 _M_has_sum(false)
229 {
230 }
231
232 ~__trans_scan_body()
233 {
234 // 17.6.5.12 tells us to not worry about catching exceptions from destructors.
235 if (_M_has_sum)
236 sum().~_Tp();
237 }
238
239 _Tp&
240 sum() const
241 {
242 __TBB_ASSERT(_M_has_sum, "sum expected");
243 return *const_cast<_Tp*>(reinterpret_cast<_Tp const*>(_M_sum_storage));
244 }
245
246 void
247 operator()(const tbb::blocked_range<_Index>& __range, tbb::pre_scan_tag)
248 {
249 _Index __i = __range.begin();
250 _Index __j = __range.end();
251 if (!_M_has_sum)
252 {
253 new (&_M_sum_storage) _Tp(_M_u(__i));
254 _M_has_sum = true;
255 ++__i;
256 if (__i == __j)
257 return;
258 }
259 sum() = _M_brick_reduce(__i, __j, sum());
260 }
261
262 void
263 operator()(const tbb::blocked_range<_Index>& __range, tbb::final_scan_tag)
264 {
265 sum() = _M_scan(__range.begin(), __range.end(), sum());
266 }
267
268 void
269 reverse_join(__trans_scan_body& __a)
270 {
271 if (_M_has_sum)
272 {
273 sum() = _M_combine(__a.sum(), sum());
274 }
275 else
276 {
277 new (&_M_sum_storage) _Tp(__a.sum());
278 _M_has_sum = true;
279 }
280 }
281
282 void
283 assign(__trans_scan_body& __b)
284 {
285 sum() = __b.sum();
286 }
287};
288
289template <typename _Index>
290_Index
291__split(_Index __m)
292{
293 _Index __k = 1;
294 while (2 * __k < __m)
295 __k *= 2;
296 return __k;
297}
298
299//------------------------------------------------------------------------
300// __parallel_strict_scan
301//------------------------------------------------------------------------
302
303template <typename _Index, typename _Tp, typename _Rp, typename _Cp>
304void
305__upsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsize, _Rp __reduce, _Cp __combine)
306{
307 if (__m == 1)
308 __r[0] = __reduce(__i * __tilesize, __lastsize);
309 else
310 {
311 _Index __k = __split(__m);
312 tbb::parallel_invoke(
313 [=] { __tbb_backend::__upsweep(__i, __k, __tilesize, __r, __tilesize, __reduce, __combine); },
314 [=] {
315 __tbb_backend::__upsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize, __reduce, __combine);
316 });
317 if (__m == 2 * __k)
318 __r[__m - 1] = __combine(__r[__k - 1], __r[__m - 1]);
319 }
320}
321
322template <typename _Index, typename _Tp, typename _Cp, typename _Sp>
323void
324__downsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsize, _Tp __initial, _Cp __combine,
325 _Sp __scan)
326{
327 if (__m == 1)
328 __scan(__i * __tilesize, __lastsize, __initial);
329 else
330 {
331 const _Index __k = __split(__m);
332 tbb::parallel_invoke(
333 [=] { __tbb_backend::__downsweep(__i, __k, __tilesize, __r, __tilesize, __initial, __combine, __scan); },
334 // Assumes that __combine never throws.
335 //TODO: Consider adding a requirement for user functors to be constant.
336 [=, &__combine] {
337 __tbb_backend::__downsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize,
338 __combine(__initial, __r[__k - 1]), __combine, __scan);
339 });
340 }
341}
342
343// Adapted from Intel(R) Cilk(TM) version from cilkpub.
344// Let i:len denote a counted interval of length n starting at i. s denotes a generalized-sum value.
345// Expected actions of the functors are:
346// reduce(i,len) -> s -- return reduction value of i:len.
347// combine(s1,s2) -> s -- return merged sum
348// apex(s) -- do any processing necessary between reduce and scan.
349// scan(i,len,initial) -- perform scan over i:len starting with initial.
350// The initial range 0:n is partitioned into consecutive subranges.
351// reduce and scan are each called exactly once per subrange.
352// Thus callers can rely upon side effects in reduce.
353// combine must not throw an exception.
354// apex is called exactly once, after all calls to reduce and before all calls to scan.
355// For example, it's useful for allocating a __buffer used by scan but whose size is the sum of all reduction values.
356// T must have a trivial constructor and destructor.
357template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap>
358void
359__parallel_strict_scan(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial,
360 _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
361{
362 tbb::this_task_arena::isolate([=, &__combine]() {
363 if (__n > 1)
364 {
365 _Index __p = tbb::this_task_arena::max_concurrency();
366 const _Index __slack = 4;
367 _Index __tilesize = (__n - 1) / (__slack * __p) + 1;
368 _Index __m = (__n - 1) / __tilesize;
369 __buffer<_Tp> __buf(__m + 1);
370 _Tp* __r = __buf.get();
371 __tbb_backend::__upsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __reduce,
372 __combine);
373
374 // When __apex is a no-op and __combine has no side effects, a good optimizer
375 // should be able to eliminate all code between here and __apex.
376 // Alternatively, provide a default value for __apex that can be
377 // recognized by metaprogramming that conditionlly executes the following.
378 size_t __k = __m + 1;
379 _Tp __t = __r[__k - 1];
380 while ((__k &= __k - 1))
381 __t = __combine(__r[__k - 1], __t);
382 __apex(__combine(__initial, __t));
383 __tbb_backend::__downsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __initial,
384 __combine, __scan);
385 return;
386 }
387 // Fewer than 2 elements in sequence, or out of memory. Handle has single block.
388 _Tp __sum = __initial;
389 if (__n)
390 __sum = __combine(__sum, __reduce(_Index(0), __n));
391 __apex(__sum);
392 if (__n)
393 __scan(_Index(0), __n, __initial);
394 });
395}
396
397template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp>
398_Tp
399__parallel_transform_scan(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __n, _Up __u, _Tp __init,
400 _Cp __combine, _Rp __brick_reduce, _Sp __scan)
401{
402 __trans_scan_body<_Index, _Up, _Tp, _Cp, _Rp, _Sp> __body(__u, __init, __combine, __brick_reduce, __scan);
403 auto __range = tbb::blocked_range<_Index>(0, __n);
404 tbb::this_task_arena::isolate([__range, &__body]() { tbb::parallel_scan(__range, __body); });
405 return __body.sum();
406}
407
408//------------------------------------------------------------------------
409// parallel_stable_sort
410//------------------------------------------------------------------------
411
412//------------------------------------------------------------------------
413// stable_sort utilities
414//
415// These are used by parallel implementations but do not depend on them.
416//------------------------------------------------------------------------
417#define _PSTL_MERGE_CUT_OFF 2000
418
419template <typename _Func>
420class __func_task;
421template <typename _Func>
422class __root_task;
423
424#if TBB_INTERFACE_VERSION <= 12000
425class __task : public tbb::task
426{
427 public:
428 template <typename _Fn>
429 __task*
430 make_continuation(_Fn&& __f)
431 {
432 return new (allocate_continuation()) __func_task<typename std::decay<_Fn>::type>(std::forward<_Fn>(__f));
433 }
434
435 template <typename _Fn>
436 __task*
437 make_child_of(__task* parent, _Fn&& __f)
438 {
439 return new (parent->allocate_child()) __func_task<typename std::decay<_Fn>::type>(std::forward<_Fn>(__f));
440 }
441
442 template <typename _Fn>
443 __task*
444 make_additional_child_of(tbb::task* parent, _Fn&& __f)
445 {
446 return new (tbb::task::allocate_additional_child_of(*parent))
447 __func_task<typename std::decay<_Fn>::type>(std::forward<_Fn>(__f));
448 }
449
450 inline void
451 recycle_as_continuation()
452 {
453 tbb::task::recycle_as_continuation();
454 }
455
456 inline void
457 recycle_as_child_of(__task* parent)
458 {
459 tbb::task::recycle_as_child_of(*parent);
460 }
461
462 inline void
463 spawn(__task* __t)
464 {
465 tbb::task::spawn(*__t);
466 }
467
468 template <typename _Fn>
469 static inline void
470 spawn_root_and_wait(__root_task<_Fn>& __root)
471 {
472 tbb::task::spawn_root_and_wait(*__root._M_task);
473 }
474};
475
476template <typename _Func>
477class __func_task : public __task
478{
479 _Func _M_func;
480
481 tbb::task*
482 execute()
483 {
484 return _M_func(this);
485 };
486
487 public:
488 template <typename _Fn>
489 __func_task(_Fn&& __f) : _M_func{std::forward<_Fn>(__f)}
490 {
491 }
492
493 _Func&
494 body()
495 {
496 return _M_func;
497 }
498};
499
500template <typename _Func>
501class __root_task
502{
503 tbb::task* _M_task;
504
505 public:
506 template <typename... Args>
507 __root_task(Args&&... args)
508 : _M_task{new (tbb::task::allocate_root()) __func_task<_Func>{_Func(std::forward<Args>(args)...)}}
509 {
510 }
511
512 friend class __task;
513 friend class __func_task<_Func>;
514};
515
516#else // TBB_INTERFACE_VERSION <= 12000
517class __task : public tbb::detail::d1::task
518{
519 protected:
520 tbb::detail::d1::small_object_allocator _M_allocator{};
521 tbb::detail::d1::execution_data* _M_execute_data{};
522 __task* _M_parent{};
523 std::atomic<int> _M_refcount{};
524 bool _M_recycle{};
525
526 template <typename _Fn>
527 __task*
528 allocate_func_task(_Fn&& __f)
529 {
530 _LIBCPP_ASSERT_UNCATEGORIZED(_M_execute_data != nullptr, "");
531 tbb::detail::d1::small_object_allocator __alloc{};
532 auto __t =
533 __alloc.new_object<__func_task<typename std::decay<_Fn>::type>>(*_M_execute_data, std::forward<_Fn>(__f));
534 __t->_M_allocator = __alloc;
535 return __t;
536 }
537
538 public:
539 __task*
540 parent()
541 {
542 return _M_parent;
543 }
544
545 void
546 set_ref_count(int __n)
547 {
548 _M_refcount.store(__n, std::memory_order_release);
549 }
550
551 template <typename _Fn>
552 __task*
553 make_continuation(_Fn&& __f)
554 {
555 auto __t = allocate_func_task(std::forward<_Fn&&>(__f));
556 __t->_M_parent = _M_parent;
557 _M_parent = nullptr;
558 return __t;
559 }
560
561 template <typename _Fn>
562 __task*
563 make_child_of(__task* __parent, _Fn&& __f)
564 {
565 auto __t = allocate_func_task(std::forward<_Fn&&>(__f));
566 __t->_M_parent = __parent;
567 return __t;
568 }
569
570 template <typename _Fn>
571 __task*
572 make_additional_child_of(__task* __parent, _Fn&& __f)
573 {
574 auto __t = make_child_of(__parent, std::forward<_Fn>(__f));
575 _LIBCPP_ASSERT_UNCATEGORIZED(__parent->_M_refcount.load(std::memory_order_relaxed) > 0, "");
576 ++__parent->_M_refcount;
577 return __t;
578 }
579
580 inline void
581 recycle_as_continuation()
582 {
583 _M_recycle = true;
584 }
585
586 inline void
587 recycle_as_child_of(__task* parent)
588 {
589 _M_recycle = true;
590 _M_parent = parent;
591 }
592
593 inline void
594 spawn(__task* __t)
595 {
596 _LIBCPP_ASSERT_UNCATEGORIZED(_M_execute_data != nullptr, "");
597 tbb::detail::d1::spawn(*__t, *_M_execute_data->context);
598 }
599
600 template <typename _Fn>
601 static inline void
602 spawn_root_and_wait(__root_task<_Fn>& __root)
603 {
604 tbb::detail::d1::execute_and_wait(*__root._M_func_task, __root._M_context, __root._M_wait_object,
605 __root._M_context);
606 }
607
608 template <typename _Func>
609 friend class __func_task;
610};
611
612template <typename _Func>
613class __func_task : public __task
614{
615 _Func _M_func;
616
617 __task*
618 execute(tbb::detail::d1::execution_data& __ed) override
619 {
620 _M_execute_data = &__ed;
621 _M_recycle = false;
622 __task* __next = _M_func(this);
623 return finalize(__next);
624 };
625
626 __task*
627 cancel(tbb::detail::d1::execution_data& __ed) override
628 {
629 return finalize(nullptr);
630 }
631
632 __task*
633 finalize(__task* __next)
634 {
635 bool __recycle = _M_recycle;
636 _M_recycle = false;
637
638 if (__recycle)
639 {
640 return __next;
641 }
642
643 auto __parent = _M_parent;
644 auto __alloc = _M_allocator;
645 auto __ed = _M_execute_data;
646
647 this->~__func_task();
648
649 _LIBCPP_ASSERT_UNCATEGORIZED(__parent != nullptr, "");
650 _LIBCPP_ASSERT_UNCATEGORIZED(__parent->_M_refcount.load(std::memory_order_relaxed) > 0, "");
651 if (--__parent->_M_refcount == 0)
652 {
653 _LIBCPP_ASSERT_UNCATEGORIZED(__next == nullptr, "");
654 __alloc.deallocate(this, *__ed);
655 return __parent;
656 }
657
658 return __next;
659 }
660
661 friend class __root_task<_Func>;
662
663 public:
664 template <typename _Fn>
665 __func_task(_Fn&& __f) : _M_func(std::forward<_Fn>(__f))
666 {
667 }
668
669 _Func&
670 body()
671 {
672 return _M_func;
673 }
674};
675
676template <typename _Func>
677class __root_task : public __task
678{
679 __task*
680 execute(tbb::detail::d1::execution_data& __ed) override
681 {
682 _M_wait_object.release();
683 return nullptr;
684 };
685
686 __task*
687 cancel(tbb::detail::d1::execution_data& __ed) override
688 {
689 _M_wait_object.release();
690 return nullptr;
691 }
692
693 __func_task<_Func>* _M_func_task{};
694 tbb::detail::d1::wait_context _M_wait_object{0};
695 tbb::task_group_context _M_context{};
696
697 public:
698 template <typename... Args>
699 __root_task(Args&&... args) : _M_wait_object{1}
700 {
701 tbb::detail::d1::small_object_allocator __alloc{};
702 _M_func_task = __alloc.new_object<__func_task<_Func>>(_Func(std::forward<Args>(args)...));
703 _M_func_task->_M_allocator = __alloc;
704 _M_func_task->_M_parent = this;
705 _M_refcount.store(1, std::memory_order_relaxed);
706 }
707
708 friend class __task;
709};
710#endif // TBB_INTERFACE_VERSION <= 12000
711
712template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _Compare, typename _Cleanup,
713 typename _LeafMerge>
714class __merge_func
715{
716 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1;
717 typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2;
718 typedef typename std::common_type<_DifferenceType1, _DifferenceType2>::type _SizeType;
719 typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type _ValueType;
720
721 _RandomAccessIterator1 _M_x_beg;
722 _RandomAccessIterator2 _M_z_beg;
723
724 _SizeType _M_xs, _M_xe;
725 _SizeType _M_ys, _M_ye;
726 _SizeType _M_zs;
727 _Compare _M_comp;
728 _LeafMerge _M_leaf_merge;
729 _SizeType _M_nsort; //number of elements to be sorted for partial_sort alforithm
730
731 static const _SizeType __merge_cut_off = _PSTL_MERGE_CUT_OFF;
732
733 bool _root; //means a task is merging root task
734 bool _x_orig; //"true" means X(or left ) subrange is in the original container; false - in the buffer
735 bool _y_orig; //"true" means Y(or right) subrange is in the original container; false - in the buffer
736 bool _split; //"true" means a merge task is a split task for parallel merging, the execution logic differs
737
738 bool
739 is_partial() const
740 {
741 return _M_nsort > 0;
742 }
743
744 struct __move_value
745 {
746 template <typename Iterator1, typename Iterator2>
747 void
748 operator()(Iterator1 __x, Iterator2 __z)
749 {
750 *__z = std::move(*__x);
751 }
752 };
753
754 struct __move_value_construct
755 {
756 template <typename Iterator1, typename Iterator2>
757 void
758 operator()(Iterator1 __x, Iterator2 __z)
759 {
760 ::new (std::addressof(*__z)) _ValueType(std::move(*__x));
761 }
762 };
763
764 struct __move_range
765 {
766 template <typename Iterator1, typename Iterator2>
767 Iterator2
768 operator()(Iterator1 __first1, Iterator1 __last1, Iterator2 __first2)
769 {
770 if (__last1 - __first1 < __merge_cut_off)
771 return std::move(__first1, __last1, __first2);
772
773 auto __n = __last1 - __first1;
774 tbb::parallel_for(tbb::blocked_range<_SizeType>(0, __n, __merge_cut_off),
775 [__first1, __first2](const tbb::blocked_range<_SizeType>& __range) {
776 std::move(__first1 + __range.begin(), __first1 + __range.end(),
777 __first2 + __range.begin());
778 });
779 return __first2 + __n;
780 }
781 };
782
783 struct __move_range_construct
784 {
785 template <typename Iterator1, typename Iterator2>
786 Iterator2
787 operator()(Iterator1 __first1, Iterator1 __last1, Iterator2 __first2)
788 {
789 if (__last1 - __first1 < __merge_cut_off)
790 {
791 for (; __first1 != __last1; ++__first1, ++__first2)
792 __move_value_construct()(__first1, __first2);
793 return __first2;
794 }
795
796 auto __n = __last1 - __first1;
797 tbb::parallel_for(tbb::blocked_range<_SizeType>(0, __n, __merge_cut_off),
798 [__first1, __first2](const tbb::blocked_range<_SizeType>& __range) {
799 for (auto i = __range.begin(); i != __range.end(); ++i)
800 __move_value_construct()(__first1 + i, __first2 + i);
801 });
802 return __first2 + __n;
803 }
804 };
805
806 struct __cleanup_range
807 {
808 template <typename Iterator>
809 void
810 operator()(Iterator __first, Iterator __last)
811 {
812 if (__last - __first < __merge_cut_off)
813 _Cleanup()(__first, __last);
814 else
815 {
816 auto __n = __last - __first;
817 tbb::parallel_for(tbb::blocked_range<_SizeType>(0, __n, __merge_cut_off),
818 [__first](const tbb::blocked_range<_SizeType>& __range) {
819 _Cleanup()(__first + __range.begin(), __first + __range.end());
820 });
821 }
822 }
823 };
824
825 public:
826 __merge_func(_SizeType __xs, _SizeType __xe, _SizeType __ys, _SizeType __ye, _SizeType __zs, _Compare __comp,
827 _Cleanup, _LeafMerge __leaf_merge, _SizeType __nsort, _RandomAccessIterator1 __x_beg,
828 _RandomAccessIterator2 __z_beg, bool __x_orig, bool __y_orig, bool __root)
829 : _M_xs(__xs), _M_xe(__xe), _M_ys(__ys), _M_ye(__ye), _M_zs(__zs), _M_x_beg(__x_beg), _M_z_beg(__z_beg),
830 _M_comp(__comp), _M_leaf_merge(__leaf_merge), _M_nsort(__nsort), _root(__root),
831 _x_orig(__x_orig), _y_orig(__y_orig), _split(false)
832 {
833 }
834
835 bool
836 is_left(_SizeType __idx) const
837 {
838 return _M_xs == __idx;
839 }
840
841 template <typename IndexType>
842 void
843 set_odd(IndexType __idx, bool __on_off)
844 {
845 if (is_left(__idx))
846 _x_orig = __on_off;
847 else
848 _y_orig = __on_off;
849 }
850
851 __task*
852 operator()(__task* __self);
853
854 private:
855 __merge_func*
856 parent_merge(__task* __self) const
857 {
858 return _root ? nullptr : &static_cast<__func_task<__merge_func>*>(__self->parent())->body();
859 }
860 bool
861 x_less_y()
862 {
863 const auto __nx = (_M_xe - _M_xs);
864 const auto __ny = (_M_ye - _M_ys);
865 _LIBCPP_ASSERT_UNCATEGORIZED(__nx > 0 && __ny > 0, "");
866
867 _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, "");
868 _LIBCPP_ASSERT_UNCATEGORIZED(!is_partial(), "");
869
870 if (_x_orig)
871 {
872 _LIBCPP_ASSERT_UNCATEGORIZED(std::is_sorted(_M_x_beg + _M_xs, _M_x_beg + _M_xe, _M_comp), "");
873 _LIBCPP_ASSERT_UNCATEGORIZED(std::is_sorted(_M_x_beg + _M_ys, _M_x_beg + _M_ye, _M_comp), "");
874 return !_M_comp(*(_M_x_beg + _M_ys), *(_M_x_beg + _M_xe - 1));
875 }
876
877 _LIBCPP_ASSERT_UNCATEGORIZED(std::is_sorted(_M_z_beg + _M_xs, _M_z_beg + _M_xe, _M_comp), "");
878 _LIBCPP_ASSERT_UNCATEGORIZED(std::is_sorted(_M_z_beg + _M_ys, _M_z_beg + _M_ye, _M_comp), "");
879 return !_M_comp(*(_M_z_beg + _M_zs + __nx), *(_M_z_beg + _M_zs + __nx - 1));
880 }
881 void
882 move_x_range()
883 {
884 const auto __nx = (_M_xe - _M_xs);
885 const auto __ny = (_M_ye - _M_ys);
886 _LIBCPP_ASSERT_UNCATEGORIZED(__nx > 0 && __ny > 0, "");
887
888 if (_x_orig)
889 __move_range_construct()(_M_x_beg + _M_xs, _M_x_beg + _M_xe, _M_z_beg + _M_zs);
890 else
891 {
892 __move_range()(_M_z_beg + _M_zs, _M_z_beg + _M_zs + __nx, _M_x_beg + _M_xs);
893 __cleanup_range()(_M_z_beg + _M_zs, _M_z_beg + _M_zs + __nx);
894 }
895
896 _x_orig = !_x_orig;
897 }
898 void
899 move_y_range()
900 {
901 const auto __nx = (_M_xe - _M_xs);
902 const auto __ny = (_M_ye - _M_ys);
903
904 if (_y_orig)
905 __move_range_construct()(_M_x_beg + _M_ys, _M_x_beg + _M_ye, _M_z_beg + _M_zs + __nx);
906 else
907 {
908 __move_range()(_M_z_beg + _M_zs + __nx, _M_z_beg + _M_zs + __nx + __ny, _M_x_beg + _M_ys);
909 __cleanup_range()(_M_z_beg + _M_zs + __nx, _M_z_beg + _M_zs + __nx + __ny);
910 }
911
912 _y_orig = !_y_orig;
913 }
914 __task*
915 merge_ranges(__task* __self)
916 {
917 _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, ""); // two merged subrange must be lie into the same buffer
918
919 const auto __nx = (_M_xe - _M_xs);
920 const auto __ny = (_M_ye - _M_ys);
921 const auto __n = __nx + __ny;
922
923 // need to merge {x} and {y}
924 if (__n > __merge_cut_off)
925 return split_merging(__self);
926
927 //merge to buffer
928 if (_x_orig)
929 {
930 _M_leaf_merge(_M_x_beg + _M_xs, _M_x_beg + _M_xe, _M_x_beg + _M_ys, _M_x_beg + _M_ye, _M_z_beg + _M_zs,
931 _M_comp, __move_value_construct(), __move_value_construct(), __move_range_construct(),
932 __move_range_construct());
933 _LIBCPP_ASSERT_UNCATEGORIZED(parent_merge(__self), ""); //not root merging task
934 }
935 //merge to "origin"
936 else
937 {
938 _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, "");
939
940 _LIBCPP_ASSERT_UNCATEGORIZED(
941 is_partial() || std::is_sorted(_M_z_beg + _M_xs, _M_z_beg + _M_xe, _M_comp), "");
942 _LIBCPP_ASSERT_UNCATEGORIZED(
943 is_partial() || std::is_sorted(_M_z_beg + _M_ys, _M_z_beg + _M_ye, _M_comp), "");
944
945 const auto __nx = (_M_xe - _M_xs);
946 const auto __ny = (_M_ye - _M_ys);
947
948 _M_leaf_merge(_M_z_beg + _M_xs, _M_z_beg + _M_xe, _M_z_beg + _M_ys, _M_z_beg + _M_ye, _M_x_beg + _M_zs,
949 _M_comp, __move_value(), __move_value(), __move_range(), __move_range());
950
951 __cleanup_range()(_M_z_beg + _M_xs, _M_z_beg + _M_xe);
952 __cleanup_range()(_M_z_beg + _M_ys, _M_z_beg + _M_ye);
953 }
954 return nullptr;
955 }
956
957 __task*
958 process_ranges(__task* __self)
959 {
960 _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, "");
961 _LIBCPP_ASSERT_UNCATEGORIZED(!_split, "");
962
963 auto p = parent_merge(__self);
964
965 if (!p)
966 { //root merging task
967
968 //optimization, just for sort algorithm, //{x} <= {y}
969 if (!is_partial() && x_less_y()) //we have a solution
970 {
971 if (!_x_orig)
972 { //we have to move the solution to the origin
973 move_x_range(); //parallel moving
974 move_y_range(); //parallel moving
975 }
976 return nullptr;
977 }
978 //else: if we have data in the origin,
979 //we have to move data to the buffer for final merging into the origin.
980 if (_x_orig)
981 {
982 move_x_range(); //parallel moving
983 move_y_range(); //parallel moving
984 }
985 // need to merge {x} and {y}.
986 return merge_ranges(__self);
987 }
988 //else: not root merging task (parent_merge() == NULL)
989 //optimization, just for sort algorithm, //{x} <= {y}
990 if (!is_partial() && x_less_y())
991 {
992 const auto id_range = _M_zs;
993 p->set_odd(id_range, _x_orig);
994 return nullptr;
995 }
996 //else: we have to revert "_x(y)_orig" flag of the parent merging task
997 const auto id_range = _M_zs;
998 p->set_odd(id_range, !_x_orig);
999
1000 return merge_ranges(__self);
1001 }
1002
1003 //splitting as merge task into 2 of the same level
1004 __task*
1005 split_merging(__task* __self)
1006 {
1007 _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, "");
1008 const auto __nx = (_M_xe - _M_xs);
1009 const auto __ny = (_M_ye - _M_ys);
1010
1011 _SizeType __xm{};
1012 _SizeType __ym{};
1013 if (__nx < __ny)
1014 {
1015 __ym = _M_ys + __ny / 2;
1016
1017 if (_x_orig)
1018 __xm = std::upper_bound(_M_x_beg + _M_xs, _M_x_beg + _M_xe, *(_M_x_beg + __ym), _M_comp) - _M_x_beg;
1019 else
1020 __xm = std::upper_bound(_M_z_beg + _M_xs, _M_z_beg + _M_xe, *(_M_z_beg + __ym), _M_comp) - _M_z_beg;
1021 }
1022 else
1023 {
1024 __xm = _M_xs + __nx / 2;
1025
1026 if (_y_orig)
1027 __ym = std::lower_bound(_M_x_beg + _M_ys, _M_x_beg + _M_ye, *(_M_x_beg + __xm), _M_comp) - _M_x_beg;
1028 else
1029 __ym = std::lower_bound(_M_z_beg + _M_ys, _M_z_beg + _M_ye, *(_M_z_beg + __xm), _M_comp) - _M_z_beg;
1030 }
1031
1032 auto __zm = _M_zs + ((__xm - _M_xs) + (__ym - _M_ys));
1033 __merge_func __right_func(__xm, _M_xe, __ym, _M_ye, __zm, _M_comp, _Cleanup(), _M_leaf_merge, _M_nsort,
1034 _M_x_beg, _M_z_beg, _x_orig, _y_orig, _root);
1035 __right_func._split = true;
1036 auto __merge_task = __self->make_additional_child_of(__self->parent(), std::move(__right_func));
1037 __self->spawn(__merge_task);
1038 __self->recycle_as_continuation();
1039
1040 _M_xe = __xm;
1041 _M_ye = __ym;
1042 _split = true;
1043
1044 return __self;
1045 }
1046};
1047
1048template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename __M_Compare, typename _Cleanup,
1049 typename _LeafMerge>
1050__task*
1051__merge_func<_RandomAccessIterator1, _RandomAccessIterator2, __M_Compare, _Cleanup, _LeafMerge>::
1052operator()(__task* __self)
1053{
1054 //a. split merge task into 2 of the same level; the special logic,
1055 //without processing(process_ranges) adjacent sub-ranges x and y
1056 if (_split)
1057 return merge_ranges(__self);
1058
1059 //b. General merging of adjacent sub-ranges x and y (with optimization in case of {x} <= {y} )
1060
1061 //1. x and y are in the even buffer
1062 //2. x and y are in the odd buffer
1063 if (_x_orig == _y_orig)
1064 return process_ranges(__self);
1065
1066 //3. x is in even buffer, y is in the odd buffer
1067 //4. x is in odd buffer, y is in the even buffer
1068 if (!parent_merge(__self))
1069 { //root merge task
1070 if (_x_orig)
1071 move_x_range();
1072 else
1073 move_y_range();
1074 }
1075 else
1076 {
1077 const _SizeType __nx = (_M_xe - _M_xs);
1078 const _SizeType __ny = (_M_ye - _M_ys);
1079 _LIBCPP_ASSERT_UNCATEGORIZED(__nx > 0, "");
1080 _LIBCPP_ASSERT_UNCATEGORIZED(__nx > 0, "");
1081
1082 if (__nx < __ny)
1083 move_x_range();
1084 else
1085 move_y_range();
1086 }
1087
1088 return process_ranges(__self);
1089}
1090
1091template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _Compare, typename _LeafSort>
1092class __stable_sort_func
1093{
1094 public:
1095 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1;
1096 typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2;
1097 typedef typename std::common_type<_DifferenceType1, _DifferenceType2>::type _SizeType;
1098
1099 private:
1100 _RandomAccessIterator1 _M_xs, _M_xe, _M_x_beg;
1101 _RandomAccessIterator2 _M_zs, _M_z_beg;
1102 _Compare _M_comp;
1103 _LeafSort _M_leaf_sort;
1104 bool _M_root;
1105 _SizeType _M_nsort; //zero or number of elements to be sorted for partial_sort alforithm
1106
1107 public:
1108 __stable_sort_func(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __zs,
1109 bool __root, _Compare __comp, _LeafSort __leaf_sort, _SizeType __nsort,
1110 _RandomAccessIterator1 __x_beg, _RandomAccessIterator2 __z_beg)
1111 : _M_xs(__xs), _M_xe(__xe), _M_x_beg(__x_beg), _M_zs(__zs), _M_z_beg(__z_beg), _M_comp(__comp),
1112 _M_leaf_sort(__leaf_sort), _M_root(__root), _M_nsort(__nsort)
1113 {
1114 }
1115
1116 __task*
1117 operator()(__task* __self);
1118};
1119
1120#define _PSTL_STABLE_SORT_CUT_OFF 500
1121
1122template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _Compare, typename _LeafSort>
1123__task*
1124__stable_sort_func<_RandomAccessIterator1, _RandomAccessIterator2, _Compare, _LeafSort>::operator()(__task* __self)
1125{
1126 typedef __merge_func<_RandomAccessIterator1, _RandomAccessIterator2, _Compare, __utils::__serial_destroy,
1127 __utils::__serial_move_merge>
1128 _MergeTaskType;
1129
1130 const _SizeType __n = _M_xe - _M_xs;
1131 const _SizeType __nmerge = _M_nsort > 0 ? _M_nsort : __n;
1132 const _SizeType __sort_cut_off = _PSTL_STABLE_SORT_CUT_OFF;
1133 if (__n <= __sort_cut_off)
1134 {
1135 _M_leaf_sort(_M_xs, _M_xe, _M_comp);
1136 _LIBCPP_ASSERT_UNCATEGORIZED(!_M_root, "");
1137 return nullptr;
1138 }
1139
1140 const _RandomAccessIterator1 __xm = _M_xs + __n / 2;
1141 const _RandomAccessIterator2 __zm = _M_zs + (__xm - _M_xs);
1142 const _RandomAccessIterator2 __ze = _M_zs + __n;
1143 _MergeTaskType __m(_MergeTaskType(_M_xs - _M_x_beg, __xm - _M_x_beg, __xm - _M_x_beg, _M_xe - _M_x_beg,
1144 _M_zs - _M_z_beg, _M_comp, __utils::__serial_destroy(),
1145 __utils::__serial_move_merge(__nmerge), _M_nsort, _M_x_beg, _M_z_beg,
1146 /*x_orig*/ true, /*y_orig*/ true, /*root*/ _M_root));
1147 auto __parent = __self->make_continuation(std::move(__m));
1148 __parent->set_ref_count(2);
1149 auto __right = __self->make_child_of(
1150 __parent, __stable_sort_func(__xm, _M_xe, __zm, false, _M_comp, _M_leaf_sort, _M_nsort, _M_x_beg, _M_z_beg));
1151 __self->spawn(__right);
1152 __self->recycle_as_child_of(__parent);
1153 _M_root = false;
1154 _M_xe = __xm;
1155
1156 return __self;
1157}
1158
1159template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
1160void
1161__parallel_stable_sort(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __xs,
1162 _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort, std::size_t __nsort = 0)
1163{
1164 tbb::this_task_arena::isolate([=, &__nsort]() {
1165 //sorting based on task tree and parallel merge
1166 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _ValueType;
1167 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
1168 const _DifferenceType __n = __xe - __xs;
1169 if (__nsort == __n)
1170 __nsort = 0; // 'partial_sort' becames 'sort'
1171
1172 const _DifferenceType __sort_cut_off = _PSTL_STABLE_SORT_CUT_OFF;
1173 if (__n > __sort_cut_off)
1174 {
1175 __buffer<_ValueType> __buf(__n);
1176 __root_task<__stable_sort_func<_RandomAccessIterator, _ValueType*, _Compare, _LeafSort>> __root{
1177 __xs, __xe, __buf.get(), true, __comp, __leaf_sort, __nsort, __xs, __buf.get()};
1178 __task::spawn_root_and_wait(__root);
1179 return;
1180 }
1181 //serial sort
1182 __leaf_sort(__xs, __xe, __comp);
1183 });
1184}
1185
1186//------------------------------------------------------------------------
1187// parallel_merge
1188//------------------------------------------------------------------------
1189template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _RandomAccessIterator3,
1190 typename _Compare, typename _LeafMerge>
1191class __merge_func_static
1192{
1193 _RandomAccessIterator1 _M_xs, _M_xe;
1194 _RandomAccessIterator2 _M_ys, _M_ye;
1195 _RandomAccessIterator3 _M_zs;
1196 _Compare _M_comp;
1197 _LeafMerge _M_leaf_merge;
1198
1199 public:
1200 __merge_func_static(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys,
1201 _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp,
1202 _LeafMerge __leaf_merge)
1203 : _M_xs(__xs), _M_xe(__xe), _M_ys(__ys), _M_ye(__ye), _M_zs(__zs), _M_comp(__comp), _M_leaf_merge(__leaf_merge)
1204 {
1205 }
1206
1207 __task*
1208 operator()(__task* __self);
1209};
1210
1211//TODO: consider usage of parallel_for with a custom blocked_range
1212template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _RandomAccessIterator3,
1213 typename __M_Compare, typename _LeafMerge>
1214__task*
1215__merge_func_static<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3, __M_Compare, _LeafMerge>::
1216operator()(__task* __self)
1217{
1218 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1;
1219 typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2;
1220 typedef typename std::common_type<_DifferenceType1, _DifferenceType2>::type _SizeType;
1221 const _SizeType __n = (_M_xe - _M_xs) + (_M_ye - _M_ys);
1222 const _SizeType __merge_cut_off = _PSTL_MERGE_CUT_OFF;
1223 if (__n <= __merge_cut_off)
1224 {
1225 _M_leaf_merge(_M_xs, _M_xe, _M_ys, _M_ye, _M_zs, _M_comp);
1226 return nullptr;
1227 }
1228
1229 _RandomAccessIterator1 __xm;
1230 _RandomAccessIterator2 __ym;
1231 if (_M_xe - _M_xs < _M_ye - _M_ys)
1232 {
1233 __ym = _M_ys + (_M_ye - _M_ys) / 2;
1234 __xm = std::upper_bound(_M_xs, _M_xe, *__ym, _M_comp);
1235 }
1236 else
1237 {
1238 __xm = _M_xs + (_M_xe - _M_xs) / 2;
1239 __ym = std::lower_bound(_M_ys, _M_ye, *__xm, _M_comp);
1240 }
1241 const _RandomAccessIterator3 __zm = _M_zs + ((__xm - _M_xs) + (__ym - _M_ys));
1242 auto __right = __self->make_additional_child_of(
1243 __self->parent(), __merge_func_static(__xm, _M_xe, __ym, _M_ye, __zm, _M_comp, _M_leaf_merge));
1244 __self->spawn(__right);
1245 __self->recycle_as_continuation();
1246 _M_xe = __xm;
1247 _M_ye = __ym;
1248
1249 return __self;
1250}
1251
1252template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2,
1253 typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
1254void
1255__parallel_merge(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator1 __xs,
1256 _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye,
1257 _RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge)
1258{
1259 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1;
1260 typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2;
1261 typedef typename std::common_type<_DifferenceType1, _DifferenceType2>::type _SizeType;
1262 const _SizeType __n = (__xe - __xs) + (__ye - __ys);
1263 const _SizeType __merge_cut_off = _PSTL_MERGE_CUT_OFF;
1264 if (__n <= __merge_cut_off)
1265 {
1266 // Fall back on serial merge
1267 __leaf_merge(__xs, __xe, __ys, __ye, __zs, __comp);
1268 }
1269 else
1270 {
1271 tbb::this_task_arena::isolate([=]() {
1272 typedef __merge_func_static<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3,
1273 _Compare, _LeafMerge>
1274 _TaskType;
1275 __root_task<_TaskType> __root{__xs, __xe, __ys, __ye, __zs, __comp, __leaf_merge};
1276 __task::spawn_root_and_wait(__root);
1277 });
1278 }
1279}
1280
1281//------------------------------------------------------------------------
1282// parallel_invoke
1283//------------------------------------------------------------------------
1284template <class _ExecutionPolicy, typename _F1, typename _F2>
1285void
1286__parallel_invoke(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
1287{
1288 //TODO: a version of tbb::this_task_arena::isolate with variadic arguments pack should be added in the future
1289 tbb::this_task_arena::isolate([&]() { tbb::parallel_invoke(std::forward<_F1>(__f1), std::forward<_F2>(__f2)); });
1290}
1291
1292} // namespace __tbb_backend
1293} // namespace __pstl
1294
1295#endif /* _PSTL_PARALLEL_BACKEND_TBB_H */
lib/libcxx/include/__pstl/internal/parallel_backend_utils.h created+260
......@@ -0,0 +1,260 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_PARALLEL_BACKEND_UTILS_H
11#define _PSTL_PARALLEL_BACKEND_UTILS_H
12
13#include <__assert>
14#include <__config>
15#include <__iterator/iterator_traits.h>
16#include <__memory/addressof.h>
17
18#include "utils.h"
19
20namespace __pstl
21{
22
23namespace __utils
24{
25
26//! Destroy sequence [xs,xe)
27struct __serial_destroy
28{
29 template <typename _RandomAccessIterator>
30 void
31 operator()(_RandomAccessIterator __zs, _RandomAccessIterator __ze)
32 {
33 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _ValueType;
34 while (__zs != __ze)
35 {
36 --__ze;
37 (*__ze).~_ValueType();
38 }
39 }
40};
41
42//! Merge sequences [__xs,__xe) and [__ys,__ye) to output sequence [__zs,(__xe-__xs)+(__ye-__ys)), using std::move
43struct __serial_move_merge
44{
45 const std::size_t _M_nmerge;
46
47 explicit __serial_move_merge(std::size_t __nmerge) : _M_nmerge(__nmerge) {}
48 template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare,
49 class _MoveValueX, class _MoveValueY, class _MoveSequenceX, class _MoveSequenceY>
50 void
51 operator()(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys,
52 _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp, _MoveValueX __move_value_x,
53 _MoveValueY __move_value_y, _MoveSequenceX __move_sequence_x, _MoveSequenceY __move_sequence_y)
54 {
55 constexpr bool __same_move_val = std::is_same<_MoveValueX, _MoveValueY>::value;
56 constexpr bool __same_move_seq = std::is_same<_MoveSequenceX, _MoveSequenceY>::value;
57
58 auto __n = _M_nmerge;
59 _LIBCPP_ASSERT_UNCATEGORIZED(__n > 0, "");
60
61 auto __nx = __xe - __xs;
62 //auto __ny = __ye - __ys;
63 _RandomAccessIterator3 __zs_beg = __zs;
64
65 if (__xs != __xe)
66 {
67 if (__ys != __ye)
68 {
69 for (;;)
70 {
71 if (__comp(*__ys, *__xs))
72 {
73 const auto __i = __zs - __zs_beg;
74 if (__i < __nx)
75 __move_value_x(__ys, __zs);
76 else
77 __move_value_y(__ys, __zs);
78 ++__zs, --__n;
79 if (++__ys == __ye)
80 {
81 break;
82 }
83 else if (__n == 0)
84 {
85 const auto __j = __zs - __zs_beg;
86 if (__same_move_seq || __j < __nx)
87 __zs = __move_sequence_x(__ys, __ye, __zs);
88 else
89 __zs = __move_sequence_y(__ys, __ye, __zs);
90 break;
91 }
92 }
93 else
94 {
95 const auto __i = __zs - __zs_beg;
96 if (__same_move_val || __i < __nx)
97 __move_value_x(__xs, __zs);
98 else
99 __move_value_y(__xs, __zs);
100 ++__zs, --__n;
101 if (++__xs == __xe)
102 {
103 const auto __j = __zs - __zs_beg;
104 if (__same_move_seq || __j < __nx)
105 __move_sequence_x(__ys, __ye, __zs);
106 else
107 __move_sequence_y(__ys, __ye, __zs);
108 return;
109 }
110 else if (__n == 0)
111 {
112 const auto __j = __zs - __zs_beg;
113 if (__same_move_seq || __j < __nx)
114 {
115 __zs = __move_sequence_x(__xs, __xe, __zs);
116 __move_sequence_x(__ys, __ye, __zs);
117 }
118 else
119 {
120 __zs = __move_sequence_y(__xs, __xe, __zs);
121 __move_sequence_y(__ys, __ye, __zs);
122 }
123 return;
124 }
125 }
126 }
127 }
128 __ys = __xs;
129 __ye = __xe;
130 }
131 const auto __i = __zs - __zs_beg;
132 if (__same_move_seq || __i < __nx)
133 __move_sequence_x(__ys, __ye, __zs);
134 else
135 __move_sequence_y(__ys, __ye, __zs);
136 }
137};
138
139template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
140 typename _CopyConstructRange>
141_OutputIterator
142__set_union_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
143 _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
144 _CopyConstructRange __cc_range)
145{
146 using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
147
148 for (; __first1 != __last1; ++__result)
149 {
150 if (__first2 == __last2)
151 return __cc_range(__first1, __last1, __result);
152 if (__comp(*__first2, *__first1))
153 {
154 ::new (std::addressof(*__result)) _Tp(*__first2);
155 ++__first2;
156 }
157 else
158 {
159 ::new (std::addressof(*__result)) _Tp(*__first1);
160 if (!__comp(*__first1, *__first2))
161 ++__first2;
162 ++__first1;
163 }
164 }
165 return __cc_range(__first2, __last2, __result);
166}
167
168template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare>
169_OutputIterator
170__set_intersection_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
171 _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp)
172{
173 using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
174
175 for (; __first1 != __last1 && __first2 != __last2;)
176 {
177 if (__comp(*__first1, *__first2))
178 ++__first1;
179 else
180 {
181 if (!__comp(*__first2, *__first1))
182 {
183 ::new (std::addressof(*__result)) _Tp(*__first1);
184 ++__result;
185 ++__first1;
186 }
187 ++__first2;
188 }
189 }
190 return __result;
191}
192
193template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
194 typename _CopyConstructRange>
195_OutputIterator
196__set_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
197 _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
198 _CopyConstructRange __cc_range)
199{
200 using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
201
202 for (; __first1 != __last1;)
203 {
204 if (__first2 == __last2)
205 return __cc_range(__first1, __last1, __result);
206
207 if (__comp(*__first1, *__first2))
208 {
209 ::new (std::addressof(*__result)) _Tp(*__first1);
210 ++__result;
211 ++__first1;
212 }
213 else
214 {
215 if (!__comp(*__first2, *__first1))
216 ++__first1;
217 ++__first2;
218 }
219 }
220 return __result;
221}
222template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
223 typename _CopyConstructRange>
224_OutputIterator
225__set_symmetric_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
226 _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
227 _CopyConstructRange __cc_range)
228{
229 using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
230
231 for (; __first1 != __last1;)
232 {
233 if (__first2 == __last2)
234 return __cc_range(__first1, __last1, __result);
235
236 if (__comp(*__first1, *__first2))
237 {
238 ::new (std::addressof(*__result)) _Tp(*__first1);
239 ++__result;
240 ++__first1;
241 }
242 else
243 {
244 if (__comp(*__first2, *__first1))
245 {
246 ::new (std::addressof(*__result)) _Tp(*__first2);
247 ++__result;
248 }
249 else
250 ++__first1;
251 ++__first2;
252 }
253 }
254 return __cc_range(__first2, __last2, __result);
255}
256
257} // namespace __utils
258} // namespace __pstl
259
260#endif /* _PSTL_PARALLEL_BACKEND_UTILS_H */
lib/libcxx/include/__pstl/internal/unseq_backend_simd.h created+697
......@@ -0,0 +1,697 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_UNSEQ_BACKEND_SIMD_H
11#define _PSTL_UNSEQ_BACKEND_SIMD_H
12
13#include <__config>
14#include <__functional/operations.h>
15#include <__iterator/iterator_traits.h>
16#include <__type_traits/is_arithmetic.h>
17#include <__type_traits/is_same.h>
18#include <__utility/move.h>
19#include <__utility/pair.h>
20#include <cstddef>
21#include <cstdint>
22
23#include <__pstl/internal/utils.h>
24
25// This header defines the minimum set of vector routines required
26// to support parallel STL.
27
28#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
29
30namespace __pstl
31{
32namespace __unseq_backend
33{
34
35// Expect vector width up to 64 (or 512 bit)
36const std::size_t __lane_size = 64;
37
38template <class _Iterator, class _DifferenceType, class _Function>
39_LIBCPP_HIDE_FROM_ABI _Iterator
40__simd_walk_1(_Iterator __first, _DifferenceType __n, _Function __f) noexcept
41{
42 _PSTL_PRAGMA_SIMD
43 for (_DifferenceType __i = 0; __i < __n; ++__i)
44 __f(__first[__i]);
45
46 return __first + __n;
47}
48
49template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Function>
50_LIBCPP_HIDE_FROM_ABI _Iterator2
51__simd_walk_2(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Function __f) noexcept
52{
53 _PSTL_PRAGMA_SIMD
54 for (_DifferenceType __i = 0; __i < __n; ++__i)
55 __f(__first1[__i], __first2[__i]);
56 return __first2 + __n;
57}
58
59template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Iterator3, class _Function>
60_LIBCPP_HIDE_FROM_ABI _Iterator3
61__simd_walk_3(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Iterator3 __first3,
62 _Function __f) noexcept
63{
64 _PSTL_PRAGMA_SIMD
65 for (_DifferenceType __i = 0; __i < __n; ++__i)
66 __f(__first1[__i], __first2[__i], __first3[__i]);
67 return __first3 + __n;
68}
69
70// TODO: check whether __simd_first() can be used here
71template <class _Index, class _DifferenceType, class _Pred>
72_LIBCPP_HIDE_FROM_ABI bool
73__simd_or(_Index __first, _DifferenceType __n, _Pred __pred) noexcept
74{
75 _DifferenceType __block_size = 4 < __n ? 4 : __n;
76 const _Index __last = __first + __n;
77 while (__last != __first)
78 {
79 int32_t __flag = 1;
80 _PSTL_PRAGMA_SIMD_REDUCTION(& : __flag)
81 for (_DifferenceType __i = 0; __i < __block_size; ++__i)
82 if (__pred(*(__first + __i)))
83 __flag = 0;
84 if (!__flag)
85 return true;
86
87 __first += __block_size;
88 if (__last - __first >= __block_size << 1)
89 {
90 // Double the block _Size. Any unnecessary iterations can be amortized against work done so far.
91 __block_size <<= 1;
92 }
93 else
94 {
95 __block_size = __last - __first;
96 }
97 }
98 return false;
99}
100
101template <class _Index1, class _DifferenceType, class _Index2, class _Pred>
102_LIBCPP_HIDE_FROM_ABI std::pair<_Index1, _Index2>
103__simd_first(_Index1 __first1, _DifferenceType __n, _Index2 __first2, _Pred __pred) noexcept
104{
105 const _Index1 __last1 = __first1 + __n;
106 const _Index2 __last2 = __first2 + __n;
107 // Experiments show good block sizes like this
108 const _DifferenceType __block_size = 8;
109 alignas(__lane_size) _DifferenceType __lane[__block_size] = {0};
110 while (__last1 - __first1 >= __block_size)
111 {
112 _DifferenceType __found = 0;
113 _DifferenceType __i;
114 _PSTL_PRAGMA_SIMD_REDUCTION(|
115 : __found) for (__i = 0; __i < __block_size; ++__i)
116 {
117 const _DifferenceType __t = __pred(__first1[__i], __first2[__i]);
118 __lane[__i] = __t;
119 __found |= __t;
120 }
121 if (__found)
122 {
123 _DifferenceType __i2;
124 // This will vectorize
125 for (__i2 = 0; __i2 < __block_size; ++__i2)
126 {
127 if (__lane[__i2])
128 break;
129 }
130 return std::make_pair(__first1 + __i2, __first2 + __i2);
131 }
132 __first1 += __block_size;
133 __first2 += __block_size;
134 }
135
136 //Keep remainder scalar
137 for (; __last1 != __first1; ++__first1, ++__first2)
138 if (__pred(*(__first1), *(__first2)))
139 return std::make_pair(__first1, __first2);
140
141 return std::make_pair(__last1, __last2);
142}
143
144template <class _Index, class _DifferenceType, class _Pred>
145_LIBCPP_HIDE_FROM_ABI _DifferenceType
146__simd_count(_Index __index, _DifferenceType __n, _Pred __pred) noexcept
147{
148 _DifferenceType __count = 0;
149 _PSTL_PRAGMA_SIMD_REDUCTION(+ : __count)
150 for (_DifferenceType __i = 0; __i < __n; ++__i)
151 if (__pred(*(__index + __i)))
152 ++__count;
153
154 return __count;
155}
156
157template <class _InputIterator, class _DifferenceType, class _OutputIterator, class _BinaryPredicate>
158_LIBCPP_HIDE_FROM_ABI _OutputIterator
159__simd_unique_copy(_InputIterator __first, _DifferenceType __n, _OutputIterator __result,
160 _BinaryPredicate __pred) noexcept
161{
162 if (__n == 0)
163 return __result;
164
165 _DifferenceType __cnt = 1;
166 __result[0] = __first[0];
167
168 _PSTL_PRAGMA_SIMD
169 for (_DifferenceType __i = 1; __i < __n; ++__i)
170 {
171 if (!__pred(__first[__i], __first[__i - 1]))
172 {
173 __result[__cnt] = __first[__i];
174 ++__cnt;
175 }
176 }
177 return __result + __cnt;
178}
179
180template <class _InputIterator, class _DifferenceType, class _OutputIterator, class _Assigner>
181_LIBCPP_HIDE_FROM_ABI _OutputIterator
182__simd_assign(_InputIterator __first, _DifferenceType __n, _OutputIterator __result, _Assigner __assigner) noexcept
183{
184 _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
185 _PSTL_PRAGMA_SIMD
186 for (_DifferenceType __i = 0; __i < __n; ++__i)
187 __assigner(__first + __i, __result + __i);
188 return __result + __n;
189}
190
191template <class _InputIterator, class _DifferenceType, class _OutputIterator, class _UnaryPredicate>
192_LIBCPP_HIDE_FROM_ABI _OutputIterator
193__simd_copy_if(_InputIterator __first, _DifferenceType __n, _OutputIterator __result, _UnaryPredicate __pred) noexcept
194{
195 _DifferenceType __cnt = 0;
196
197 _PSTL_PRAGMA_SIMD
198 for (_DifferenceType __i = 0; __i < __n; ++__i)
199 {
200 if (__pred(__first[__i]))
201 {
202 __result[__cnt] = __first[__i];
203 ++__cnt;
204 }
205 }
206 return __result + __cnt;
207}
208
209template <class _InputIterator, class _DifferenceType, class _BinaryPredicate>
210_LIBCPP_HIDE_FROM_ABI _DifferenceType
211__simd_calc_mask_2(_InputIterator __first, _DifferenceType __n, bool* __mask, _BinaryPredicate __pred) noexcept
212{
213 _DifferenceType __count = 0;
214
215 _PSTL_PRAGMA_SIMD_REDUCTION(+ : __count)
216 for (_DifferenceType __i = 0; __i < __n; ++__i)
217 {
218 __mask[__i] = !__pred(__first[__i], __first[__i - 1]);
219 __count += __mask[__i];
220 }
221 return __count;
222}
223
224template <class _InputIterator, class _DifferenceType, class _UnaryPredicate>
225_LIBCPP_HIDE_FROM_ABI _DifferenceType
226__simd_calc_mask_1(_InputIterator __first, _DifferenceType __n, bool* __mask, _UnaryPredicate __pred) noexcept
227{
228 _DifferenceType __count = 0;
229
230 _PSTL_PRAGMA_SIMD_REDUCTION(+ : __count)
231 for (_DifferenceType __i = 0; __i < __n; ++__i)
232 {
233 __mask[__i] = __pred(__first[__i]);
234 __count += __mask[__i];
235 }
236 return __count;
237}
238
239template <class _InputIterator, class _DifferenceType, class _OutputIterator, class _Assigner>
240_LIBCPP_HIDE_FROM_ABI void
241__simd_copy_by_mask(_InputIterator __first, _DifferenceType __n, _OutputIterator __result, bool* __mask,
242 _Assigner __assigner) noexcept
243{
244 _DifferenceType __cnt = 0;
245 _PSTL_PRAGMA_SIMD
246 for (_DifferenceType __i = 0; __i < __n; ++__i)
247 {
248 if (__mask[__i])
249 {
250 {
251 __assigner(__first + __i, __result + __cnt);
252 ++__cnt;
253 }
254 }
255 }
256}
257
258template <class _InputIterator, class _DifferenceType, class _OutputIterator1, class _OutputIterator2>
259_LIBCPP_HIDE_FROM_ABI void
260__simd_partition_by_mask(_InputIterator __first, _DifferenceType __n, _OutputIterator1 __out_true,
261 _OutputIterator2 __out_false, bool* __mask) noexcept
262{
263 _DifferenceType __cnt_true = 0, __cnt_false = 0;
264 _PSTL_PRAGMA_SIMD
265 for (_DifferenceType __i = 0; __i < __n; ++__i)
266 {
267 if (__mask[__i])
268 {
269 __out_true[__cnt_true] = __first[__i];
270 ++__cnt_true;
271 }
272 else
273 {
274 __out_false[__cnt_false] = __first[__i];
275 ++__cnt_false;
276 }
277 }
278}
279
280template <class _Index, class _DifferenceType, class _Generator>
281_LIBCPP_HIDE_FROM_ABI _Index
282__simd_generate_n(_Index __first, _DifferenceType __size, _Generator __g) noexcept
283{
284 _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
285 _PSTL_PRAGMA_SIMD
286 for (_DifferenceType __i = 0; __i < __size; ++__i)
287 __first[__i] = __g();
288 return __first + __size;
289}
290
291template <class _Index, class _BinaryPredicate>
292_LIBCPP_HIDE_FROM_ABI _Index
293__simd_adjacent_find(_Index __first, _Index __last, _BinaryPredicate __pred, bool __or_semantic) noexcept
294{
295 if (__last - __first < 2)
296 return __last;
297
298 typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType;
299 _DifferenceType __i = 0;
300
301 // Experiments show good block sizes like this
302 //TODO: to consider tuning block_size for various data types
303 const _DifferenceType __block_size = 8;
304 alignas(__lane_size) _DifferenceType __lane[__block_size] = {0};
305 while (__last - __first >= __block_size)
306 {
307 _DifferenceType __found = 0;
308 _PSTL_PRAGMA_SIMD_REDUCTION(|
309 : __found) for (__i = 0; __i < __block_size - 1; ++__i)
310 {
311 //TODO: to improve SIMD vectorization
312 const _DifferenceType __t = __pred(*(__first + __i), *(__first + __i + 1));
313 __lane[__i] = __t;
314 __found |= __t;
315 }
316
317 //Process a pair of elements on a boundary of a data block
318 if (__first + __block_size < __last && __pred(*(__first + __i), *(__first + __i + 1)))
319 __lane[__i] = __found = 1;
320
321 if (__found)
322 {
323 if (__or_semantic)
324 return __first;
325
326 // This will vectorize
327 for (__i = 0; __i < __block_size; ++__i)
328 if (__lane[__i])
329 break;
330 return __first + __i; //As far as found is true a __result (__lane[__i] is true) is guaranteed
331 }
332 __first += __block_size;
333 }
334 //Process the rest elements
335 for (; __last - __first > 1; ++__first)
336 if (__pred(*__first, *(__first + 1)))
337 return __first;
338
339 return __last;
340}
341
342// It was created to reduce the code inside std::enable_if
343template <typename _Tp, typename _BinaryOperation>
344using is_arithmetic_plus = std::integral_constant<bool, std::is_arithmetic<_Tp>::value &&
345 std::is_same<_BinaryOperation, std::plus<_Tp>>::value>;
346
347// Exclusive scan for "+" and arithmetic types
348template <class _InputIterator, class _Size, class _OutputIterator, class _UnaryOperation, class _Tp,
349 class _BinaryOperation>
350_LIBCPP_HIDE_FROM_ABI
351typename std::enable_if<is_arithmetic_plus<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
352__simd_scan(_InputIterator __first, _Size __n, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init,
353 _BinaryOperation, /*Inclusive*/ std::false_type)
354{
355 _PSTL_PRAGMA_SIMD_SCAN(+ : __init)
356 for (_Size __i = 0; __i < __n; ++__i)
357 {
358 __result[__i] = __init;
359 _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(__init)
360 __init += __unary_op(__first[__i]);
361 }
362 return std::make_pair(__result + __n, __init);
363}
364
365// As soon as we cannot call __binary_op in "combiner" we create a wrapper over _Tp to encapsulate __binary_op
366template <typename _Tp, typename _BinaryOp>
367struct _Combiner
368{
369 _Tp __value_;
370 _BinaryOp* __bin_op_; // Here is a pointer to function because of default ctor
371
372 _LIBCPP_HIDE_FROM_ABI _Combiner() : __value_{}, __bin_op_(nullptr) {}
373 _LIBCPP_HIDE_FROM_ABI
374 _Combiner(const _Tp& __value, const _BinaryOp* __bin_op)
375 : __value_(__value), __bin_op_(const_cast<_BinaryOp*>(__bin_op)) {}
376 _LIBCPP_HIDE_FROM_ABI _Combiner(const _Combiner& __obj) : __value_{}, __bin_op_(__obj.__bin_op) {}
377
378 _LIBCPP_HIDE_FROM_ABI void
379 operator()(const _Combiner& __obj)
380 {
381 __value_ = (*__bin_op_)(__value_, __obj.__value_);
382 }
383};
384
385// Exclusive scan for other binary operations and types
386template <class _InputIterator, class _Size, class _OutputIterator, class _UnaryOperation, class _Tp,
387 class _BinaryOperation>
388_LIBCPP_HIDE_FROM_ABI
389typename std::enable_if<!is_arithmetic_plus<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
390__simd_scan(_InputIterator __first, _Size __n, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init,
391 _BinaryOperation __binary_op, /*Inclusive*/ std::false_type)
392{
393 typedef _Combiner<_Tp, _BinaryOperation> _CombinerType;
394 _CombinerType __combined_init{__init, &__binary_op};
395
396 _PSTL_PRAGMA_DECLARE_REDUCTION(__bin_op, _CombinerType)
397 _PSTL_PRAGMA_SIMD_SCAN(__bin_op : __combined_init)
398 for (_Size __i = 0; __i < __n; ++__i)
399 {
400 __result[__i] = __combined_init.__value_;
401 _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(__combined_init)
402 __combined_init.__value_ = __binary_op(__combined_init.__value_, __unary_op(__first[__i]));
403 }
404 return std::make_pair(__result + __n, __combined_init.__value_);
405}
406
407// Inclusive scan for "+" and arithmetic types
408template <class _InputIterator, class _Size, class _OutputIterator, class _UnaryOperation, class _Tp,
409 class _BinaryOperation>
410_LIBCPP_HIDE_FROM_ABI
411typename std::enable_if<is_arithmetic_plus<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
412__simd_scan(_InputIterator __first, _Size __n, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init,
413 _BinaryOperation, /*Inclusive*/ std::true_type)
414{
415 _PSTL_PRAGMA_SIMD_SCAN(+ : __init)
416 for (_Size __i = 0; __i < __n; ++__i)
417 {
418 __init += __unary_op(__first[__i]);
419 _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(__init)
420 __result[__i] = __init;
421 }
422 return std::make_pair(__result + __n, __init);
423}
424
425// Inclusive scan for other binary operations and types
426template <class _InputIterator, class _Size, class _OutputIterator, class _UnaryOperation, class _Tp,
427 class _BinaryOperation>
428_LIBCPP_HIDE_FROM_ABI
429typename std::enable_if<!is_arithmetic_plus<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
430__simd_scan(_InputIterator __first, _Size __n, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init,
431 _BinaryOperation __binary_op, std::true_type)
432{
433 typedef _Combiner<_Tp, _BinaryOperation> _CombinerType;
434 _CombinerType __combined_init{__init, &__binary_op};
435
436 _PSTL_PRAGMA_DECLARE_REDUCTION(__bin_op, _CombinerType)
437 _PSTL_PRAGMA_SIMD_SCAN(__bin_op : __combined_init)
438 for (_Size __i = 0; __i < __n; ++__i)
439 {
440 __combined_init.__value_ = __binary_op(__combined_init.__value_, __unary_op(__first[__i]));
441 _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(__combined_init)
442 __result[__i] = __combined_init.__value_;
443 }
444 return std::make_pair(__result + __n, __combined_init.__value_);
445}
446
447// [restriction] - std::iterator_traits<_ForwardIterator>::value_type should be DefaultConstructible.
448// complexity [violation] - We will have at most (__n-1 + number_of_lanes) comparisons instead of at most __n-1.
449template <typename _ForwardIterator, typename _Size, typename _Compare>
450_LIBCPP_HIDE_FROM_ABI _ForwardIterator
451__simd_min_element(_ForwardIterator __first, _Size __n, _Compare __comp) noexcept
452{
453 if (__n == 0)
454 {
455 return __first;
456 }
457
458 typedef typename std::iterator_traits<_ForwardIterator>::value_type _ValueType;
459 struct _ComplexType
460 {
461 _ValueType __min_val_;
462 _Size __min_ind_;
463 _Compare* __min_comp_;
464
465 _LIBCPP_HIDE_FROM_ABI _ComplexType() : __min_val_{}, __min_ind_{}, __min_comp_(nullptr) {}
466 _LIBCPP_HIDE_FROM_ABI _ComplexType(const _ValueType& __val, const _Compare* __comp)
467 : __min_val_(__val), __min_ind_(0), __min_comp_(const_cast<_Compare*>(__comp))
468 {
469 }
470 _LIBCPP_HIDE_FROM_ABI _ComplexType(const _ComplexType& __obj)
471 : __min_val_(__obj.__min_val_), __min_ind_(__obj.__min_ind_), __min_comp_(__obj.__min_comp_)
472 {
473 }
474
475 _PSTL_PRAGMA_DECLARE_SIMD
476 _LIBCPP_HIDE_FROM_ABI void
477 operator()(const _ComplexType& __obj)
478 {
479 if (!(*__min_comp_)(__min_val_, __obj.__min_val_) &&
480 ((*__min_comp_)(__obj.__min_val_, __min_val_) || __obj.__min_ind_ - __min_ind_ < 0))
481 {
482 __min_val_ = __obj.__min_val_;
483 __min_ind_ = __obj.__min_ind_;
484 }
485 }
486 };
487
488 _ComplexType __init{*__first, &__comp};
489
490 _PSTL_PRAGMA_DECLARE_REDUCTION(__min_func, _ComplexType)
491
492 _PSTL_PRAGMA_SIMD_REDUCTION(__min_func : __init)
493 for (_Size __i = 1; __i < __n; ++__i)
494 {
495 const _ValueType __min_val = __init.__min_val_;
496 const _ValueType __current = __first[__i];
497 if (__comp(__current, __min_val))
498 {
499 __init.__min_val_ = __current;
500 __init.__min_ind_ = __i;
501 }
502 }
503 return __first + __init.__min_ind_;
504}
505
506// [restriction] - std::iterator_traits<_ForwardIterator>::value_type should be DefaultConstructible.
507// complexity [violation] - We will have at most (2*(__n-1) + 4*number_of_lanes) comparisons instead of at most [1.5*(__n-1)].
508template <typename _ForwardIterator, typename _Size, typename _Compare>
509_LIBCPP_HIDE_FROM_ABI std::pair<_ForwardIterator, _ForwardIterator>
510__simd_minmax_element(_ForwardIterator __first, _Size __n, _Compare __comp) noexcept
511{
512 if (__n == 0)
513 {
514 return std::make_pair(__first, __first);
515 }
516 typedef typename std::iterator_traits<_ForwardIterator>::value_type _ValueType;
517
518 struct _ComplexType
519 {
520 _ValueType __min_val_;
521 _ValueType __max_val_;
522 _Size __min_ind_;
523 _Size __max_ind_;
524 _Compare* __minmax_comp;
525
526 _LIBCPP_HIDE_FROM_ABI _ComplexType()
527 : __min_val_{}, __max_val_{}, __min_ind_{}, __max_ind_{}, __minmax_comp(nullptr) {}
528 _LIBCPP_HIDE_FROM_ABI _ComplexType(
529 const _ValueType& __min_val, const _ValueType& __max_val, const _Compare* __comp)
530 : __min_val_(__min_val), __max_val_(__max_val), __min_ind_(0), __max_ind_(0),
531 __minmax_comp(const_cast<_Compare*>(__comp))
532 {
533 }
534 _LIBCPP_HIDE_FROM_ABI _ComplexType(const _ComplexType& __obj)
535 : __min_val_(__obj.__min_val_), __max_val_(__obj.__max_val_), __min_ind_(__obj.__min_ind_),
536 __max_ind_(__obj.__max_ind_), __minmax_comp(__obj.__minmax_comp)
537 {
538 }
539
540 _LIBCPP_HIDE_FROM_ABI void
541 operator()(const _ComplexType& __obj)
542 {
543 // min
544 if ((*__minmax_comp)(__obj.__min_val_, __min_val_))
545 {
546 __min_val_ = __obj.__min_val_;
547 __min_ind_ = __obj.__min_ind_;
548 }
549 else if (!(*__minmax_comp)(__min_val_, __obj.__min_val_))
550 {
551 __min_val_ = __obj.__min_val_;
552 __min_ind_ = (__min_ind_ - __obj.__min_ind_ < 0) ? __min_ind_ : __obj.__min_ind_;
553 }
554
555 // max
556 if ((*__minmax_comp)(__max_val_, __obj.__max_val_))
557 {
558 __max_val_ = __obj.__max_val_;
559 __max_ind_ = __obj.__max_ind_;
560 }
561 else if (!(*__minmax_comp)(__obj.__max_val_, __max_val_))
562 {
563 __max_val_ = __obj.__max_val_;
564 __max_ind_ = (__max_ind_ - __obj.__max_ind_ < 0) ? __obj.__max_ind_ : __max_ind_;
565 }
566 }
567 };
568
569 _ComplexType __init{*__first, *__first, &__comp};
570
571 _PSTL_PRAGMA_DECLARE_REDUCTION(__min_func, _ComplexType);
572
573 _PSTL_PRAGMA_SIMD_REDUCTION(__min_func : __init)
574 for (_Size __i = 1; __i < __n; ++__i)
575 {
576 auto __min_val = __init.__min_val_;
577 auto __max_val = __init.__max_val_;
578 auto __current = __first + __i;
579 if (__comp(*__current, __min_val))
580 {
581 __init.__min_val_ = *__current;
582 __init.__min_ind_ = __i;
583 }
584 else if (!__comp(*__current, __max_val))
585 {
586 __init.__max_val_ = *__current;
587 __init.__max_ind_ = __i;
588 }
589 }
590 return std::make_pair(__first + __init.__min_ind_, __first + __init.__max_ind_);
591}
592
593template <class _InputIterator, class _DifferenceType, class _OutputIterator1, class _OutputIterator2,
594 class _UnaryPredicate>
595_LIBCPP_HIDE_FROM_ABI std::pair<_OutputIterator1, _OutputIterator2>
596__simd_partition_copy(_InputIterator __first, _DifferenceType __n, _OutputIterator1 __out_true,
597 _OutputIterator2 __out_false, _UnaryPredicate __pred) noexcept
598{
599 _DifferenceType __cnt_true = 0, __cnt_false = 0;
600
601 _PSTL_PRAGMA_SIMD
602 for (_DifferenceType __i = 0; __i < __n; ++__i)
603 {
604 if (__pred(__first[__i]))
605 {
606 __out_true[__cnt_true] = __first[__i];
607 ++__cnt_true;
608 }
609 else
610 {
611 __out_false[__cnt_false] = __first[__i];
612 ++__cnt_false;
613 }
614 }
615 return std::make_pair(__out_true + __cnt_true, __out_false + __cnt_false);
616}
617
618template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
619_LIBCPP_HIDE_FROM_ABI _ForwardIterator1
620__simd_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
621 _ForwardIterator2 __s_last, _BinaryPredicate __pred) noexcept
622{
623 typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferencType;
624
625 const _DifferencType __n1 = __last - __first;
626 const _DifferencType __n2 = __s_last - __s_first;
627 if (__n1 == 0 || __n2 == 0)
628 {
629 return __last; // according to the standard
630 }
631
632 // Common case
633 // If first sequence larger than second then we'll run simd_first with parameters of first sequence.
634 // Otherwise, vice versa.
635 if (__n1 < __n2)
636 {
637 for (; __first != __last; ++__first)
638 {
639 if (__unseq_backend::__simd_or(
640 __s_first, __n2,
641 __internal::__equal_value_by_pred<decltype(*__first), _BinaryPredicate>(*__first, __pred)))
642 {
643 return __first;
644 }
645 }
646 }
647 else
648 {
649 for (; __s_first != __s_last; ++__s_first)
650 {
651 const auto __result = __unseq_backend::__simd_first(
652 __first, _DifferencType(0), __n1, [__s_first, &__pred](_ForwardIterator1 __it, _DifferencType __i) {
653 return __pred(__it[__i], *__s_first);
654 });
655 if (__result != __last)
656 {
657 return __result;
658 }
659 }
660 }
661 return __last;
662}
663
664template <class _RandomAccessIterator, class _DifferenceType, class _UnaryPredicate>
665_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator
666__simd_remove_if(_RandomAccessIterator __first, _DifferenceType __n, _UnaryPredicate __pred) noexcept
667{
668 // find first element we need to remove
669 auto __current = __unseq_backend::__simd_first(
670 __first, _DifferenceType(0), __n,
671 [&__pred](_RandomAccessIterator __it, _DifferenceType __i) { return __pred(__it[__i]); });
672 __n -= __current - __first;
673
674 // if we have in sequence only one element that pred(__current[1]) != false we can exit the function
675 if (__n < 2)
676 {
677 return __current;
678 }
679
680 _DifferenceType __cnt = 0;
681 _PSTL_PRAGMA_SIMD
682 for (_DifferenceType __i = 1; __i < __n; ++__i)
683 {
684 if (!__pred(__current[__i]))
685 {
686 __current[__cnt] = std::move(__current[__i]);
687 ++__cnt;
688 }
689 }
690 return __current + __cnt;
691}
692} // namespace __unseq_backend
693} // namespace __pstl
694
695#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
696
697#endif /* _PSTL_UNSEQ_BACKEND_SIMD_H */
lib/libcxx/include/__pstl/internal/utils.h created+144
......@@ -0,0 +1,144 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _PSTL_UTILS_H
11#define _PSTL_UTILS_H
12
13#include <__config>
14#include <__exception/terminate.h>
15#include <__utility/forward.h>
16#include <new>
17
18#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
19
20namespace __pstl {
21namespace __internal {
22
23template <typename _Fp>
24_LIBCPP_HIDE_FROM_ABI auto __except_handler(_Fp __f) -> decltype(__f()) {
25#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
26 try {
27#endif // _LIBCPP_HAS_NO_EXCEPTIONS
28 return __f();
29#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
30 } catch (const std::bad_alloc&) {
31 throw; // re-throw bad_alloc according to the standard [algorithms.parallel.exceptions]
32 } catch (...) {
33 std::terminate(); // Good bye according to the standard [algorithms.parallel.exceptions]
34 }
35#endif // _LIBCPP_HAS_NO_EXCEPTIONS
36}
37
38template <typename _Fp>
39_LIBCPP_HIDE_FROM_ABI void __invoke_if(std::true_type, _Fp __f) {
40 __f();
41}
42
43template <typename _Fp>
44_LIBCPP_HIDE_FROM_ABI void __invoke_if(std::false_type, _Fp) {}
45
46template <typename _Fp>
47_LIBCPP_HIDE_FROM_ABI void __invoke_if_not(std::false_type, _Fp __f) {
48 __f();
49}
50
51template <typename _Fp>
52_LIBCPP_HIDE_FROM_ABI void __invoke_if_not(std::true_type, _Fp) {}
53
54template <typename _F1, typename _F2>
55_LIBCPP_HIDE_FROM_ABI auto __invoke_if_else(std::true_type, _F1 __f1, _F2) -> decltype(__f1()) {
56 return __f1();
57}
58
59template <typename _F1, typename _F2>
60_LIBCPP_HIDE_FROM_ABI auto __invoke_if_else(std::false_type, _F1, _F2 __f2) -> decltype(__f2()) {
61 return __f2();
62}
63
64//! Unary operator that returns reference to its argument.
65struct __no_op {
66 template <typename _Tp>
67 _LIBCPP_HIDE_FROM_ABI _Tp&& operator()(_Tp&& __a) const {
68 return std::forward<_Tp>(__a);
69 }
70};
71
72template <typename _Pred>
73class __reorder_pred {
74 _Pred __pred_;
75
76public:
77 _LIBCPP_HIDE_FROM_ABI explicit __reorder_pred(_Pred __pred) : __pred_(__pred) {}
78
79 template <typename _FTp, typename _STp>
80 _LIBCPP_HIDE_FROM_ABI bool operator()(_FTp&& __a, _STp&& __b) {
81 return __pred_(std::forward<_STp>(__b), std::forward<_FTp>(__a));
82 }
83};
84
85//! Like a polymorphic lambda for pred(...,value)
86template <typename _Tp, typename _Predicate>
87class __equal_value_by_pred {
88 const _Tp& __value_;
89 _Predicate __pred_;
90
91public:
92 _LIBCPP_HIDE_FROM_ABI __equal_value_by_pred(const _Tp& __value, _Predicate __pred)
93 : __value_(__value), __pred_(__pred) {}
94
95 template <typename _Arg>
96 _LIBCPP_HIDE_FROM_ABI bool operator()(_Arg&& __arg) {
97 return __pred_(std::forward<_Arg>(__arg), __value_);
98 }
99};
100
101//! Like a polymorphic lambda for ==value
102template <typename _Tp>
103class __equal_value {
104 const _Tp& __value_;
105
106public:
107 _LIBCPP_HIDE_FROM_ABI explicit __equal_value(const _Tp& __value) : __value_(__value) {}
108
109 template <typename _Arg>
110 _LIBCPP_HIDE_FROM_ABI bool operator()(_Arg&& __arg) const {
111 return std::forward<_Arg>(__arg) == __value_;
112 }
113};
114
115//! Logical negation of ==value
116template <typename _Tp>
117class __not_equal_value {
118 const _Tp& __value_;
119
120public:
121 _LIBCPP_HIDE_FROM_ABI explicit __not_equal_value(const _Tp& __value) : __value_(__value) {}
122
123 template <typename _Arg>
124 _LIBCPP_HIDE_FROM_ABI bool operator()(_Arg&& __arg) const {
125 return !(std::forward<_Arg>(__arg) == __value_);
126 }
127};
128
129template <typename _ForwardIterator, typename _Compare>
130_LIBCPP_HIDE_FROM_ABI _ForwardIterator
131__cmp_iterators_by_values(_ForwardIterator __a, _ForwardIterator __b, _Compare __comp) {
132 if (__a < __b) { // we should return closer iterator
133 return __comp(*__b, *__a) ? __b : __a;
134 } else {
135 return __comp(*__a, *__b) ? __a : __b;
136 }
137}
138
139} // namespace __internal
140} // namespace __pstl
141
142#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
143
144#endif /* _PSTL_UTILS_H */
lib/libcxx/include/__pstl_algorithm created+15
......@@ -0,0 +1,15 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef __PSTL_ALGORITHM
11#define __PSTL_ALGORITHM
12
13#include <pstl/internal/glue_algorithm_impl.h>
14
15#endif /* __PSTL_ALGORITHM */
lib/libcxx/include/__pstl_memory created+15
......@@ -0,0 +1,15 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef __PSTL_MEMORY
11#define __PSTL_MEMORY
12
13#include <pstl/internal/glue_memory_impl.h>
14
15#endif /* __PSTL_MEMORY */
lib/libcxx/include/__pstl_numeric created+15
......@@ -0,0 +1,15 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef __PSTL_NUMERIC
11#define __PSTL_NUMERIC
12
13#include <pstl/internal/glue_numeric_impl.h>
14
15#endif /* __PSTL_NUMERIC */
lib/libcxx/include/__random/binomial_distribution.h+3-2
......@@ -42,7 +42,7 @@ public:
4242 public:
4343 typedef binomial_distribution distribution_type;
4444
45 explicit param_type(result_type __t = 1, double __p = 0.5);
45 _LIBCPP_HIDE_FROM_ABI explicit param_type(result_type __t = 1, double __p = 0.5);
4646
4747 _LIBCPP_INLINE_VISIBILITY
4848 result_type t() const {return __t_;}
......@@ -85,7 +85,8 @@ public:
8585 _LIBCPP_INLINE_VISIBILITY
8686 result_type operator()(_URNG& __g)
8787 {return (*this)(__g, __p_);}
88 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
88 template<class _URNG>
89 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
8990
9091 // property functions
9192 _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/clamp_to_integral.h+2-3
......@@ -12,7 +12,6 @@
1212#include <__config>
1313#include <cmath>
1414#include <limits>
15#include <type_traits>
1615
1716#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1817# pragma GCC system_header
......@@ -44,8 +43,8 @@ template <class _IntT, class _RealT>
4443_LIBCPP_INLINE_VISIBILITY
4544_IntT __clamp_to_integral(_RealT __r) _NOEXCEPT {
4645 using _Lim = numeric_limits<_IntT>;
47 const _IntT _MaxVal = __max_representable_int_for_float<_IntT, _RealT>();
48 if (__r >= ::nextafter(static_cast<_RealT>(_MaxVal), INFINITY)) {
46 const _IntT __max_val = __max_representable_int_for_float<_IntT, _RealT>();
47 if (__r >= ::nextafter(static_cast<_RealT>(__max_val), INFINITY)) {
4948 return _Lim::max();
5049 } else if (__r <= _Lim::lowest()) {
5150 return _Lim::min();
lib/libcxx/include/__random/discard_block_engine.h+4-2
......@@ -11,10 +11,12 @@
1111
1212#include <__config>
1313#include <__random/is_seed_sequence.h>
14#include <__type_traits/enable_if.h>
15#include <__type_traits/is_convertible.h>
1416#include <__utility/move.h>
17#include <cstddef>
1518#include <iosfwd>
1619#include <limits>
17#include <type_traits>
1820
1921#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2022# pragma GCC system_header
......@@ -90,7 +92,7 @@ public:
9092 seed(_Sseq& __q) {__e_.seed(__q); __n_ = 0;}
9193
9294 // generating functions
93 result_type operator()();
95 _LIBCPP_HIDE_FROM_ABI result_type operator()();
9496 _LIBCPP_INLINE_VISIBILITY
9597 void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
9698
lib/libcxx/include/__random/discrete_distribution.h+5-4
......@@ -53,10 +53,10 @@ public:
5353 : __p_(__wl.begin(), __wl.end()) {__init();}
5454#endif // _LIBCPP_CXX03_LANG
5555 template<class _UnaryOperation>
56 param_type(size_t __nw, double __xmin, double __xmax,
56 _LIBCPP_HIDE_FROM_ABI param_type(size_t __nw, double __xmin, double __xmax,
5757 _UnaryOperation __fw);
5858
59 vector<double> probabilities() const;
59 _LIBCPP_HIDE_FROM_ABI vector<double> probabilities() const;
6060
6161 friend _LIBCPP_INLINE_VISIBILITY
6262 bool operator==(const param_type& __x, const param_type& __y)
......@@ -66,7 +66,7 @@ public:
6666 {return !(__x == __y);}
6767
6868 private:
69 void __init();
69 _LIBCPP_HIDE_FROM_ABI void __init();
7070
7171 friend class discrete_distribution;
7272
......@@ -115,7 +115,8 @@ public:
115115 _LIBCPP_INLINE_VISIBILITY
116116 result_type operator()(_URNG& __g)
117117 {return (*this)(__g, __p_);}
118 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
118 template<class _URNG>
119 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
119120
120121 // property functions
121122 _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/exponential_distribution.h+2-1
......@@ -79,7 +79,8 @@ public:
7979 _LIBCPP_INLINE_VISIBILITY
8080 result_type operator()(_URNG& __g)
8181 {return (*this)(__g, __p_);}
82 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
82 template<class _URNG>
83 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
8384
8485 // property functions
8586 _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/extreme_value_distribution.h+2-1
......@@ -84,7 +84,8 @@ public:
8484 _LIBCPP_INLINE_VISIBILITY
8585 result_type operator()(_URNG& __g)
8686 {return (*this)(__g, __p_);}
87 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
87 template<class _URNG>
88 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
8889
8990 // property functions
9091 _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/fisher_f_distribution.h+2-1
......@@ -82,7 +82,8 @@ public:
8282 _LIBCPP_INLINE_VISIBILITY
8383 result_type operator()(_URNG& __g)
8484 {return (*this)(__g, __p_);}
85 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
85 template<class _URNG>
86 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
8687
8788 // property functions
8889 _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/gamma_distribution.h+2-1
......@@ -85,7 +85,8 @@ public:
8585 _LIBCPP_INLINE_VISIBILITY
8686 result_type operator()(_URNG& __g)
8787 {return (*this)(__g, __p_);}
88 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
88 template<class _URNG>
89 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
8990
9091 // property functions
9192 _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/generate_canonical.h+11-11
......@@ -30,20 +30,20 @@ template<class _RealType, size_t __bits, class _URNG>
3030_LIBCPP_HIDE_FROM_ABI _RealType
3131generate_canonical(_URNG& __g)
3232{
33 const size_t _Dt = numeric_limits<_RealType>::digits;
34 const size_t __b = _Dt < __bits ? _Dt : __bits;
33 const size_t __dt = numeric_limits<_RealType>::digits;
34 const size_t __b = __dt < __bits ? __dt : __bits;
3535#ifdef _LIBCPP_CXX03_LANG
36 const size_t __logR = __log2<uint64_t, _URNG::_Max - _URNG::_Min + uint64_t(1)>::value;
36 const size_t __log_r = __log2<uint64_t, _URNG::_Max - _URNG::_Min + uint64_t(1)>::value;
3737#else
38 const size_t __logR = __log2<uint64_t, _URNG::max() - _URNG::min() + uint64_t(1)>::value;
38 const size_t __log_r = __log2<uint64_t, _URNG::max() - _URNG::min() + uint64_t(1)>::value;
3939#endif
40 const size_t __k = __b / __logR + (__b % __logR != 0) + (__b == 0);
41 const _RealType _Rp = static_cast<_RealType>(_URNG::max() - _URNG::min()) + _RealType(1);
42 _RealType __base = _Rp;
43 _RealType _Sp = __g() - _URNG::min();
44 for (size_t __i = 1; __i < __k; ++__i, __base *= _Rp)
45 _Sp += (__g() - _URNG::min()) * __base;
46 return _Sp / __base;
40 const size_t __k = __b / __log_r + (__b % __log_r != 0) + (__b == 0);
41 const _RealType __rp = static_cast<_RealType>(_URNG::max() - _URNG::min()) + _RealType(1);
42 _RealType __base = __rp;
43 _RealType __sp = __g() - _URNG::min();
44 for (size_t __i = 1; __i < __k; ++__i, __base *= __rp)
45 __sp += (__g() - _URNG::min()) * __base;
46 return __sp / __base;
4747}
4848
4949_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__random/independent_bits_engine.h+9-6
......@@ -12,10 +12,13 @@
1212#include <__config>
1313#include <__random/is_seed_sequence.h>
1414#include <__random/log2.h>
15#include <__type_traits/conditional.h>
16#include <__type_traits/enable_if.h>
17#include <__type_traits/is_convertible.h>
1518#include <__utility/move.h>
19#include <cstddef>
1620#include <iosfwd>
1721#include <limits>
18#include <type_traits>
1922
2023#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2124# pragma GCC system_header
......@@ -161,7 +164,7 @@ public:
161164private:
162165 _LIBCPP_INLINE_VISIBILITY
163166 result_type __eval(false_type);
164 result_type __eval(true_type);
167 _LIBCPP_HIDE_FROM_ABI result_type __eval(true_type);
165168
166169 template <size_t __count>
167170 _LIBCPP_INLINE_VISIBILITY
......@@ -196,7 +199,7 @@ template<class _Engine, size_t __w, class _UIntType>
196199_UIntType
197200independent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type)
198201{
199 result_type _Sp = 0;
202 result_type __sp = 0;
200203 for (size_t __k = 0; __k < __n0; ++__k)
201204 {
202205 _Engine_result_type __u;
......@@ -204,7 +207,7 @@ independent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type)
204207 {
205208 __u = __e_() - _Engine::min();
206209 } while (__u >= __y0);
207 _Sp = static_cast<result_type>(__lshift<__w0>(_Sp) + (__u & __mask0));
210 __sp = static_cast<result_type>(__lshift<__w0>(__sp) + (__u & __mask0));
208211 }
209212 for (size_t __k = __n0; __k < __n; ++__k)
210213 {
......@@ -213,9 +216,9 @@ independent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type)
213216 {
214217 __u = __e_() - _Engine::min();
215218 } while (__u >= __y1);
216 _Sp = static_cast<result_type>(__lshift<__w0+1>(_Sp) + (__u & __mask1));
219 __sp = static_cast<result_type>(__lshift<__w0+1>(__sp) + (__u & __mask1));
217220 }
218 return _Sp;
221 return __sp;
219222}
220223
221224template<class _Eng, size_t _Wp, class _UInt>
lib/libcxx/include/__random/is_seed_sequence.h+3-1
......@@ -10,7 +10,9 @@
1010#define _LIBCPP___RANDOM_IS_SEED_SEQUENCE_H
1111
1212#include <__config>
13#include <type_traits>
13#include <__type_traits/is_convertible.h>
14#include <__type_traits/is_same.h>
15#include <__type_traits/remove_cv.h>
1416
1517#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1618# pragma GCC system_header
lib/libcxx/include/__random/is_valid.h+5-1
......@@ -10,8 +10,12 @@
1010#define _LIBCPP___RANDOM_IS_VALID_H
1111
1212#include <__config>
13#include <__type_traits/enable_if.h>
14#include <__type_traits/integral_constant.h>
15#include <__type_traits/is_same.h>
16#include <__type_traits/is_unsigned.h>
17#include <__utility/declval.h>
1318#include <cstdint>
14#include <type_traits>
1519
1620#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1721# pragma GCC system_header
lib/libcxx/include/__random/linear_congruential_engine.h+5-3
......@@ -11,9 +11,11 @@
1111
1212#include <__config>
1313#include <__random/is_seed_sequence.h>
14#include <__type_traits/enable_if.h>
15#include <__type_traits/integral_constant.h>
16#include <__type_traits/is_unsigned.h>
1417#include <cstdint>
1518#include <iosfwd>
16#include <type_traits>
1719
1820#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1921# pragma GCC system_header
......@@ -294,9 +296,9 @@ private:
294296 void seed(false_type, false_type, result_type __s) {__x_ = __s % __m;}
295297
296298 template<class _Sseq>
297 void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
299 _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
298300 template<class _Sseq>
299 void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
301 _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
300302
301303 template <class _CharT, class _Traits,
302304 class _Up, _Up _Ap, _Up _Cp, _Up _Np>
lib/libcxx/include/__random/log2.h+1-1
......@@ -10,8 +10,8 @@
1010#define _LIBCPP___RANDOM_LOG2_H
1111
1212#include <__config>
13#include <__type_traits/conditional.h>
1314#include <cstddef>
14#include <type_traits>
1515
1616#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1717# pragma GCC system_header
lib/libcxx/include/__random/lognormal_distribution.h-138
......@@ -24,142 +24,6 @@ _LIBCPP_PUSH_MACROS
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
27#ifdef _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION
28
29template<class _RealType = double>
30class _LIBCPP_TEMPLATE_VIS lognormal_distribution
31{
32public:
33 // types
34 typedef _RealType result_type;
35
36 class _LIBCPP_TEMPLATE_VIS param_type
37 {
38 normal_distribution<result_type> __nd_;
39 public:
40 typedef lognormal_distribution distribution_type;
41
42 _LIBCPP_INLINE_VISIBILITY
43 explicit param_type(result_type __m = 0, result_type __s = 1)
44 : __nd_(__m, __s) {}
45
46 _LIBCPP_INLINE_VISIBILITY
47 result_type m() const {return __nd_.mean();}
48 _LIBCPP_INLINE_VISIBILITY
49 result_type s() const {return __nd_.stddev();}
50
51 friend _LIBCPP_INLINE_VISIBILITY
52 bool operator==(const param_type& __x, const param_type& __y)
53 {return __x.__nd_ == __y.__nd_;}
54 friend _LIBCPP_INLINE_VISIBILITY
55 bool operator!=(const param_type& __x, const param_type& __y)
56 {return !(__x == __y);}
57 friend class lognormal_distribution;
58
59 template <class _CharT, class _Traits, class _RT>
60 friend
61 basic_ostream<_CharT, _Traits>&
62 operator<<(basic_ostream<_CharT, _Traits>& __os,
63 const lognormal_distribution<_RT>& __x);
64
65 template <class _CharT, class _Traits, class _RT>
66 friend
67 basic_istream<_CharT, _Traits>&
68 operator>>(basic_istream<_CharT, _Traits>& __is,
69 lognormal_distribution<_RT>& __x);
70 };
71
72private:
73 param_type __p_;
74
75public:
76 // constructor and reset functions
77#ifndef _LIBCPP_CXX03_LANG
78 _LIBCPP_INLINE_VISIBILITY
79 lognormal_distribution() : lognormal_distribution(0) {}
80 _LIBCPP_INLINE_VISIBILITY
81 explicit lognormal_distribution(result_type __m, result_type __s = 1)
82 : __p_(param_type(__m, __s)) {}
83#else
84 _LIBCPP_INLINE_VISIBILITY
85 explicit lognormal_distribution(result_type __m = 0,
86 result_type __s = 1)
87 : __p_(param_type(__m, __s)) {}
88#endif
89 _LIBCPP_INLINE_VISIBILITY
90 explicit lognormal_distribution(const param_type& __p)
91 : __p_(__p) {}
92 _LIBCPP_INLINE_VISIBILITY
93 void reset() {__p_.__nd_.reset();}
94
95 // generating functions
96 template<class _URNG>
97 _LIBCPP_INLINE_VISIBILITY
98 result_type operator()(_URNG& __g)
99 {return (*this)(__g, __p_);}
100 template<class _URNG>
101 _LIBCPP_INLINE_VISIBILITY
102 result_type operator()(_URNG& __g, const param_type& __p)
103 {return _VSTD::exp(const_cast<normal_distribution<result_type>&>(__p.__nd_)(__g));}
104
105 // property functions
106 _LIBCPP_INLINE_VISIBILITY
107 result_type m() const {return __p_.m();}
108 _LIBCPP_INLINE_VISIBILITY
109 result_type s() const {return __p_.s();}
110
111 _LIBCPP_INLINE_VISIBILITY
112 param_type param() const {return __p_;}
113 _LIBCPP_INLINE_VISIBILITY
114 void param(const param_type& __p) {__p_ = __p;}
115
116 _LIBCPP_INLINE_VISIBILITY
117 result_type min() const {return 0;}
118 _LIBCPP_INLINE_VISIBILITY
119 result_type max() const {return numeric_limits<result_type>::infinity();}
120
121 friend _LIBCPP_INLINE_VISIBILITY
122 bool operator==(const lognormal_distribution& __x,
123 const lognormal_distribution& __y)
124 {return __x.__p_ == __y.__p_;}
125 friend _LIBCPP_INLINE_VISIBILITY
126 bool operator!=(const lognormal_distribution& __x,
127 const lognormal_distribution& __y)
128 {return !(__x == __y);}
129
130 template <class _CharT, class _Traits, class _RT>
131 friend
132 basic_ostream<_CharT, _Traits>&
133 operator<<(basic_ostream<_CharT, _Traits>& __os,
134 const lognormal_distribution<_RT>& __x);
135
136 template <class _CharT, class _Traits, class _RT>
137 friend
138 basic_istream<_CharT, _Traits>&
139 operator>>(basic_istream<_CharT, _Traits>& __is,
140 lognormal_distribution<_RT>& __x);
141};
142
143template <class _CharT, class _Traits, class _RT>
144inline _LIBCPP_INLINE_VISIBILITY
145basic_ostream<_CharT, _Traits>&
146operator<<(basic_ostream<_CharT, _Traits>& __os,
147 const lognormal_distribution<_RT>& __x)
148{
149 return __os << __x.__p_.__nd_;
150}
151
152template <class _CharT, class _Traits, class _RT>
153inline _LIBCPP_INLINE_VISIBILITY
154basic_istream<_CharT, _Traits>&
155operator>>(basic_istream<_CharT, _Traits>& __is,
156 lognormal_distribution<_RT>& __x)
157{
158 return __is >> __x.__p_.__nd_;
159}
160
161#else // _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION
162
16327template<class _RealType = double>
16428class _LIBCPP_TEMPLATE_VIS lognormal_distribution
16529{
......@@ -290,8 +154,6 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
290154 return __is >> __x.__nd_;
291155}
292156
293#endif // _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION
294
295157_LIBCPP_END_NAMESPACE_STD
296158
297159_LIBCPP_POP_MACROS
lib/libcxx/include/__random/mersenne_twister_engine.h+6-7
......@@ -17,7 +17,6 @@
1717#include <cstdint>
1818#include <iosfwd>
1919#include <limits>
20#include <type_traits>
2120
2221#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2322# pragma GCC system_header
......@@ -141,7 +140,7 @@ public:
141140 explicit mersenne_twister_engine(_Sseq& __q,
142141 typename enable_if<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value>::type* = 0)
143142 {seed(__q);}
144 void seed(result_type __sd = default_seed);
143 _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd = default_seed);
145144 template<class _Sseq>
146145 _LIBCPP_INLINE_VISIBILITY
147146 typename enable_if
......@@ -153,7 +152,7 @@ public:
153152 {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());}
154153
155154 // generating functions
156 result_type operator()();
155 _LIBCPP_HIDE_FROM_ABI result_type operator()();
157156 _LIBCPP_INLINE_VISIBILITY
158157 void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
159158
......@@ -199,9 +198,9 @@ public:
199198private:
200199
201200 template<class _Sseq>
202 void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
201 _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
203202 template<class _Sseq>
204 void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
203 _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
205204
206205 template <size_t __count>
207206 _LIBCPP_INLINE_VISIBILITY
......@@ -403,9 +402,9 @@ mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
403402 const size_t __j = (__i_ + 1) % __n;
404403 const result_type __mask = __r == _Dt ? result_type(~0) :
405404 (result_type(1) << __r) - result_type(1);
406 const result_type _Yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask);
405 const result_type __yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask);
407406 const size_t __k = (__i_ + __m) % __n;
408 __x_[__i_] = __x_[__k] ^ __rshift<1>(_Yp) ^ (__a * (_Yp & 1));
407 __x_[__i_] = __x_[__k] ^ __rshift<1>(__yp) ^ (__a * (__yp & 1));
409408 result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d);
410409 __i_ = __j;
411410 __z ^= __lshift<__s>(__z) & __b;
lib/libcxx/include/__random/negative_binomial_distribution.h+5-3
......@@ -85,7 +85,8 @@ public:
8585 _LIBCPP_INLINE_VISIBILITY
8686 result_type operator()(_URNG& __g)
8787 {return (*this)(__g, __p_);}
88 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
88 template<class _URNG>
89 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
8990
9091 // property functions
9192 _LIBCPP_INLINE_VISIBILITY
......@@ -135,8 +136,9 @@ negative_binomial_distribution<_IntType>::operator()(_URNG& __urng, const param_
135136 else
136137 ++__f;
137138 }
138 _LIBCPP_ASSERT(__f >= 0, "std::negative_binomial_distribution should never produce negative values. "
139 "This is almost certainly a signed integer overflow issue on __f.");
139 _LIBCPP_ASSERT_UNCATEGORIZED(__f >= 0,
140 "std::negative_binomial_distribution should never produce negative values. "
141 "This is almost certainly a signed integer overflow issue on __f.");
140142 return __f;
141143 }
142144 return poisson_distribution<result_type>(gamma_distribution<double>
lib/libcxx/include/__random/normal_distribution.h+18-17
......@@ -86,7 +86,8 @@ public:
8686 _LIBCPP_INLINE_VISIBILITY
8787 result_type operator()(_URNG& __g)
8888 {return (*this)(__g, __p_);}
89 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
89 template<class _URNG>
90 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
9091
9192 // property functions
9293 _LIBCPP_INLINE_VISIBILITY
......@@ -133,30 +134,30 @@ _RealType
133134normal_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
134135{
135136 static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
136 result_type _Up;
137 result_type __up;
137138 if (__v_hot_)
138139 {
139140 __v_hot_ = false;
140 _Up = __v_;
141 __up = __v_;
141142 }
142143 else
143144 {
144 uniform_real_distribution<result_type> _Uni(-1, 1);
145 uniform_real_distribution<result_type> __uni(-1, 1);
145146 result_type __u;
146147 result_type __v;
147148 result_type __s;
148149 do
149150 {
150 __u = _Uni(__g);
151 __v = _Uni(__g);
151 __u = __uni(__g);
152 __v = __uni(__g);
152153 __s = __u * __u + __v * __v;
153154 } while (__s > 1 || __s == 0);
154 result_type _Fp = _VSTD::sqrt(-2 * _VSTD::log(__s) / __s);
155 __v_ = __v * _Fp;
155 result_type __fp = _VSTD::sqrt(-2 * _VSTD::log(__s) / __s);
156 __v_ = __v * __fp;
156157 __v_hot_ = true;
157 _Up = __u * _Fp;
158 __up = __u * __fp;
158159 }
159 return _Up * __p.stddev() + __p.mean();
160 return __up * __p.stddev() + __p.mean();
160161}
161162
162163template <class _CharT, class _Traits, class _RT>
......@@ -189,16 +190,16 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
189190 __is.flags(_Istream::dec | _Istream::skipws);
190191 result_type __mean;
191192 result_type __stddev;
192 result_type _Vp = 0;
193 bool _V_hot = false;
194 __is >> __mean >> __stddev >> _V_hot;
195 if (_V_hot)
196 __is >> _Vp;
193 result_type __vp = 0;
194 bool __v_hot = false;
195 __is >> __mean >> __stddev >> __v_hot;
196 if (__v_hot)
197 __is >> __vp;
197198 if (!__is.fail())
198199 {
199200 __x.param(param_type(__mean, __stddev));
200 __x.__v_hot_ = _V_hot;
201 __x.__v_ = _Vp;
201 __x.__v_hot_ = __v_hot;
202 __x.__v_ = __vp;
202203 }
203204 return __is;
204205}
lib/libcxx/include/__random/piecewise_constant_distribution.h+9-8
......@@ -41,19 +41,19 @@ public:
4141 public:
4242 typedef piecewise_constant_distribution distribution_type;
4343
44 param_type();
44 _LIBCPP_HIDE_FROM_ABI param_type();
4545 template<class _InputIteratorB, class _InputIteratorW>
46 param_type(_InputIteratorB __f_b, _InputIteratorB __l_b,
46 _LIBCPP_HIDE_FROM_ABI param_type(_InputIteratorB __f_b, _InputIteratorB __l_b,
4747 _InputIteratorW __f_w);
4848#ifndef _LIBCPP_CXX03_LANG
4949 template<class _UnaryOperation>
50 param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
50 _LIBCPP_HIDE_FROM_ABI param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
5151#endif // _LIBCPP_CXX03_LANG
5252 template<class _UnaryOperation>
53 param_type(size_t __nw, result_type __xmin, result_type __xmax,
53 _LIBCPP_HIDE_FROM_ABI param_type(size_t __nw, result_type __xmin, result_type __xmax,
5454 _UnaryOperation __fw);
55 param_type(param_type const&) = default;
56 param_type & operator=(const param_type& __rhs);
55 _LIBCPP_HIDE_FROM_ABI param_type(param_type const&) = default;
56 _LIBCPP_HIDE_FROM_ABI param_type & operator=(const param_type& __rhs);
5757
5858 _LIBCPP_INLINE_VISIBILITY
5959 vector<result_type> intervals() const {return __b_;}
......@@ -68,7 +68,7 @@ public:
6868 {return !(__x == __y);}
6969
7070 private:
71 void __init();
71 _LIBCPP_HIDE_FROM_ABI void __init();
7272
7373 friend class piecewise_constant_distribution;
7474
......@@ -125,7 +125,8 @@ public:
125125 _LIBCPP_INLINE_VISIBILITY
126126 result_type operator()(_URNG& __g)
127127 {return (*this)(__g, __p_);}
128 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
128 template<class _URNG>
129 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
129130
130131 // property functions
131132 _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/piecewise_linear_distribution.h+13-12
......@@ -41,19 +41,19 @@ public:
4141 public:
4242 typedef piecewise_linear_distribution distribution_type;
4343
44 param_type();
44 _LIBCPP_HIDE_FROM_ABI param_type();
4545 template<class _InputIteratorB, class _InputIteratorW>
46 param_type(_InputIteratorB __f_b, _InputIteratorB __l_b,
46 _LIBCPP_HIDE_FROM_ABI param_type(_InputIteratorB __f_b, _InputIteratorB __l_b,
4747 _InputIteratorW __f_w);
4848#ifndef _LIBCPP_CXX03_LANG
4949 template<class _UnaryOperation>
50 param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
50 _LIBCPP_HIDE_FROM_ABI param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
5151#endif // _LIBCPP_CXX03_LANG
5252 template<class _UnaryOperation>
53 param_type(size_t __nw, result_type __xmin, result_type __xmax,
53 _LIBCPP_HIDE_FROM_ABI param_type(size_t __nw, result_type __xmin, result_type __xmax,
5454 _UnaryOperation __fw);
55 param_type(param_type const&) = default;
56 param_type & operator=(const param_type& __rhs);
55 _LIBCPP_HIDE_FROM_ABI param_type(param_type const&) = default;
56 _LIBCPP_HIDE_FROM_ABI param_type & operator=(const param_type& __rhs);
5757
5858 _LIBCPP_INLINE_VISIBILITY
5959 vector<result_type> intervals() const {return __b_;}
......@@ -68,7 +68,7 @@ public:
6868 {return !(__x == __y);}
6969
7070 private:
71 void __init();
71 _LIBCPP_HIDE_FROM_ABI void __init();
7272
7373 friend class piecewise_linear_distribution;
7474
......@@ -125,7 +125,8 @@ public:
125125 _LIBCPP_INLINE_VISIBILITY
126126 result_type operator()(_URNG& __g)
127127 {return (*this)(__g, __p_);}
128 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
128 template<class _URNG>
129 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
129130
130131 // property functions
131132 _LIBCPP_INLINE_VISIBILITY
......@@ -188,23 +189,23 @@ void
188189piecewise_linear_distribution<_RealType>::param_type::__init()
189190{
190191 __areas_.assign(__densities_.size() - 1, result_type());
191 result_type _Sp = 0;
192 result_type __sp = 0;
192193 for (size_t __i = 0; __i < __areas_.size(); ++__i)
193194 {
194195 __areas_[__i] = (__densities_[__i+1] + __densities_[__i]) *
195196 (__b_[__i+1] - __b_[__i]) * .5;
196 _Sp += __areas_[__i];
197 __sp += __areas_[__i];
197198 }
198199 for (size_t __i = __areas_.size(); __i > 1;)
199200 {
200201 --__i;
201 __areas_[__i] = __areas_[__i-1] / _Sp;
202 __areas_[__i] = __areas_[__i-1] / __sp;
202203 }
203204 __areas_[0] = 0;
204205 for (size_t __i = 1; __i < __areas_.size(); ++__i)
205206 __areas_[__i] += __areas_[__i-1];
206207 for (size_t __i = 0; __i < __densities_.size(); ++__i)
207 __densities_[__i] /= _Sp;
208 __densities_[__i] /= __sp;
208209}
209210
210211template<class _RealType>
lib/libcxx/include/__random/poisson_distribution.h+9-8
......@@ -52,7 +52,7 @@ public:
5252 public:
5353 typedef poisson_distribution distribution_type;
5454
55 explicit param_type(double __mean = 1.0);
55 _LIBCPP_HIDE_FROM_ABI explicit param_type(double __mean = 1.0);
5656
5757 _LIBCPP_INLINE_VISIBILITY
5858 double mean() const {return __mean_;}
......@@ -93,7 +93,8 @@ public:
9393 _LIBCPP_INLINE_VISIBILITY
9494 result_type operator()(_URNG& __g)
9595 {return (*this)(__g, __p_);}
96 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
96 template<class _URNG>
97 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
9798
9899 // property functions
99100 _LIBCPP_INLINE_VISIBILITY
......@@ -144,12 +145,12 @@ poisson_distribution<_IntType>::param_type::param_type(double __mean)
144145 __d_ = 6 * __mean_ * __mean_;
145146 __l_ = _VSTD::trunc(__mean_ - 1.1484);
146147 __omega_ = .3989423 / __s_;
147 double __b1_ = .4166667E-1 / __mean_;
148 double __b2_ = .3 * __b1_ * __b1_;
149 __c3_ = .1428571 * __b1_ * __b2_;
150 __c2_ = __b2_ - 15. * __c3_;
151 __c1_ = __b1_ - 6. * __b2_ + 45. * __c3_;
152 __c0_ = 1. - __b1_ + 3. * __b2_ - 15. * __c3_;
148 double __b1 = .4166667E-1 / __mean_;
149 double __b2 = .3 * __b1 * __b1;
150 __c3_ = .1428571 * __b1 * __b2;
151 __c2_ = __b2 - 15. * __c3_;
152 __c1_ = __b1 - 6. * __b2 + 45. * __c3_;
153 __c0_ = 1. - __b1 + 3. * __b2 - 15. * __c3_;
153154 __c_ = .1069 / __mean_;
154155 }
155156}
lib/libcxx/include/__random/random_device.h+2-2
......@@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2323
2424#if !defined(_LIBCPP_HAS_NO_RANDOM_DEVICE)
2525
26class _LIBCPP_TYPE_VIS random_device
26class _LIBCPP_EXPORTED_FROM_ABI random_device
2727{
2828#ifdef _LIBCPP_USING_DEV_RANDOM
2929 int __f_;
......@@ -58,7 +58,7 @@ public:
5858
5959 // constructors
6060#ifndef _LIBCPP_CXX03_LANG
61 random_device() : random_device("/dev/urandom") {}
61 _LIBCPP_HIDE_FROM_ABI random_device() : random_device("/dev/urandom") {}
6262 explicit random_device(const string& __token);
6363#else
6464 explicit random_device(const string& __token = "/dev/urandom");
lib/libcxx/include/__random/seed_seq.h+4-2
......@@ -13,6 +13,8 @@
1313#include <__algorithm/fill.h>
1414#include <__algorithm/max.h>
1515#include <__config>
16#include <__iterator/iterator_traits.h>
17#include <cstdint>
1618#include <initializer_list>
1719#include <vector>
1820
......@@ -52,7 +54,7 @@ public:
5254
5355 // generating functions
5456 template<class _RandomAccessIterator>
55 void generate(_RandomAccessIterator __first, _RandomAccessIterator __last);
57 _LIBCPP_HIDE_FROM_ABI void generate(_RandomAccessIterator __first, _RandomAccessIterator __last);
5658
5759 // property functions
5860 _LIBCPP_INLINE_VISIBILITY
......@@ -70,7 +72,7 @@ public:
7072
7173private:
7274 template<class _InputIterator>
73 void __init(_InputIterator __first, _InputIterator __last);
75 _LIBCPP_HIDE_FROM_ABI void __init(_InputIterator __first, _InputIterator __last);
7476
7577 vector<result_type> __v_;
7678};
lib/libcxx/include/__random/shuffle_order_engine.h+10-7
......@@ -12,10 +12,13 @@
1212#include <__algorithm/equal.h>
1313#include <__config>
1414#include <__random/is_seed_sequence.h>
15#include <__type_traits/enable_if.h>
16#include <__type_traits/integral_constant.h>
17#include <__type_traits/is_convertible.h>
1518#include <__utility/move.h>
19#include <cstddef>
1620#include <cstdint>
1721#include <iosfwd>
18#include <type_traits>
1922
2023#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2124# pragma GCC system_header
......@@ -201,10 +204,10 @@ private:
201204 _LIBCPP_INLINE_VISIBILITY
202205 result_type __evalf()
203206 {
204 const double _Fp = __d == 0 ?
207 const double __fp = __d == 0 ?
205208 __n / (2. * 0x8000000000000000ull) :
206209 __n / (double)__d;
207 const size_t __j = static_cast<size_t>(_Fp * (__y_ - _Min));
210 const size_t __j = static_cast<size_t>(__fp * (__y_ - _Min));
208211 __y_ = __v_[__j];
209212 __v_[__j] = __e_();
210213 return __y_;
......@@ -262,16 +265,16 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
262265 typedef basic_istream<_CharT, _Traits> _Istream;
263266 __is.flags(_Istream::dec | _Istream::skipws);
264267 _Eng __e;
265 result_type _Vp[_Kp+1];
268 result_type __vp[_Kp+1];
266269 __is >> __e;
267270 for (size_t __i = 0; __i < _Kp+1; ++__i)
268 __is >> _Vp[__i];
271 __is >> __vp[__i];
269272 if (!__is.fail())
270273 {
271274 __x.__e_ = __e;
272275 for (size_t __i = 0; __i < _Kp; ++__i)
273 __x.__v_[__i] = _Vp[__i];
274 __x.__y_ = _Vp[_Kp];
276 __x.__v_[__i] = __vp[__i];
277 __x.__y_ = __vp[_Kp];
275278 }
276279 return __is;
277280}
lib/libcxx/include/__random/student_t_distribution.h+2-1
......@@ -81,7 +81,8 @@ public:
8181 _LIBCPP_INLINE_VISIBILITY
8282 result_type operator()(_URNG& __g)
8383 {return (*this)(__g, __p_);}
84 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
84 template<class _URNG>
85 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
8586
8687 // property functions
8788 _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__random/subtract_with_carry_engine.h+5-6
......@@ -18,7 +18,6 @@
1818#include <cstdint>
1919#include <iosfwd>
2020#include <limits>
21#include <type_traits>
2221
2322#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2423# pragma GCC system_header
......@@ -121,7 +120,7 @@ public:
121120 {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());}
122121
123122 // generating functions
124 result_type operator()();
123 _LIBCPP_HIDE_FROM_ABI result_type operator()();
125124 _LIBCPP_INLINE_VISIBILITY
126125 void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
127126
......@@ -155,12 +154,12 @@ public:
155154
156155private:
157156
158 void seed(result_type __sd, integral_constant<unsigned, 1>);
159 void seed(result_type __sd, integral_constant<unsigned, 2>);
157 _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd, integral_constant<unsigned, 1>);
158 _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd, integral_constant<unsigned, 2>);
160159 template<class _Sseq>
161 void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
160 _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
162161 template<class _Sseq>
163 void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
162 _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
164163};
165164
166165template<class _UIntType, size_t __w, size_t __s, size_t __r>
lib/libcxx/include/__random/uniform_int_distribution.h+43-40
......@@ -9,15 +9,16 @@
99#ifndef _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
1010#define _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
1111
12#include <__bit/countl.h>
1213#include <__config>
1314#include <__random/is_valid.h>
1415#include <__random/log2.h>
15#include <bit>
16#include <__type_traits/conditional.h>
17#include <__type_traits/make_unsigned.h>
1618#include <cstddef>
1719#include <cstdint>
1820#include <iosfwd>
1921#include <limits>
20#include <type_traits>
2122
2223#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2324# pragma GCC system_header
......@@ -63,14 +64,14 @@ private:
6364
6465public:
6566 // constructors and seeding functions
66 __independent_bits_engine(_Engine& __e, size_t __w);
67 _LIBCPP_HIDE_FROM_ABI __independent_bits_engine(_Engine& __e, size_t __w);
6768
6869 // generating functions
69 result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
70 _LIBCPP_HIDE_FROM_ABI result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
7071
7172private:
72 result_type __eval(false_type);
73 result_type __eval(true_type);
73 _LIBCPP_HIDE_FROM_ABI result_type __eval(false_type);
74 _LIBCPP_HIDE_FROM_ABI result_type __eval(true_type);
7475};
7576
7677template<class _Engine, class _UIntType>
......@@ -120,8 +121,8 @@ template<class _Engine, class _UIntType>
120121_UIntType
121122__independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
122123{
123 const size_t _WRt = numeric_limits<result_type>::digits;
124 result_type _Sp = 0;
124 const size_t __w_rt = numeric_limits<result_type>::digits;
125 result_type __sp = 0;
125126 for (size_t __k = 0; __k < __n0_; ++__k)
126127 {
127128 _Engine_result_type __u;
......@@ -129,11 +130,11 @@ __independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
129130 {
130131 __u = __e_() - _Engine::min();
131132 } while (__u >= __y0_);
132 if (__w0_ < _WRt)
133 _Sp <<= __w0_;
133 if (__w0_ < __w_rt)
134 __sp <<= __w0_;
134135 else
135 _Sp = 0;
136 _Sp += __u & __mask0_;
136 __sp = 0;
137 __sp += __u & __mask0_;
137138 }
138139 for (size_t __k = __n0_; __k < __n_; ++__k)
139140 {
......@@ -142,13 +143,13 @@ __independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
142143 {
143144 __u = __e_() - _Engine::min();
144145 } while (__u >= __y1_);
145 if (__w0_ < _WRt - 1)
146 _Sp <<= __w0_ + 1;
146 if (__w0_ < __w_rt - 1)
147 __sp <<= __w0_ + 1;
147148 else
148 _Sp = 0;
149 _Sp += __u & __mask1_;
149 __sp = 0;
150 __sp += __u & __mask1_;
150151 }
151 return _Sp;
152 return __sp;
152153}
153154
154155template<class _IntType = int>
......@@ -166,12 +167,12 @@ public:
166167 public:
167168 typedef uniform_int_distribution distribution_type;
168169
169 explicit param_type(result_type __a = 0,
170 _LIBCPP_HIDE_FROM_ABI explicit param_type(result_type __a = 0,
170171 result_type __b = numeric_limits<result_type>::max())
171172 : __a_(__a), __b_(__b) {}
172173
173 result_type a() const {return __a_;}
174 result_type b() const {return __b_;}
174 _LIBCPP_HIDE_FROM_ABI result_type a() const {return __a_;}
175 _LIBCPP_HIDE_FROM_ABI result_type b() const {return __b_;}
175176
176177 _LIBCPP_HIDE_FROM_ABI
177178 friend bool operator==(const param_type& __x, const param_type& __y)
......@@ -187,8 +188,8 @@ private:
187188public:
188189 // constructors and reset functions
189190#ifndef _LIBCPP_CXX03_LANG
190 uniform_int_distribution() : uniform_int_distribution(0) {}
191 explicit uniform_int_distribution(
191 _LIBCPP_HIDE_FROM_ABI uniform_int_distribution() : uniform_int_distribution(0) {}
192 _LIBCPP_HIDE_FROM_ABI explicit uniform_int_distribution(
192193 result_type __a, result_type __b = numeric_limits<result_type>::max())
193194 : __p_(param_type(__a, __b)) {}
194195#else
......@@ -197,23 +198,25 @@ public:
197198 result_type __b = numeric_limits<result_type>::max())
198199 : __p_(param_type(__a, __b)) {}
199200#endif
200 explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}
201 void reset() {}
201 _LIBCPP_HIDE_FROM_ABI explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}
202 _LIBCPP_HIDE_FROM_ABI void reset() {}
202203
203204 // generating functions
204 template<class _URNG> result_type operator()(_URNG& __g)
205 template<class _URNG>
206 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g)
205207 {return (*this)(__g, __p_);}
206 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
208 template<class _URNG>
209 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
207210
208211 // property functions
209 result_type a() const {return __p_.a();}
210 result_type b() const {return __p_.b();}
212 _LIBCPP_HIDE_FROM_ABI result_type a() const {return __p_.a();}
213 _LIBCPP_HIDE_FROM_ABI result_type b() const {return __p_.b();}
211214
212 param_type param() const {return __p_;}
213 void param(const param_type& __p) {__p_ = __p;}
215 _LIBCPP_HIDE_FROM_ABI param_type param() const {return __p_;}
216 _LIBCPP_HIDE_FROM_ABI void param(const param_type& __p) {__p_ = __p;}
214217
215 result_type min() const {return a();}
216 result_type max() const {return b();}
218 _LIBCPP_HIDE_FROM_ABI result_type min() const {return a();}
219 _LIBCPP_HIDE_FROM_ABI result_type max() const {return b();}
217220
218221 _LIBCPP_HIDE_FROM_ABI
219222 friend bool operator==(const uniform_int_distribution& __x,
......@@ -234,22 +237,22 @@ _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
234237 static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
235238 typedef __conditional_t<sizeof(result_type) <= sizeof(uint32_t), uint32_t, __make_unsigned_t<result_type> >
236239 _UIntType;
237 const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1);
238 if (_Rp == 1)
240 const _UIntType __rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1);
241 if (__rp == 1)
239242 return __p.a();
240 const size_t _Dt = numeric_limits<_UIntType>::digits;
243 const size_t __dt = numeric_limits<_UIntType>::digits;
241244 typedef __independent_bits_engine<_URNG, _UIntType> _Eng;
242 if (_Rp == 0)
243 return static_cast<result_type>(_Eng(__g, _Dt)());
244 size_t __w = _Dt - std::__countl_zero(_Rp) - 1;
245 if ((_Rp & (numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0)
245 if (__rp == 0)
246 return static_cast<result_type>(_Eng(__g, __dt)());
247 size_t __w = __dt - std::__countl_zero(__rp) - 1;
248 if ((__rp & (numeric_limits<_UIntType>::max() >> (__dt - __w))) != 0)
246249 ++__w;
247250 _Eng __e(__g, __w);
248251 _UIntType __u;
249252 do
250253 {
251254 __u = __e();
252 } while (__u >= _Rp);
255 } while (__u >= __rp);
253256 return static_cast<result_type>(__u + __p.a());
254257}
255258
lib/libcxx/include/__random/uniform_random_bit_generator.h+4-3
......@@ -13,7 +13,8 @@
1313#include <__concepts/invocable.h>
1414#include <__concepts/same_as.h>
1515#include <__config>
16#include <type_traits>
16#include <__functional/invoke.h>
17#include <__type_traits/integral_constant.h>
1718
1819#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1920# pragma GCC system_header
......@@ -24,7 +25,7 @@ _LIBCPP_PUSH_MACROS
2425
2526_LIBCPP_BEGIN_NAMESPACE_STD
2627
27#if _LIBCPP_STD_VER > 17
28#if _LIBCPP_STD_VER >= 20
2829
2930// [rand.req.urng]
3031template<class _Gen>
......@@ -36,7 +37,7 @@ concept uniform_random_bit_generator =
3637 requires bool_constant<(_Gen::min() < _Gen::max())>::value;
3738 };
3839
39#endif // _LIBCPP_STD_VER > 17
40#endif // _LIBCPP_STD_VER >= 20
4041
4142_LIBCPP_END_NAMESPACE_STD
4243
lib/libcxx/include/__random/uniform_real_distribution.h+1-2
......@@ -14,7 +14,6 @@
1414#include <__random/is_valid.h>
1515#include <iosfwd>
1616#include <limits>
17#include <type_traits>
1817
1918#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2019# pragma GCC system_header
......@@ -65,7 +64,7 @@ public:
6564#ifndef _LIBCPP_CXX03_LANG
6665 _LIBCPP_INLINE_VISIBILITY
6766 uniform_real_distribution() : uniform_real_distribution(0) {}
68 explicit uniform_real_distribution(result_type __a, result_type __b = 1)
67 _LIBCPP_HIDE_FROM_ABI explicit uniform_real_distribution(result_type __a, result_type __b = 1)
6968 : __p_(param_type(__a, __b)) {}
7069#else
7170 _LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/__ranges/access.h+2-2
......@@ -29,7 +29,7 @@
2929
3030_LIBCPP_BEGIN_NAMESPACE_STD
3131
32#if _LIBCPP_STD_VER > 17
32#if _LIBCPP_STD_VER >= 20
3333
3434namespace ranges {
3535 template <class _Tp>
......@@ -223,7 +223,7 @@ inline namespace __cpo {
223223} // namespace __cpo
224224} // namespace ranges
225225
226#endif // _LIBCPP_STD_VER > 17
226#endif // _LIBCPP_STD_VER >= 20
227227
228228_LIBCPP_END_NAMESPACE_STD
229229
lib/libcxx/include/__ranges/all.h+5-3
......@@ -11,6 +11,8 @@
1111#define _LIBCPP___RANGES_ALL_H
1212
1313#include <__config>
14#include <__functional/compose.h> // TODO(modules): Those should not be required
15#include <__functional/perfect_forward.h> //
1416#include <__iterator/concepts.h>
1517#include <__iterator/iterator_traits.h>
1618#include <__ranges/access.h>
......@@ -18,10 +20,10 @@
1820#include <__ranges/owning_view.h>
1921#include <__ranges/range_adaptor.h>
2022#include <__ranges/ref_view.h>
23#include <__type_traits/decay.h>
2124#include <__utility/auto_cast.h>
2225#include <__utility/declval.h>
2326#include <__utility/forward.h>
24#include <type_traits>
2527
2628#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2729# pragma GCC system_header
......@@ -29,7 +31,7 @@
2931
3032_LIBCPP_BEGIN_NAMESPACE_STD
3133
32#if _LIBCPP_STD_VER > 17
34#if _LIBCPP_STD_VER >= 20
3335
3436namespace ranges::views {
3537
......@@ -77,7 +79,7 @@ using all_t = decltype(views::all(std::declval<_Range>()));
7779
7880} // namespace ranges::views
7981
80#endif // _LIBCPP_STD_VER > 17
82#endif // _LIBCPP_STD_VER >= 20
8183
8284_LIBCPP_END_NAMESPACE_STD
8385
lib/libcxx/include/__ranges/as_rvalue_view.h+6-1
......@@ -28,6 +28,9 @@
2828# pragma GCC system_header
2929#endif
3030
31_LIBCPP_PUSH_MACROS
32#include <__undef_macros>
33
3134#if _LIBCPP_STD_VER >= 23
3235
3336_LIBCPP_BEGIN_NAMESPACE_STD
......@@ -125,7 +128,7 @@ struct __fn : __range_adaptor_closure<__fn> {
125128} // namespace __as_rvalue
126129
127130inline namespace __cpo {
128constexpr auto as_rvalue = __as_rvalue::__fn{};
131inline constexpr auto as_rvalue = __as_rvalue::__fn{};
129132} // namespace __cpo
130133} // namespace views
131134} // namespace ranges
......@@ -134,4 +137,6 @@ _LIBCPP_END_NAMESPACE_STD
134137
135138#endif // _LIBCPP_STD_VER >= 23
136139
140_LIBCPP_POP_MACROS
141
137142#endif // _LIBCPP___RANGES_AS_RVALUE_H
lib/libcxx/include/__ranges/common_view.h+7-3
......@@ -24,15 +24,17 @@
2424#include <__ranges/view_interface.h>
2525#include <__utility/forward.h>
2626#include <__utility/move.h>
27#include <type_traits>
2827
2928#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3029# pragma GCC system_header
3130#endif
3231
32_LIBCPP_PUSH_MACROS
33#include <__undef_macros>
34
3335_LIBCPP_BEGIN_NAMESPACE_STD
3436
35#if _LIBCPP_STD_VER > 17
37#if _LIBCPP_STD_VER >= 20
3638
3739namespace ranges {
3840
......@@ -130,8 +132,10 @@ inline namespace __cpo {
130132} // namespace views
131133} // namespace ranges
132134
133#endif // _LIBCPP_STD_VER > 17
135#endif // _LIBCPP_STD_VER >= 20
134136
135137_LIBCPP_END_NAMESPACE_STD
136138
139_LIBCPP_POP_MACROS
140
137141#endif // _LIBCPP___RANGES_COMMON_VIEW_H
lib/libcxx/include/__ranges/concepts.h+5-2
......@@ -37,7 +37,7 @@
3737
3838_LIBCPP_BEGIN_NAMESPACE_STD
3939
40#if _LIBCPP_STD_VER > 17
40#if _LIBCPP_STD_VER >= 20
4141
4242namespace ranges {
4343
......@@ -73,6 +73,9 @@ namespace ranges {
7373 template <range _Rp>
7474 using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>;
7575
76 template <range _Rp>
77 using range_common_reference_t = iter_common_reference_t<iterator_t<_Rp>>;
78
7679 // [range.sized]
7780 template <class _Tp>
7881 concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); };
......@@ -140,7 +143,7 @@ namespace ranges {
140143
141144} // namespace ranges
142145
143#endif // _LIBCPP_STD_VER > 17
146#endif // _LIBCPP_STD_VER >= 20
144147
145148_LIBCPP_END_NAMESPACE_STD
146149
lib/libcxx/include/__ranges/container_compatible_range.h created+33
......@@ -0,0 +1,33 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H
11#define _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H
12
13#include <__concepts/convertible_to.h>
14#include <__config>
15#include <__ranges/concepts.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18# pragma GCC system_header
19#endif
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23#if _LIBCPP_STD_VER >= 23
24
25template <class _Range, class _Tp>
26concept _ContainerCompatibleRange =
27 ranges::input_range<_Range> && convertible_to<ranges::range_reference_t<_Range>, _Tp>;
28
29#endif // _LIBCPP_STD_VER >= 23
30
31_LIBCPP_END_NAMESPACE_STD
32
33#endif // _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H
lib/libcxx/include/__ranges/copyable_box.h deleted-180
......@@ -1,180 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_COPYABLE_BOX_H
11#define _LIBCPP___RANGES_COPYABLE_BOX_H
12
13#include <__concepts/constructible.h>
14#include <__concepts/copyable.h>
15#include <__concepts/movable.h>
16#include <__config>
17#include <__memory/addressof.h>
18#include <__memory/construct_at.h>
19#include <__utility/move.h>
20#include <optional>
21#include <type_traits>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24# pragma GCC system_header
25#endif
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29#if _LIBCPP_STD_VER > 17
30
31// __copyable_box allows turning a type that is copy-constructible (but maybe not copy-assignable) into
32// a type that is both copy-constructible and copy-assignable. It does that by introducing an empty state
33// and basically doing destroy-then-copy-construct in the assignment operator. The empty state is necessary
34// to handle the case where the copy construction fails after destroying the object.
35//
36// In some cases, we can completely avoid the use of an empty state; we provide a specialization of
37// __copyable_box that does this, see below for the details.
38
39template<class _Tp>
40concept __copy_constructible_object = copy_constructible<_Tp> && is_object_v<_Tp>;
41
42namespace ranges {
43 // Primary template - uses std::optional and introduces an empty state in case assignment fails.
44 template<__copy_constructible_object _Tp>
45 class __copyable_box {
46 _LIBCPP_NO_UNIQUE_ADDRESS optional<_Tp> __val_;
47
48 public:
49 template<class ..._Args>
50 requires is_constructible_v<_Tp, _Args...>
51 _LIBCPP_HIDE_FROM_ABI
52 constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
53 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
54 : __val_(in_place, std::forward<_Args>(__args)...)
55 { }
56
57 _LIBCPP_HIDE_FROM_ABI
58 constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
59 requires default_initializable<_Tp>
60 : __val_(in_place)
61 { }
62
63 _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default;
64 _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default;
65
66 _LIBCPP_HIDE_FROM_ABI
67 constexpr __copyable_box& operator=(__copyable_box const& __other)
68 noexcept(is_nothrow_copy_constructible_v<_Tp>)
69 {
70 if (this != std::addressof(__other)) {
71 if (__other.__has_value()) __val_.emplace(*__other);
72 else __val_.reset();
73 }
74 return *this;
75 }
76
77 _LIBCPP_HIDE_FROM_ABI
78 __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default;
79
80 _LIBCPP_HIDE_FROM_ABI
81 constexpr __copyable_box& operator=(__copyable_box&& __other)
82 noexcept(is_nothrow_move_constructible_v<_Tp>)
83 {
84 if (this != std::addressof(__other)) {
85 if (__other.__has_value()) __val_.emplace(std::move(*__other));
86 else __val_.reset();
87 }
88 return *this;
89 }
90
91 _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; }
92 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; }
93
94 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return __val_.operator->(); }
95 _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return __val_.operator->(); }
96
97 _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); }
98 };
99
100 // This partial specialization implements an optimization for when we know we don't need to store
101 // an empty state to represent failure to perform an assignment. For copy-assignment, this happens:
102 //
103 // 1. If the type is copyable (which includes copy-assignment), we can use the type's own assignment operator
104 // directly and avoid using std::optional.
105 // 2. If the type is not copyable, but it is nothrow-copy-constructible, then we can implement assignment as
106 // destroy-and-then-construct and we know it will never fail, so we don't need an empty state.
107 //
108 // The exact same reasoning can be applied for move-assignment, with copyable replaced by movable and
109 // nothrow-copy-constructible replaced by nothrow-move-constructible. This specialization is enabled
110 // whenever we can apply any of these optimizations for both the copy assignment and the move assignment
111 // operator.
112 template<class _Tp>
113 concept __doesnt_need_empty_state_for_copy = copyable<_Tp> || is_nothrow_copy_constructible_v<_Tp>;
114
115 template<class _Tp>
116 concept __doesnt_need_empty_state_for_move = movable<_Tp> || is_nothrow_move_constructible_v<_Tp>;
117
118 template<__copy_constructible_object _Tp>
119 requires __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp>
120 class __copyable_box<_Tp> {
121 _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
122
123 public:
124 template<class ..._Args>
125 requires is_constructible_v<_Tp, _Args...>
126 _LIBCPP_HIDE_FROM_ABI
127 constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
128 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
129 : __val_(std::forward<_Args>(__args)...)
130 { }
131
132 _LIBCPP_HIDE_FROM_ABI
133 constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
134 requires default_initializable<_Tp>
135 : __val_()
136 { }
137
138 _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default;
139 _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default;
140
141 // Implementation of assignment operators in case we perform optimization (1)
142 _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box const&) requires copyable<_Tp> = default;
143 _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default;
144
145 // Implementation of assignment operators in case we perform optimization (2)
146 _LIBCPP_HIDE_FROM_ABI
147 constexpr __copyable_box& operator=(__copyable_box const& __other) noexcept {
148 static_assert(is_nothrow_copy_constructible_v<_Tp>);
149 if (this != std::addressof(__other)) {
150 std::destroy_at(std::addressof(__val_));
151 std::construct_at(std::addressof(__val_), __other.__val_);
152 }
153 return *this;
154 }
155
156 _LIBCPP_HIDE_FROM_ABI
157 constexpr __copyable_box& operator=(__copyable_box&& __other) noexcept {
158 static_assert(is_nothrow_move_constructible_v<_Tp>);
159 if (this != std::addressof(__other)) {
160 std::destroy_at(std::addressof(__val_));
161 std::construct_at(std::addressof(__val_), std::move(__other.__val_));
162 }
163 return *this;
164 }
165
166 _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; }
167 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; }
168
169 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return std::addressof(__val_); }
170 _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return std::addressof(__val_); }
171
172 _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; }
173 };
174} // namespace ranges
175
176#endif // _LIBCPP_STD_VER > 17
177
178_LIBCPP_END_NAMESPACE_STD
179
180#endif // _LIBCPP___RANGES_COPYABLE_BOX_H
lib/libcxx/include/__ranges/counted.h+4-3
......@@ -19,10 +19,11 @@
1919#include <__iterator/iterator_traits.h>
2020#include <__memory/pointer_traits.h>
2121#include <__ranges/subrange.h>
22#include <__type_traits/decay.h>
2223#include <__utility/forward.h>
2324#include <__utility/move.h>
25#include <cstddef>
2426#include <span>
25#include <type_traits>
2627
2728#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2829# pragma GCC system_header
......@@ -30,7 +31,7 @@
3031
3132_LIBCPP_BEGIN_NAMESPACE_STD
3233
33#if _LIBCPP_STD_VER > 17
34#if _LIBCPP_STD_VER >= 20
3435
3536namespace ranges::views {
3637
......@@ -75,7 +76,7 @@ inline namespace __cpo {
7576
7677} // namespace ranges::views
7778
78#endif // _LIBCPP_STD_VER > 17
79#endif // _LIBCPP_STD_VER >= 20
7980
8081_LIBCPP_END_NAMESPACE_STD
8182
lib/libcxx/include/__ranges/dangling.h+2-2
......@@ -21,7 +21,7 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24#if _LIBCPP_STD_VER > 17
24#if _LIBCPP_STD_VER >= 20
2525
2626namespace ranges {
2727struct dangling {
......@@ -35,7 +35,7 @@ using borrowed_iterator_t = _If<borrowed_range<_Rp>, iterator_t<_Rp>, dangling>;
3535// borrowed_subrange_t defined in <__ranges/subrange.h>
3636} // namespace ranges
3737
38#endif // _LIBCPP_STD_VER > 17
38#endif // _LIBCPP_STD_VER >= 20
3939
4040_LIBCPP_END_NAMESPACE_STD
4141
lib/libcxx/include/__ranges/data.h+2-2
......@@ -30,7 +30,7 @@
3030
3131_LIBCPP_BEGIN_NAMESPACE_STD
3232
33#if _LIBCPP_STD_VER > 17
33#if _LIBCPP_STD_VER >= 20
3434
3535// [range.prim.data]
3636
......@@ -105,7 +105,7 @@ inline namespace __cpo {
105105} // namespace __cpo
106106} // namespace ranges
107107
108#endif // _LIBCPP_STD_VER > 17
108#endif // _LIBCPP_STD_VER >= 20
109109
110110_LIBCPP_END_NAMESPACE_STD
111111
lib/libcxx/include/__ranges/drop_view.h+45-10
......@@ -30,13 +30,19 @@
3030#include <__ranges/iota_view.h>
3131#include <__ranges/non_propagating_cache.h>
3232#include <__ranges/range_adaptor.h>
33#include <__ranges/repeat_view.h>
3334#include <__ranges/size.h>
3435#include <__ranges/subrange.h>
3536#include <__ranges/view_interface.h>
37#include <__type_traits/conditional.h>
38#include <__type_traits/decay.h>
39#include <__type_traits/is_nothrow_constructible.h>
40#include <__type_traits/make_unsigned.h>
41#include <__type_traits/remove_cvref.h>
3642#include <__utility/auto_cast.h>
3743#include <__utility/forward.h>
3844#include <__utility/move.h>
39#include <type_traits>
45#include <cstddef>
4046
4147#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
4248# pragma GCC system_header
......@@ -47,7 +53,7 @@ _LIBCPP_PUSH_MACROS
4753
4854_LIBCPP_BEGIN_NAMESPACE_STD
4955
50#if _LIBCPP_STD_VER > 17
56#if _LIBCPP_STD_VER >= 20
5157
5258namespace ranges {
5359 template<view _View>
......@@ -66,14 +72,14 @@ namespace ranges {
6672 _View __base_ = _View();
6773
6874public:
69 drop_view() requires default_initializable<_View> = default;
75 _LIBCPP_HIDE_FROM_ABI drop_view() requires default_initializable<_View> = default;
7076
7177 _LIBCPP_HIDE_FROM_ABI
72 constexpr drop_view(_View __base, range_difference_t<_View> __count)
78 constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 drop_view(_View __base, range_difference_t<_View> __count)
7379 : __count_(__count)
7480 , __base_(std::move(__base))
7581 {
76 _LIBCPP_ASSERT(__count_ >= 0, "count must be greater than or equal to zero.");
82 _LIBCPP_ASSERT_UNCATEGORIZED(__count_ >= 0, "count must be greater than or equal to zero.");
7783 }
7884
7985 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
......@@ -255,13 +261,39 @@ struct __fn {
255261 {
256262 // Introducing local variables avoids calculating `min` and `distance` twice (at the cost of diverging from the
257263 // expression used in the `noexcept` clause and the return statement).
258 auto dist = ranges::distance(__rng);
259 auto clamped = std::min<_Dist>(dist, std::forward<_Np>(__n));
264 auto __dist = ranges::distance(__rng);
265 auto __clamped = std::min<_Dist>(__dist, std::forward<_Np>(__n));
260266 return _RawRange(
261 ranges::begin(__rng) + clamped,
267 ranges::begin(__rng) + __clamped,
262268 ranges::end(__rng),
263 std::__to_unsigned_like(dist - clamped)
269 std::__to_unsigned_like(__dist - __clamped)
264270 );}
271// clang-format off
272#if _LIBCPP_STD_VER >= 23
273 // [range.drop.overview]: the `repeat_view` "_RawRange models sized_range" case.
274 template <class _Range,
275 convertible_to<range_difference_t<_Range>> _Np,
276 class _RawRange = remove_cvref_t<_Range>,
277 class _Dist = range_difference_t<_Range>>
278 requires (__is_repeat_specialization<_RawRange> && sized_range<_RawRange>)
279 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
280 noexcept(noexcept(views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))))
281 -> decltype( views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))
282 { return views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); }
283
284 // [range.drop.overview]: the `repeat_view` "otherwise" case.
285 template <class _Range,
286 convertible_to<range_difference_t<_Range>> _Np,
287 class _RawRange = remove_cvref_t<_Range>,
288 class _Dist = range_difference_t<_Range>>
289 requires (__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>)
290 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI
291 constexpr auto operator()(_Range&& __range, _Np&&) const
292 noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))))
293 -> decltype( _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))
294 { return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)); }
295#endif
296// clang-format on
265297
266298 // [range.drop.overview]: the "otherwise" case.
267299 template <class _Range, convertible_to<range_difference_t<_Range>> _Np,
......@@ -269,6 +301,9 @@ struct __fn {
269301 // Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other
270302 // overloads.
271303 requires (!(__is_empty_view<_RawRange> ||
304#if _LIBCPP_STD_VER >= 23
305 __is_repeat_specialization<_RawRange> ||
306#endif
272307 (__is_subrange_specialization_with_store_size<_RawRange> &&
273308 sized_range<_RawRange> &&
274309 random_access_range<_RawRange>) ||
......@@ -299,7 +334,7 @@ inline namespace __cpo {
299334
300335} // namespace ranges
301336
302#endif // _LIBCPP_STD_VER > 17
337#endif // _LIBCPP_STD_VER >= 20
303338
304339_LIBCPP_END_NAMESPACE_STD
305340
lib/libcxx/include/__ranges/drop_while_view.h+7-6
......@@ -20,8 +20,8 @@
2020#include <__ranges/access.h>
2121#include <__ranges/all.h>
2222#include <__ranges/concepts.h>
23#include <__ranges/copyable_box.h>
2423#include <__ranges/enable_borrowed_range.h>
24#include <__ranges/movable_box.h>
2525#include <__ranges/non_propagating_cache.h>
2626#include <__ranges/range_adaptor.h>
2727#include <__ranges/view_interface.h>
......@@ -51,7 +51,7 @@ public:
5151 requires default_initializable<_View> && default_initializable<_Pred>
5252 = default;
5353
54 _LIBCPP_HIDE_FROM_ABI constexpr drop_while_view(_View __base, _Pred __pred)
54 _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 drop_while_view(_View __base, _Pred __pred)
5555 : __base_(std::move(__base)), __pred_(std::in_place, std::move(__pred)) {}
5656
5757 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
......@@ -65,9 +65,10 @@ public:
6565 _LIBCPP_HIDE_FROM_ABI constexpr const _Pred& pred() const { return *__pred_; }
6666
6767 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
68 _LIBCPP_ASSERT(__pred_.__has_value(),
69 "drop_while_view needs to have a non-empty predicate before calling begin() -- did a previous "
70 "assignment to this drop_while_view fail?");
68 _LIBCPP_ASSERT_UNCATEGORIZED(
69 __pred_.__has_value(),
70 "drop_while_view needs to have a non-empty predicate before calling begin() -- did a previous "
71 "assignment to this drop_while_view fail?");
7172 if constexpr (_UseCache) {
7273 if (!__cached_begin_.__has_value()) {
7374 __cached_begin_.__emplace(ranges::find_if_not(__base_, std::cref(*__pred_)));
......@@ -82,7 +83,7 @@ public:
8283
8384private:
8485 _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
85 _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
86 _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_;
8687
8788 static constexpr bool _UseCache = forward_range<_View>;
8889 using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
lib/libcxx/include/__ranges/elements_view.h+7-7
......@@ -26,9 +26,9 @@
2626#include <__ranges/range_adaptor.h>
2727#include <__ranges/size.h>
2828#include <__ranges/view_interface.h>
29#include <__tuple_dir/tuple_element.h>
30#include <__tuple_dir/tuple_like.h>
31#include <__tuple_dir/tuple_size.h>
29#include <__tuple/tuple_element.h>
30#include <__tuple/tuple_like.h>
31#include <__tuple/tuple_size.h>
3232#include <__type_traits/is_reference.h>
3333#include <__type_traits/maybe_const.h>
3434#include <__type_traits/remove_cv.h>
......@@ -224,9 +224,9 @@ public:
224224 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
225225 requires forward_range<_Base>
226226 {
227 auto temp = *this;
227 auto __temp = *this;
228228 ++__current_;
229 return temp;
229 return __temp;
230230 }
231231
232232 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
......@@ -239,9 +239,9 @@ public:
239239 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
240240 requires bidirectional_range<_Base>
241241 {
242 auto temp = *this;
242 auto __temp = *this;
243243 --__current_;
244 return temp;
244 return __temp;
245245 }
246246
247247 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n)
lib/libcxx/include/__ranges/empty.h+2-2
......@@ -22,7 +22,7 @@
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727// [range.prim.empty]
2828
......@@ -75,7 +75,7 @@ inline namespace __cpo {
7575} // namespace __cpo
7676} // namespace ranges
7777
78#endif // _LIBCPP_STD_VER > 17
78#endif // _LIBCPP_STD_VER >= 20
7979
8080_LIBCPP_END_NAMESPACE_STD
8181
lib/libcxx/include/__ranges/empty_view.h+4-3
......@@ -13,7 +13,8 @@
1313#include <__config>
1414#include <__ranges/enable_borrowed_range.h>
1515#include <__ranges/view_interface.h>
16#include <type_traits>
16#include <__type_traits/is_object.h>
17#include <cstddef>
1718
1819#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1920# pragma GCC system_header
......@@ -21,7 +22,7 @@
2122
2223_LIBCPP_BEGIN_NAMESPACE_STD
2324
24#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2526
2627namespace ranges {
2728 template<class _Tp>
......@@ -46,7 +47,7 @@ namespace ranges {
4647 } // namespace views
4748} // namespace ranges
4849
49#endif // _LIBCPP_STD_VER > 17
50#endif // _LIBCPP_STD_VER >= 20
5051
5152_LIBCPP_END_NAMESPACE_STD
5253
lib/libcxx/include/__ranges/enable_borrowed_range.h+2-2
......@@ -22,7 +22,7 @@
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
25#if _LIBCPP_STD_VER > 17
25#if _LIBCPP_STD_VER >= 20
2626
2727namespace ranges {
2828
......@@ -33,7 +33,7 @@ inline constexpr bool enable_borrowed_range = false;
3333
3434} // namespace ranges
3535
36#endif // _LIBCPP_STD_VER > 17
36#endif // _LIBCPP_STD_VER >= 20
3737
3838_LIBCPP_END_NAMESPACE_STD
3939
lib/libcxx/include/__ranges/enable_view.h+2-2
......@@ -23,7 +23,7 @@
2323
2424_LIBCPP_BEGIN_NAMESPACE_STD
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727
2828namespace ranges {
2929
......@@ -43,7 +43,7 @@ inline constexpr bool enable_view = derived_from<_Tp, view_base> ||
4343
4444} // namespace ranges
4545
46#endif // _LIBCPP_STD_VER > 17
46#endif // _LIBCPP_STD_VER >= 20
4747
4848_LIBCPP_END_NAMESPACE_STD
4949
lib/libcxx/include/__ranges/filter_view.h+16-13
......@@ -11,12 +11,12 @@
1111#define _LIBCPP___RANGES_FILTER_VIEW_H
1212
1313#include <__algorithm/ranges_find_if.h>
14#include <__assert>
1415#include <__concepts/constructible.h>
1516#include <__concepts/copyable.h>
1617#include <__concepts/derived_from.h>
1718#include <__concepts/equality_comparable.h>
1819#include <__config>
19#include <__debug>
2020#include <__functional/bind_back.h>
2121#include <__functional/invoke.h>
2222#include <__functional/reference_wrapper.h>
......@@ -28,14 +28,17 @@
2828#include <__ranges/access.h>
2929#include <__ranges/all.h>
3030#include <__ranges/concepts.h>
31#include <__ranges/copyable_box.h>
31#include <__ranges/movable_box.h>
3232#include <__ranges/non_propagating_cache.h>
3333#include <__ranges/range_adaptor.h>
3434#include <__ranges/view_interface.h>
35#include <__type_traits/conditional.h>
36#include <__type_traits/decay.h>
37#include <__type_traits/is_nothrow_constructible.h>
38#include <__type_traits/is_object.h>
3539#include <__utility/forward.h>
3640#include <__utility/in_place.h>
3741#include <__utility/move.h>
38#include <type_traits>
3942
4043#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
4144# pragma GCC system_header
......@@ -43,14 +46,14 @@
4346
4447_LIBCPP_BEGIN_NAMESPACE_STD
4548
46#if _LIBCPP_STD_VER > 17
49#if _LIBCPP_STD_VER >= 20
4750
4851namespace ranges {
4952 template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
5053 requires view<_View> && is_object_v<_Pred>
5154 class filter_view : public view_interface<filter_view<_View, _Pred>> {
5255 _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
53 _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
56 _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_;
5457
5558 // We cache the result of begin() to allow providing an amortized O(1) begin() whenever
5659 // the underlying range is at least a forward_range.
......@@ -65,10 +68,8 @@ namespace ranges {
6568 _LIBCPP_HIDE_FROM_ABI
6669 filter_view() requires default_initializable<_View> && default_initializable<_Pred> = default;
6770
68 _LIBCPP_HIDE_FROM_ABI
69 constexpr filter_view(_View __base, _Pred __pred)
70 : __base_(std::move(__base)), __pred_(in_place, std::move(__pred))
71 { }
71 _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 filter_view(_View __base, _Pred __pred)
72 : __base_(std::move(__base)), __pred_(in_place, std::move(__pred)) {}
7273
7374 template<class _Vp = _View>
7475 _LIBCPP_HIDE_FROM_ABI
......@@ -81,7 +82,9 @@ namespace ranges {
8182
8283 _LIBCPP_HIDE_FROM_ABI
8384 constexpr __iterator begin() {
84 _LIBCPP_ASSERT(__pred_.__has_value(), "Trying to call begin() on a filter_view that does not have a valid predicate.");
85 _LIBCPP_ASSERT_UNCATEGORIZED(
86 __pred_.__has_value(),
87 "Trying to call begin() on a filter_view that does not have a valid predicate.");
8588 if constexpr (_UseCache) {
8689 if (!__cached_begin_.__has_value()) {
8790 __cached_begin_.__emplace(ranges::find_if(__base_, std::ref(*__pred_)));
......@@ -180,9 +183,9 @@ namespace ranges {
180183 }
181184 _LIBCPP_HIDE_FROM_ABI
182185 constexpr __iterator operator--(int) requires bidirectional_range<_View> {
183 auto tmp = *this;
186 auto __tmp = *this;
184187 --*this;
185 return tmp;
188 return __tmp;
186189 }
187190
188191 _LIBCPP_HIDE_FROM_ABI
......@@ -257,7 +260,7 @@ inline namespace __cpo {
257260
258261} // namespace ranges
259262
260#endif // _LIBCPP_STD_VER > 17
263#endif // _LIBCPP_STD_VER >= 20
261264
262265_LIBCPP_END_NAMESPACE_STD
263266
lib/libcxx/include/__ranges/from_range.h created+33
......@@ -0,0 +1,33 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_FROM_RANGE_H
11#define _LIBCPP___RANGES_FROM_RANGE_H
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21#if _LIBCPP_STD_VER >= 23
22
23struct from_range_t {
24 explicit from_range_t() = default;
25};
26
27inline constexpr from_range_t from_range{};
28
29#endif // _LIBCPP_STD_VER >= 23
30
31_LIBCPP_END_NAMESPACE_STD
32
33#endif // _LIBCPP___RANGES_FROM_RANGE_H
lib/libcxx/include/__ranges/iota_view.h+17-13
......@@ -27,12 +27,15 @@
2727#include <__iterator/incrementable_traits.h>
2828#include <__iterator/iterator_traits.h>
2929#include <__iterator/unreachable_sentinel.h>
30#include <__ranges/copyable_box.h>
3130#include <__ranges/enable_borrowed_range.h>
31#include <__ranges/movable_box.h>
3232#include <__ranges/view_interface.h>
33#include <__type_traits/conditional.h>
34#include <__type_traits/is_nothrow_copy_constructible.h>
35#include <__type_traits/make_unsigned.h>
36#include <__type_traits/type_identity.h>
3337#include <__utility/forward.h>
3438#include <__utility/move.h>
35#include <type_traits>
3639
3740#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3841# pragma GCC system_header
......@@ -40,12 +43,12 @@
4043
4144_LIBCPP_BEGIN_NAMESPACE_STD
4245
43#if _LIBCPP_STD_VER > 17
46#if _LIBCPP_STD_VER >= 20
4447
4548namespace ranges {
4649 template<class _Int>
4750 struct __get_wider_signed {
48 static auto __call() {
51 consteval static auto __call() {
4952 if constexpr (sizeof(_Int) < sizeof(short)) return type_identity<short>{};
5053 else if constexpr (sizeof(_Int) < sizeof(int)) return type_identity<int>{};
5154 else if constexpr (sizeof(_Int) < sizeof(long)) return type_identity<long>{};
......@@ -278,7 +281,8 @@ namespace ranges {
278281 public:
279282 _LIBCPP_HIDE_FROM_ABI
280283 __sentinel() = default;
281 constexpr explicit __sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {}
284 _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_BoundSentinel __bound_sentinel)
285 : __bound_sentinel_(std::move(__bound_sentinel)) {}
282286
283287 _LIBCPP_HIDE_FROM_ABI
284288 friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
......@@ -311,28 +315,28 @@ namespace ranges {
311315 constexpr explicit iota_view(_Start __value) : __value_(std::move(__value)) { }
312316
313317 _LIBCPP_HIDE_FROM_ABI
314 constexpr iota_view(type_identity_t<_Start> __value, type_identity_t<_BoundSentinel> __bound_sentinel)
318 constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(type_identity_t<_Start> __value, type_identity_t<_BoundSentinel> __bound_sentinel)
315319 : __value_(std::move(__value)), __bound_sentinel_(std::move(__bound_sentinel)) {
316320 // Validate the precondition if possible.
317321 if constexpr (totally_ordered_with<_Start, _BoundSentinel>) {
318 _LIBCPP_ASSERT(ranges::less_equal()(__value_, __bound_sentinel_),
319 "Precondition violated: value is greater than bound.");
322 _LIBCPP_ASSERT_UNCATEGORIZED(ranges::less_equal()(__value_, __bound_sentinel_),
323 "Precondition violated: value is greater than bound.");
320324 }
321325 }
322326
323327 _LIBCPP_HIDE_FROM_ABI
324 constexpr iota_view(__iterator __first, __iterator __last)
328 constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __iterator __last)
325329 requires same_as<_Start, _BoundSentinel>
326330 : iota_view(std::move(__first.__value_), std::move(__last.__value_)) {}
327331
328332 _LIBCPP_HIDE_FROM_ABI
329 constexpr iota_view(__iterator __first, _BoundSentinel __last)
333 constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, _BoundSentinel __last)
330334 requires same_as<_BoundSentinel, unreachable_sentinel_t>
331335 : iota_view(std::move(__first.__value_), std::move(__last)) {}
332336
333337 _LIBCPP_HIDE_FROM_ABI
334 constexpr iota_view(__iterator __first, __sentinel __last)
335 requires(!same_as<_Start, _BoundSentinel> && !same_as<_Start, unreachable_sentinel_t>)
338 constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __sentinel __last)
339 requires(!same_as<_Start, _BoundSentinel> && !same_as<_BoundSentinel, unreachable_sentinel_t>)
336340 : iota_view(std::move(__first.__value_), std::move(__last.__bound_sentinel_)) {}
337341
338342 _LIBCPP_HIDE_FROM_ABI
......@@ -403,7 +407,7 @@ inline namespace __cpo {
403407} // namespace views
404408} // namespace ranges
405409
406#endif // _LIBCPP_STD_VER > 17
410#endif // _LIBCPP_STD_VER >= 20
407411
408412_LIBCPP_END_NAMESPACE_STD
409413
lib/libcxx/include/__ranges/join_view.h+6-5
......@@ -22,6 +22,7 @@
2222#include <__iterator/iterator_traits.h>
2323#include <__iterator/iterator_with_data.h>
2424#include <__iterator/segmented_iterator.h>
25#include <__memory/addressof.h>
2526#include <__ranges/access.h>
2627#include <__ranges/all.h>
2728#include <__ranges/concepts.h>
......@@ -29,10 +30,10 @@
2930#include <__ranges/non_propagating_cache.h>
3031#include <__ranges/range_adaptor.h>
3132#include <__ranges/view_interface.h>
33#include <__type_traits/common_type.h>
3234#include <__type_traits/maybe_const.h>
3335#include <__utility/forward.h>
3436#include <optional>
35#include <type_traits>
3637
3738#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3839# pragma GCC system_header
......@@ -43,7 +44,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
4344// Note: `join_view` is still marked experimental because there is an ABI-breaking change that affects `join_view` in
4445// the pipeline (https://isocpp.org/files/papers/D2770R0.html).
4546// TODO: make `join_view` non-experimental once D2770 is implemented.
46#if _LIBCPP_STD_VER > 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
47#if _LIBCPP_STD_VER >= 20 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
4748
4849namespace ranges {
4950 template<class>
......@@ -394,8 +395,8 @@ inline namespace __cpo {
394395template <class _JoinViewIterator>
395396 requires(_JoinViewIterator::__is_join_view_iterator &&
396397 ranges::common_range<typename _JoinViewIterator::_Parent> &&
397 __is_cpp17_random_access_iterator<typename _JoinViewIterator::_Outer>::value &&
398 __is_cpp17_random_access_iterator<typename _JoinViewIterator::_Inner>::value)
398 __has_random_access_iterator_category<typename _JoinViewIterator::_Outer>::value &&
399 __has_random_access_iterator_category<typename _JoinViewIterator::_Inner>::value)
399400struct __segmented_iterator_traits<_JoinViewIterator> {
400401
401402 using __segment_iterator =
......@@ -435,7 +436,7 @@ struct __segmented_iterator_traits<_JoinViewIterator> {
435436 }
436437};
437438
438#endif // #if _LIBCPP_STD_VER > 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
439#endif // #if _LIBCPP_STD_VER >= 20 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
439440
440441_LIBCPP_END_NAMESPACE_STD
441442
lib/libcxx/include/__ranges/lazy_split_view.h+11-7
......@@ -12,6 +12,7 @@
1212
1313#include <__algorithm/ranges_find.h>
1414#include <__algorithm/ranges_mismatch.h>
15#include <__assert>
1516#include <__concepts/constructible.h>
1617#include <__concepts/convertible_to.h>
1718#include <__concepts/derived_from.h>
......@@ -34,10 +35,13 @@
3435#include <__ranges/single_view.h>
3536#include <__ranges/subrange.h>
3637#include <__ranges/view_interface.h>
38#include <__type_traits/conditional.h>
39#include <__type_traits/decay.h>
40#include <__type_traits/is_nothrow_constructible.h>
3741#include <__type_traits/maybe_const.h>
42#include <__type_traits/remove_reference.h>
3843#include <__utility/forward.h>
3944#include <__utility/move.h>
40#include <type_traits>
4145
4246#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
4347# pragma GCC system_header
......@@ -45,7 +49,7 @@
4549
4650_LIBCPP_BEGIN_NAMESPACE_STD
4751
48#if _LIBCPP_STD_VER > 17
52#if _LIBCPP_STD_VER >= 20
4953
5054namespace ranges {
5155
......@@ -78,14 +82,14 @@ public:
7882 requires default_initializable<_View> && default_initializable<_Pattern> = default;
7983
8084 _LIBCPP_HIDE_FROM_ABI
81 constexpr lazy_split_view(_View __base, _Pattern __pattern)
85 constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 lazy_split_view(_View __base, _Pattern __pattern)
8286 : __base_(std::move(__base)), __pattern_(std::move(__pattern)) {}
8387
8488 template <input_range _Range>
8589 requires constructible_from<_View, views::all_t<_Range>> &&
8690 constructible_from<_Pattern, single_view<range_value_t<_Range>>>
8791 _LIBCPP_HIDE_FROM_ABI
88 constexpr lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
92 constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
8993 : __base_(views::all(std::forward<_Range>(__r)))
9094 , __pattern_(views::single(std::move(__e))) {}
9195
......@@ -276,7 +280,7 @@ private:
276280
277281 _LIBCPP_HIDE_FROM_ABI
278282 friend constexpr bool operator==(const __outer_iterator& __x, default_sentinel_t) {
279 _LIBCPP_ASSERT(__x.__parent_, "Cannot call comparison on a default-constructed iterator.");
283 _LIBCPP_ASSERT_UNCATEGORIZED(__x.__parent_, "Cannot call comparison on a default-constructed iterator.");
280284 return __x.__current() == ranges::end(__x.__parent_base()) && !__x.__trailing_empty_;
281285 }
282286 };
......@@ -307,7 +311,7 @@ private:
307311
308312 _LIBCPP_HIDE_FROM_ABI
309313 constexpr bool __is_done() const {
310 _LIBCPP_ASSERT(__i_.__parent_, "Cannot call comparison on a default-constructed iterator.");
314 _LIBCPP_ASSERT_UNCATEGORIZED(__i_.__parent_, "Cannot call comparison on a default-constructed iterator.");
311315
312316 auto [__pcur, __pend] = ranges::subrange{__i_.__parent_->__pattern_};
313317 auto __end = ranges::end(__i_.__parent_->__base_);
......@@ -458,7 +462,7 @@ inline namespace __cpo {
458462
459463} // namespace ranges
460464
461#endif // _LIBCPP_STD_VER > 17
465#endif // _LIBCPP_STD_VER >= 20
462466
463467_LIBCPP_END_NAMESPACE_STD
464468
lib/libcxx/include/__ranges/movable_box.h created+206
......@@ -0,0 +1,206 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_MOVABLE_BOX_H
11#define _LIBCPP___RANGES_MOVABLE_BOX_H
12
13#include <__concepts/constructible.h>
14#include <__concepts/copyable.h>
15#include <__concepts/movable.h>
16#include <__config>
17#include <__memory/addressof.h>
18#include <__memory/construct_at.h>
19#include <__type_traits/is_nothrow_constructible.h>
20#include <__type_traits/is_nothrow_copy_constructible.h>
21#include <__type_traits/is_nothrow_default_constructible.h>
22#include <__utility/move.h>
23#include <optional>
24
25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26# pragma GCC system_header
27#endif
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31#if _LIBCPP_STD_VER >= 20
32
33// __movable_box allows turning a type that is move-constructible (but maybe not move-assignable) into
34// a type that is both move-constructible and move-assignable. It does that by introducing an empty state
35// and basically doing destroy-then-copy-construct in the assignment operator. The empty state is necessary
36// to handle the case where the copy construction fails after destroying the object.
37//
38// In some cases, we can completely avoid the use of an empty state; we provide a specialization of
39// __movable_box that does this, see below for the details.
40
41// until C++23, `__movable_box` was named `__copyable_box` and required the stored type to be copy-constructible, not
42// just move-constructible; we preserve the old behavior in pre-C++23 modes.
43template <class _Tp>
44concept __movable_box_object =
45# if _LIBCPP_STD_VER >= 23
46 move_constructible<_Tp>
47# else
48 copy_constructible<_Tp>
49# endif
50 && is_object_v<_Tp>;
51
52namespace ranges {
53// Primary template - uses std::optional and introduces an empty state in case assignment fails.
54template <__movable_box_object _Tp>
55class __movable_box {
56 _LIBCPP_NO_UNIQUE_ADDRESS optional<_Tp> __val_;
57
58public:
59 template <class... _Args>
60 requires is_constructible_v<_Tp, _Args...>
61 _LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box(in_place_t, _Args&&... __args) noexcept(
62 is_nothrow_constructible_v<_Tp, _Args...>)
63 : __val_(in_place, std::forward<_Args>(__args)...) {}
64
65 _LIBCPP_HIDE_FROM_ABI constexpr __movable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
66 requires default_initializable<_Tp>
67 : __val_(in_place) {}
68
69 _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box const&) = default;
70 _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box&&) = default;
71
72 _LIBCPP_HIDE_FROM_ABI constexpr __movable_box&
73 operator=(__movable_box const& __other) noexcept(is_nothrow_copy_constructible_v<_Tp>)
74# if _LIBCPP_STD_VER >= 23
75 requires copy_constructible<_Tp>
76# endif
77 {
78 if (this != std::addressof(__other)) {
79 if (__other.__has_value())
80 __val_.emplace(*__other);
81 else
82 __val_.reset();
83 }
84 return *this;
85 }
86
87 _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box&&)
88 requires movable<_Tp>
89 = default;
90
91 _LIBCPP_HIDE_FROM_ABI constexpr __movable_box&
92 operator=(__movable_box&& __other) noexcept(is_nothrow_move_constructible_v<_Tp>) {
93 if (this != std::addressof(__other)) {
94 if (__other.__has_value())
95 __val_.emplace(std::move(*__other));
96 else
97 __val_.reset();
98 }
99 return *this;
100 }
101
102 _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; }
103 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; }
104
105 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { return __val_.operator->(); }
106 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { return __val_.operator->(); }
107
108 _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); }
109};
110
111// This partial specialization implements an optimization for when we know we don't need to store
112// an empty state to represent failure to perform an assignment. For copy-assignment, this happens:
113//
114// 1. If the type is copyable (which includes copy-assignment), we can use the type's own assignment operator
115// directly and avoid using std::optional.
116// 2. If the type is not copyable, but it is nothrow-copy-constructible, then we can implement assignment as
117// destroy-and-then-construct and we know it will never fail, so we don't need an empty state.
118//
119// The exact same reasoning can be applied for move-assignment, with copyable replaced by movable and
120// nothrow-copy-constructible replaced by nothrow-move-constructible. This specialization is enabled
121// whenever we can apply any of these optimizations for both the copy assignment and the move assignment
122// operator.
123
124# if _LIBCPP_STD_VER >= 23
125template <class _Tp>
126concept __doesnt_need_empty_state =
127 (copy_constructible<_Tp>
128 // 1. If copy_constructible<T> is true, movable-box<T> should store only a T if either T models
129 // copyable, or is_nothrow_move_constructible_v<T> && is_nothrow_copy_constructible_v<T> is true.
130 ? copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Tp>)
131 // 2. Otherwise, movable-box<T> should store only a T if either T models movable or
132 // is_nothrow_move_constructible_v<T> is true.
133 : movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
134# else
135
136template <class _Tp>
137concept __doesnt_need_empty_state_for_copy = copyable<_Tp> || is_nothrow_copy_constructible_v<_Tp>;
138
139template <class _Tp>
140concept __doesnt_need_empty_state_for_move = movable<_Tp> || is_nothrow_move_constructible_v<_Tp>;
141
142template <class _Tp>
143concept __doesnt_need_empty_state = __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp>;
144# endif
145
146template <__movable_box_object _Tp>
147 requires __doesnt_need_empty_state<_Tp>
148class __movable_box<_Tp> {
149 _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
150
151public:
152 template <class... _Args>
153 requires is_constructible_v<_Tp, _Args...>
154 _LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box(in_place_t, _Args&&... __args) noexcept(
155 is_nothrow_constructible_v<_Tp, _Args...>)
156 : __val_(std::forward<_Args>(__args)...) {}
157
158 _LIBCPP_HIDE_FROM_ABI constexpr __movable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
159 requires default_initializable<_Tp>
160 : __val_() {}
161
162 _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box const&) = default;
163 _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box&&) = default;
164
165 // Implementation of assignment operators in case we perform optimization (1)
166 _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box const&)
167 requires copyable<_Tp>
168 = default;
169 _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box&&)
170 requires movable<_Tp>
171 = default;
172
173 // Implementation of assignment operators in case we perform optimization (2)
174 _LIBCPP_HIDE_FROM_ABI constexpr __movable_box& operator=(__movable_box const& __other) noexcept {
175 static_assert(is_nothrow_copy_constructible_v<_Tp>);
176 if (this != std::addressof(__other)) {
177 std::destroy_at(std::addressof(__val_));
178 std::construct_at(std::addressof(__val_), __other.__val_);
179 }
180 return *this;
181 }
182
183 _LIBCPP_HIDE_FROM_ABI constexpr __movable_box& operator=(__movable_box&& __other) noexcept {
184 static_assert(is_nothrow_move_constructible_v<_Tp>);
185 if (this != std::addressof(__other)) {
186 std::destroy_at(std::addressof(__val_));
187 std::construct_at(std::addressof(__val_), std::move(__other.__val_));
188 }
189 return *this;
190 }
191
192 _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; }
193 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; }
194
195 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { return std::addressof(__val_); }
196 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { return std::addressof(__val_); }
197
198 _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; }
199};
200} // namespace ranges
201
202#endif // _LIBCPP_STD_VER >= 20
203
204_LIBCPP_END_NAMESPACE_STD
205
206#endif // _LIBCPP___RANGES_MOVABLE_BOX_H
lib/libcxx/include/__ranges/non_propagating_cache.h+7-7
......@@ -16,7 +16,6 @@
1616#include <__memory/addressof.h>
1717#include <__utility/forward.h>
1818#include <optional>
19#include <type_traits>
2019
2120#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2221# pragma GCC system_header
......@@ -24,7 +23,7 @@
2423
2524_LIBCPP_BEGIN_NAMESPACE_STD
2625
27#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2827
2928namespace ranges {
3029 // __non_propagating_cache is a helper type that allows storing an optional value in it,
......@@ -44,10 +43,11 @@ namespace ranges {
4443 // This helper class is needed to perform copy and move elision when
4544 // constructing the contained type from an iterator.
4645 struct __wrapper {
47 template<class ..._Args>
48 constexpr explicit __wrapper(__forward_tag, _Args&& ...__args) : __t_(std::forward<_Args>(__args)...) { }
49 template<class _Fn>
50 constexpr explicit __wrapper(__from_tag, _Fn const& __f) : __t_(__f()) { }
46 template <class... _Args>
47 _LIBCPP_HIDE_FROM_ABI constexpr explicit __wrapper(__forward_tag, _Args&&... __args)
48 : __t_(std::forward<_Args>(__args)...) {}
49 template <class _Fn>
50 _LIBCPP_HIDE_FROM_ABI constexpr explicit __wrapper(__from_tag, _Fn const& __f) : __t_(__f()) {}
5151 _Tp __t_;
5252 };
5353
......@@ -107,7 +107,7 @@ namespace ranges {
107107 struct __empty_cache { };
108108} // namespace ranges
109109
110#endif // _LIBCPP_STD_VER > 17
110#endif // _LIBCPP_STD_VER >= 20
111111
112112_LIBCPP_END_NAMESPACE_STD
113113
lib/libcxx/include/__ranges/owning_view.h+11-6
......@@ -20,16 +20,19 @@
2020#include <__ranges/enable_borrowed_range.h>
2121#include <__ranges/size.h>
2222#include <__ranges/view_interface.h>
23#include <__type_traits/remove_cvref.h>
2324#include <__utility/move.h>
24#include <type_traits>
2525
2626#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2727# pragma GCC system_header
2828#endif
2929
30_LIBCPP_PUSH_MACROS
31#include <__undef_macros>
32
3033_LIBCPP_BEGIN_NAMESPACE_STD
3134
32#if _LIBCPP_STD_VER > 17
35#if _LIBCPP_STD_VER >= 20
3336
3437namespace ranges {
3538 template<range _Rp>
......@@ -38,11 +41,11 @@ namespace ranges {
3841 _Rp __r_ = _Rp();
3942
4043public:
41 owning_view() requires default_initializable<_Rp> = default;
44 _LIBCPP_HIDE_FROM_ABI owning_view() requires default_initializable<_Rp> = default;
4245 _LIBCPP_HIDE_FROM_ABI constexpr owning_view(_Rp&& __r) : __r_(std::move(__r)) {}
4346
44 owning_view(owning_view&&) = default;
45 owning_view& operator=(owning_view&&) = default;
47 _LIBCPP_HIDE_FROM_ABI owning_view(owning_view&&) = default;
48 _LIBCPP_HIDE_FROM_ABI owning_view& operator=(owning_view&&) = default;
4649
4750 _LIBCPP_HIDE_FROM_ABI constexpr _Rp& base() & noexcept { return __r_; }
4851 _LIBCPP_HIDE_FROM_ABI constexpr const _Rp& base() const& noexcept { return __r_; }
......@@ -76,8 +79,10 @@ public:
7679
7780} // namespace ranges
7881
79#endif // _LIBCPP_STD_VER > 17
82#endif // _LIBCPP_STD_VER >= 20
8083
8184_LIBCPP_END_NAMESPACE_STD
8285
86_LIBCPP_POP_MACROS
87
8388#endif // _LIBCPP___RANGES_OWNING_VIEW_H
lib/libcxx/include/__ranges/range_adaptor.h+11-4
......@@ -18,17 +18,22 @@
1818#include <__functional/compose.h>
1919#include <__functional/invoke.h>
2020#include <__ranges/concepts.h>
21#include <__type_traits/decay.h>
22#include <__type_traits/is_nothrow_constructible.h>
23#include <__type_traits/remove_cvref.h>
2124#include <__utility/forward.h>
2225#include <__utility/move.h>
23#include <type_traits>
2426
2527#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2628# pragma GCC system_header
2729#endif
2830
31_LIBCPP_PUSH_MACROS
32#include <__undef_macros>
33
2934_LIBCPP_BEGIN_NAMESPACE_STD
3035
31#if _LIBCPP_STD_VER > 17
36#if _LIBCPP_STD_VER >= 20
3237
3338// CRTP base that one can derive from in order to be considered a range adaptor closure
3439// by the library. When deriving from this class, a pipe operator will be provided to
......@@ -42,7 +47,7 @@ struct __range_adaptor_closure;
4247// i.e. something that can be called via the `x | f` notation.
4348template <class _Fn>
4449struct __range_adaptor_closure_t : _Fn, __range_adaptor_closure<__range_adaptor_closure_t<_Fn>> {
45 constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(std::move(__f)) { }
50 _LIBCPP_HIDE_FROM_ABI constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(std::move(__f)) { }
4651};
4752_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__range_adaptor_closure_t);
4853
......@@ -70,8 +75,10 @@ struct __range_adaptor_closure {
7075 { return __range_adaptor_closure_t(std::__compose(std::forward<_OtherClosure>(__c2), std::forward<_Closure>(__c1))); }
7176};
7277
73#endif // _LIBCPP_STD_VER > 17
78#endif // _LIBCPP_STD_VER >= 20
7479
7580_LIBCPP_END_NAMESPACE_STD
7681
82_LIBCPP_POP_MACROS
83
7784#endif // _LIBCPP___RANGES_RANGE_ADAPTOR_H
lib/libcxx/include/__ranges/rbegin.h+6-3
......@@ -17,8 +17,11 @@
1717#include <__iterator/readable_traits.h>
1818#include <__iterator/reverse_iterator.h>
1919#include <__ranges/access.h>
20#include <__type_traits/decay.h>
21#include <__type_traits/is_reference.h>
22#include <__type_traits/remove_cvref.h>
23#include <__type_traits/remove_reference.h>
2024#include <__utility/auto_cast.h>
21#include <type_traits>
2225
2326#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2427# pragma GCC system_header
......@@ -26,7 +29,7 @@
2629
2730_LIBCPP_BEGIN_NAMESPACE_STD
2831
29#if _LIBCPP_STD_VER > 17
32#if _LIBCPP_STD_VER >= 20
3033
3134// [ranges.access.rbegin]
3235
......@@ -124,7 +127,7 @@ inline namespace __cpo {
124127} // namespace __cpo
125128} // namespace ranges
126129
127#endif // _LIBCPP_STD_VER > 17
130#endif // _LIBCPP_STD_VER >= 20
128131
129132_LIBCPP_END_NAMESPACE_STD
130133
lib/libcxx/include/__ranges/ref_view.h+4-3
......@@ -24,8 +24,9 @@
2424#include <__ranges/enable_borrowed_range.h>
2525#include <__ranges/size.h>
2626#include <__ranges/view_interface.h>
27#include <__type_traits/is_object.h>
28#include <__utility/declval.h>
2729#include <__utility/forward.h>
28#include <type_traits>
2930
3031#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3132# pragma GCC system_header
......@@ -33,7 +34,7 @@
3334
3435_LIBCPP_BEGIN_NAMESPACE_STD
3536
36#if _LIBCPP_STD_VER > 17
37#if _LIBCPP_STD_VER >= 20
3738
3839namespace ranges {
3940 template<range _Range>
......@@ -81,7 +82,7 @@ public:
8182 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
8283} // namespace ranges
8384
84#endif // _LIBCPP_STD_VER > 17
85#endif // _LIBCPP_STD_VER >= 20
8586
8687_LIBCPP_END_NAMESPACE_STD
8788
lib/libcxx/include/__ranges/rend.h+6-3
......@@ -18,8 +18,11 @@
1818#include <__iterator/reverse_iterator.h>
1919#include <__ranges/access.h>
2020#include <__ranges/rbegin.h>
21#include <__type_traits/decay.h>
22#include <__type_traits/is_reference.h>
23#include <__type_traits/remove_cvref.h>
24#include <__type_traits/remove_reference.h>
2125#include <__utility/auto_cast.h>
22#include <type_traits>
2326
2427#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2528# pragma GCC system_header
......@@ -27,7 +30,7 @@
2730
2831_LIBCPP_BEGIN_NAMESPACE_STD
2932
30#if _LIBCPP_STD_VER > 17
33#if _LIBCPP_STD_VER >= 20
3134
3235// [range.access.rend]
3336
......@@ -128,7 +131,7 @@ inline namespace __cpo {
128131} // namespace __cpo
129132} // namespace ranges
130133
131#endif // _LIBCPP_STD_VER > 17
134#endif // _LIBCPP_STD_VER >= 20
132135
133136_LIBCPP_END_NAMESPACE_STD
134137
lib/libcxx/include/__ranges/repeat_view.h created+260
......@@ -0,0 +1,260 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_REPEAT_VIEW_H
11#define _LIBCPP___RANGES_REPEAT_VIEW_H
12
13#include <__concepts/constructible.h>
14#include <__concepts/same_as.h>
15#include <__concepts/semiregular.h>
16#include <__config>
17#include <__iterator/concepts.h>
18#include <__iterator/iterator_traits.h>
19#include <__iterator/unreachable_sentinel.h>
20#include <__memory/addressof.h>
21#include <__ranges/iota_view.h>
22#include <__ranges/movable_box.h>
23#include <__ranges/view_interface.h>
24#include <__type_traits/is_object.h>
25#include <__type_traits/make_unsigned.h>
26#include <__type_traits/remove_cv.h>
27#include <__utility/forward.h>
28#include <__utility/in_place.h>
29#include <__utility/move.h>
30#include <__utility/piecewise_construct.h>
31#include <tuple>
32
33#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
34# pragma GCC system_header
35#endif
36
37_LIBCPP_BEGIN_NAMESPACE_STD
38
39#if _LIBCPP_STD_VER >= 23
40
41namespace ranges {
42
43template <class _Tp>
44concept __integer_like_with_usable_difference_type =
45 __signed_integer_like<_Tp> || (__integer_like<_Tp> && weakly_incrementable<_Tp>);
46
47template <class _Tp>
48struct __repeat_view_iterator_difference {
49 using type = _IotaDiffT<_Tp>;
50};
51
52template <__signed_integer_like _Tp>
53struct __repeat_view_iterator_difference<_Tp> {
54 using type = _Tp;
55};
56
57template <class _Tp>
58using __repeat_view_iterator_difference_t = typename __repeat_view_iterator_difference<_Tp>::type;
59
60namespace views::__drop {
61struct __fn;
62} // namespace views::__drop
63
64namespace views::__take {
65struct __fn;
66} // namespace views::__take
67
68template <move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
69 requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> &&
70 (__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>))
71class repeat_view : public view_interface<repeat_view<_Tp, _Bound>> {
72 friend struct views::__take::__fn;
73 friend struct views::__drop::__fn;
74 class __iterator;
75
76public:
77 _LIBCPP_HIDE_FROM_ABI repeat_view()
78 requires default_initializable<_Tp>
79 = default;
80
81 _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(const _Tp& __value, _Bound __bound_sentinel = _Bound())
82 requires copy_constructible<_Tp>
83 : __value_(in_place, __value), __bound_(__bound_sentinel) {
84 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
85 _LIBCPP_ASSERT(__bound_ >= 0, "The value of bound must be greater than or equal to 0");
86 }
87
88 _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(_Tp&& __value, _Bound __bound_sentinel = _Bound())
89 : __value_(in_place, std::move(__value)), __bound_(__bound_sentinel) {
90 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
91 _LIBCPP_ASSERT(__bound_ >= 0, "The value of bound must be greater than or equal to 0");
92 }
93
94 template <class... _TpArgs, class... _BoundArgs>
95 requires(constructible_from<_Tp, _TpArgs...> && constructible_from<_Bound, _BoundArgs...>)
96 _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(
97 piecewise_construct_t, tuple<_TpArgs...> __value_args, tuple<_BoundArgs...> __bound_args = tuple<>{})
98 : __value_(in_place, std::make_from_tuple<_Tp>(std::move(__value_args))),
99 __bound_(std::make_from_tuple<_Bound>(std::move(__bound_args))) {
100 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
101 _LIBCPP_ASSERT(
102 __bound_ >= 0, "The behavior is undefined if Bound is not unreachable_sentinel_t and bound is negative");
103 }
104
105 _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() const { return __iterator(std::addressof(*__value_)); }
106
107 _LIBCPP_HIDE_FROM_ABI constexpr __iterator end() const
108 requires(!same_as<_Bound, unreachable_sentinel_t>)
109 {
110 return __iterator(std::addressof(*__value_), __bound_);
111 }
112
113 _LIBCPP_HIDE_FROM_ABI constexpr unreachable_sentinel_t end() const noexcept { return unreachable_sentinel; }
114
115 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
116 requires(!same_as<_Bound, unreachable_sentinel_t>)
117 {
118 return std::__to_unsigned_like(__bound_);
119 }
120
121private:
122 __movable_box<_Tp> __value_;
123 _LIBCPP_NO_UNIQUE_ADDRESS _Bound __bound_ = _Bound();
124};
125
126template <class _Tp, class _Bound>
127repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>;
128
129// [range.repeat.iterator]
130template <move_constructible _Tp, semiregular _Bound>
131 requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> &&
132 (__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>))
133class repeat_view<_Tp, _Bound>::__iterator {
134 friend class repeat_view;
135
136 using _IndexT = conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
137
138 _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(const _Tp* __value, _IndexT __bound_sentinel = _IndexT())
139 : __value_(__value), __current_(__bound_sentinel) {}
140
141public:
142 using iterator_concept = random_access_iterator_tag;
143 using iterator_category = random_access_iterator_tag;
144 using value_type = _Tp;
145 using difference_type = __repeat_view_iterator_difference_t<_IndexT>;
146
147 _LIBCPP_HIDE_FROM_ABI __iterator() = default;
148
149 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const noexcept { return *__value_; }
150
151 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
152 ++__current_;
153 return *this;
154 }
155
156 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) {
157 auto __tmp = *this;
158 ++*this;
159 return __tmp;
160 }
161
162 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--() {
163 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
164 _LIBCPP_ASSERT(__current_ > 0, "The value of bound must be greater than or equal to 0");
165 --__current_;
166 return *this;
167 }
168
169 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) {
170 auto __tmp = *this;
171 --*this;
172 return __tmp;
173 }
174
175 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n) {
176 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
177 _LIBCPP_ASSERT(__current_ + __n >= 0, "The value of bound must be greater than or equal to 0");
178 __current_ += __n;
179 return *this;
180 }
181
182 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n) {
183 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
184 _LIBCPP_ASSERT(__current_ - __n >= 0, "The value of bound must be greater than or equal to 0");
185 __current_ -= __n;
186 return *this;
187 }
188
189 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](difference_type __n) const noexcept { return *(*this + __n); }
190
191 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
192 return __x.__current_ == __y.__current_;
193 }
194
195 _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) {
196 return __x.__current_ <=> __y.__current_;
197 }
198
199 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n) {
200 __i += __n;
201 return __i;
202 }
203
204 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i) {
205 __i += __n;
206 return __i;
207 }
208
209 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n) {
210 __i -= __n;
211 return __i;
212 }
213
214 _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) {
215 return static_cast<difference_type>(__x.__current_) - static_cast<difference_type>(__y.__current_);
216 }
217
218private:
219 const _Tp* __value_ = nullptr;
220 _IndexT __current_ = _IndexT();
221};
222
223// clang-format off
224namespace views {
225namespace __repeat {
226struct __fn {
227 template <class _Tp>
228 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __value) const
229 noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value))))
230 -> decltype( ranges::repeat_view(std::forward<_Tp>(__value)))
231 { return ranges::repeat_view(std::forward<_Tp>(__value)); }
232
233
234 template <class _Tp, class _Bound>
235 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __value, _Bound&& __bound_sentinel) const
236 noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel))))
237 -> decltype( ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)))
238 { return ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)); }
239};
240} // namespace __repeat
241// clang-format on
242
243inline namespace __cpo {
244inline constexpr auto repeat = __repeat::__fn{};
245} // namespace __cpo
246} // namespace views
247
248template <class _Tp>
249inline constexpr bool __is_repeat_specialization = false;
250
251template <class _Tp, class _Bound>
252inline constexpr bool __is_repeat_specialization<repeat_view<_Tp, _Bound>> = true;
253
254} // namespace ranges
255
256#endif // _LIBCPP_STD_VER >= 23
257
258_LIBCPP_END_NAMESPACE_STD
259
260#endif // _LIBCPP___RANGES_REPEAT_VIEW_H
lib/libcxx/include/__ranges/reverse_view.h+4-3
......@@ -24,9 +24,10 @@
2424#include <__ranges/size.h>
2525#include <__ranges/subrange.h>
2626#include <__ranges/view_interface.h>
27#include <__type_traits/conditional.h>
28#include <__type_traits/remove_cvref.h>
2729#include <__utility/forward.h>
2830#include <__utility/move.h>
29#include <type_traits>
3031
3132#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3233# pragma GCC system_header
......@@ -34,7 +35,7 @@
3435
3536_LIBCPP_BEGIN_NAMESPACE_STD
3637
37#if _LIBCPP_STD_VER > 17
38#if _LIBCPP_STD_VER >= 20
3839
3940namespace ranges {
4041 template<view _View>
......@@ -184,7 +185,7 @@ namespace ranges {
184185 } // namespace views
185186} // namespace ranges
186187
187#endif // _LIBCPP_STD_VER > 17
188#endif // _LIBCPP_STD_VER >= 20
188189
189190_LIBCPP_END_NAMESPACE_STD
190191
lib/libcxx/include/__ranges/single_view.h+40-38
......@@ -12,13 +12,15 @@
1212
1313#include <__concepts/constructible.h>
1414#include <__config>
15#include <__ranges/copyable_box.h>
15#include <__ranges/movable_box.h>
1616#include <__ranges/range_adaptor.h>
1717#include <__ranges/view_interface.h>
18#include <__type_traits/decay.h>
19#include <__type_traits/is_object.h>
1820#include <__utility/forward.h>
1921#include <__utility/in_place.h>
2022#include <__utility/move.h>
21#include <type_traits>
23#include <cstddef>
2224
2325#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2426# pragma GCC system_header
......@@ -26,51 +28,51 @@
2628
2729_LIBCPP_BEGIN_NAMESPACE_STD
2830
29#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
3032
3133namespace ranges {
32 template<copy_constructible _Tp>
33 requires is_object_v<_Tp>
34 class single_view : public view_interface<single_view<_Tp>> {
35 __copyable_box<_Tp> __value_;
36
37 public:
38 _LIBCPP_HIDE_FROM_ABI
39 single_view() requires default_initializable<_Tp> = default;
40
41 _LIBCPP_HIDE_FROM_ABI
42 constexpr explicit single_view(const _Tp& __t) : __value_(in_place, __t) {}
43
44 _LIBCPP_HIDE_FROM_ABI
45 constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {}
46
47 template<class... _Args>
48 requires constructible_from<_Tp, _Args...>
49 _LIBCPP_HIDE_FROM_ABI
50 constexpr explicit single_view(in_place_t, _Args&&... __args)
34# if _LIBCPP_STD_VER >= 23
35template <move_constructible _Tp>
36# else
37template <copy_constructible _Tp>
38# endif
39 requires is_object_v<_Tp>
40class single_view : public view_interface<single_view<_Tp>> {
41 __movable_box<_Tp> __value_;
42
43public:
44 _LIBCPP_HIDE_FROM_ABI single_view()
45 requires default_initializable<_Tp>
46 = default;
47
48 _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(const _Tp& __t)
49# if _LIBCPP_STD_VER >= 23
50 requires copy_constructible<_Tp>
51# endif
52 : __value_(in_place, __t) {
53 }
54
55 _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {}
56
57 template <class... _Args>
58 requires constructible_from<_Tp, _Args...>
59 _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(in_place_t, _Args&&... __args)
5160 : __value_{in_place, std::forward<_Args>(__args)...} {}
5261
53 _LIBCPP_HIDE_FROM_ABI
54 constexpr _Tp* begin() noexcept { return data(); }
62 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* begin() noexcept { return data(); }
5563
56 _LIBCPP_HIDE_FROM_ABI
57 constexpr const _Tp* begin() const noexcept { return data(); }
64 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* begin() const noexcept { return data(); }
5865
59 _LIBCPP_HIDE_FROM_ABI
60 constexpr _Tp* end() noexcept { return data() + 1; }
66 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* end() noexcept { return data() + 1; }
6167
62 _LIBCPP_HIDE_FROM_ABI
63 constexpr const _Tp* end() const noexcept { return data() + 1; }
68 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* end() const noexcept { return data() + 1; }
6469
65 _LIBCPP_HIDE_FROM_ABI
66 static constexpr size_t size() noexcept { return 1; }
70 _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 1; }
6771
68 _LIBCPP_HIDE_FROM_ABI
69 constexpr _Tp* data() noexcept { return __value_.operator->(); }
72 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* data() noexcept { return __value_.operator->(); }
7073
71 _LIBCPP_HIDE_FROM_ABI
72 constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
73 };
74 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
75};
7476
7577template<class _Tp>
7678single_view(_Tp) -> single_view<_Tp>;
......@@ -95,7 +97,7 @@ inline namespace __cpo {
9597} // namespace views
9698} // namespace ranges
9799
98#endif // _LIBCPP_STD_VER > 17
100#endif // _LIBCPP_STD_VER >= 20
99101
100102_LIBCPP_END_NAMESPACE_STD
101103
lib/libcxx/include/__ranges/size.h+2-2
......@@ -30,7 +30,7 @@
3030
3131_LIBCPP_BEGIN_NAMESPACE_STD
3232
33#if _LIBCPP_STD_VER > 17
33#if _LIBCPP_STD_VER >= 20
3434
3535namespace ranges {
3636 template<class>
......@@ -141,7 +141,7 @@ inline namespace __cpo {
141141} // namespace __cpo
142142} // namespace ranges
143143
144#endif // _LIBCPP_STD_VER > 17
144#endif // _LIBCPP_STD_VER >= 20
145145
146146_LIBCPP_END_NAMESPACE_STD
147147
lib/libcxx/include/__ranges/split_view.h+3-2
......@@ -75,13 +75,14 @@ public:
7575 requires default_initializable<_View> && default_initializable<_Pattern>
7676 = default;
7777
78 _LIBCPP_HIDE_FROM_ABI constexpr split_view(_View __base, _Pattern __pattern)
78 _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 split_view(_View __base, _Pattern __pattern)
7979 : __base_(std::move(__base)), __pattern_(std::move((__pattern))) {}
8080
8181 template <forward_range _Range>
8282 requires constructible_from<_View, views::all_t<_Range>> &&
8383 constructible_from<_Pattern, single_view<range_value_t<_Range>>>
84 _LIBCPP_HIDE_FROM_ABI constexpr split_view(_Range&& __range, range_value_t<_Range> __elem)
84 _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23
85 split_view(_Range&& __range, range_value_t<_Range> __elem)
8586 : __base_(views::all(std::forward<_Range>(__range))), __pattern_(views::single(std::move(__elem))) {}
8687
8788 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
lib/libcxx/include/__ranges/subrange.h+12-7
......@@ -29,9 +29,9 @@
2929#include <__ranges/enable_borrowed_range.h>
3030#include <__ranges/size.h>
3131#include <__ranges/view_interface.h>
32#include <__tuple_dir/pair_like.h>
33#include <__tuple_dir/tuple_element.h>
34#include <__tuple_dir/tuple_size.h>
32#include <__tuple/pair_like.h>
33#include <__tuple/tuple_element.h>
34#include <__tuple/tuple_size.h>
3535#include <__type_traits/conditional.h>
3636#include <__type_traits/decay.h>
3737#include <__type_traits/is_pointer.h>
......@@ -46,9 +46,12 @@
4646# pragma GCC system_header
4747#endif
4848
49_LIBCPP_PUSH_MACROS
50#include <__undef_macros>
51
4952_LIBCPP_BEGIN_NAMESPACE_STD
5053
51#if _LIBCPP_STD_VER > 17
54#if _LIBCPP_STD_VER >= 20
5255
5356namespace ranges {
5457 template<class _From, class _To>
......@@ -82,7 +85,7 @@ namespace ranges {
8285
8386 private:
8487 static constexpr bool _MustProvideSizeAtConstruction = !_StoreSize; // just to improve compiler diagnostics
85 struct _Empty { constexpr _Empty(auto) noexcept { } };
88 struct _Empty { _LIBCPP_HIDE_FROM_ABI constexpr _Empty(auto) noexcept { } };
8689 using _Size = conditional_t<_StoreSize, make_unsigned_t<iter_difference_t<_Iter>>, _Empty>;
8790 _LIBCPP_NO_UNIQUE_ADDRESS _Iter __begin_ = _Iter();
8891 _LIBCPP_NO_UNIQUE_ADDRESS _Sent __end_ = _Sent();
......@@ -105,7 +108,7 @@ namespace ranges {
105108 : __begin_(std::move(__iter)), __end_(std::move(__sent)), __size_(__n)
106109 {
107110 if constexpr (sized_sentinel_for<_Sent, _Iter>)
108 _LIBCPP_ASSERT((__end_ - __begin_) == static_cast<iter_difference_t<_Iter>>(__n),
111 _LIBCPP_ASSERT_UNCATEGORIZED((__end_ - __begin_) == static_cast<iter_difference_t<_Iter>>(__n),
109112 "std::ranges::subrange was passed an invalid size hint");
110113 }
111114
......@@ -284,8 +287,10 @@ struct tuple_element<1, const ranges::subrange<_Ip, _Sp, _Kp>> {
284287 using type = _Sp;
285288};
286289
287#endif // _LIBCPP_STD_VER > 17
290#endif // _LIBCPP_STD_VER >= 20
288291
289292_LIBCPP_END_NAMESPACE_STD
290293
294_LIBCPP_POP_MACROS
295
291296#endif // _LIBCPP___RANGES_SUBRANGE_H
lib/libcxx/include/__ranges/take_view.h+38-5
......@@ -31,14 +31,18 @@
3131#include <__ranges/enable_borrowed_range.h>
3232#include <__ranges/iota_view.h>
3333#include <__ranges/range_adaptor.h>
34#include <__ranges/repeat_view.h>
3435#include <__ranges/size.h>
3536#include <__ranges/subrange.h>
3637#include <__ranges/view_interface.h>
38#include <__type_traits/decay.h>
39#include <__type_traits/is_nothrow_constructible.h>
3740#include <__type_traits/maybe_const.h>
41#include <__type_traits/remove_cvref.h>
3842#include <__utility/auto_cast.h>
3943#include <__utility/forward.h>
4044#include <__utility/move.h>
41#include <type_traits>
45#include <cstddef>
4246
4347#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
4448# pragma GCC system_header
......@@ -49,7 +53,7 @@ _LIBCPP_PUSH_MACROS
4953
5054_LIBCPP_BEGIN_NAMESPACE_STD
5155
52#if _LIBCPP_STD_VER > 17
56#if _LIBCPP_STD_VER >= 20
5357
5458namespace ranges {
5559
......@@ -64,9 +68,10 @@ public:
6468 _LIBCPP_HIDE_FROM_ABI
6569 take_view() requires default_initializable<_View> = default;
6670
67 _LIBCPP_HIDE_FROM_ABI constexpr take_view(_View __base, range_difference_t<_View> __count)
71 _LIBCPP_HIDE_FROM_ABI
72 constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 take_view(_View __base, range_difference_t<_View> __count)
6873 : __base_(std::move(__base)), __count_(__count) {
69 _LIBCPP_ASSERT(__count >= 0, "count has to be greater than or equal to zero");
74 _LIBCPP_ASSERT_UNCATEGORIZED(__count >= 0, "count has to be greater than or equal to zero");
7075 }
7176
7277 _LIBCPP_HIDE_FROM_ABI
......@@ -297,6 +302,31 @@ struct __fn {
297302 *ranges::begin(__rng),
298303 *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
299304 ); }
305// clang-format off
306#if _LIBCPP_STD_VER >= 23
307 // [range.take.overview]: the `repeat_view` "_RawRange models sized_range" case.
308 template <class _Range,
309 convertible_to<range_difference_t<_Range>> _Np,
310 class _RawRange = remove_cvref_t<_Range>,
311 class _Dist = range_difference_t<_Range>>
312 requires(__is_repeat_specialization<_RawRange> && sized_range<_RawRange>)
313 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
314 noexcept(noexcept(views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))))
315 -> decltype( views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))
316 { return views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); }
317
318 // [range.take.overview]: the `repeat_view` "otherwise" case.
319 template <class _Range,
320 convertible_to<range_difference_t<_Range>> _Np,
321 class _RawRange = remove_cvref_t<_Range>,
322 class _Dist = range_difference_t<_Range>>
323 requires(__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>)
324 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
325 noexcept(noexcept(views::repeat(*__range.__value_, static_cast<_Dist>(__n))))
326 -> decltype( views::repeat(*__range.__value_, static_cast<_Dist>(__n)))
327 { return views::repeat(*__range.__value_, static_cast<_Dist>(__n)); }
328#endif
329// clang-format on
300330
301331 // [range.take.overview]: the "otherwise" case.
302332 template <class _Range, convertible_to<range_difference_t<_Range>> _Np,
......@@ -304,6 +334,9 @@ struct __fn {
304334 // Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other
305335 // overloads.
306336 requires (!(__is_empty_view<_RawRange> ||
337#if _LIBCPP_STD_VER >= 23
338 __is_repeat_specialization<_RawRange> ||
339#endif
307340 (__is_iota_specialization<_RawRange> &&
308341 sized_range<_RawRange> &&
309342 random_access_range<_RawRange>) ||
......@@ -334,7 +367,7 @@ inline namespace __cpo {
334367
335368} // namespace ranges
336369
337#endif // _LIBCPP_STD_VER > 17
370#endif // _LIBCPP_STD_VER >= 20
338371
339372_LIBCPP_END_NAMESPACE_STD
340373
lib/libcxx/include/__ranges/take_while_view.h+3-3
......@@ -20,7 +20,7 @@
2020#include <__ranges/access.h>
2121#include <__ranges/all.h>
2222#include <__ranges/concepts.h>
23#include <__ranges/copyable_box.h>
23#include <__ranges/movable_box.h>
2424#include <__ranges/range_adaptor.h>
2525#include <__ranges/view_interface.h>
2626#include <__type_traits/decay.h>
......@@ -60,14 +60,14 @@ class take_while_view : public view_interface<take_while_view<_View, _Pred>> {
6060 class __sentinel;
6161
6262 _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
63 _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
63 _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_;
6464
6565public:
6666 _LIBCPP_HIDE_FROM_ABI take_while_view()
6767 requires default_initializable<_View> && default_initializable<_Pred>
6868 = default;
6969
70 _LIBCPP_HIDE_FROM_ABI constexpr take_while_view(_View __base, _Pred __pred)
70 _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 take_while_view(_View __base, _Pred __pred)
7171 : __base_(std::move(__base)), __pred_(std::in_place, std::move(__pred)) {}
7272
7373 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
lib/libcxx/include/__ranges/to.h created+247
......@@ -0,0 +1,247 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_TO_H
11#define _LIBCPP___RANGES_TO_H
12
13#include <__algorithm/ranges_copy.h>
14#include <__concepts/constructible.h>
15#include <__concepts/convertible_to.h>
16#include <__concepts/derived_from.h>
17#include <__concepts/same_as.h>
18#include <__config>
19#include <__functional/bind_back.h>
20#include <__iterator/back_insert_iterator.h>
21#include <__iterator/insert_iterator.h>
22#include <__iterator/iterator_traits.h>
23#include <__ranges/access.h>
24#include <__ranges/concepts.h>
25#include <__ranges/from_range.h>
26#include <__ranges/range_adaptor.h>
27#include <__ranges/size.h>
28#include <__ranges/transform_view.h>
29#include <__type_traits/add_pointer.h>
30#include <__type_traits/is_const.h>
31#include <__type_traits/is_volatile.h>
32#include <__type_traits/type_identity.h>
33#include <__utility/declval.h>
34#include <__utility/forward.h>
35#include <cstddef>
36
37#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
38# pragma GCC system_header
39#endif
40
41_LIBCPP_BEGIN_NAMESPACE_STD
42
43#if _LIBCPP_STD_VER >= 23
44
45namespace ranges {
46
47// TODO(clang-15): in the Standard, it's a `constexpr bool` variable, not a concept, but constexpr variables don't
48// short-circuit properly on Clang 15 (fixed in later versions), so use a concept as a workaround.
49template <class _Container>
50concept __reservable_container = sized_range<_Container> && requires(_Container& __c, range_size_t<_Container> __n) {
51 __c.reserve(__n);
52 { __c.capacity() } -> same_as<decltype(__n)>;
53 { __c.max_size() } -> same_as<decltype(__n)>;
54};
55
56template <class _Container, class _Ref>
57constexpr bool __container_insertable = requires(_Container& __c, _Ref&& __ref) {
58 requires(
59 requires { __c.push_back(std::forward<_Ref>(__ref)); } ||
60 requires { __c.insert(__c.end(), std::forward<_Ref>(__ref)); });
61};
62
63template <class _Ref, class _Container>
64_LIBCPP_HIDE_FROM_ABI constexpr auto __container_inserter(_Container& __c) {
65 if constexpr (requires { __c.push_back(std::declval<_Ref>()); }) {
66 return std::back_inserter(__c);
67 } else {
68 return std::inserter(__c, __c.end());
69 }
70}
71
72// Note: making this a concept allows short-circuiting the second condition.
73template <class _Container, class _Range>
74concept __try_non_recursive_conversion =
75 !input_range<_Container> || convertible_to<range_reference_t<_Range>, range_value_t<_Container>>;
76
77template <class _Container, class _Range, class... _Args>
78concept __constructible_from_iter_pair =
79 common_range<_Range> && requires { typename iterator_traits<iterator_t<_Range>>::iterator_category; } &&
80 derived_from<typename iterator_traits<iterator_t<_Range>>::iterator_category, input_iterator_tag> &&
81 constructible_from<_Container, iterator_t<_Range>, sentinel_t<_Range>, _Args...>;
82
83template <class>
84concept __always_false = false;
85
86// `ranges::to` base template -- the `_Container` type is a simple type template parameter.
87template <class _Container, input_range _Range, class... _Args>
88 requires(!view<_Container>)
89_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Container to(_Range&& __range, _Args&&... __args) {
90 // Mandates: C is a cv-unqualified class type.
91 static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const");
92 static_assert(
93 !is_volatile_v<_Container>, "The target container cannot be volatile-qualified, please remove the volatile");
94
95 // First see if the non-recursive case applies -- the conversion target is either:
96 // - a range with a convertible value type;
97 // - a non-range type which might support being created from the input argument(s) (e.g. an `optional`).
98 if constexpr (__try_non_recursive_conversion<_Container, _Range>) {
99 // Case 1 -- construct directly from the given range.
100 if constexpr (constructible_from<_Container, _Range, _Args...>) {
101 return _Container(std::forward<_Range>(__range), std::forward<_Args>(__args)...);
102 }
103
104 // Case 2 -- construct using the `from_range_t` tagged constructor.
105 else if constexpr (constructible_from<_Container, from_range_t, _Range, _Args...>) {
106 return _Container(from_range, std::forward<_Range>(__range), std::forward<_Args>(__args)...);
107 }
108
109 // Case 3 -- construct from a begin-end iterator pair.
110 else if constexpr (__constructible_from_iter_pair<_Container, _Range, _Args...>) {
111 return _Container(ranges::begin(__range), ranges::end(__range), std::forward<_Args>(__args)...);
112 }
113
114 // Case 4 -- default-construct (or construct from the extra arguments) and insert, reserving the size if possible.
115 else if constexpr (constructible_from<_Container, _Args...> &&
116 __container_insertable<_Container, range_reference_t<_Range>>) {
117 _Container __result(std::forward<_Args>(__args)...);
118 if constexpr (sized_range<_Range> && __reservable_container<_Container>) {
119 __result.reserve(static_cast<range_size_t<_Container>>(ranges::size(__range)));
120 }
121
122 ranges::copy(__range, ranges::__container_inserter<range_reference_t<_Range>>(__result));
123
124 return __result;
125
126 } else {
127 static_assert(__always_false<_Container>, "ranges::to: unable to convert to the given container type.");
128 }
129
130 // Try the recursive case.
131 } else if constexpr (input_range<range_reference_t<_Range>>) {
132 return ranges::to<_Container>(
133 __range | views::transform([](auto&& __elem) {
134 return ranges::to<range_value_t<_Container>>(std::forward<decltype(__elem)>(__elem));
135 }),
136 std::forward<_Args>(__args)...);
137
138 } else {
139 static_assert(__always_false<_Container>, "ranges::to: unable to convert to the given container type.");
140 }
141}
142
143template <class _Range>
144struct __minimal_input_iterator {
145 using iterator_category = input_iterator_tag;
146 using value_type = range_value_t<_Range>;
147 using difference_type = ptrdiff_t;
148 using pointer = add_pointer_t<range_reference_t<_Range>>;
149 using reference = range_reference_t<_Range>;
150
151 reference operator*() const;
152 pointer operator->() const;
153 __minimal_input_iterator& operator++();
154 __minimal_input_iterator operator++(int);
155 bool operator==(const __minimal_input_iterator&) const;
156};
157
158// Deduces the full type of the container from the given template template parameter.
159template <template <class...> class _Container, input_range _Range, class... _Args>
160struct _Deducer {
161 _LIBCPP_HIDE_FROM_ABI static constexpr auto __deduce_func() {
162 using _InputIter = __minimal_input_iterator<_Range>;
163
164 // Case 1 -- can construct directly from the given range.
165 if constexpr (requires { _Container(std::declval<_Range>(), std::declval<_Args>()...); }) {
166 using _Result = decltype( //
167 _Container(std::declval<_Range>(), std::declval<_Args>()...));
168 return type_identity<_Result>{};
169
170 // Case 2 -- can construct from the given range using the `from_range_t` tagged constructor.
171 } else if constexpr ( //
172 requires { _Container(from_range, std::declval<_Range>(), std::declval<_Args>()...); }) {
173 using _Result = //
174 decltype(_Container(from_range, std::declval<_Range>(), std::declval<_Args>()...));
175 return type_identity<_Result>{};
176
177 // Case 3 -- can construct from a begin-end iterator pair.
178 } else if constexpr ( //
179 requires { _Container(std::declval<_InputIter>(), std::declval<_InputIter>(), std::declval<_Args>()...); }) {
180 using _Result =
181 decltype(_Container(std::declval<_InputIter>(), std::declval<_InputIter>(), std::declval<_Args>()...));
182 return type_identity<_Result>{};
183
184 } else {
185 static_assert(__always_false<_Range>,
186 "ranges::to: unable to deduce the container type from the template template argument.");
187 }
188 }
189
190 using type = typename decltype(__deduce_func())::type;
191};
192
193// `ranges::to` specialization -- `_Container` is a template template parameter requiring deduction to figure out the
194// container element type.
195template <template <class...> class _Container, input_range _Range, class... _Args>
196_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Range&& __range, _Args&&... __args) {
197 using _DeduceExpr = typename _Deducer<_Container, _Range, _Args...>::type;
198 return ranges::to<_DeduceExpr>(std::forward<_Range>(__range), std::forward<_Args>(__args)...);
199}
200
201// Range adaptor closure object 1 -- wrapping the `ranges::to` version where `_Container` is a simple type template
202// parameter.
203template <class _Container, class... _Args>
204 requires(!view<_Container>)
205_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Args&&... __args) {
206 // Mandates: C is a cv-unqualified class type.
207 static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const");
208 static_assert(
209 !is_volatile_v<_Container>, "The target container cannot be volatile-qualified, please remove the volatile");
210
211 auto __to_func = []<input_range _Range, class... _Tail>(_Range && __range, _Tail && ... __tail)
212 requires requires { //
213 /**/ ranges::to<_Container>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
214 }
215 {
216 return ranges::to<_Container>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
217 };
218
219 return __range_adaptor_closure_t(std::__bind_back(__to_func, std::forward<_Args>(__args)...));
220}
221
222// Range adaptor closure object 2 -- wrapping the `ranges::to` version where `_Container` is a template template
223// parameter.
224template <template <class...> class _Container, class... _Args>
225_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Args&&... __args) {
226 // clang-format off
227 auto __to_func = []<input_range _Range, class... _Tail,
228 class _DeducedExpr = typename _Deducer<_Container, _Range, _Tail...>::type>
229 (_Range&& __range, _Tail&& ... __tail)
230 requires requires { //
231 /**/ ranges::to<_DeducedExpr>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
232 }
233 {
234 return ranges::to<_DeducedExpr>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
235 };
236 // clang-format on
237
238 return __range_adaptor_closure_t(std::__bind_back(__to_func, std::forward<_Args>(__args)...));
239}
240
241} // namespace ranges
242
243#endif // _LIBCPP_STD_VER >= 23
244
245_LIBCPP_END_NAMESPACE_STD
246
247#endif // _LIBCPP___RANGES_TO_H
lib/libcxx/include/__ranges/transform_view.h+31-14
......@@ -20,22 +20,28 @@
2020#include <__config>
2121#include <__functional/bind_back.h>
2222#include <__functional/invoke.h>
23#include <__functional/perfect_forward.h>
2324#include <__iterator/concepts.h>
2425#include <__iterator/iterator_traits.h>
2526#include <__memory/addressof.h>
2627#include <__ranges/access.h>
2728#include <__ranges/all.h>
2829#include <__ranges/concepts.h>
29#include <__ranges/copyable_box.h>
3030#include <__ranges/empty.h>
31#include <__ranges/movable_box.h>
3132#include <__ranges/range_adaptor.h>
3233#include <__ranges/size.h>
3334#include <__ranges/view_interface.h>
35#include <__type_traits/conditional.h>
36#include <__type_traits/decay.h>
37#include <__type_traits/is_nothrow_constructible.h>
38#include <__type_traits/is_object.h>
39#include <__type_traits/is_reference.h>
3440#include <__type_traits/maybe_const.h>
41#include <__type_traits/remove_cvref.h>
3542#include <__utility/forward.h>
3643#include <__utility/in_place.h>
3744#include <__utility/move.h>
38#include <type_traits>
3945
4046#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
4147# pragma GCC system_header
......@@ -43,7 +49,7 @@
4349
4450_LIBCPP_BEGIN_NAMESPACE_STD
4551
46#if _LIBCPP_STD_VER > 17
52#if _LIBCPP_STD_VER >= 20
4753
4854namespace ranges {
4955
......@@ -57,13 +63,17 @@ concept __transform_view_constraints =
5763 regular_invocable<_Fn&, range_reference_t<_View>> &&
5864 __can_reference<invoke_result_t<_Fn&, range_reference_t<_View>>>;
5965
60template<input_range _View, copy_constructible _Fn>
66# if _LIBCPP_STD_VER >= 23
67template <input_range _View, move_constructible _Fn>
68# else
69template <input_range _View, copy_constructible _Fn>
70# endif
6171 requires __transform_view_constraints<_View, _Fn>
6272class transform_view : public view_interface<transform_view<_View, _Fn>> {
6373 template<bool> class __iterator;
6474 template<bool> class __sentinel;
6575
66 _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Fn> __func_;
76 _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Fn> __func_;
6777 _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
6878
6979public:
......@@ -72,7 +82,7 @@ public:
7282 requires default_initializable<_View> && default_initializable<_Fn> = default;
7383
7484 _LIBCPP_HIDE_FROM_ABI
75 constexpr transform_view(_View __base, _Fn __func)
85 constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 transform_view(_View __base, _Fn __func)
7686 : __func_(std::in_place, std::move(__func)), __base_(std::move(__base)) {}
7787
7888 _LIBCPP_HIDE_FROM_ABI
......@@ -146,7 +156,7 @@ struct __transform_view_iterator_category_base<_View, _Fn> {
146156 using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category;
147157
148158 using iterator_category = conditional_t<
149 is_lvalue_reference_v<invoke_result_t<_Fn&, range_reference_t<_View>>>,
159 is_reference_v<invoke_result_t<_Fn&, range_reference_t<_View>>>,
150160 conditional_t<
151161 derived_from<_Cat, contiguous_iterator_tag>,
152162 random_access_iterator_tag,
......@@ -156,11 +166,14 @@ struct __transform_view_iterator_category_base<_View, _Fn> {
156166 >;
157167};
158168
159template<input_range _View, copy_constructible _Fn>
169# if _LIBCPP_STD_VER >= 23
170template <input_range _View, move_constructible _Fn>
171# else
172template <input_range _View, copy_constructible _Fn>
173# endif
160174 requires __transform_view_constraints<_View, _Fn>
161template<bool _Const>
162class transform_view<_View, _Fn>::__iterator
163 : public __transform_view_iterator_category_base<_View, _Fn> {
175template <bool _Const>
176class transform_view<_View, _Fn>::__iterator : public __transform_view_iterator_category_base<_View, _Fn> {
164177
165178 using _Parent = __maybe_const<_Const, transform_view>;
166179 using _Base = __maybe_const<_Const, _View>;
......@@ -352,9 +365,13 @@ public:
352365 }
353366};
354367
355template<input_range _View, copy_constructible _Fn>
368# if _LIBCPP_STD_VER >= 23
369template <input_range _View, move_constructible _Fn>
370# else
371template <input_range _View, copy_constructible _Fn>
372# endif
356373 requires __transform_view_constraints<_View, _Fn>
357template<bool _Const>
374template <bool _Const>
358375class transform_view<_View, _Fn>::__sentinel {
359376 using _Parent = __maybe_const<_Const, transform_view>;
360377 using _Base = __maybe_const<_Const, _View>;
......@@ -435,7 +452,7 @@ inline namespace __cpo {
435452
436453} // namespace ranges
437454
438#endif // _LIBCPP_STD_VER > 17
455#endif // _LIBCPP_STD_VER >= 20
439456
440457_LIBCPP_END_NAMESPACE_STD
441458
lib/libcxx/include/__ranges/view_interface.h+6-6
......@@ -31,7 +31,7 @@
3131
3232_LIBCPP_BEGIN_NAMESPACE_STD
3333
34#if _LIBCPP_STD_VER > 17
34#if _LIBCPP_STD_VER >= 20
3535
3636namespace ranges {
3737
......@@ -118,7 +118,7 @@ public:
118118 constexpr decltype(auto) front()
119119 requires forward_range<_D2>
120120 {
121 _LIBCPP_ASSERT(!empty(),
121 _LIBCPP_ASSERT_UNCATEGORIZED(!empty(),
122122 "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
123123 return *ranges::begin(__derived());
124124 }
......@@ -128,7 +128,7 @@ public:
128128 constexpr decltype(auto) front() const
129129 requires forward_range<const _D2>
130130 {
131 _LIBCPP_ASSERT(!empty(),
131 _LIBCPP_ASSERT_UNCATEGORIZED(!empty(),
132132 "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
133133 return *ranges::begin(__derived());
134134 }
......@@ -138,7 +138,7 @@ public:
138138 constexpr decltype(auto) back()
139139 requires bidirectional_range<_D2> && common_range<_D2>
140140 {
141 _LIBCPP_ASSERT(!empty(),
141 _LIBCPP_ASSERT_UNCATEGORIZED(!empty(),
142142 "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
143143 return *ranges::prev(ranges::end(__derived()));
144144 }
......@@ -148,7 +148,7 @@ public:
148148 constexpr decltype(auto) back() const
149149 requires bidirectional_range<const _D2> && common_range<const _D2>
150150 {
151 _LIBCPP_ASSERT(!empty(),
151 _LIBCPP_ASSERT_UNCATEGORIZED(!empty(),
152152 "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
153153 return *ranges::prev(ranges::end(__derived()));
154154 }
......@@ -170,7 +170,7 @@ public:
170170
171171} // namespace ranges
172172
173#endif // _LIBCPP_STD_VER > 17
173#endif // _LIBCPP_STD_VER >= 20
174174
175175_LIBCPP_END_NAMESPACE_STD
176176
lib/libcxx/include/__ranges/views.h+2-2
......@@ -18,7 +18,7 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21#if _LIBCPP_STD_VER > 17
21#if _LIBCPP_STD_VER >= 20
2222
2323namespace ranges {
2424
......@@ -28,7 +28,7 @@ namespace views { }
2828
2929namespace views = ranges::views;
3030
31#endif // _LIBCPP_STD_VER > 17
31#endif // _LIBCPP_STD_VER >= 20
3232
3333_LIBCPP_END_NAMESPACE_STD
3434
lib/libcxx/include/__ranges/zip_view.h+8-4
......@@ -30,11 +30,13 @@
3030#include <__ranges/enable_borrowed_range.h>
3131#include <__ranges/size.h>
3232#include <__ranges/view_interface.h>
33#include <__type_traits/is_nothrow_move_constructible.h>
34#include <__type_traits/make_unsigned.h>
35#include <__utility/declval.h>
3336#include <__utility/forward.h>
3437#include <__utility/integer_sequence.h>
3538#include <__utility/move.h>
3639#include <tuple>
37#include <type_traits>
3840
3941#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
4042# pragma GCC system_header
......@@ -45,7 +47,7 @@ _LIBCPP_PUSH_MACROS
4547
4648_LIBCPP_BEGIN_NAMESPACE_STD
4749
48#if _LIBCPP_STD_VER > 20
50#if _LIBCPP_STD_VER >= 23
4951
5052namespace ranges {
5153
......@@ -77,7 +79,9 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_transform(_Fun&& __f, _Tuple&& __tu
7779template <class _Fun, class _Tuple>
7880_LIBCPP_HIDE_FROM_ABI constexpr void __tuple_for_each(_Fun&& __f, _Tuple&& __tuple) {
7981 std::apply(
80 [&]<class... _Types>(_Types&&... __elements) { (std::invoke(__f, std::forward<_Types>(__elements)), ...); },
82 [&]<class... _Types>(_Types&&... __elements) {
83 (static_cast<void>(std::invoke(__f, std::forward<_Types>(__elements))), ...);
84 },
8185 std::forward<_Tuple>(__tuple));
8286}
8387
......@@ -503,7 +507,7 @@ inline namespace __cpo {
503507} // namespace views
504508} // namespace ranges
505509
506#endif // _LIBCPP_STD_VER > 20
510#endif // _LIBCPP_STD_VER >= 23
507511
508512_LIBCPP_END_NAMESPACE_STD
509513
lib/libcxx/include/__split_buffer+193-162
......@@ -23,9 +23,18 @@
2323#include <__memory/compressed_pair.h>
2424#include <__memory/pointer_traits.h>
2525#include <__memory/swap_allocator.h>
26#include <__type_traits/add_lvalue_reference.h>
27#include <__type_traits/enable_if.h>
28#include <__type_traits/integral_constant.h>
29#include <__type_traits/is_nothrow_default_constructible.h>
30#include <__type_traits/is_nothrow_move_assignable.h>
31#include <__type_traits/is_nothrow_move_constructible.h>
32#include <__type_traits/is_swappable.h>
33#include <__type_traits/is_trivially_destructible.h>
34#include <__type_traits/remove_reference.h>
2635#include <__utility/forward.h>
2736#include <__utility/move.h>
28#include <type_traits>
37#include <cstddef>
2938
3039#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3140# pragma GCC system_header
......@@ -44,139 +53,173 @@ _LIBCPP_BEGIN_NAMESPACE_STD
4453template <class _Tp, class _Allocator = allocator<_Tp> >
4554struct __split_buffer
4655{
47private:
48 __split_buffer(const __split_buffer&);
49 __split_buffer& operator=(const __split_buffer&);
5056public:
51 typedef _Tp value_type;
52 typedef _Allocator allocator_type;
53 typedef __libcpp_remove_reference_t<allocator_type> __alloc_rr;
54 typedef allocator_traits<__alloc_rr> __alloc_traits;
55 typedef value_type& reference;
56 typedef const value_type& const_reference;
57 typedef typename __alloc_traits::size_type size_type;
58 typedef typename __alloc_traits::difference_type difference_type;
59 typedef typename __alloc_traits::pointer pointer;
60 typedef typename __alloc_traits::const_pointer const_pointer;
61 typedef pointer iterator;
62 typedef const_pointer const_iterator;
63
64 pointer __first_;
65 pointer __begin_;
66 pointer __end_;
67 __compressed_pair<pointer, allocator_type> __end_cap_;
68
69 typedef __add_lvalue_reference_t<allocator_type> __alloc_ref;
70 typedef __add_lvalue_reference_t<allocator_type> __alloc_const_ref;
71
72 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __alloc_rr& __alloc() _NOEXCEPT {return __end_cap_.second();}
73 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const __alloc_rr& __alloc() const _NOEXCEPT {return __end_cap_.second();}
74 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer& __end_cap() _NOEXCEPT {return __end_cap_.first();}
75 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const pointer& __end_cap() const _NOEXCEPT {return __end_cap_.first();}
76
77 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
78 __split_buffer()
79 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
80 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
81 explicit __split_buffer(__alloc_rr& __a);
82 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
83 explicit __split_buffer(const __alloc_rr& __a);
84 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a);
85 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~__split_buffer();
86
87 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c)
88 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
89 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c, const __alloc_rr& __a);
90 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer& operator=(__split_buffer&& __c)
91 _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
92 is_nothrow_move_assignable<allocator_type>::value) ||
93 !__alloc_traits::propagate_on_container_move_assignment::value);
94
95 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {return __begin_;}
96 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {return __begin_;}
97 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {return __end_;}
98 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {return __end_;}
99
100 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
101 void clear() _NOEXCEPT
102 {__destruct_at_end(__begin_);}
103 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const {return static_cast<size_type>(__end_ - __begin_);}
104 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const {return __end_ == __begin_;}
105 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const {return static_cast<size_type>(__end_cap() - __first_);}
106 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const {return static_cast<size_type>(__begin_ - __first_);}
107 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const {return static_cast<size_type>(__end_cap() - __end_);}
108
109 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() {return *__begin_;}
110 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const {return *__begin_;}
111 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() {return *(__end_ - 1);}
112 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const {return *(__end_ - 1);}
113
114 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n);
115 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
116 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(const_reference __x);
117 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(const_reference __x);
118 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __x);
119 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x);
120 template <class... _Args>
121 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args);
122
123 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_front() {__destruct_at_begin(__begin_+1);}
124 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_back() {__destruct_at_end(__end_-1);}
125
126 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n);
127 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n, const_reference __x);
128 template <class _InputIter>
129 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value>
130 __construct_at_end(_InputIter __first, _InputIter __last);
131 template <class _ForwardIterator>
132 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value>
133 __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
134
135 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin)
136 {__destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());}
137 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
138 void __destruct_at_begin(pointer __new_begin, false_type);
139 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
140 void __destruct_at_begin(pointer __new_begin, true_type);
141
142 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
143 void __destruct_at_end(pointer __new_last) _NOEXCEPT
144 {__destruct_at_end(__new_last, false_type());}
145 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
146 void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT;
147 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
148 void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT;
149
150 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer& __x)
151 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
152 __is_nothrow_swappable<__alloc_rr>::value);
57 using value_type = _Tp;
58 using allocator_type = _Allocator;
59 using __alloc_rr = __libcpp_remove_reference_t<allocator_type>;
60 using __alloc_traits = allocator_traits<__alloc_rr>;
61 using reference = value_type&;
62 using const_reference = const value_type&;
63 using size_type = typename __alloc_traits::size_type;
64 using difference_type = typename __alloc_traits::difference_type;
65 using pointer = typename __alloc_traits::pointer;
66 using const_pointer = typename __alloc_traits::const_pointer;
67 using iterator = pointer;
68 using const_iterator = const_pointer;
69
70 pointer __first_;
71 pointer __begin_;
72 pointer __end_;
73 __compressed_pair<pointer, allocator_type> __end_cap_;
74
75 using __alloc_ref = __add_lvalue_reference_t<allocator_type>;
76 using __alloc_const_ref = __add_lvalue_reference_t<allocator_type>;
77
78 __split_buffer(const __split_buffer&) = delete;
79 __split_buffer& operator=(const __split_buffer&) = delete;
80
81 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer()
82 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
83 : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __default_init_tag()) {}
84
85 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(__alloc_rr& __a)
86 : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) {}
87
88 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(const __alloc_rr& __a)
89 : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) {}
90
91 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
92 __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a);
93
94 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c)
95 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
96
97 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c, const __alloc_rr& __a);
98
99 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer& operator=(__split_buffer&& __c)
100 _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
101 is_nothrow_move_assignable<allocator_type>::value) ||
102 !__alloc_traits::propagate_on_container_move_assignment::value);
103
104 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~__split_buffer();
105
106 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __alloc_rr& __alloc() _NOEXCEPT { return __end_cap_.second(); }
107 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const __alloc_rr& __alloc() const _NOEXCEPT {
108 return __end_cap_.second();
109 }
110
111 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer& __end_cap() _NOEXCEPT { return __end_cap_.first(); }
112 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const pointer& __end_cap() const _NOEXCEPT {
113 return __end_cap_.first();
114 }
115
116 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __begin_; }
117 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __begin_; }
118
119 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __end_; }
120 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __end_; }
121
122 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __destruct_at_end(__begin_); }
123
124 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const {
125 return static_cast<size_type>(__end_ - __begin_);
126 }
127
128 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const { return __end_ == __begin_; }
129
130 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const {
131 return static_cast<size_type>(__end_cap() - __first_);
132 }
133
134 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const {
135 return static_cast<size_type>(__begin_ - __first_);
136 }
137
138 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const {
139 return static_cast<size_type>(__end_cap() - __end_);
140 }
141
142 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() { return *__begin_; }
143 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const { return *__begin_; }
144 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() { return *(__end_ - 1); }
145 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const { return *(__end_ - 1); }
146
147 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n);
148 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
149 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(const_reference __x);
150 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(const_reference __x);
151 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __x);
152 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x);
153
154 template <class... _Args>
155 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args);
156
157 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_front() { __destruct_at_begin(__begin_ + 1); }
158 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_back() { __destruct_at_end(__end_ - 1); }
159
160 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n);
161 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n, const_reference __x);
162
163 template <class _InputIter>
164 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
165 __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value>
166 __construct_at_end(_InputIter __first, _InputIter __last);
167
168 template <class _ForwardIterator>
169 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
170 __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value>
171 __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
172
173 template <class _Iterator, class _Sentinel>
174 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
175 void __construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last);
176
177 template <class _Iterator>
178 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
179 void __construct_at_end_with_size(_Iterator __first, size_type __n);
180
181 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin) {
182 __destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());
183 }
184
185 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin, false_type);
186 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin, true_type);
187
188 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last) _NOEXCEPT {
189 __destruct_at_end(__new_last, false_type());
190 }
191
192 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT;
193 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT;
153194
154 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
195 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer& __x)
196 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<__alloc_rr>::value);
197
198 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
155199
156200private:
157 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
158 void __move_assign_alloc(__split_buffer& __c, true_type)
159 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
160 {
161 __alloc() = _VSTD::move(__c.__alloc());
162 }
201 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer& __c, true_type)
202 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
203 __alloc() = _VSTD::move(__c.__alloc());
204 }
205
206 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT {}
207
208 struct _ConstructTransaction {
209 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction(
210 pointer* __p, size_type __n) _NOEXCEPT
211 : __pos_(*__p),
212 __end_(*__p + __n),
213 __dest_(__p) {}
163214
164 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
165 void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT
166 {}
167
168 struct _ConstructTransaction {
169 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction(pointer* __p, size_type __n) _NOEXCEPT
170 : __pos_(*__p), __end_(*__p + __n), __dest_(__p) {
171 }
172 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() {
173 *__dest_ = __pos_;
174 }
175 pointer __pos_;
176 const pointer __end_;
177 private:
178 pointer *__dest_;
179 };
215 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { *__dest_ = __pos_; }
216
217 pointer __pos_;
218 const pointer __end_;
219
220 private:
221 pointer* __dest_;
222 };
180223};
181224
182225template <class _Tp, class _Allocator>
......@@ -241,9 +284,16 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_referen
241284
242285template <class _Tp, class _Allocator>
243286template <class _InputIter>
244_LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value>
287_LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value>
245288__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last)
246289{
290 __construct_at_end_with_sentinel(__first, __last);
291}
292
293template <class _Tp, class _Allocator>
294template <class _Iterator, class _Sentinel>
295_LIBCPP_CONSTEXPR_SINCE_CXX20
296void __split_buffer<_Tp, _Allocator>::__construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last) {
247297 __alloc_rr& __a = this->__alloc();
248298 for (; __first != __last; ++__first)
249299 {
......@@ -261,13 +311,19 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIt
261311 ++this->__end_;
262312 }
263313}
264
265314template <class _Tp, class _Allocator>
266315template <class _ForwardIterator>
267_LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value>
316_LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value>
268317__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
269318{
270 _ConstructTransaction __tx(&this->__end_, _VSTD::distance(__first, __last));
319 __construct_at_end_with_size(__first, std::distance(__first, __last));
320}
321
322template <class _Tp, class _Allocator>
323template <class _ForwardIterator>
324_LIBCPP_CONSTEXPR_SINCE_CXX20
325void __split_buffer<_Tp, _Allocator>::__construct_at_end_with_size(_ForwardIterator __first, size_type __n) {
326 _ConstructTransaction __tx(&this->__end_, __n);
271327 for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void) ++__first) {
272328 __alloc_traits::construct(this->__alloc(),
273329 _VSTD::__to_address(__tx.__pos_), *__first);
......@@ -328,31 +384,6 @@ __split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __sta
328384 __end_cap() = __first_ + __cap;
329385}
330386
331template <class _Tp, class _Allocator>
332_LIBCPP_CONSTEXPR_SINCE_CXX20
333inline
334__split_buffer<_Tp, _Allocator>::__split_buffer()
335 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
336 : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __default_init_tag())
337{
338}
339
340template <class _Tp, class _Allocator>
341_LIBCPP_CONSTEXPR_SINCE_CXX20
342inline
343__split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a)
344 : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
345{
346}
347
348template <class _Tp, class _Allocator>
349_LIBCPP_CONSTEXPR_SINCE_CXX20
350inline
351__split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a)
352 : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
353{
354}
355
356387template <class _Tp, class _Allocator>
357388_LIBCPP_CONSTEXPR_SINCE_CXX20
358389__split_buffer<_Tp, _Allocator>::~__split_buffer()
......@@ -463,10 +494,10 @@ __split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
463494{
464495 if (capacity() > size())
465496 {
466#ifndef _LIBCPP_NO_EXCEPTIONS
497#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
467498 try
468499 {
469#endif // _LIBCPP_NO_EXCEPTIONS
500#endif // _LIBCPP_HAS_NO_EXCEPTIONS
470501 __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc());
471502 __t.__construct_at_end(move_iterator<pointer>(__begin_),
472503 move_iterator<pointer>(__end_));
......@@ -475,12 +506,12 @@ __split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
475506 _VSTD::swap(__begin_, __t.__begin_);
476507 _VSTD::swap(__end_, __t.__end_);
477508 _VSTD::swap(__end_cap(), __t.__end_cap());
478#ifndef _LIBCPP_NO_EXCEPTIONS
509#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
479510 }
480511 catch (...)
481512 {
482513 }
483#endif // _LIBCPP_NO_EXCEPTIONS
514#endif // _LIBCPP_HAS_NO_EXCEPTIONS
484515 }
485516}
486517
lib/libcxx/include/__std_mbstate_t.h created+29
......@@ -0,0 +1,29 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___STD_MBSTATE_T_H
11#define _LIBCPP___STD_MBSTATE_T_H
12
13#include <__config>
14#include <__mbstate_t.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20// The goal of this header is to provide std::mbstate_t without requiring all
21// of <cuchar> or <cwchar>.
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25using ::mbstate_t _LIBCPP_USING_IF_EXISTS;
26
27_LIBCPP_END_NAMESPACE_STD
28
29#endif // _LIBCPP___STD_MBSTATE_T_H
lib/libcxx/include/__std_stream deleted-361
......@@ -1,361 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___STD_STREAM
11#define _LIBCPP___STD_STREAM
12
13#include <__config>
14#include <__locale>
15#include <cstdio>
16#include <istream>
17#include <ostream>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29static const int __limit = 8;
30
31// __stdinbuf
32
33template <class _CharT>
34class _LIBCPP_HIDDEN __stdinbuf
35 : public basic_streambuf<_CharT, char_traits<_CharT> >
36{
37public:
38 typedef _CharT char_type;
39 typedef char_traits<char_type> traits_type;
40 typedef typename traits_type::int_type int_type;
41 typedef typename traits_type::pos_type pos_type;
42 typedef typename traits_type::off_type off_type;
43 typedef typename traits_type::state_type state_type;
44
45 __stdinbuf(FILE* __fp, state_type* __st);
46
47protected:
48 virtual int_type underflow();
49 virtual int_type uflow();
50 virtual int_type pbackfail(int_type __c = traits_type::eof());
51 virtual void imbue(const locale& __loc);
52
53private:
54
55 FILE* __file_;
56 const codecvt<char_type, char, state_type>* __cv_;
57 state_type* __st_;
58 int __encoding_;
59 int_type __last_consumed_;
60 bool __last_consumed_is_next_;
61 bool __always_noconv_;
62
63 __stdinbuf(const __stdinbuf&);
64 __stdinbuf& operator=(const __stdinbuf&);
65
66 int_type __getchar(bool __consume);
67};
68
69template <class _CharT>
70__stdinbuf<_CharT>::__stdinbuf(FILE* __fp, state_type* __st)
71 : __file_(__fp),
72 __st_(__st),
73 __last_consumed_(traits_type::eof()),
74 __last_consumed_is_next_(false)
75{
76 imbue(this->getloc());
77}
78
79template <class _CharT>
80void
81__stdinbuf<_CharT>::imbue(const locale& __loc)
82{
83 __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
84 __encoding_ = __cv_->encoding();
85 __always_noconv_ = __cv_->always_noconv();
86 if (__encoding_ > __limit)
87 __throw_runtime_error("unsupported locale for standard input");
88}
89
90template <class _CharT>
91typename __stdinbuf<_CharT>::int_type
92__stdinbuf<_CharT>::underflow()
93{
94 return __getchar(false);
95}
96
97template <class _CharT>
98typename __stdinbuf<_CharT>::int_type
99__stdinbuf<_CharT>::uflow()
100{
101 return __getchar(true);
102}
103
104template <class _CharT>
105typename __stdinbuf<_CharT>::int_type
106__stdinbuf<_CharT>::__getchar(bool __consume)
107{
108 if (__last_consumed_is_next_)
109 {
110 int_type __result = __last_consumed_;
111 if (__consume)
112 {
113 __last_consumed_ = traits_type::eof();
114 __last_consumed_is_next_ = false;
115 }
116 return __result;
117 }
118 char __extbuf[__limit];
119 int __nread = _VSTD::max(1, __encoding_);
120 for (int __i = 0; __i < __nread; ++__i)
121 {
122 int __c = getc(__file_);
123 if (__c == EOF)
124 return traits_type::eof();
125 __extbuf[__i] = static_cast<char>(__c);
126 }
127 char_type __1buf;
128 if (__always_noconv_)
129 __1buf = static_cast<char_type>(__extbuf[0]);
130 else
131 {
132 const char* __enxt;
133 char_type* __inxt;
134 codecvt_base::result __r;
135 do
136 {
137 state_type __sv_st = *__st_;
138 __r = __cv_->in(*__st_, __extbuf, __extbuf + __nread, __enxt,
139 &__1buf, &__1buf + 1, __inxt);
140 switch (__r)
141 {
142 case _VSTD::codecvt_base::ok:
143 break;
144 case codecvt_base::partial:
145 *__st_ = __sv_st;
146 if (__nread == sizeof(__extbuf))
147 return traits_type::eof();
148 {
149 int __c = getc(__file_);
150 if (__c == EOF)
151 return traits_type::eof();
152 __extbuf[__nread] = static_cast<char>(__c);
153 }
154 ++__nread;
155 break;
156 case codecvt_base::error:
157 return traits_type::eof();
158 case _VSTD::codecvt_base::noconv:
159 __1buf = static_cast<char_type>(__extbuf[0]);
160 break;
161 }
162 } while (__r == _VSTD::codecvt_base::partial);
163 }
164 if (!__consume)
165 {
166 for (int __i = __nread; __i > 0;)
167 {
168 if (ungetc(traits_type::to_int_type(__extbuf[--__i]), __file_) == EOF)
169 return traits_type::eof();
170 }
171 }
172 else
173 __last_consumed_ = traits_type::to_int_type(__1buf);
174 return traits_type::to_int_type(__1buf);
175}
176
177template <class _CharT>
178typename __stdinbuf<_CharT>::int_type
179__stdinbuf<_CharT>::pbackfail(int_type __c)
180{
181 if (traits_type::eq_int_type(__c, traits_type::eof()))
182 {
183 if (!__last_consumed_is_next_)
184 {
185 __c = __last_consumed_;
186 __last_consumed_is_next_ = !traits_type::eq_int_type(__last_consumed_,
187 traits_type::eof());
188 }
189 return __c;
190 }
191 if (__last_consumed_is_next_)
192 {
193 char __extbuf[__limit];
194 char* __enxt;
195 const char_type __ci = traits_type::to_char_type(__last_consumed_);
196 const char_type* __inxt;
197 switch (__cv_->out(*__st_, &__ci, &__ci + 1, __inxt,
198 __extbuf, __extbuf + sizeof(__extbuf), __enxt))
199 {
200 case _VSTD::codecvt_base::ok:
201 break;
202 case _VSTD::codecvt_base::noconv:
203 __extbuf[0] = static_cast<char>(__last_consumed_);
204 __enxt = __extbuf + 1;
205 break;
206 case codecvt_base::partial:
207 case codecvt_base::error:
208 return traits_type::eof();
209 }
210 while (__enxt > __extbuf)
211 if (ungetc(*--__enxt, __file_) == EOF)
212 return traits_type::eof();
213 }
214 __last_consumed_ = __c;
215 __last_consumed_is_next_ = true;
216 return __c;
217}
218
219// __stdoutbuf
220
221template <class _CharT>
222class _LIBCPP_HIDDEN __stdoutbuf
223 : public basic_streambuf<_CharT, char_traits<_CharT> >
224{
225public:
226 typedef _CharT char_type;
227 typedef char_traits<char_type> traits_type;
228 typedef typename traits_type::int_type int_type;
229 typedef typename traits_type::pos_type pos_type;
230 typedef typename traits_type::off_type off_type;
231 typedef typename traits_type::state_type state_type;
232
233 __stdoutbuf(FILE* __fp, state_type* __st);
234
235protected:
236 virtual int_type overflow (int_type __c = traits_type::eof());
237 virtual streamsize xsputn(const char_type* __s, streamsize __n);
238 virtual int sync();
239 virtual void imbue(const locale& __loc);
240
241private:
242 FILE* __file_;
243 const codecvt<char_type, char, state_type>* __cv_;
244 state_type* __st_;
245 bool __always_noconv_;
246
247 __stdoutbuf(const __stdoutbuf&);
248 __stdoutbuf& operator=(const __stdoutbuf&);
249};
250
251template <class _CharT>
252__stdoutbuf<_CharT>::__stdoutbuf(FILE* __fp, state_type* __st)
253 : __file_(__fp),
254 __cv_(&use_facet<codecvt<char_type, char, state_type> >(this->getloc())),
255 __st_(__st),
256 __always_noconv_(__cv_->always_noconv())
257{
258}
259
260template <class _CharT>
261typename __stdoutbuf<_CharT>::int_type
262__stdoutbuf<_CharT>::overflow(int_type __c)
263{
264 char __extbuf[__limit];
265 char_type __1buf;
266 if (!traits_type::eq_int_type(__c, traits_type::eof()))
267 {
268 __1buf = traits_type::to_char_type(__c);
269 if (__always_noconv_)
270 {
271 if (fwrite(&__1buf, sizeof(char_type), 1, __file_) != 1)
272 return traits_type::eof();
273 }
274 else
275 {
276 char* __extbe = __extbuf;
277 codecvt_base::result __r;
278 char_type* pbase = &__1buf;
279 char_type* pptr = pbase + 1;
280 do
281 {
282 const char_type* __e;
283 __r = __cv_->out(*__st_, pbase, pptr, __e,
284 __extbuf,
285 __extbuf + sizeof(__extbuf),
286 __extbe);
287 if (__e == pbase)
288 return traits_type::eof();
289 if (__r == codecvt_base::noconv)
290 {
291 if (fwrite(pbase, 1, 1, __file_) != 1)
292 return traits_type::eof();
293 }
294 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
295 {
296 size_t __nmemb = static_cast<size_t>(__extbe - __extbuf);
297 if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb)
298 return traits_type::eof();
299 if (__r == codecvt_base::partial)
300 {
301 pbase = const_cast<char_type*>(__e);
302 }
303 }
304 else
305 return traits_type::eof();
306 } while (__r == codecvt_base::partial);
307 }
308 }
309 return traits_type::not_eof(__c);
310}
311
312template <class _CharT>
313streamsize
314__stdoutbuf<_CharT>::xsputn(const char_type* __s, streamsize __n)
315{
316 if (__always_noconv_)
317 return fwrite(__s, sizeof(char_type), __n, __file_);
318 streamsize __i = 0;
319 for (; __i < __n; ++__i, ++__s)
320 if (overflow(traits_type::to_int_type(*__s)) == traits_type::eof())
321 break;
322 return __i;
323}
324
325template <class _CharT>
326int
327__stdoutbuf<_CharT>::sync()
328{
329 char __extbuf[__limit];
330 codecvt_base::result __r;
331 do
332 {
333 char* __extbe;
334 __r = __cv_->unshift(*__st_, __extbuf,
335 __extbuf + sizeof(__extbuf),
336 __extbe);
337 size_t __nmemb = static_cast<size_t>(__extbe - __extbuf);
338 if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb)
339 return -1;
340 } while (__r == codecvt_base::partial);
341 if (__r == codecvt_base::error)
342 return -1;
343 if (fflush(__file_))
344 return -1;
345 return 0;
346}
347
348template <class _CharT>
349void
350__stdoutbuf<_CharT>::imbue(const locale& __loc)
351{
352 sync();
353 __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
354 __always_noconv_ = __cv_->always_noconv();
355}
356
357_LIBCPP_END_NAMESPACE_STD
358
359_LIBCPP_POP_MACROS
360
361#endif // _LIBCPP___STD_STREAM
lib/libcxx/include/__stop_token/atomic_unique_lock.h created+139
......@@ -0,0 +1,139 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___STOP_TOKEN_ATOMIC_UNIQUE_GUARD_H
11#define _LIBCPP___STOP_TOKEN_ATOMIC_UNIQUE_GUARD_H
12
13#include <__bit/popcount.h>
14#include <__config>
15#include <atomic>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18# pragma GCC system_header
19#endif
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23#if _LIBCPP_STD_VER >= 20
24
25// This class implements an RAII unique_lock without a mutex.
26// It uses std::atomic<State>,
27// where State contains a lock bit and might contain other data,
28// and LockedBit is the value of State when the lock bit is set, e.g 1 << 2
29template <class _State, _State _LockedBit>
30class _LIBCPP_AVAILABILITY_SYNC __atomic_unique_lock {
31 static_assert(std::popcount(_LockedBit) == 1, "LockedBit must be an integer where only one bit is set");
32
33 std::atomic<_State>& __state_;
34 bool __is_locked_;
35
36public:
37 _LIBCPP_HIDE_FROM_ABI explicit __atomic_unique_lock(std::atomic<_State>& __state) noexcept
38 : __state_(__state), __is_locked_(true) {
39 __lock();
40 }
41
42 template <class _Pred>
43 _LIBCPP_HIDE_FROM_ABI __atomic_unique_lock(std::atomic<_State>& __state, _Pred&& __give_up_locking) noexcept
44 : __state_(__state), __is_locked_(false) {
45 __is_locked_ = __lock_impl(__give_up_locking, __set_locked_bit, std::memory_order_acquire);
46 }
47
48 template <class _Pred, class _UnaryFunction>
49 _LIBCPP_HIDE_FROM_ABI __atomic_unique_lock(
50 std::atomic<_State>& __state,
51 _Pred&& __give_up_locking,
52 _UnaryFunction&& __state_after_lock,
53 std::memory_order __locked_ordering) noexcept
54 : __state_(__state), __is_locked_(false) {
55 __is_locked_ = __lock_impl(__give_up_locking, __state_after_lock, __locked_ordering);
56 }
57
58 __atomic_unique_lock(const __atomic_unique_lock&) = delete;
59 __atomic_unique_lock(__atomic_unique_lock&&) = delete;
60 __atomic_unique_lock& operator=(const __atomic_unique_lock&) = delete;
61 __atomic_unique_lock& operator=(__atomic_unique_lock&&) = delete;
62
63 _LIBCPP_HIDE_FROM_ABI ~__atomic_unique_lock() {
64 if (__is_locked_) {
65 __unlock();
66 }
67 }
68
69 _LIBCPP_HIDE_FROM_ABI bool __owns_lock() const noexcept { return __is_locked_; }
70
71 _LIBCPP_HIDE_FROM_ABI void __lock() noexcept {
72 const auto __never_give_up_locking = [](_State) { return false; };
73 // std::memory_order_acquire because we'd like to make sure that all the read operations after the lock can read the
74 // up-to-date values.
75 __lock_impl(__never_give_up_locking, __set_locked_bit, std::memory_order_acquire);
76 __is_locked_ = true;
77 }
78
79 _LIBCPP_HIDE_FROM_ABI void __unlock() noexcept {
80 // unset the _LockedBit. `memory_order_release` because we need to make sure all the write operations before calling
81 // `__unlock` will be made visible to other threads
82 __state_.fetch_and(static_cast<_State>(~_LockedBit), std::memory_order_release);
83 __state_.notify_all();
84 __is_locked_ = false;
85 }
86
87private:
88 template <class _Pred, class _UnaryFunction>
89 _LIBCPP_HIDE_FROM_ABI bool
90 __lock_impl(_Pred&& __give_up_locking, // while trying to lock the state, if the predicate returns true, give up
91 // locking and return
92 _UnaryFunction&& __state_after_lock,
93 std::memory_order __locked_ordering) noexcept {
94 // At this stage, until we exit the inner while loop, other than the atomic state, we are not reading any order
95 // dependent values that is written on other threads, or writing anything that needs to be seen on other threads.
96 // Therefore `memory_order_relaxed` is enough.
97 _State __current_state = __state_.load(std::memory_order_relaxed);
98 do {
99 while (true) {
100 if (__give_up_locking(__current_state)) {
101 // user provided early return condition. fail to lock
102 return false;
103 } else if ((__current_state & _LockedBit) != 0) {
104 // another thread has locked the state, we need to wait
105 __state_.wait(__current_state, std::memory_order_relaxed);
106 // when it is woken up by notifyAll or spuriously, the __state_
107 // might have changed. reload the state
108 // Note that the new state's _LockedBit may or may not equal to 0
109 __current_state = __state_.load(std::memory_order_relaxed);
110 } else {
111 // at least for now, it is not locked. we can try `compare_exchange_weak` to lock it.
112 // Note that the variable `__current_state`'s lock bit has to be 0 at this point.
113 break;
114 }
115 }
116 } while (!__state_.compare_exchange_weak(
117 __current_state, // if __state_ has the same value of __current_state, lock bit must be zero before exchange and
118 // we are good to lock/exchange and return. If _state has a different value, because other
119 // threads locked it between the `break` statement above and this statement, exchange will fail
120 // and go back to the inner while loop above.
121 __state_after_lock(__current_state), // state after lock. Usually it should be __current_state | _LockedBit.
122 // Some use cases need to set other bits at the same time as an atomic
123 // operation therefore we accept a function
124 __locked_ordering, // sucessful exchange order. Usually it should be std::memory_order_acquire.
125 // Some use cases need more strict ordering therefore we accept it as a parameter
126 std::memory_order_relaxed // fail to exchange order. We don't need any ordering as we are going back to the
127 // inner while loop
128 ));
129 return true;
130 }
131
132 _LIBCPP_HIDE_FROM_ABI static constexpr auto __set_locked_bit = [](_State __state) { return __state | _LockedBit; };
133};
134
135#endif // _LIBCPP_STD_VER >= 20
136
137_LIBCPP_END_NAMESPACE_STD
138
139#endif // _LIBCPP___STOP_TOKEN_ATOMIC_UNIQUE_GUARD_H
lib/libcxx/include/__stop_token/intrusive_list_view.h created+85
......@@ -0,0 +1,85 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___STOP_TOKEN_INTRUSIVE_LIST_VIEW_H
11#define _LIBCPP___STOP_TOKEN_INTRUSIVE_LIST_VIEW_H
12
13#include <__assert>
14#include <__config>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22#if _LIBCPP_STD_VER >= 20
23
24template <class _Derived>
25struct __intrusive_node_base {
26 _Derived* __next_ = nullptr;
27 _Derived* __prev_ = nullptr;
28};
29
30// This class is a view of underlying double-linked list.
31// It does not own the nodes. It provides user-friendly
32// operations on the linked list.
33template <class _Node>
34struct __intrusive_list_view {
35 _LIBCPP_HIDE_FROM_ABI __intrusive_list_view() = default;
36 _LIBCPP_HIDE_FROM_ABI __intrusive_list_view(__intrusive_list_view const&) = default;
37 _LIBCPP_HIDE_FROM_ABI __intrusive_list_view(__intrusive_list_view&&) = default;
38 _LIBCPP_HIDE_FROM_ABI __intrusive_list_view& operator=(__intrusive_list_view const&) = default;
39 _LIBCPP_HIDE_FROM_ABI __intrusive_list_view& operator=(__intrusive_list_view&&) = default;
40 _LIBCPP_HIDE_FROM_ABI ~__intrusive_list_view() = default;
41
42 _LIBCPP_HIDE_FROM_ABI bool __empty() const noexcept { return __head_ == nullptr; }
43
44 _LIBCPP_HIDE_FROM_ABI void __push_front(_Node* __node) noexcept {
45 __node->__next_ = __head_;
46 if (__head_) {
47 __head_->__prev_ = __node;
48 }
49 __head_ = __node;
50 }
51
52 _LIBCPP_HIDE_FROM_ABI _Node* __pop_front() noexcept {
53 _Node* __front = __head_;
54 __head_ = __head_->__next_;
55 if (__head_) {
56 __head_->__prev_ = nullptr;
57 }
58 // OK not to set __front->__next_ = nullptr as __front is not part of the list anymore
59 return __front;
60 }
61
62 _LIBCPP_HIDE_FROM_ABI void __remove(_Node* __node) noexcept {
63 if (__node->__prev_) {
64 // prev exists, set its next to our next to skip __node
65 __node->__prev_->__next_ = __node->__next_;
66 if (__node->__next_) {
67 __node->__next_->__prev_ = __node->__prev_;
68 }
69 } else {
70 _LIBCPP_ASSERT_INTERNAL(__node == __head_, "Node to be removed has no prev node, so it has to be the head");
71 __pop_front();
72 }
73 }
74
75 _LIBCPP_HIDE_FROM_ABI bool __is_head(_Node* __node) noexcept { return __node == __head_; }
76
77private:
78 _Node* __head_ = nullptr;
79};
80
81#endif // _LIBCPP_STD_VER >= 20
82
83_LIBCPP_END_NAMESPACE_STD
84
85#endif // _LIBCPP___STOP_TOKEN_INTRUSIVE_LIST_VIEW_H
lib/libcxx/include/__stop_token/intrusive_shared_ptr.h created+134
......@@ -0,0 +1,134 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___STOP_TOKEN_INTRUSIVE_SHARED_PTR_H
11#define _LIBCPP___STOP_TOKEN_INTRUSIVE_SHARED_PTR_H
12
13#include <__atomic/atomic.h>
14#include <__atomic/memory_order.h>
15#include <__config>
16#include <__type_traits/is_reference.h>
17#include <__utility/move.h>
18#include <__utility/swap.h>
19#include <cstddef>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22# pragma GCC system_header
23#endif
24
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30#if _LIBCPP_STD_VER >= 20
31
32// For intrusive_shared_ptr to work with a type T, specialize __intrusive_shared_ptr_traits<T> and implement
33// the following function:
34//
35// static std::atomic<U>& __get_atomic_ref_count(T&);
36//
37// where U must be an integral type representing the number of references to the object.
38template <class _Tp>
39struct __intrusive_shared_ptr_traits;
40
41// A reference counting shared_ptr for types whose reference counter
42// is stored inside the class _Tp itself.
43// When the reference count goes to zero, the destructor of _Tp will be called
44template <class _Tp>
45struct __intrusive_shared_ptr {
46 _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr() = default;
47
48 _LIBCPP_HIDE_FROM_ABI explicit __intrusive_shared_ptr(_Tp* __raw_ptr) : __raw_ptr_(__raw_ptr) {
49 if (__raw_ptr_)
50 __increment_ref_count(*__raw_ptr_);
51 }
52
53 _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr(const __intrusive_shared_ptr& __other) noexcept
54 : __raw_ptr_(__other.__raw_ptr_) {
55 if (__raw_ptr_)
56 __increment_ref_count(*__raw_ptr_);
57 }
58
59 _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr(__intrusive_shared_ptr&& __other) noexcept
60 : __raw_ptr_(__other.__raw_ptr_) {
61 __other.__raw_ptr_ = nullptr;
62 }
63
64 _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr& operator=(const __intrusive_shared_ptr& __other) noexcept {
65 if (__other.__raw_ptr_ != __raw_ptr_) {
66 if (__other.__raw_ptr_) {
67 __increment_ref_count(*__other.__raw_ptr_);
68 }
69 if (__raw_ptr_) {
70 __decrement_ref_count(*__raw_ptr_);
71 }
72 __raw_ptr_ = __other.__raw_ptr_;
73 }
74 return *this;
75 }
76
77 _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr& operator=(__intrusive_shared_ptr&& __other) noexcept {
78 __intrusive_shared_ptr(std::move(__other)).swap(*this);
79 return *this;
80 }
81
82 _LIBCPP_HIDE_FROM_ABI ~__intrusive_shared_ptr() {
83 if (__raw_ptr_) {
84 __decrement_ref_count(*__raw_ptr_);
85 }
86 }
87
88 _LIBCPP_HIDE_FROM_ABI _Tp* operator->() const noexcept { return __raw_ptr_; }
89 _LIBCPP_HIDE_FROM_ABI _Tp& operator*() const noexcept { return *__raw_ptr_; }
90 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { return __raw_ptr_ != nullptr; }
91
92 _LIBCPP_HIDE_FROM_ABI void swap(__intrusive_shared_ptr& __other) { std::swap(__raw_ptr_, __other.__raw_ptr_); }
93
94 _LIBCPP_HIDE_FROM_ABI friend void swap(__intrusive_shared_ptr& __lhs, __intrusive_shared_ptr& __rhs) {
95 __lhs.swap(__rhs);
96 }
97
98 _LIBCPP_HIDE_FROM_ABI friend bool constexpr
99 operator==(const __intrusive_shared_ptr&, const __intrusive_shared_ptr&) = default;
100
101 _LIBCPP_HIDE_FROM_ABI friend bool constexpr operator==(const __intrusive_shared_ptr& __ptr, std::nullptr_t) {
102 return __ptr.__raw_ptr_ == nullptr;
103 }
104
105private:
106 _Tp* __raw_ptr_ = nullptr;
107
108 // the memory order for increment/decrement the counter is the same for shared_ptr
109 // increment is relaxed and decrement is acq_rel
110 _LIBCPP_HIDE_FROM_ABI static void __increment_ref_count(_Tp& __obj) {
111 __get_atomic_ref_count(__obj).fetch_add(1, std::memory_order_relaxed);
112 }
113
114 _LIBCPP_HIDE_FROM_ABI static void __decrement_ref_count(_Tp& __obj) {
115 if (__get_atomic_ref_count(__obj).fetch_sub(1, std::memory_order_acq_rel) == 1) {
116 delete &__obj;
117 }
118 }
119
120 _LIBCPP_HIDE_FROM_ABI static decltype(auto) __get_atomic_ref_count(_Tp& __obj) {
121 using __ret_type = decltype(__intrusive_shared_ptr_traits<_Tp>::__get_atomic_ref_count(__obj));
122 static_assert(
123 std::is_reference_v<__ret_type>, "__get_atomic_ref_count should return a reference to the atomic counter");
124 return __intrusive_shared_ptr_traits<_Tp>::__get_atomic_ref_count(__obj);
125 }
126};
127
128#endif // _LIBCPP_STD_VER >= 20
129
130_LIBCPP_END_NAMESPACE_STD
131
132_LIBCPP_POP_MACROS
133
134#endif // _LIBCPP___STOP_TOKEN_INTRUSIVE_SHARED_PTR_H
lib/libcxx/include/__stop_token/stop_callback.h created+99
......@@ -0,0 +1,99 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___STOP_TOKEN_STOP_CALLBACK_H
11#define _LIBCPP___STOP_TOKEN_STOP_CALLBACK_H
12
13#include <__availability>
14#include <__concepts/constructible.h>
15#include <__concepts/destructible.h>
16#include <__concepts/invocable.h>
17#include <__config>
18#include <__stop_token/intrusive_shared_ptr.h>
19#include <__stop_token/stop_state.h>
20#include <__stop_token/stop_token.h>
21#include <__type_traits/is_nothrow_constructible.h>
22#include <__utility/forward.h>
23#include <__utility/move.h>
24
25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26# pragma GCC system_header
27#endif
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31#if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
32
33template <class _Callback>
34class _LIBCPP_AVAILABILITY_SYNC stop_callback : private __stop_callback_base {
35 static_assert(invocable<_Callback>,
36 "Mandates: stop_callback is instantiated with an argument for the template parameter Callback that "
37 "satisfies invocable.");
38 static_assert(destructible<_Callback>,
39 "Mandates: stop_callback is instantiated with an argument for the template parameter Callback that "
40 "satisfies destructible.");
41
42public:
43 using callback_type = _Callback;
44
45 template <class _Cb>
46 requires constructible_from<_Callback, _Cb>
47 _LIBCPP_HIDE_FROM_ABI explicit stop_callback(const stop_token& __st,
48 _Cb&& __cb) noexcept(is_nothrow_constructible_v<_Callback, _Cb>)
49 : stop_callback(__private_tag{}, __st.__state_, std::forward<_Cb>(__cb)) {}
50
51 template <class _Cb>
52 requires constructible_from<_Callback, _Cb>
53 _LIBCPP_HIDE_FROM_ABI explicit stop_callback(stop_token&& __st,
54 _Cb&& __cb) noexcept(is_nothrow_constructible_v<_Callback, _Cb>)
55 : stop_callback(__private_tag{}, std::move(__st.__state_), std::forward<_Cb>(__cb)) {}
56
57 _LIBCPP_HIDE_FROM_ABI ~stop_callback() {
58 if (__state_) {
59 __state_->__remove_callback(this);
60 }
61 }
62
63 stop_callback(const stop_callback&) = delete;
64 stop_callback(stop_callback&&) = delete;
65 stop_callback& operator=(const stop_callback&) = delete;
66 stop_callback& operator=(stop_callback&&) = delete;
67
68private:
69 _LIBCPP_NO_UNIQUE_ADDRESS _Callback __callback_;
70 __intrusive_shared_ptr<__stop_state> __state_;
71
72 friend __stop_callback_base;
73
74 struct __private_tag {};
75
76 template <class _StatePtr, class _Cb>
77 _LIBCPP_HIDE_FROM_ABI explicit stop_callback(__private_tag, _StatePtr&& __state, _Cb&& __cb) noexcept(
78 is_nothrow_constructible_v<_Callback, _Cb>)
79 : __stop_callback_base([](__stop_callback_base* __cb_base) noexcept {
80 // stop callback is supposed to only be called once
81 std::forward<_Callback>(static_cast<stop_callback*>(__cb_base)->__callback_)();
82 }),
83 __callback_(std::forward<_Cb>(__cb)),
84 __state_() {
85 if (__state && __state->__add_callback(this)) {
86 // st.stop_requested() was false and this is successfully added to the linked list
87 __state_ = std::forward<_StatePtr>(__state);
88 }
89 }
90};
91
92template <class _Callback>
93_LIBCPP_AVAILABILITY_SYNC stop_callback(stop_token, _Callback) -> stop_callback<_Callback>;
94
95#endif // _LIBCPP_STD_VER >= 20
96
97_LIBCPP_END_NAMESPACE_STD
98
99#endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
lib/libcxx/include/__stop_token/stop_source.h created+92
......@@ -0,0 +1,92 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___STOP_TOKEN_STOP_SOURCE_H
11#define _LIBCPP___STOP_TOKEN_STOP_SOURCE_H
12
13#include <__availability>
14#include <__config>
15#include <__stop_token/intrusive_shared_ptr.h>
16#include <__stop_token/stop_state.h>
17#include <__stop_token/stop_token.h>
18#include <__utility/move.h>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21# pragma GCC system_header
22#endif
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26#if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
27
28struct nostopstate_t {
29 explicit nostopstate_t() = default;
30};
31
32inline constexpr nostopstate_t nostopstate{};
33
34class _LIBCPP_AVAILABILITY_SYNC stop_source {
35public:
36 _LIBCPP_HIDE_FROM_ABI stop_source() : __state_(new __stop_state()) { __state_->__increment_stop_source_counter(); }
37
38 _LIBCPP_HIDE_FROM_ABI explicit stop_source(nostopstate_t) noexcept : __state_(nullptr) {}
39
40 _LIBCPP_HIDE_FROM_ABI stop_source(const stop_source& __other) noexcept : __state_(__other.__state_) {
41 if (__state_) {
42 __state_->__increment_stop_source_counter();
43 }
44 }
45
46 _LIBCPP_HIDE_FROM_ABI stop_source(stop_source&& __other) noexcept = default;
47
48 _LIBCPP_HIDE_FROM_ABI stop_source& operator=(const stop_source& __other) noexcept {
49 // increment `__other` first so that we don't hit 0 in case of self-assignment
50 if (__other.__state_) {
51 __other.__state_->__increment_stop_source_counter();
52 }
53 if (__state_) {
54 __state_->__decrement_stop_source_counter();
55 }
56 __state_ = __other.__state_;
57 return *this;
58 }
59
60 _LIBCPP_HIDE_FROM_ABI stop_source& operator=(stop_source&&) noexcept = default;
61
62 _LIBCPP_HIDE_FROM_ABI ~stop_source() {
63 if (__state_) {
64 __state_->__decrement_stop_source_counter();
65 }
66 }
67
68 _LIBCPP_HIDE_FROM_ABI void swap(stop_source& __other) noexcept { __state_.swap(__other.__state_); }
69
70 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI stop_token get_token() const noexcept { return stop_token(__state_); }
71
72 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_possible() const noexcept { return __state_ != nullptr; }
73
74 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_requested() const noexcept {
75 return __state_ != nullptr && __state_->__stop_requested();
76 }
77
78 _LIBCPP_HIDE_FROM_ABI bool request_stop() noexcept { return __state_ && __state_->__request_stop(); }
79
80 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend bool operator==(const stop_source&, const stop_source&) noexcept = default;
81
82 _LIBCPP_HIDE_FROM_ABI friend void swap(stop_source& __lhs, stop_source& __rhs) noexcept { __lhs.swap(__rhs); }
83
84private:
85 __intrusive_shared_ptr<__stop_state> __state_;
86};
87
88#endif // _LIBCPP_STD_VER >= 20
89
90_LIBCPP_END_NAMESPACE_STD
91
92#endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
lib/libcxx/include/__stop_token/stop_state.h created+236
......@@ -0,0 +1,236 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___STOP_TOKEN_STOP_STATE_H
11#define _LIBCPP___STOP_TOKEN_STOP_STATE_H
12
13#include <__availability>
14#include <__config>
15#include <__stop_token/atomic_unique_lock.h>
16#include <__stop_token/intrusive_list_view.h>
17#include <atomic>
18#include <cstdint>
19#include <thread>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22# pragma GCC system_header
23#endif
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27#if _LIBCPP_STD_VER >= 20
28
29struct __stop_callback_base : __intrusive_node_base<__stop_callback_base> {
30 using __callback_fn_t = void(__stop_callback_base*) noexcept;
31 _LIBCPP_HIDE_FROM_ABI explicit __stop_callback_base(__callback_fn_t* __callback_fn) : __callback_fn_(__callback_fn) {}
32
33 _LIBCPP_HIDE_FROM_ABI void __invoke() noexcept { __callback_fn_(this); }
34
35 __callback_fn_t* __callback_fn_;
36 atomic<bool> __completed_ = false;
37 bool* __destroyed_ = nullptr;
38};
39
40class __stop_state {
41 static constexpr uint32_t __stop_requested_bit = 1;
42 static constexpr uint32_t __callback_list_locked_bit = 1 << 1;
43 static constexpr uint32_t __stop_source_counter_shift = 2;
44
45 // The "stop_source counter" is not used for lifetime reference counting.
46 // When the number of stop_source reaches 0, the remaining stop_tokens's
47 // stop_possible will return false. We need this counter to track this.
48 //
49 // The "callback list locked" bit implements the atomic_unique_lock to
50 // guard the operations on the callback list
51 //
52 // 31 - 2 | 1 | 0 |
53 // stop_source counter | callback list locked | stop_requested |
54 atomic<uint32_t> __state_ = 0;
55
56 // Reference count for stop_token + stop_callback + stop_source
57 // When the counter reaches zero, the state is destroyed
58 // It is used by __intrusive_shared_ptr, but it is stored here for better layout
59 atomic<uint32_t> __ref_count_ = 0;
60
61 using __state_t = uint32_t;
62 using __callback_list_lock = __atomic_unique_lock<__state_t, __callback_list_locked_bit>;
63 using __callback_list = __intrusive_list_view<__stop_callback_base>;
64
65 __callback_list __callback_list_;
66 thread::id __requesting_thread_;
67
68public:
69 _LIBCPP_HIDE_FROM_ABI __stop_state() noexcept = default;
70
71 _LIBCPP_HIDE_FROM_ABI void __increment_stop_source_counter() noexcept {
72 _LIBCPP_ASSERT_UNCATEGORIZED(
73 __state_.load(std::memory_order_relaxed) <= static_cast<__state_t>(~(1 << __stop_source_counter_shift)),
74 "stop_source's counter reaches the maximum. Incrementing the counter will overflow");
75 __state_.fetch_add(1 << __stop_source_counter_shift, std::memory_order_relaxed);
76 }
77
78 // We are not destroying the object after counter decrements to zero, nor do we have
79 // operations depend on the ordering of decrementing the counter. relaxed is enough.
80 _LIBCPP_HIDE_FROM_ABI void __decrement_stop_source_counter() noexcept {
81 _LIBCPP_ASSERT_UNCATEGORIZED(
82 __state_.load(std::memory_order_relaxed) >= static_cast<__state_t>(1 << __stop_source_counter_shift),
83 "stop_source's counter is 0. Decrementing the counter will underflow");
84 __state_.fetch_sub(1 << __stop_source_counter_shift, std::memory_order_relaxed);
85 }
86
87 _LIBCPP_HIDE_FROM_ABI bool __stop_requested() const noexcept {
88 // acquire because [thread.stoptoken.intro] A call to request_stop that returns true
89 // synchronizes with a call to stop_requested on an associated stop_token or stop_source
90 // object that returns true.
91 // request_stop's compare_exchange_weak has release which syncs with this acquire
92 return (__state_.load(std::memory_order_acquire) & __stop_requested_bit) != 0;
93 }
94
95 _LIBCPP_HIDE_FROM_ABI bool __stop_possible_for_stop_token() const noexcept {
96 // [stoptoken.mem] false if "a stop request was not made and there are no associated stop_source objects"
97 // Todo: Can this be std::memory_order_relaxed as the standard does not say anything except not to introduce data
98 // race?
99 __state_t __curent_state = __state_.load(std::memory_order_acquire);
100 return ((__curent_state & __stop_requested_bit) != 0) || ((__curent_state >> __stop_source_counter_shift) != 0);
101 }
102
103 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __request_stop() noexcept {
104 auto __cb_list_lock = __try_lock_for_request_stop();
105 if (!__cb_list_lock.__owns_lock()) {
106 return false;
107 }
108 __requesting_thread_ = this_thread::get_id();
109
110 while (!__callback_list_.__empty()) {
111 auto __cb = __callback_list_.__pop_front();
112
113 // allow other callbacks to be removed while invoking the current callback
114 __cb_list_lock.__unlock();
115
116 bool __destroyed = false;
117 __cb->__destroyed_ = &__destroyed;
118
119 __cb->__invoke();
120
121 // __cb's invoke function could potentially delete itself. We need to check before accessing __cb's member
122 if (!__destroyed) {
123 // needs to set __destroyed_ pointer to nullptr, otherwise it points to a local variable
124 // which is to be destroyed at the end of the loop
125 __cb->__destroyed_ = nullptr;
126
127 // [stopcallback.cons] If callback is concurrently executing on another thread, then the return
128 // from the invocation of callback strongly happens before ([intro.races]) callback is destroyed.
129 // this release syncs with the acquire in the remove_callback
130 __cb->__completed_.store(true, std::memory_order_release);
131 __cb->__completed_.notify_all();
132 }
133
134 __cb_list_lock.__lock();
135 }
136
137 return true;
138 }
139
140 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __add_callback(__stop_callback_base* __cb) noexcept {
141 // If it is already stop_requested. Do not try to request it again.
142 const auto __give_up_trying_to_lock_condition = [__cb](__state_t __state) {
143 if ((__state & __stop_requested_bit) != 0) {
144 // already stop requested, synchronously run the callback and no need to lock the list again
145 __cb->__invoke();
146 return true;
147 }
148 // no stop source. no need to lock the list to add the callback as it can never be invoked
149 return (__state >> __stop_source_counter_shift) == 0;
150 };
151
152 __callback_list_lock __cb_list_lock(__state_, __give_up_trying_to_lock_condition);
153
154 if (!__cb_list_lock.__owns_lock()) {
155 return false;
156 }
157
158 __callback_list_.__push_front(__cb);
159
160 return true;
161 // unlock here: [thread.stoptoken.intro] Registration of a callback synchronizes with the invocation of
162 // that callback.
163 // Note: this release sync with the acquire in the request_stop' __try_lock_for_request_stop
164 }
165
166 // called by the destructor of stop_callback
167 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void __remove_callback(__stop_callback_base* __cb) noexcept {
168 __callback_list_lock __cb_list_lock(__state_);
169
170 // under below condition, the request_stop call just popped __cb from the list and could execute it now
171 bool __potentially_executing_now = __cb->__prev_ == nullptr && !__callback_list_.__is_head(__cb);
172
173 if (__potentially_executing_now) {
174 auto __requested_thread = __requesting_thread_;
175 __cb_list_lock.__unlock();
176
177 if (std::this_thread::get_id() != __requested_thread) {
178 // [stopcallback.cons] If callback is concurrently executing on another thread, then the return
179 // from the invocation of callback strongly happens before ([intro.races]) callback is destroyed.
180 __cb->__completed_.wait(false, std::memory_order_acquire);
181 } else {
182 // The destructor of stop_callback runs on the same thread of the thread that invokes the callback.
183 // The callback is potentially invoking its own destuctor. Set the flag to avoid accessing destroyed
184 // members on the invoking side
185 if (__cb->__destroyed_) {
186 *__cb->__destroyed_ = true;
187 }
188 }
189 } else {
190 __callback_list_.__remove(__cb);
191 }
192 }
193
194private:
195 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI __callback_list_lock __try_lock_for_request_stop() noexcept {
196 // If it is already stop_requested, do not try to request stop or lock the list again.
197 const auto __lock_fail_condition = [](__state_t __state) { return (__state & __stop_requested_bit) != 0; };
198
199 // set locked and requested bit at the same time
200 const auto __after_lock_state = [](__state_t __state) {
201 return __state | __callback_list_locked_bit | __stop_requested_bit;
202 };
203
204 // acq because [thread.stoptoken.intro] Registration of a callback synchronizes with the invocation of that
205 // callback. We are going to invoke the callback after getting the lock, acquire so that we can see the
206 // registration of a callback (and other writes that happens-before the add_callback)
207 // Note: the rel (unlock) in the add_callback syncs with this acq
208 // rel because [thread.stoptoken.intro] A call to request_stop that returns true synchronizes with a call
209 // to stop_requested on an associated stop_token or stop_source object that returns true.
210 // We need to make sure that all writes (including user code) before request_stop will be made visible
211 // to the threads that waiting for `stop_requested == true`
212 // Note: this rel syncs with the acq in `stop_requested`
213 const auto __locked_ordering = std::memory_order_acq_rel;
214
215 return __callback_list_lock(__state_, __lock_fail_condition, __after_lock_state, __locked_ordering);
216 }
217
218 template <class _Tp>
219 friend struct __intrusive_shared_ptr_traits;
220};
221
222template <class _Tp>
223struct __intrusive_shared_ptr_traits;
224
225template <>
226struct __intrusive_shared_ptr_traits<__stop_state> {
227 _LIBCPP_HIDE_FROM_ABI static atomic<uint32_t>& __get_atomic_ref_count(__stop_state& __state) {
228 return __state.__ref_count_;
229 }
230};
231
232#endif // _LIBCPP_STD_VER >= 20
233
234_LIBCPP_END_NAMESPACE_STD
235
236#endif // _LIBCPP___STOP_TOKEN_STOP_STATE_H
lib/libcxx/include/__stop_token/stop_token.h created+64
......@@ -0,0 +1,64 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___STOP_TOKEN_STOP_TOKEN_H
11#define _LIBCPP___STOP_TOKEN_STOP_TOKEN_H
12
13#include <__availability>
14#include <__config>
15#include <__stop_token/intrusive_shared_ptr.h>
16#include <__stop_token/stop_state.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19# pragma GCC system_header
20#endif
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24#if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
25
26class _LIBCPP_AVAILABILITY_SYNC stop_token {
27public:
28 _LIBCPP_HIDE_FROM_ABI stop_token() noexcept = default;
29
30 _LIBCPP_HIDE_FROM_ABI stop_token(const stop_token&) noexcept = default;
31 _LIBCPP_HIDE_FROM_ABI stop_token(stop_token&&) noexcept = default;
32 _LIBCPP_HIDE_FROM_ABI stop_token& operator=(const stop_token&) noexcept = default;
33 _LIBCPP_HIDE_FROM_ABI stop_token& operator=(stop_token&&) noexcept = default;
34 _LIBCPP_HIDE_FROM_ABI ~stop_token() = default;
35
36 _LIBCPP_HIDE_FROM_ABI void swap(stop_token& __other) noexcept { __state_.swap(__other.__state_); }
37
38 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_requested() const noexcept {
39 return __state_ != nullptr && __state_->__stop_requested();
40 }
41
42 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_possible() const noexcept {
43 return __state_ != nullptr && __state_->__stop_possible_for_stop_token();
44 }
45
46 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend bool operator==(const stop_token&, const stop_token&) noexcept = default;
47
48 _LIBCPP_HIDE_FROM_ABI friend void swap(stop_token& __lhs, stop_token& __rhs) noexcept { __lhs.swap(__rhs); }
49
50private:
51 __intrusive_shared_ptr<__stop_state> __state_;
52
53 friend class stop_source;
54 template <class _Tp>
55 friend class stop_callback;
56
57 _LIBCPP_HIDE_FROM_ABI explicit stop_token(const __intrusive_shared_ptr<__stop_state>& __state) : __state_(__state) {}
58};
59
60#endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
61
62_LIBCPP_END_NAMESPACE_STD
63
64#endif // _LIBCPP___STOP_TOKEN_STOP_TOKEN_H
lib/libcxx/include/__string/char_traits.h+122-115
......@@ -18,11 +18,11 @@
1818#include <__config>
1919#include <__functional/hash.h>
2020#include <__iterator/iterator_traits.h>
21#include <__string/constexpr_c_functions.h>
2122#include <__type_traits/is_constant_evaluated.h>
2223#include <cstddef>
2324#include <cstdint>
2425#include <cstdio>
25#include <cstring>
2626#include <iosfwd>
2727
2828#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
......@@ -73,7 +73,7 @@ exposition-only to document what members a char_traits specialization should pro
7373
7474//
7575// Temporary extension to provide a base template for std::char_traits.
76// TODO: Remove in LLVM 18.
76// TODO(LLVM-18): Remove this class.
7777//
7878template <class _CharT>
7979struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, char8_t, char16_t or char32_t is non-standard and is provided for a temporary period. It will be removed in LLVM 18, so please migrate off of it.")
......@@ -85,14 +85,14 @@ struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, cha
8585 using pos_type = streampos;
8686 using state_type = mbstate_t;
8787
88 static inline void _LIBCPP_CONSTEXPR_SINCE_CXX17
88 static inline void _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI
8989 assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
90 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
90 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
9191 {return __c1 == __c2;}
92 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
92 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
9393 {return __c1 < __c2;}
9494
95 static _LIBCPP_CONSTEXPR_SINCE_CXX17
95 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
9696 int compare(const char_type* __s1, const char_type* __s2, size_t __n) {
9797 for (; __n; --__n, ++__s1, ++__s2)
9898 {
......@@ -120,7 +120,7 @@ struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, cha
120120 }
121121 return nullptr;
122122 }
123 static _LIBCPP_CONSTEXPR_SINCE_CXX20
123 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
124124 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) {
125125 if (__n == 0) return __s1;
126126 char_type* __r = __s1;
......@@ -142,7 +142,8 @@ struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, cha
142142 static _LIBCPP_CONSTEXPR_SINCE_CXX20
143143 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) {
144144 if (!__libcpp_is_constant_evaluated()) {
145 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
145 _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
146 __s2 < __s1 || __s2 >= __s1 + __n, "char_traits::copy overlapped range");
146147 }
147148 char_type* __r = __s1;
148149 for (; __n; --__n, ++__s1, ++__s2)
......@@ -158,37 +159,18 @@ struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, cha
158159 return __r;
159160 }
160161
161 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
162 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
162163 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
163 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
164 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
164165 {return char_type(__c);}
165 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
166 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
166167 {return int_type(__c);}
167 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
168 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
168169 {return __c1 == __c2;}
169 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
170 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
170171 {return int_type(EOF);}
171172};
172173
173template <class _CharT>
174_LIBCPP_HIDE_FROM_ABI static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
175_CharT* __char_traits_move(_CharT* __dest, const _CharT* __source, size_t __n) _NOEXCEPT
176{
177#ifdef _LIBCPP_COMPILER_GCC
178 if (__libcpp_is_constant_evaluated()) {
179 if (__n == 0)
180 return __dest;
181 _CharT* __allocation = new _CharT[__n];
182 std::copy_n(__source, __n, __allocation);
183 std::copy_n(static_cast<const _CharT*>(__allocation), __n, __dest);
184 delete[] __allocation;
185 return __dest;
186 }
187#endif
188 ::__builtin_memmove(__dest, __source, __n * sizeof(_CharT));
189 return __dest;
190}
191
192174// char_traits<char>
193175
194176template <>
......@@ -199,62 +181,83 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char>
199181 using off_type = streamoff;
200182 using pos_type = streampos;
201183 using state_type = mbstate_t;
202#if _LIBCPP_STD_VER > 17
184#if _LIBCPP_STD_VER >= 20
203185 using comparison_category = strong_ordering;
204186#endif
205187
206 static inline _LIBCPP_CONSTEXPR_SINCE_CXX17
188 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
207189 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
208 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
190
191 // TODO: Make this _LIBCPP_HIDE_FROM_ABI
192 static inline _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
209193 {return __c1 == __c2;}
210 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
194 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
211195 {return (unsigned char)__c1 < (unsigned char)__c2;}
212196
213 static _LIBCPP_CONSTEXPR_SINCE_CXX17 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
214 if (__n == 0)
215 return 0;
216 return std::__constexpr_memcmp(__s1, __s2, __n);
217 }
197 // __constexpr_memcmp requires a trivially lexicographically comparable type, but char is not when char is a signed type
198 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
199 compare(const char_type* __lhs, const char_type* __rhs, size_t __count) _NOEXCEPT {
200 if (__libcpp_is_constant_evaluated()) {
201#ifdef _LIBCPP_COMPILER_CLANG_BASED
202 return __builtin_memcmp(__lhs, __rhs, __count);
203#else
204 while (__count != 0) {
205 if (lt(*__lhs, *__rhs))
206 return -1;
207 if (lt(*__rhs, *__lhs))
208 return 1;
218209
219 static inline size_t _LIBCPP_CONSTEXPR_SINCE_CXX17 length(const char_type* __s) _NOEXCEPT {
220 return std::__constexpr_strlen(__s);
221 }
210 __count -= sizeof(char_type);
211 ++__lhs;
212 ++__rhs;
213 }
214 return 0;
215#endif // _LIBCPP_COMPILER_CLANG_BASED
216 } else {
217 return __builtin_memcmp(__lhs, __rhs, __count);
218 }
219 }
222220
223 static _LIBCPP_CONSTEXPR_SINCE_CXX17
224 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
225 if (__n == 0)
226 return nullptr;
227 return std::__constexpr_char_memchr(__s, static_cast<int>(__a), __n);
228 }
221 static inline _LIBCPP_HIDE_FROM_ABI size_t _LIBCPP_CONSTEXPR_SINCE_CXX17 length(const char_type* __s) _NOEXCEPT {
222 return std::__constexpr_strlen(__s);
223 }
229224
230 static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
225 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
226 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
227 if (__n == 0)
228 return nullptr;
229 return std::__constexpr_memchr(__s, __a, __n);
230 }
231
232 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
231233 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
232 return std::__char_traits_move(__s1, __s2, __n);
234 return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
233235 }
234236
235 static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
237 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
236238 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
237239 if (!__libcpp_is_constant_evaluated())
238 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
240 _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
241 __s2 < __s1 || __s2 >= __s1 + __n, "char_traits::copy overlapped range");
239242 std::copy_n(__s2, __n, __s1);
240243 return __s1;
241244 }
242245
243 static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
246 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
244247 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
245248 std::fill_n(__s, __n, __a);
246249 return __s;
247250 }
248251
249 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
252 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
250253 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
251 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
254 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
252255 {return char_type(__c);}
253 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
256 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
254257 {return int_type((unsigned char)__c);}
255 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
258 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
256259 {return __c1 == __c2;}
257 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
260 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
258261 {return int_type(EOF);}
259262};
260263
......@@ -269,62 +272,64 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
269272 using off_type = streamoff;
270273 using pos_type = streampos;
271274 using state_type = mbstate_t;
272#if _LIBCPP_STD_VER > 17
275#if _LIBCPP_STD_VER >= 20
273276 using comparison_category = strong_ordering;
274277#endif
275278
276 static inline _LIBCPP_CONSTEXPR_SINCE_CXX17
279 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
277280 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
278 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
281 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
279282 {return __c1 == __c2;}
280 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
283 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
281284 {return __c1 < __c2;}
282285
283 static _LIBCPP_CONSTEXPR_SINCE_CXX17 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
286 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
287 compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
284288 if (__n == 0)
285 return 0;
289 return 0;
286290 return std::__constexpr_wmemcmp(__s1, __s2, __n);
287291 }
288292
289 static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT {
293 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT {
290294 return std::__constexpr_wcslen(__s);
291295 }
292296
293 static _LIBCPP_CONSTEXPR_SINCE_CXX17
297 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
294298 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
295299 if (__n == 0)
296300 return nullptr;
297301 return std::__constexpr_wmemchr(__s, __a, __n);
298302 }
299303
300 static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
304 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
301305 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
302 return std::__char_traits_move(__s1, __s2, __n);
306 return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
303307 }
304308
305 static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
309 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
306310 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
307311 if (!__libcpp_is_constant_evaluated())
308 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
312 _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
313 __s2 < __s1 || __s2 >= __s1 + __n, "char_traits::copy overlapped range");
309314 std::copy_n(__s2, __n, __s1);
310315 return __s1;
311316 }
312317
313 static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
318 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
314319 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
315320 std::fill_n(__s, __n, __a);
316321 return __s;
317322 }
318323
319 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
324 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
320325 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
321 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
326 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
322327 {return char_type(__c);}
323 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
328 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
324329 {return int_type(__c);}
325 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
330 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
326331 {return __c1 == __c2;}
327 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
332 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
328333 {return int_type(WEOF);}
329334};
330335#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
......@@ -339,56 +344,57 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
339344 using off_type = streamoff;
340345 using pos_type = u8streampos;
341346 using state_type = mbstate_t;
342#if _LIBCPP_STD_VER > 17
347#if _LIBCPP_STD_VER >= 20
343348 using comparison_category = strong_ordering;
344349#endif
345350
346 static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
351 static inline _LIBCPP_HIDE_FROM_ABI constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
347352 {__c1 = __c2;}
348 static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
353 static inline _LIBCPP_HIDE_FROM_ABI constexpr bool eq(char_type __c1, char_type __c2) noexcept
349354 {return __c1 == __c2;}
350 static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
355 static inline _LIBCPP_HIDE_FROM_ABI constexpr bool lt(char_type __c1, char_type __c2) noexcept
351356 {return __c1 < __c2;}
352357
353358 static _LIBCPP_HIDE_FROM_ABI constexpr int
354359 compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
355 return std::__constexpr_memcmp(__s1, __s2, __n);
360 return std::__constexpr_memcmp(__s1, __s2, __element_count(__n));
356361 }
357362
358 static constexpr
363 static _LIBCPP_HIDE_FROM_ABI constexpr
359364 size_t length(const char_type* __s) _NOEXCEPT;
360365
361366 _LIBCPP_INLINE_VISIBILITY static constexpr
362367 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
363368
364 static _LIBCPP_CONSTEXPR_SINCE_CXX20
369 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
365370 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
366 return std::__char_traits_move(__s1, __s2, __n);
371 return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
367372 }
368373
369 static _LIBCPP_CONSTEXPR_SINCE_CXX20
374 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
370375 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
371376 if (!__libcpp_is_constant_evaluated())
372 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
377 _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
378 __s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
373379 std::copy_n(__s2, __n, __s1);
374380 return __s1;
375381 }
376382
377 static _LIBCPP_CONSTEXPR_SINCE_CXX20
383 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
378384 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
379385 std::fill_n(__s, __n, __a);
380386 return __s;
381387 }
382388
383 static inline constexpr int_type not_eof(int_type __c) noexcept
389 static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type not_eof(int_type __c) noexcept
384390 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
385 static inline constexpr char_type to_char_type(int_type __c) noexcept
391 static inline _LIBCPP_HIDE_FROM_ABI constexpr char_type to_char_type(int_type __c) noexcept
386392 {return char_type(__c);}
387 static inline constexpr int_type to_int_type(char_type __c) noexcept
393 static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type to_int_type(char_type __c) noexcept
388394 {return int_type(__c);}
389 static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
395 static inline _LIBCPP_HIDE_FROM_ABI constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
390396 {return __c1 == __c2;}
391 static inline constexpr int_type eof() noexcept
397 static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type eof() noexcept
392398 {return int_type(EOF);}
393399};
394400
......@@ -427,15 +433,15 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
427433 using off_type = streamoff;
428434 using pos_type = u16streampos;
429435 using state_type = mbstate_t;
430#if _LIBCPP_STD_VER > 17
436#if _LIBCPP_STD_VER >= 20
431437 using comparison_category = strong_ordering;
432438#endif
433439
434 static inline _LIBCPP_CONSTEXPR_SINCE_CXX17
440 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
435441 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
436 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
442 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
437443 {return __c1 == __c2;}
438 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
444 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
439445 {return __c1 < __c2;}
440446
441447 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
......@@ -447,13 +453,14 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
447453
448454 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
449455 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
450 return std::__char_traits_move(__s1, __s2, __n);
456 return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
451457 }
452458
453459 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
454460 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
455461 if (!__libcpp_is_constant_evaluated())
456 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
462 _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
463 __s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
457464 std::copy_n(__s2, __n, __s1);
458465 return __s1;
459466 }
......@@ -464,15 +471,15 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
464471 return __s;
465472 }
466473
467 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
474 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
468475 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
469 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
476 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
470477 {return char_type(__c);}
471 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
478 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
472479 {return int_type(__c);}
473 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
480 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
474481 {return __c1 == __c2;}
475 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
482 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
476483 {return int_type(0xFFFF);}
477484};
478485
......@@ -521,15 +528,15 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
521528 using off_type = streamoff;
522529 using pos_type = u32streampos;
523530 using state_type = mbstate_t;
524#if _LIBCPP_STD_VER > 17
531#if _LIBCPP_STD_VER >= 20
525532 using comparison_category = strong_ordering;
526533#endif
527534
528 static inline _LIBCPP_CONSTEXPR_SINCE_CXX17
535 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
529536 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
530 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
537 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
531538 {return __c1 == __c2;}
532 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
539 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
533540 {return __c1 < __c2;}
534541
535542 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
......@@ -541,7 +548,7 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
541548
542549 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
543550 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
544 return std::__char_traits_move(__s1, __s2, __n);
551 return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
545552 }
546553
547554 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -556,15 +563,15 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
556563 return __s;
557564 }
558565
559 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
566 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
560567 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
561 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
568 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
562569 {return char_type(__c);}
563 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
570 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
564571 {return int_type(__c);}
565 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
572 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
566573 {return __c1 == __c2;}
567 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
574 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
568575 {return int_type(0xFFFFFFFF);}
569576};
570577
lib/libcxx/include/__string/constexpr_c_functions.h created+219
......@@ -0,0 +1,219 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___STRING_CONSTEXPR_C_FUNCTIONS_H
10#define _LIBCPP___STRING_CONSTEXPR_C_FUNCTIONS_H
11
12#include <__config>
13#include <__memory/addressof.h>
14#include <__memory/construct_at.h>
15#include <__type_traits/datasizeof.h>
16#include <__type_traits/is_always_bitcastable.h>
17#include <__type_traits/is_assignable.h>
18#include <__type_traits/is_constant_evaluated.h>
19#include <__type_traits/is_constructible.h>
20#include <__type_traits/is_equality_comparable.h>
21#include <__type_traits/is_same.h>
22#include <__type_traits/is_trivially_copyable.h>
23#include <__type_traits/is_trivially_lexicographically_comparable.h>
24#include <__type_traits/remove_cv.h>
25#include <__utility/is_pointer_in_range.h>
26#include <cstddef>
27
28#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
29# pragma GCC system_header
30#endif
31
32_LIBCPP_BEGIN_NAMESPACE_STD
33
34// Type used to encode that a function takes an integer that represents a number
35// of elements as opposed to a number of bytes.
36enum class __element_count : size_t {};
37
38inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t __constexpr_strlen(const char* __str) {
39 // GCC currently doesn't support __builtin_strlen for heap-allocated memory during constant evaluation.
40 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70816
41#ifdef _LIBCPP_COMPILER_GCC
42 if (__libcpp_is_constant_evaluated()) {
43 size_t __i = 0;
44 for (; __str[__i] != '\0'; ++__i)
45 ;
46 return __i;
47 }
48#endif
49 return __builtin_strlen(__str);
50}
51
52// Because of __libcpp_is_trivially_lexicographically_comparable we know that comparing the object representations is
53// equivalent to a std::memcmp. Since we have multiple objects contiguously in memory, we can call memcmp once instead
54// of invoking it on every object individually.
55template <class _Tp, class _Up>
56_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int
57__constexpr_memcmp(const _Tp* __lhs, const _Up* __rhs, __element_count __n) {
58 static_assert(__libcpp_is_trivially_lexicographically_comparable<_Tp, _Up>::value,
59 "_Tp and _Up have to be trivially lexicographically comparable");
60
61 auto __count = static_cast<size_t>(__n);
62
63 if (__libcpp_is_constant_evaluated()) {
64#ifdef _LIBCPP_COMPILER_CLANG_BASED
65 if (sizeof(_Tp) == 1 && !is_same<_Tp, bool>::value)
66 return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp));
67#endif
68
69 while (__count != 0) {
70 if (*__lhs < *__rhs)
71 return -1;
72 if (*__rhs < *__lhs)
73 return 1;
74
75 --__count;
76 ++__lhs;
77 ++__rhs;
78 }
79 return 0;
80 } else {
81 return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp));
82 }
83}
84
85// Because of __libcpp_is_trivially_equality_comparable we know that comparing the object representations is equivalent
86// to a std::memcmp(...) == 0. Since we have multiple objects contiguously in memory, we can call memcmp once instead
87// of invoking it on every object individually.
88template <class _Tp, class _Up>
89_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
90__constexpr_memcmp_equal(const _Tp* __lhs, const _Up* __rhs, __element_count __n) {
91 static_assert(__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
92 "_Tp and _Up have to be trivially equality comparable");
93
94 auto __count = static_cast<size_t>(__n);
95
96 if (__libcpp_is_constant_evaluated()) {
97#ifdef _LIBCPP_COMPILER_CLANG_BASED
98 if (sizeof(_Tp) == 1 && is_integral<_Tp>::value && !is_same<_Tp, bool>::value)
99 return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp)) == 0;
100#endif
101 while (__count != 0) {
102 if (*__lhs != *__rhs)
103 return false;
104
105 --__count;
106 ++__lhs;
107 ++__rhs;
108 }
109 return true;
110 } else {
111 return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp)) == 0;
112 }
113}
114
115template <class _Tp, class _Up>
116_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __constexpr_memchr(_Tp* __str, _Up __value, size_t __count) {
117 static_assert(sizeof(_Tp) == 1 && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
118 "Calling memchr on non-trivially equality comparable types is unsafe.");
119
120 if (__libcpp_is_constant_evaluated()) {
121// use __builtin_char_memchr to optimize constexpr evaluation if we can
122#if _LIBCPP_STD_VER >= 17 && __has_builtin(__builtin_char_memchr)
123 if constexpr (is_same_v<remove_cv_t<_Tp>, char> && is_same_v<remove_cv_t<_Up>, char>)
124 return __builtin_char_memchr(__str, __value, __count);
125#endif
126
127 for (; __count; --__count) {
128 if (*__str == __value)
129 return __str;
130 ++__str;
131 }
132 return nullptr;
133 } else {
134 char __value_buffer = 0;
135 __builtin_memcpy(&__value_buffer, &__value, sizeof(char));
136 return static_cast<_Tp*>(__builtin_memchr(__str, __value_buffer, __count));
137 }
138}
139
140// This function performs an assignment to an existing, already alive TriviallyCopyable object
141// from another TriviallyCopyable object.
142//
143// It basically works around the fact that TriviallyCopyable objects are not required to be
144// syntactically copy/move constructible or copy/move assignable. Technically, only one of the
145// four operations is required to be syntactically valid -- but at least one definitely has to
146// be valid.
147//
148// This is necessary in order to implement __constexpr_memmove below in a way that mirrors as
149// closely as possible what the compiler's __builtin_memmove is able to do.
150template <class _Tp, class _Up, __enable_if_t<is_assignable<_Tp&, _Up const&>::value, int> = 0>
151_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& __assign_trivially_copyable(_Tp& __dest, _Up const& __src) {
152 __dest = __src;
153 return __dest;
154}
155
156// clang-format off
157template <class _Tp, class _Up, __enable_if_t<!is_assignable<_Tp&, _Up const&>::value &&
158 is_assignable<_Tp&, _Up&&>::value, int> = 0>
159// clang-format on
160_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& __assign_trivially_copyable(_Tp& __dest, _Up& __src) {
161 __dest =
162 static_cast<_Up&&>(__src); // this is safe, we're not actually moving anything since the assignment is trivial
163 return __dest;
164}
165
166// clang-format off
167template <class _Tp, class _Up, __enable_if_t<!is_assignable<_Tp&, _Up const&>::value &&
168 !is_assignable<_Tp&, _Up&&>::value &&
169 is_constructible<_Tp, _Up const&>::value, int> = 0>
170// clang-format on
171_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& __assign_trivially_copyable(_Tp& __dest, _Up const& __src) {
172 // _Tp is trivially destructible, so we don't need to call its destructor to end the lifetime of the object
173 // that was there previously
174 std::__construct_at(std::addressof(__dest), __src);
175 return __dest;
176}
177
178// clang-format off
179template <class _Tp, class _Up, __enable_if_t<!is_assignable<_Tp&, _Up const&>::value &&
180 !is_assignable<_Tp&, _Up&&>::value &&
181 !is_constructible<_Tp, _Up const&>::value &&
182 is_constructible<_Tp, _Up&&>::value, int> = 0>
183// clang-format on
184_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& __assign_trivially_copyable(_Tp& __dest, _Up& __src) {
185 // _Tp is trivially destructible, so we don't need to call its destructor to end the lifetime of the object
186 // that was there previously
187 std::__construct_at(
188 std::addressof(__dest),
189 static_cast<_Up&&>(__src)); // this is safe, we're not actually moving anything since the constructor is trivial
190 return __dest;
191}
192
193template <class _Tp, class _Up, __enable_if_t<__is_always_bitcastable<_Up, _Tp>::value, int> = 0>
194_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
195__constexpr_memmove(_Tp* __dest, _Up* __src, __element_count __n) {
196 size_t __count = static_cast<size_t>(__n);
197 if (__libcpp_is_constant_evaluated()) {
198#ifdef _LIBCPP_COMPILER_CLANG_BASED
199 if (is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value) {
200 ::__builtin_memmove(__dest, __src, __count * sizeof(_Tp));
201 return __dest;
202 }
203#endif
204 if (std::__is_pointer_in_range(__src, __src + __count, __dest)) {
205 for (; __count > 0; --__count)
206 std::__assign_trivially_copyable(__dest[__count - 1], __src[__count - 1]);
207 } else {
208 for (size_t __i = 0; __i != __count; ++__i)
209 std::__assign_trivially_copyable(__dest[__i], __src[__i]);
210 }
211 } else if (__count > 0) {
212 ::__builtin_memmove(__dest, __src, (__count - 1) * sizeof(_Tp) + __libcpp_datasizeof<_Tp>::value);
213 }
214 return __dest;
215}
216
217_LIBCPP_END_NAMESPACE_STD
218
219#endif // _LIBCPP___STRING_CONSTEXPR_C_FUNCTIONS_H
lib/libcxx/include/__string/extern_template_lists.h+95-96
......@@ -28,104 +28,103 @@
2828// functions supporting new c++ version / API changes. Typically entries
2929// must never be removed from the stable list.
3030#define _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
31 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
32 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
33 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
34 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&)) \
35 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
36 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, allocator<_CharType> const&)) \
37 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
38 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
39 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
40 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
41 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
42 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
43 _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
44 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
45 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
46 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
47 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \
48 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
49 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
50 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
51 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
52 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
53 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
54 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
55 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
56 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
57 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
58 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
59 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
60 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
61 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
62 _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
63 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
64 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \
65 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
66 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
67 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
68 _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
69 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \
70 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
71 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
72 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
73 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \
74 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
75 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
76 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
77 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
78 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
31 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
32 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
33 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
34 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&)) \
35 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
36 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&, allocator<_CharType> const&)) \
37 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
38 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::~basic_string()) \
39 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
40 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
41 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
42 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type)) \
43 _Func(_LIBCPP_EXPORTED_FROM_ABI const _CharType& basic_string<_CharType>::at(size_type) const) \
44 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
45 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
46 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
47 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \
48 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::reserve(size_type)) \
49 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
50 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
51 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
52 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
53 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
54 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(size_type, value_type)) \
55 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
56 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
57 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
58 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
59 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::push_back(value_type)) \
60 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
61 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
62 _Func(_LIBCPP_EXPORTED_FROM_ABI const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
63 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
64 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \
65 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
66 _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(value_type const*) const) \
67 _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
68 _Func(_LIBCPP_EXPORTED_FROM_ABI _CharType& basic_string<_CharType>::at(size_type)) \
69 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \
70 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
71 _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
72 _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
73 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \
74 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
75 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
76 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
77 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::resize(size_type, value_type)) \
78 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
7979
8080#define _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
81 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
82 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
83 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
84 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
85 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
86 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
87 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
88 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
89 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
90 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
91 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \
92 _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
93 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
94 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
95 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
96 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*, size_type)) \
97 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*)) \
98 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
99 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
100 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
101 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
102 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
103 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
104 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
105 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
106 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
107 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
108 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
109 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \
110 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \
111 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
112 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
113 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
114 _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
115 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
116 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \
117 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
118 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
119 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
120 _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
121 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
122 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
123 _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
124 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
125 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
126 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
127 _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
128 _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
81 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
82 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
83 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
84 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
85 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
86 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::~basic_string()) \
87 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
88 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
89 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
90 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type)) \
91 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \
92 _Func(_LIBCPP_EXPORTED_FROM_ABI const _CharType& basic_string<_CharType>::at(size_type) const) \
93 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
94 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
95 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
96 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*, size_type)) \
97 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*)) \
98 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::reserve(size_type)) \
99 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
100 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
101 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
102 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
103 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
104 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(size_type, value_type)) \
105 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
106 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
107 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
108 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \
109 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \
110 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::push_back(value_type)) \
111 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
112 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
113 _Func(_LIBCPP_EXPORTED_FROM_ABI const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
114 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
115 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \
116 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
117 _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(value_type const*) const) \
118 _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
119 _Func(_LIBCPP_EXPORTED_FROM_ABI _CharType& basic_string<_CharType>::at(size_type)) \
120 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
121 _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
122 _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
123 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
124 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
125 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
126 _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::resize(size_type, value_type)) \
127 _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
129128
130129
131130#endif // _LIBCPP___STRING_EXTERN_TEMPLATE_LISTS_H
lib/libcxx/include/__support/musl/xlocale.h+2-1
......@@ -37,7 +37,8 @@ inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoll_l(const wchar_t* __nptr, wchar_
3737 return ::wcstoll(__nptr, __endptr, __base);
3838}
3939
40inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoull_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) {
40inline _LIBCPP_HIDE_FROM_ABI_C unsigned long long
41wcstoull_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) {
4142 return ::wcstoull(__nptr, __endptr, __base);
4243}
4344
lib/libcxx/include/__support/solaris/floatingpoint.h deleted-13
......@@ -1,13 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#define atof sun_atof
10#define strtod sun_strtod
11#include_next "floatingpoint.h"
12#undef atof
13#undef strtod
lib/libcxx/include/__support/solaris/wchar.h deleted-46
......@@ -1,46 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#define iswalpha sun_iswalpha
10#define iswupper sun_iswupper
11#define iswlower sun_iswlower
12#define iswdigit sun_iswdigit
13#define iswxdigit sun_iswxdigit
14#define iswalnum sun_iswalnum
15#define iswspace sun_iswspace
16#define iswpunct sun_iswpunct
17#define iswprint sun_iswprint
18#define iswgraph sun_iswgraph
19#define iswcntrl sun_iswcntrl
20#define iswctype sun_iswctype
21#define towlower sun_towlower
22#define towupper sun_towupper
23#define wcswcs sun_wcswcs
24#define wcswidth sun_wcswidth
25#define wcwidth sun_wcwidth
26#define wctype sun_wctype
27#define _WCHAR_T 1
28#include_next "wchar.h"
29#undef iswalpha
30#undef iswupper
31#undef iswlower
32#undef iswdigit
33#undef iswxdigit
34#undef iswalnum
35#undef iswspace
36#undef iswpunct
37#undef iswprint
38#undef iswgraph
39#undef iswcntrl
40#undef iswctype
41#undef towlower
42#undef towupper
43#undef wcswcs
44#undef wcswidth
45#undef wcwidth
46#undef wctype
lib/libcxx/include/__support/solaris/xlocale.h deleted-75
......@@ -1,75 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9////////////////////////////////////////////////////////////////////////////////
10// Minimal xlocale implementation for Solaris. This implements the subset of
11// the xlocale APIs that libc++ depends on.
12////////////////////////////////////////////////////////////////////////////////
13#ifndef __XLOCALE_H_INCLUDED
14#define __XLOCALE_H_INCLUDED
15
16#include <stdlib.h>
17
18#ifdef __cplusplus
19extern "C" {
20#endif
21
22
23int snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...);
24int asprintf_l(char **__s, locale_t __l, const char *__format, ...);
25
26int sscanf_l(const char *__s, locale_t __l, const char *__format, ...);
27
28int toupper_l(int __c, locale_t __l);
29int tolower_l(int __c, locale_t __l);
30
31struct lconv *localeconv(void);
32struct lconv *localeconv_l(locale_t __l);
33
34// FIXME: These are quick-and-dirty hacks to make things pretend to work
35inline _LIBCPP_HIDE_FROM_ABI long long
36strtoll_l(const char *__nptr, char **__endptr, int __base, locale_t __loc) {
37 return ::strtoll(__nptr, __endptr, __base);
38}
39
40inline _LIBCPP_HIDE_FROM_ABI long
41strtol_l(const char *__nptr, char **__endptr, int __base, locale_t __loc) {
42 return ::strtol(__nptr, __endptr, __base);
43}
44
45inline _LIBCPP_HIDE_FROM_ABI unsigned long long
46strtoull_l(const char *__nptr, char **__endptr, int __base, locale_t __loc)
47 return ::strtoull(__nptr, __endptr, __base);
48}
49
50inline _LIBCPP_HIDE_FROM_ABI unsigned long
51strtoul_l(const char *__nptr, char **__endptr, int __base, locale_t __loc) {
52 return ::strtoul(__nptr, __endptr, __base);
53}
54
55inline _LIBCPP_HIDE_FROM_ABI float
56strtof_l(const char *__nptr, char **__endptr, locale_t __loc) {
57 return ::strtof(__nptr, __endptr);
58}
59
60inline _LIBCPP_HIDE_FROM_ABI double
61strtod_l(const char *__nptr, char **__endptr, locale_t __loc) {
62 return ::strtod(__nptr, __endptr);
63}
64
65inline _LIBCPP_HIDE_FROM_ABI long double
66strtold_l(const char *__nptr, char **__endptr, locale_t __loc) {
67 return ::strtold(__nptr, __endptr);
68}
69
70
71#ifdef __cplusplus
72}
73#endif
74
75#endif
lib/libcxx/include/__support/win32/locale_win32.h+6-6
......@@ -221,8 +221,8 @@ decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l );
221221#define strtof_l _strtof_l
222222#define strtold_l _strtold_l
223223#else
224_LIBCPP_FUNC_VIS float strtof_l(const char*, char**, locale_t);
225_LIBCPP_FUNC_VIS long double strtold_l(const char*, char**, locale_t);
224_LIBCPP_EXPORTED_FROM_ABI float strtof_l(const char*, char**, locale_t);
225_LIBCPP_EXPORTED_FROM_ABI long double strtold_l(const char*, char**, locale_t);
226226#endif
227227inline _LIBCPP_HIDE_FROM_ABI int
228228islower_l(int __c, _locale_t __loc)
......@@ -256,7 +256,7 @@ isupper_l(int __c, _locale_t __loc)
256256#define towupper_l _towupper_l
257257#define towlower_l _towlower_l
258258#if defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x0800
259_LIBCPP_FUNC_VIS size_t strftime_l(char *ret, size_t n, const char *format,
259_LIBCPP_EXPORTED_FROM_ABI size_t strftime_l(char *ret, size_t n, const char *format,
260260 const struct tm *tm, locale_t loc);
261261#else
262262#define strftime_l _strftime_l
......@@ -265,9 +265,9 @@ _LIBCPP_FUNC_VIS size_t strftime_l(char *ret, size_t n, const char *format,
265265#define sprintf_l( __s, __l, __f, ... ) _sprintf_l( __s, __f, __l, __VA_ARGS__ )
266266#define vsprintf_l( __s, __l, __f, ... ) _vsprintf_l( __s, __f, __l, __VA_ARGS__ )
267267#define vsnprintf_l( __s, __n, __l, __f, ... ) _vsnprintf_l( __s, __n, __f, __l, __VA_ARGS__ )
268_LIBCPP_FUNC_VIS int snprintf_l(char *__ret, size_t __n, locale_t __loc, const char *__format, ...);
269_LIBCPP_FUNC_VIS int asprintf_l( char **__ret, locale_t __loc, const char *__format, ... );
270_LIBCPP_FUNC_VIS int vasprintf_l( char **__ret, locale_t __loc, const char *__format, va_list __ap );
268_LIBCPP_EXPORTED_FROM_ABI int snprintf_l(char *__ret, size_t __n, locale_t __loc, const char *__format, ...);
269_LIBCPP_EXPORTED_FROM_ABI int asprintf_l( char **__ret, locale_t __loc, const char *__format, ... );
270_LIBCPP_EXPORTED_FROM_ABI int vasprintf_l( char **__ret, locale_t __loc, const char *__format, va_list __ap );
271271
272272// not-so-pressing FIXME: use locale to determine blank characters
273273inline int isblank_l( int __c, locale_t /*loc*/ )
lib/libcxx/include/__system_error/errc.h created+217
......@@ -0,0 +1,217 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ERRC
11#define _LIBCPP___ERRC
12
13/*
14 system_error synopsis
15
16namespace std
17{
18
19enum class errc
20{
21 address_family_not_supported, // EAFNOSUPPORT
22 address_in_use, // EADDRINUSE
23 address_not_available, // EADDRNOTAVAIL
24 already_connected, // EISCONN
25 argument_list_too_long, // E2BIG
26 argument_out_of_domain, // EDOM
27 bad_address, // EFAULT
28 bad_file_descriptor, // EBADF
29 bad_message, // EBADMSG
30 broken_pipe, // EPIPE
31 connection_aborted, // ECONNABORTED
32 connection_already_in_progress, // EALREADY
33 connection_refused, // ECONNREFUSED
34 connection_reset, // ECONNRESET
35 cross_device_link, // EXDEV
36 destination_address_required, // EDESTADDRREQ
37 device_or_resource_busy, // EBUSY
38 directory_not_empty, // ENOTEMPTY
39 executable_format_error, // ENOEXEC
40 file_exists, // EEXIST
41 file_too_large, // EFBIG
42 filename_too_long, // ENAMETOOLONG
43 function_not_supported, // ENOSYS
44 host_unreachable, // EHOSTUNREACH
45 identifier_removed, // EIDRM
46 illegal_byte_sequence, // EILSEQ
47 inappropriate_io_control_operation, // ENOTTY
48 interrupted, // EINTR
49 invalid_argument, // EINVAL
50 invalid_seek, // ESPIPE
51 io_error, // EIO
52 is_a_directory, // EISDIR
53 message_size, // EMSGSIZE
54 network_down, // ENETDOWN
55 network_reset, // ENETRESET
56 network_unreachable, // ENETUNREACH
57 no_buffer_space, // ENOBUFS
58 no_child_process, // ECHILD
59 no_link, // ENOLINK
60 no_lock_available, // ENOLCK
61 no_message_available, // ENODATA
62 no_message, // ENOMSG
63 no_protocol_option, // ENOPROTOOPT
64 no_space_on_device, // ENOSPC
65 no_stream_resources, // ENOSR
66 no_such_device_or_address, // ENXIO
67 no_such_device, // ENODEV
68 no_such_file_or_directory, // ENOENT
69 no_such_process, // ESRCH
70 not_a_directory, // ENOTDIR
71 not_a_socket, // ENOTSOCK
72 not_a_stream, // ENOSTR
73 not_connected, // ENOTCONN
74 not_enough_memory, // ENOMEM
75 not_supported, // ENOTSUP
76 operation_canceled, // ECANCELED
77 operation_in_progress, // EINPROGRESS
78 operation_not_permitted, // EPERM
79 operation_not_supported, // EOPNOTSUPP
80 operation_would_block, // EWOULDBLOCK
81 owner_dead, // EOWNERDEAD
82 permission_denied, // EACCES
83 protocol_error, // EPROTO
84 protocol_not_supported, // EPROTONOSUPPORT
85 read_only_file_system, // EROFS
86 resource_deadlock_would_occur, // EDEADLK
87 resource_unavailable_try_again, // EAGAIN
88 result_out_of_range, // ERANGE
89 state_not_recoverable, // ENOTRECOVERABLE
90 stream_timeout, // ETIME
91 text_file_busy, // ETXTBSY
92 timed_out, // ETIMEDOUT
93 too_many_files_open_in_system, // ENFILE
94 too_many_files_open, // EMFILE
95 too_many_links, // EMLINK
96 too_many_symbolic_link_levels, // ELOOP
97 value_too_large, // EOVERFLOW
98 wrong_protocol_type // EPROTOTYPE
99};
100
101*/
102
103#include <__config>
104#include <cerrno>
105
106#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
107# pragma GCC system_header
108#endif
109
110_LIBCPP_BEGIN_NAMESPACE_STD
111
112// Some error codes are not present on all platforms, so we provide equivalents
113// for them:
114
115//enum class errc
116_LIBCPP_DECLARE_STRONG_ENUM(errc)
117{
118 address_family_not_supported = EAFNOSUPPORT,
119 address_in_use = EADDRINUSE,
120 address_not_available = EADDRNOTAVAIL,
121 already_connected = EISCONN,
122 argument_list_too_long = E2BIG,
123 argument_out_of_domain = EDOM,
124 bad_address = EFAULT,
125 bad_file_descriptor = EBADF,
126 bad_message = EBADMSG,
127 broken_pipe = EPIPE,
128 connection_aborted = ECONNABORTED,
129 connection_already_in_progress = EALREADY,
130 connection_refused = ECONNREFUSED,
131 connection_reset = ECONNRESET,
132 cross_device_link = EXDEV,
133 destination_address_required = EDESTADDRREQ,
134 device_or_resource_busy = EBUSY,
135 directory_not_empty = ENOTEMPTY,
136 executable_format_error = ENOEXEC,
137 file_exists = EEXIST,
138 file_too_large = EFBIG,
139 filename_too_long = ENAMETOOLONG,
140 function_not_supported = ENOSYS,
141 host_unreachable = EHOSTUNREACH,
142 identifier_removed = EIDRM,
143 illegal_byte_sequence = EILSEQ,
144 inappropriate_io_control_operation = ENOTTY,
145 interrupted = EINTR,
146 invalid_argument = EINVAL,
147 invalid_seek = ESPIPE,
148 io_error = EIO,
149 is_a_directory = EISDIR,
150 message_size = EMSGSIZE,
151 network_down = ENETDOWN,
152 network_reset = ENETRESET,
153 network_unreachable = ENETUNREACH,
154 no_buffer_space = ENOBUFS,
155 no_child_process = ECHILD,
156 no_link = ENOLINK,
157 no_lock_available = ENOLCK,
158#ifdef ENODATA
159 no_message_available = ENODATA,
160#else
161 no_message_available = ENOMSG,
162#endif
163 no_message = ENOMSG,
164 no_protocol_option = ENOPROTOOPT,
165 no_space_on_device = ENOSPC,
166#ifdef ENOSR
167 no_stream_resources = ENOSR,
168#else
169 no_stream_resources = ENOMEM,
170#endif
171 no_such_device_or_address = ENXIO,
172 no_such_device = ENODEV,
173 no_such_file_or_directory = ENOENT,
174 no_such_process = ESRCH,
175 not_a_directory = ENOTDIR,
176 not_a_socket = ENOTSOCK,
177#ifdef ENOSTR
178 not_a_stream = ENOSTR,
179#else
180 not_a_stream = EINVAL,
181#endif
182 not_connected = ENOTCONN,
183 not_enough_memory = ENOMEM,
184 not_supported = ENOTSUP,
185 operation_canceled = ECANCELED,
186 operation_in_progress = EINPROGRESS,
187 operation_not_permitted = EPERM,
188 operation_not_supported = EOPNOTSUPP,
189 operation_would_block = EWOULDBLOCK,
190 owner_dead = EOWNERDEAD,
191 permission_denied = EACCES,
192 protocol_error = EPROTO,
193 protocol_not_supported = EPROTONOSUPPORT,
194 read_only_file_system = EROFS,
195 resource_deadlock_would_occur = EDEADLK,
196 resource_unavailable_try_again = EAGAIN,
197 result_out_of_range = ERANGE,
198 state_not_recoverable = ENOTRECOVERABLE,
199#ifdef ETIME
200 stream_timeout = ETIME,
201#else
202 stream_timeout = ETIMEDOUT,
203#endif
204 text_file_busy = ETXTBSY,
205 timed_out = ETIMEDOUT,
206 too_many_files_open_in_system = ENFILE,
207 too_many_files_open = EMFILE,
208 too_many_links = EMLINK,
209 too_many_symbolic_link_levels = ELOOP,
210 value_too_large = EOVERFLOW,
211 wrong_protocol_type = EPROTOTYPE
212};
213_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc)
214
215_LIBCPP_END_NAMESPACE_STD
216
217#endif // _LIBCPP___ERRC
lib/libcxx/include/__system_error/error_category.h created+75
......@@ -0,0 +1,75 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___SYSTEM_ERROR_ERROR_CATEGORY_H
11#define _LIBCPP___SYSTEM_ERROR_ERROR_CATEGORY_H
12
13#include <__compare/ordering.h>
14#include <__config>
15#include <string>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18# pragma GCC system_header
19#endif
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23class _LIBCPP_EXPORTED_FROM_ABI error_condition;
24class _LIBCPP_EXPORTED_FROM_ABI error_code;
25
26class _LIBCPP_HIDDEN __do_message;
27
28class _LIBCPP_EXPORTED_FROM_ABI error_category {
29public:
30 virtual ~error_category() _NOEXCEPT;
31
32#if defined(_LIBCPP_ERROR_CATEGORY_DEFINE_LEGACY_INLINE_FUNCTIONS)
33 error_category() noexcept;
34#else
35 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 error_category() _NOEXCEPT = default;
36#endif
37 error_category(const error_category&) = delete;
38 error_category& operator=(const error_category&) = delete;
39
40 virtual const char* name() const _NOEXCEPT = 0;
41 virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;
42 virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;
43 virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;
44 virtual string message(int __ev) const = 0;
45
46 _LIBCPP_HIDE_FROM_ABI bool operator==(const error_category& __rhs) const _NOEXCEPT { return this == &__rhs; }
47
48#if _LIBCPP_STD_VER >= 20
49
50 _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const error_category& __rhs) const noexcept {
51 return compare_three_way()(this, std::addressof(__rhs));
52 }
53
54#else // _LIBCPP_STD_VER >= 20
55
56 _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_category& __rhs) const _NOEXCEPT { return !(*this == __rhs); }
57
58 _LIBCPP_HIDE_FROM_ABI bool operator<(const error_category& __rhs) const _NOEXCEPT { return this < &__rhs; }
59
60#endif // _LIBCPP_STD_VER >= 20
61
62 friend class _LIBCPP_HIDDEN __do_message;
63};
64
65class _LIBCPP_HIDDEN __do_message : public error_category {
66public:
67 string message(int __ev) const override;
68};
69
70_LIBCPP_EXPORTED_FROM_ABI const error_category& generic_category() _NOEXCEPT;
71_LIBCPP_EXPORTED_FROM_ABI const error_category& system_category() _NOEXCEPT;
72
73_LIBCPP_END_NAMESPACE_STD
74
75#endif // _LIBCPP___SYSTEM_ERROR_ERROR_CATEGORY_H
lib/libcxx/include/__system_error/error_code.h created+145
......@@ -0,0 +1,145 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___SYSTEM_ERROR_ERROR_CODE_H
11#define _LIBCPP___SYSTEM_ERROR_ERROR_CODE_H
12
13#include <__compare/ordering.h>
14#include <__config>
15#include <__functional/hash.h>
16#include <__functional/unary_function.h>
17#include <__system_error/errc.h>
18#include <__system_error/error_category.h>
19#include <__system_error/error_condition.h>
20#include <cstddef>
21#include <string>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24# pragma GCC system_header
25#endif
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29template <class _Tp>
30struct _LIBCPP_TEMPLATE_VIS is_error_code_enum : public false_type {};
31
32#if _LIBCPP_STD_VER >= 17
33template <class _Tp>
34inline constexpr bool is_error_code_enum_v = is_error_code_enum<_Tp>::value;
35#endif
36
37namespace __adl_only {
38// Those cause ADL to trigger but they are not viable candidates,
39// so they are never actually selected.
40void make_error_code() = delete;
41} // namespace __adl_only
42
43class _LIBCPP_EXPORTED_FROM_ABI error_code {
44 int __val_;
45 const error_category* __cat_;
46
47public:
48 _LIBCPP_HIDE_FROM_ABI error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {}
49
50 _LIBCPP_HIDE_FROM_ABI error_code(int __val, const error_category& __cat) _NOEXCEPT : __val_(__val), __cat_(&__cat) {}
51
52 template <class _Ep>
53 _LIBCPP_HIDE_FROM_ABI
54 error_code(_Ep __e, typename enable_if<is_error_code_enum<_Ep>::value>::type* = nullptr) _NOEXCEPT {
55 using __adl_only::make_error_code;
56 *this = make_error_code(__e);
57 }
58
59 _LIBCPP_HIDE_FROM_ABI void assign(int __val, const error_category& __cat) _NOEXCEPT {
60 __val_ = __val;
61 __cat_ = &__cat;
62 }
63
64 template <class _Ep>
65 _LIBCPP_HIDE_FROM_ABI typename enable_if< is_error_code_enum<_Ep>::value, error_code& >::type
66 operator=(_Ep __e) _NOEXCEPT {
67 using __adl_only::make_error_code;
68 *this = make_error_code(__e);
69 return *this;
70 }
71
72 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT {
73 __val_ = 0;
74 __cat_ = &system_category();
75 }
76
77 _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
78
79 _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
80
81 _LIBCPP_HIDE_FROM_ABI error_condition default_error_condition() const _NOEXCEPT {
82 return __cat_->default_error_condition(__val_);
83 }
84
85 string message() const;
86
87 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; }
88};
89
90inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(errc __e) _NOEXCEPT {
91 return error_code(static_cast<int>(__e), generic_category());
92}
93
94inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_code& __x, const error_code& __y) _NOEXCEPT {
95 return __x.category() == __y.category() && __x.value() == __y.value();
96}
97
98inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT {
99 return __x.category().equivalent(__x.value(), __y) || __y.category().equivalent(__x, __y.value());
100}
101
102#if _LIBCPP_STD_VER <= 17
103inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT {
104 return __y == __x;
105}
106#endif
107
108#if _LIBCPP_STD_VER <= 17
109
110inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT {
111 return !(__x == __y);
112}
113
114inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT {
115 return !(__x == __y);
116}
117
118inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT {
119 return !(__x == __y);
120}
121
122inline _LIBCPP_HIDE_FROM_ABI bool operator<(const error_code& __x, const error_code& __y) _NOEXCEPT {
123 return __x.category() < __y.category() || (__x.category() == __y.category() && __x.value() < __y.value());
124}
125
126#else // _LIBCPP_STD_VER <= 17
127
128inline _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const error_code& __x, const error_code& __y) noexcept {
129 if (auto __c = __x.category() <=> __y.category(); __c != 0)
130 return __c;
131 return __x.value() <=> __y.value();
132}
133
134#endif // _LIBCPP_STD_VER <= 17
135
136template <>
137struct _LIBCPP_TEMPLATE_VIS hash<error_code> : public __unary_function<error_code, size_t> {
138 _LIBCPP_HIDE_FROM_ABI size_t operator()(const error_code& __ec) const _NOEXCEPT {
139 return static_cast<size_t>(__ec.value());
140 }
141};
142
143_LIBCPP_END_NAMESPACE_STD
144
145#endif // _LIBCPP___SYSTEM_ERROR_ERROR_CODE_H
lib/libcxx/include/__system_error/error_condition.h created+132
......@@ -0,0 +1,132 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___SYSTEM_ERROR_ERROR_CONDITION_H
11#define _LIBCPP___SYSTEM_ERROR_ERROR_CONDITION_H
12
13#include <__compare/ordering.h>
14#include <__config>
15#include <__functional/hash.h>
16#include <__functional/unary_function.h>
17#include <__system_error/errc.h>
18#include <__system_error/error_category.h>
19#include <cstddef>
20#include <string>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23# pragma GCC system_header
24#endif
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _Tp>
29struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum : public false_type {};
30
31#if _LIBCPP_STD_VER >= 17
32template <class _Tp>
33inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<_Tp>::value;
34#endif
35
36template <>
37struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc> : true_type {};
38
39#ifdef _LIBCPP_CXX03_LANG
40template <>
41struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx> : true_type {};
42#endif
43
44namespace __adl_only {
45// Those cause ADL to trigger but they are not viable candidates,
46// so they are never actually selected.
47void make_error_condition() = delete;
48} // namespace __adl_only
49
50class _LIBCPP_EXPORTED_FROM_ABI error_condition {
51 int __val_;
52 const error_category* __cat_;
53
54public:
55 _LIBCPP_HIDE_FROM_ABI error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {}
56
57 _LIBCPP_HIDE_FROM_ABI error_condition(int __val, const error_category& __cat) _NOEXCEPT
58 : __val_(__val),
59 __cat_(&__cat) {}
60
61 template <class _Ep>
62 _LIBCPP_HIDE_FROM_ABI
63 error_condition(_Ep __e, typename enable_if<is_error_condition_enum<_Ep>::value>::type* = nullptr) _NOEXCEPT {
64 using __adl_only::make_error_condition;
65 *this = make_error_condition(__e);
66 }
67
68 _LIBCPP_HIDE_FROM_ABI void assign(int __val, const error_category& __cat) _NOEXCEPT {
69 __val_ = __val;
70 __cat_ = &__cat;
71 }
72
73 template <class _Ep>
74 _LIBCPP_HIDE_FROM_ABI typename enable_if< is_error_condition_enum<_Ep>::value, error_condition& >::type
75 operator=(_Ep __e) _NOEXCEPT {
76 using __adl_only::make_error_condition;
77 *this = make_error_condition(__e);
78 return *this;
79 }
80
81 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT {
82 __val_ = 0;
83 __cat_ = &generic_category();
84 }
85
86 _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
87
88 _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
89 string message() const;
90
91 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; }
92};
93
94inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(errc __e) _NOEXCEPT {
95 return error_condition(static_cast<int>(__e), generic_category());
96}
97
98inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT {
99 return __x.category() == __y.category() && __x.value() == __y.value();
100}
101
102#if _LIBCPP_STD_VER <= 17
103
104inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT {
105 return !(__x == __y);
106}
107
108inline _LIBCPP_HIDE_FROM_ABI bool operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT {
109 return __x.category() < __y.category() || (__x.category() == __y.category() && __x.value() < __y.value());
110}
111
112#else // _LIBCPP_STD_VER <= 17
113
114inline _LIBCPP_HIDE_FROM_ABI strong_ordering
115operator<=>(const error_condition& __x, const error_condition& __y) noexcept {
116 if (auto __c = __x.category() <=> __y.category(); __c != 0)
117 return __c;
118 return __x.value() <=> __y.value();
119}
120
121#endif // _LIBCPP_STD_VER <= 17
122
123template <>
124struct _LIBCPP_TEMPLATE_VIS hash<error_condition> : public __unary_function<error_condition, size_t> {
125 _LIBCPP_HIDE_FROM_ABI size_t operator()(const error_condition& __ec) const _NOEXCEPT {
126 return static_cast<size_t>(__ec.value());
127 }
128};
129
130_LIBCPP_END_NAMESPACE_STD
131
132#endif // _LIBCPP___SYSTEM_ERROR_ERROR_CONDITION_H
lib/libcxx/include/__system_error/system_error.h created+48
......@@ -0,0 +1,48 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___SYSTEM_ERROR_SYSTEM_ERROR_H
11#define _LIBCPP___SYSTEM_ERROR_SYSTEM_ERROR_H
12
13#include <__config>
14#include <__system_error/error_category.h>
15#include <__system_error/error_code.h>
16#include <stdexcept>
17#include <string>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25class _LIBCPP_EXPORTED_FROM_ABI system_error : public runtime_error {
26 error_code __ec_;
27
28public:
29 system_error(error_code __ec, const string& __what_arg);
30 system_error(error_code __ec, const char* __what_arg);
31 system_error(error_code __ec);
32 system_error(int __ev, const error_category& __ecat, const string& __what_arg);
33 system_error(int __ev, const error_category& __ecat, const char* __what_arg);
34 system_error(int __ev, const error_category& __ecat);
35 _LIBCPP_HIDE_FROM_ABI system_error(const system_error&) _NOEXCEPT = default;
36 ~system_error() _NOEXCEPT override;
37
38 _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
39
40private:
41 static string __init(const error_code&, string);
42};
43
44_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_system_error(int __ev, const char* __what_arg);
45
46_LIBCPP_END_NAMESPACE_STD
47
48#endif // _LIBCPP___SYSTEM_ERROR_SYSTEM_ERROR_H
lib/libcxx/include/__thread/formatter.h created+80
......@@ -0,0 +1,80 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___THREAD_FORMATTER_H
11#define _LIBCPP___THREAD_FORMATTER_H
12
13#include <__concepts/arithmetic.h>
14#include <__config>
15#include <__format/concepts.h>
16#include <__format/format_parse_context.h>
17#include <__format/formatter.h>
18#include <__format/formatter_integral.h>
19#include <__format/parser_std_format_spec.h>
20#include <__thread/id.h>
21#include <__type_traits/conditional.h>
22#include <__type_traits/is_pointer.h>
23#include <__type_traits/is_same.h>
24#include <cstdint>
25
26#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27# pragma GCC system_header
28#endif
29
30#if _LIBCPP_STD_VER >= 23
31
32_LIBCPP_BEGIN_NAMESPACE_STD
33
34#ifndef _LIBCPP_HAS_NO_THREADS
35
36template <__fmt_char_type _CharT>
37struct _LIBCPP_TEMPLATE_VIS formatter<__thread_id, _CharT> {
38 public:
39 template <class _ParseContext>
40 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
41 return __parser_.__parse(__ctx, __format_spec::__fields_fill_align_width);
42 }
43
44 template <class _FormatContext>
45 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(__thread_id __id, _FormatContext& __ctx) const {
46 // In __threading_support __libcpp_thread_id is either a
47 // unsigned long long or a pthread_t.
48 //
49 // The type of pthread_t is left unspecified in POSIX so it can be any
50 // type. The most logical types are an integral or pointer.
51 // On Linux systems pthread_t is an unsigned long long.
52 // On Apple systems pthread_t is a pointer type.
53 //
54 // Note the output should match what the stream operator does. Since
55 // the ostream operator has been shipped years before this formatter
56 // was added to the Standard, this formatter does what the stream
57 // operator does. This may require platform specific changes.
58
59 using _Tp = decltype(__get_underlying_id(__id));
60 using _Cp = conditional_t<integral<_Tp>, _Tp, conditional_t<is_pointer_v<_Tp>, uintptr_t, void>>;
61 static_assert(!is_same_v<_Cp, void>, "unsupported thread::id type, please file a bug report");
62
63 __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
64 if constexpr (is_pointer_v<_Tp>) {
65 __specs.__std_.__alternate_form_ = true;
66 __specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case;
67 }
68 return __formatter::__format_integer(reinterpret_cast<_Cp>(__get_underlying_id(__id)), __ctx, __specs);
69 }
70
71 __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__right};
72};
73
74#endif // !_LIBCPP_HAS_NO_THREADS
75
76_LIBCPP_END_NAMESPACE_STD
77
78#endif // _LIBCPP_STD_VER >= 23
79
80#endif // _LIBCPP___THREAD_FORMATTER_H
lib/libcxx/include/__thread/id.h created+121
......@@ -0,0 +1,121 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___THREAD_ID_H
11#define _LIBCPP___THREAD_ID_H
12
13#include <__compare/ordering.h>
14#include <__config>
15#include <__fwd/hash.h>
16#include <__threading_support>
17#include <iosfwd>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#ifndef _LIBCPP_HAS_NO_THREADS
26class _LIBCPP_EXPORTED_FROM_ABI __thread_id;
27
28namespace this_thread {
29
30_LIBCPP_HIDE_FROM_ABI __thread_id get_id() _NOEXCEPT;
31
32} // namespace this_thread
33
34template <>
35struct hash<__thread_id>;
36
37class _LIBCPP_TEMPLATE_VIS __thread_id {
38 // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
39 // NULL is the no-thread value on Darwin. Someone needs to check
40 // on other platforms. We assume 0 works everywhere for now.
41 __libcpp_thread_id __id_;
42
43 static _LIBCPP_HIDE_FROM_ABI bool
44 __lt_impl(__thread_id __x, __thread_id __y) _NOEXCEPT { // id==0 is always less than any other thread_id
45 if (__x.__id_ == 0)
46 return __y.__id_ != 0;
47 if (__y.__id_ == 0)
48 return false;
49 return __libcpp_thread_id_less(__x.__id_, __y.__id_);
50 }
51
52public:
53 _LIBCPP_HIDE_FROM_ABI __thread_id() _NOEXCEPT : __id_(0) {}
54
55 _LIBCPP_HIDE_FROM_ABI void __reset() { __id_ = 0; }
56
57 friend _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT;
58# if _LIBCPP_STD_VER <= 17
59 friend _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT;
60# else // _LIBCPP_STD_VER <= 17
61 friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept;
62# endif // _LIBCPP_STD_VER <= 17
63
64 template <class _CharT, class _Traits>
65 friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
66 operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
67
68private:
69 _LIBCPP_HIDE_FROM_ABI __thread_id(__libcpp_thread_id __id) : __id_(__id) {}
70
71 _LIBCPP_HIDE_FROM_ABI friend __libcpp_thread_id __get_underlying_id(const __thread_id __id) { return __id.__id_; }
72
73 friend __thread_id this_thread::get_id() _NOEXCEPT;
74 friend class _LIBCPP_EXPORTED_FROM_ABI thread;
75 friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
76};
77
78inline _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT {
79 // Don't pass id==0 to underlying routines
80 if (__x.__id_ == 0)
81 return __y.__id_ == 0;
82 if (__y.__id_ == 0)
83 return false;
84 return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
85}
86
87# if _LIBCPP_STD_VER <= 17
88
89inline _LIBCPP_HIDE_FROM_ABI bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x == __y); }
90
91inline _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT {
92 return __thread_id::__lt_impl(__x.__id_, __y.__id_);
93}
94
95inline _LIBCPP_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); }
96inline _LIBCPP_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; }
97inline _LIBCPP_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); }
98
99# else // _LIBCPP_STD_VER <= 17
100
101inline _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept {
102 if (__x == __y)
103 return strong_ordering::equal;
104 if (__thread_id::__lt_impl(__x, __y))
105 return strong_ordering::less;
106 return strong_ordering::greater;
107}
108
109# endif // _LIBCPP_STD_VER <= 17
110
111namespace this_thread {
112
113inline _LIBCPP_HIDE_FROM_ABI __thread_id get_id() _NOEXCEPT { return __libcpp_thread_get_current_id(); }
114
115} // namespace this_thread
116
117#endif // !_LIBCPP_HAS_NO_THREADS
118
119_LIBCPP_END_NAMESPACE_STD
120
121#endif // _LIBCPP___THREAD_ID_H
lib/libcxx/include/__thread/this_thread.h created+87
......@@ -0,0 +1,87 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___THREAD_THIS_THREAD_H
11#define _LIBCPP___THREAD_THIS_THREAD_H
12
13#include <__chrono/steady_clock.h>
14#include <__chrono/time_point.h>
15#include <__condition_variable/condition_variable.h>
16#include <__config>
17#include <__mutex/mutex.h>
18#include <__mutex/unique_lock.h>
19#include <__threading_support>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22# pragma GCC system_header
23#endif
24
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30namespace this_thread
31{
32
33_LIBCPP_EXPORTED_FROM_ABI void sleep_for(const chrono::nanoseconds& __ns);
34
35template <class _Rep, class _Period>
36_LIBCPP_HIDE_FROM_ABI void
37sleep_for(const chrono::duration<_Rep, _Period>& __d)
38{
39 if (__d > chrono::duration<_Rep, _Period>::zero())
40 {
41 // The standard guarantees a 64bit signed integer resolution for nanoseconds,
42 // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits>
43 // and issues with long double folding on PowerPC with GCC.
44 _LIBCPP_CONSTEXPR chrono::duration<long double> __max =
45 chrono::duration<long double>(9223372036.0L);
46 chrono::nanoseconds __ns;
47 if (__d < __max)
48 {
49 __ns = chrono::duration_cast<chrono::nanoseconds>(__d);
50 if (__ns < __d)
51 ++__ns;
52 }
53 else
54 __ns = chrono::nanoseconds::max();
55 this_thread::sleep_for(__ns);
56 }
57}
58
59template <class _Clock, class _Duration>
60_LIBCPP_HIDE_FROM_ABI void
61sleep_until(const chrono::time_point<_Clock, _Duration>& __t)
62{
63 mutex __mut;
64 condition_variable __cv;
65 unique_lock<mutex> __lk(__mut);
66 while (_Clock::now() < __t)
67 __cv.wait_until(__lk, __t);
68}
69
70template <class _Duration>
71inline _LIBCPP_INLINE_VISIBILITY
72void
73sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)
74{
75 this_thread::sleep_for(__t - chrono::steady_clock::now());
76}
77
78inline _LIBCPP_INLINE_VISIBILITY
79void yield() _NOEXCEPT {__libcpp_thread_yield();}
80
81} // namespace this_thread
82
83_LIBCPP_END_NAMESPACE_STD
84
85_LIBCPP_POP_MACROS
86
87#endif // _LIBCPP___THREAD_THIS_THREAD_H
lib/libcxx/include/__thread/thread.h created+297
......@@ -0,0 +1,297 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___THREAD_THREAD_H
11#define _LIBCPP___THREAD_THREAD_H
12
13#include <__condition_variable/condition_variable.h>
14#include <__config>
15#include <__exception/terminate.h>
16#include <__functional/hash.h>
17#include <__functional/unary_function.h>
18#include <__memory/unique_ptr.h>
19#include <__mutex/mutex.h>
20#include <__system_error/system_error.h>
21#include <__thread/id.h>
22#include <__threading_support>
23#include <__utility/forward.h>
24#include <iosfwd>
25#include <tuple>
26
27#ifndef _LIBCPP_HAS_NO_LOCALIZATION
28# include <locale>
29# include <sstream>
30#endif
31
32#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
33# pragma GCC system_header
34#endif
35
36_LIBCPP_BEGIN_NAMESPACE_STD
37
38template <class _Tp> class __thread_specific_ptr;
39class _LIBCPP_EXPORTED_FROM_ABI __thread_struct;
40class _LIBCPP_HIDDEN __thread_struct_imp;
41class __assoc_sub_state;
42
43_LIBCPP_EXPORTED_FROM_ABI __thread_specific_ptr<__thread_struct>& __thread_local_data();
44
45class _LIBCPP_EXPORTED_FROM_ABI __thread_struct
46{
47 __thread_struct_imp* __p_;
48
49 __thread_struct(const __thread_struct&);
50 __thread_struct& operator=(const __thread_struct&);
51public:
52 __thread_struct();
53 ~__thread_struct();
54
55 void notify_all_at_thread_exit(condition_variable*, mutex*);
56 void __make_ready_at_thread_exit(__assoc_sub_state*);
57};
58
59template <class _Tp>
60class __thread_specific_ptr
61{
62 __libcpp_tls_key __key_;
63
64 // Only __thread_local_data() may construct a __thread_specific_ptr
65 // and only with _Tp == __thread_struct.
66 static_assert((is_same<_Tp, __thread_struct>::value), "");
67 __thread_specific_ptr();
68 friend _LIBCPP_EXPORTED_FROM_ABI __thread_specific_ptr<__thread_struct>& __thread_local_data();
69
70 __thread_specific_ptr(const __thread_specific_ptr&);
71 __thread_specific_ptr& operator=(const __thread_specific_ptr&);
72
73 _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
74
75public:
76 typedef _Tp* pointer;
77
78 ~__thread_specific_ptr();
79
80 _LIBCPP_INLINE_VISIBILITY
81 pointer get() const {return static_cast<_Tp*>(__libcpp_tls_get(__key_));}
82 _LIBCPP_INLINE_VISIBILITY
83 pointer operator*() const {return *get();}
84 _LIBCPP_INLINE_VISIBILITY
85 pointer operator->() const {return get();}
86 void set_pointer(pointer __p);
87};
88
89template <class _Tp>
90void _LIBCPP_TLS_DESTRUCTOR_CC
91__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
92{
93 delete static_cast<pointer>(__p);
94}
95
96template <class _Tp>
97__thread_specific_ptr<_Tp>::__thread_specific_ptr()
98{
99 int __ec =
100 __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
101 if (__ec)
102 __throw_system_error(__ec, "__thread_specific_ptr construction failed");
103}
104
105template <class _Tp>
106__thread_specific_ptr<_Tp>::~__thread_specific_ptr()
107{
108 // __thread_specific_ptr is only created with a static storage duration
109 // so this destructor is only invoked during program termination. Invoking
110 // pthread_key_delete(__key_) may prevent other threads from deleting their
111 // thread local data. For this reason we leak the key.
112}
113
114template <class _Tp>
115void
116__thread_specific_ptr<_Tp>::set_pointer(pointer __p)
117{
118 _LIBCPP_ASSERT_UNCATEGORIZED(get() == nullptr,
119 "Attempting to overwrite thread local data");
120 std::__libcpp_tls_set(__key_, __p);
121}
122
123template<>
124struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>
125 : public __unary_function<__thread_id, size_t>
126{
127 _LIBCPP_INLINE_VISIBILITY
128 size_t operator()(__thread_id __v) const _NOEXCEPT
129 {
130 return hash<__libcpp_thread_id>()(__v.__id_);
131 }
132};
133
134#ifndef _LIBCPP_HAS_NO_LOCALIZATION
135template <class _CharT, class _Traits>
136_LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>&
137operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) {
138 // [thread.thread.id]/9
139 // Effects: Inserts the text representation for charT of id into out.
140 //
141 // [thread.thread.id]/2
142 // The text representation for the character type charT of an
143 // object of type thread::id is an unspecified sequence of charT
144 // such that, for two objects of type thread::id x and y, if
145 // x == y is true, the thread::id objects have the same text
146 // representation, and if x != y is true, the thread::id objects
147 // have distinct text representations.
148 //
149 // Since various flags in the output stream can affect how the
150 // thread id is represented (e.g. numpunct or showbase), we
151 // use a temporary stream instead and just output the thread
152 // id representation as a string.
153
154 basic_ostringstream<_CharT, _Traits> __sstr;
155 __sstr.imbue(locale::classic());
156 __sstr << __id.__id_;
157 return __os << __sstr.str();
158}
159#endif // _LIBCPP_HAS_NO_LOCALIZATION
160
161class _LIBCPP_EXPORTED_FROM_ABI thread
162{
163 __libcpp_thread_t __t_;
164
165 thread(const thread&);
166 thread& operator=(const thread&);
167public:
168 typedef __thread_id id;
169 typedef __libcpp_thread_t native_handle_type;
170
171 _LIBCPP_INLINE_VISIBILITY
172 thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
173#ifndef _LIBCPP_CXX03_LANG
174 template <class _Fp, class ..._Args,
175 class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value> >
176 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
177 explicit thread(_Fp&& __f, _Args&&... __args);
178#else // _LIBCPP_CXX03_LANG
179 template <class _Fp>
180 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
181 explicit thread(_Fp __f);
182#endif
183 ~thread();
184
185 _LIBCPP_INLINE_VISIBILITY
186 thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {
187 __t.__t_ = _LIBCPP_NULL_THREAD;
188 }
189
190 _LIBCPP_INLINE_VISIBILITY
191 thread& operator=(thread&& __t) _NOEXCEPT {
192 if (!__libcpp_thread_isnull(&__t_))
193 terminate();
194 __t_ = __t.__t_;
195 __t.__t_ = _LIBCPP_NULL_THREAD;
196 return *this;
197 }
198
199 _LIBCPP_INLINE_VISIBILITY
200 void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);}
201
202 _LIBCPP_INLINE_VISIBILITY
203 bool joinable() const _NOEXCEPT {return !__libcpp_thread_isnull(&__t_);}
204 void join();
205 void detach();
206 _LIBCPP_INLINE_VISIBILITY
207 id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);}
208 _LIBCPP_INLINE_VISIBILITY
209 native_handle_type native_handle() _NOEXCEPT {return __t_;}
210
211 static unsigned hardware_concurrency() _NOEXCEPT;
212};
213
214#ifndef _LIBCPP_CXX03_LANG
215
216template <class _TSp, class _Fp, class ..._Args, size_t ..._Indices>
217inline _LIBCPP_INLINE_VISIBILITY
218void
219__thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>)
220{
221 _VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
222}
223
224template <class _Fp>
225_LIBCPP_INLINE_VISIBILITY
226void* __thread_proxy(void* __vp)
227{
228 // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...>
229 unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
230 __thread_local_data().set_pointer(_VSTD::get<0>(*__p.get()).release());
231 typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index;
232 _VSTD::__thread_execute(*__p.get(), _Index());
233 return nullptr;
234}
235
236template <class _Fp, class ..._Args,
237 class
238 >
239thread::thread(_Fp&& __f, _Args&&... __args)
240{
241 typedef unique_ptr<__thread_struct> _TSPtr;
242 _TSPtr __tsp(new __thread_struct);
243 typedef tuple<_TSPtr, __decay_t<_Fp>, __decay_t<_Args>...> _Gp;
244 unique_ptr<_Gp> __p(
245 new _Gp(_VSTD::move(__tsp),
246 _VSTD::forward<_Fp>(__f),
247 _VSTD::forward<_Args>(__args)...));
248 int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
249 if (__ec == 0)
250 __p.release();
251 else
252 __throw_system_error(__ec, "thread constructor failed");
253}
254
255#else // _LIBCPP_CXX03_LANG
256
257template <class _Fp>
258struct __thread_invoke_pair {
259 // This type is used to pass memory for thread local storage and a functor
260 // to a newly created thread because std::pair doesn't work with
261 // std::unique_ptr in C++03.
262 _LIBCPP_HIDE_FROM_ABI __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {}
263 unique_ptr<__thread_struct> __tsp_;
264 _Fp __fn_;
265};
266
267template <class _Fp>
268_LIBCPP_HIDE_FROM_ABI void* __thread_proxy_cxx03(void* __vp)
269{
270 unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
271 __thread_local_data().set_pointer(__p->__tsp_.release());
272 (__p->__fn_)();
273 return nullptr;
274}
275
276template <class _Fp>
277thread::thread(_Fp __f)
278{
279
280 typedef __thread_invoke_pair<_Fp> _InvokePair;
281 typedef unique_ptr<_InvokePair> _PairPtr;
282 _PairPtr __pp(new _InvokePair(__f));
283 int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
284 if (__ec == 0)
285 __pp.release();
286 else
287 __throw_system_error(__ec, "thread constructor failed");
288}
289
290#endif // _LIBCPP_CXX03_LANG
291
292inline _LIBCPP_INLINE_VISIBILITY
293void swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);}
294
295_LIBCPP_END_NAMESPACE_STD
296
297#endif // _LIBCPP___THREAD_THREAD_H
lib/libcxx/include/__threading_support+19-136
......@@ -13,13 +13,9 @@
1313#include <__availability>
1414#include <__chrono/convert_to_timespec.h>
1515#include <__chrono/duration.h>
16#include <__compare/ordering.h>
1716#include <__config>
18#include <__fwd/hash.h>
1917#include <__thread/poll_with_backoff.h>
2018#include <errno.h>
21#include <iosfwd>
22#include <limits>
2319
2420#ifdef __MVS__
2521# include <__support/ibm/nanosleep.h>
......@@ -34,26 +30,26 @@
3430#elif !defined(_LIBCPP_HAS_NO_THREADS)
3531
3632#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
33// Some platforms require <bits/atomic_wide_counter.h> in order for
34// PTHREAD_COND_INITIALIZER to be expanded. Normally that would come
35// in via <pthread.h>, but it's a non-modular header on those platforms,
36// so libc++'s <math.h> usually absorbs atomic_wide_counter.h into the
37// module with <math.h> and makes atomic_wide_counter.h invisible.
38// Include <math.h> here to work around that.
39# include <math.h>
40
3741# include <pthread.h>
3842# include <sched.h>
3943#elif defined(_LIBCPP_HAS_THREAD_API_C11)
4044# include <threads.h>
4145#endif
4246
43#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
44 defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
45 defined(_LIBCPP_HAS_THREAD_API_WIN32)
46#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
47#if defined(_LIBCPP_HAS_THREAD_API_WIN32)
48#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_EXPORTED_FROM_ABI
4749#else
4850#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
4951#endif
5052
51#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
52#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
53#else
54#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
55#endif
56
5753typedef ::timespec __libcpp_timespec_t;
5854#endif // !defined(_LIBCPP_HAS_NO_THREADS)
5955
......@@ -252,28 +248,25 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
252248
253249#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
254250
255#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
256 defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL))
257
258251#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
259252
260253int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
261254{
262 pthread_mutexattr_t attr;
263 int __ec = pthread_mutexattr_init(&attr);
255 pthread_mutexattr_t __attr;
256 int __ec = pthread_mutexattr_init(&__attr);
264257 if (__ec)
265258 return __ec;
266 __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
259 __ec = pthread_mutexattr_settype(&__attr, PTHREAD_MUTEX_RECURSIVE);
267260 if (__ec) {
268 pthread_mutexattr_destroy(&attr);
261 pthread_mutexattr_destroy(&__attr);
269262 return __ec;
270263 }
271 __ec = pthread_mutex_init(__m, &attr);
264 __ec = pthread_mutex_init(__m, &__attr);
272265 if (__ec) {
273 pthread_mutexattr_destroy(&attr);
266 pthread_mutexattr_destroy(&__attr);
274267 return __ec;
275268 }
276 __ec = pthread_mutexattr_destroy(&attr);
269 __ec = pthread_mutexattr_destroy(&__attr);
277270 if (__ec) {
278271 pthread_mutex_destroy(__m);
279272 return __ec;
......@@ -380,8 +373,8 @@ int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
380373
381374__libcpp_thread_id __libcpp_thread_get_current_id()
382375{
383 const __libcpp_thread_t thread = pthread_self();
384 return __libcpp_thread_get_id(&thread);
376 const __libcpp_thread_t __current_thread = pthread_self();
377 return __libcpp_thread_get_id(&__current_thread);
385378}
386379
387380__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
......@@ -589,116 +582,6 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
589582
590583#endif
591584
592
593#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
594
595class _LIBCPP_TYPE_VIS thread;
596class _LIBCPP_TYPE_VIS __thread_id;
597
598namespace this_thread
599{
600
601_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;
602
603} // namespace this_thread
604
605template<> struct hash<__thread_id>;
606
607class _LIBCPP_TEMPLATE_VIS __thread_id
608{
609 // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
610 // NULL is the no-thread value on Darwin. Someone needs to check
611 // on other platforms. We assume 0 works everywhere for now.
612 __libcpp_thread_id __id_;
613
614 static _LIBCPP_HIDE_FROM_ABI
615 bool __lt_impl(__thread_id __x, __thread_id __y) _NOEXCEPT
616 { // id==0 is always less than any other thread_id
617 if (__x.__id_ == 0) return __y.__id_ != 0;
618 if (__y.__id_ == 0) return false;
619 return __libcpp_thread_id_less(__x.__id_, __y.__id_);
620 }
621
622public:
623 _LIBCPP_INLINE_VISIBILITY
624 __thread_id() _NOEXCEPT : __id_(0) {}
625
626 _LIBCPP_INLINE_VISIBILITY
627 void __reset() { __id_ = 0; }
628
629 friend _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT;
630#if _LIBCPP_STD_VER <= 17
631 friend _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT;
632#else // _LIBCPP_STD_VER <= 17
633 friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept;
634#endif // _LIBCPP_STD_VER <= 17
635
636 template<class _CharT, class _Traits>
637 friend
638 _LIBCPP_INLINE_VISIBILITY
639 basic_ostream<_CharT, _Traits>&
640 operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
641
642private:
643 _LIBCPP_INLINE_VISIBILITY
644 __thread_id(__libcpp_thread_id __id) : __id_(__id) {}
645
646 friend __thread_id this_thread::get_id() _NOEXCEPT;
647 friend class _LIBCPP_TYPE_VIS thread;
648 friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
649};
650
651inline _LIBCPP_HIDE_FROM_ABI
652bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT {
653 // Don't pass id==0 to underlying routines
654 if (__x.__id_ == 0)
655 return __y.__id_ == 0;
656 if (__y.__id_ == 0)
657 return false;
658 return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
659}
660
661#if _LIBCPP_STD_VER <= 17
662
663inline _LIBCPP_HIDE_FROM_ABI
664bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT {
665 return !(__x == __y);
666}
667
668inline _LIBCPP_HIDE_FROM_ABI
669bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT {
670 return __thread_id::__lt_impl(__x.__id_, __y.__id_);
671}
672
673inline _LIBCPP_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); }
674inline _LIBCPP_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; }
675inline _LIBCPP_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); }
676
677#else // _LIBCPP_STD_VER <= 17
678
679inline _LIBCPP_HIDE_FROM_ABI
680strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept {
681 if (__x == __y)
682 return strong_ordering::equal;
683 if (__thread_id::__lt_impl(__x, __y))
684 return strong_ordering::less;
685 return strong_ordering::greater;
686}
687
688#endif // _LIBCPP_STD_VER <= 17
689
690namespace this_thread
691{
692
693inline _LIBCPP_INLINE_VISIBILITY
694__thread_id
695get_id() _NOEXCEPT
696{
697 return __libcpp_thread_get_current_id();
698}
699
700} // namespace this_thread
701
702585#endif // !_LIBCPP_HAS_NO_THREADS
703586
704587_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__tree+74-76
......@@ -13,11 +13,11 @@
1313#include <__algorithm/min.h>
1414#include <__assert>
1515#include <__config>
16#include <__debug>
1716#include <__functional/invoke.h>
1817#include <__iterator/distance.h>
1918#include <__iterator/iterator_traits.h>
2019#include <__iterator/next.h>
20#include <__memory/addressof.h>
2121#include <__memory/allocator_traits.h>
2222#include <__memory/compressed_pair.h>
2323#include <__memory/pointer_traits.h>
......@@ -26,6 +26,7 @@
2626#include <__type_traits/can_extract_key.h>
2727#include <__type_traits/conditional.h>
2828#include <__type_traits/is_const.h>
29#include <__type_traits/is_copy_constructible.h>
2930#include <__type_traits/is_nothrow_copy_constructible.h>
3031#include <__type_traits/is_nothrow_default_constructible.h>
3132#include <__type_traits/is_nothrow_move_assignable.h>
......@@ -167,7 +168,7 @@ inline _LIBCPP_INLINE_VISIBILITY
167168_NodePtr
168169__tree_min(_NodePtr __x) _NOEXCEPT
169170{
170 _LIBCPP_ASSERT(__x != nullptr, "Root node shouldn't be null");
171 _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Root node shouldn't be null");
171172 while (__x->__left_ != nullptr)
172173 __x = __x->__left_;
173174 return __x;
......@@ -179,7 +180,7 @@ inline _LIBCPP_INLINE_VISIBILITY
179180_NodePtr
180181__tree_max(_NodePtr __x) _NOEXCEPT
181182{
182 _LIBCPP_ASSERT(__x != nullptr, "Root node shouldn't be null");
183 _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Root node shouldn't be null");
183184 while (__x->__right_ != nullptr)
184185 __x = __x->__right_;
185186 return __x;
......@@ -190,7 +191,7 @@ template <class _NodePtr>
190191_LIBCPP_HIDE_FROM_ABI _NodePtr
191192__tree_next(_NodePtr __x) _NOEXCEPT
192193{
193 _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
194 _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
194195 if (__x->__right_ != nullptr)
195196 return _VSTD::__tree_min(__x->__right_);
196197 while (!_VSTD::__tree_is_left_child(__x))
......@@ -203,7 +204,7 @@ inline _LIBCPP_INLINE_VISIBILITY
203204_EndNodePtr
204205__tree_next_iter(_NodePtr __x) _NOEXCEPT
205206{
206 _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
207 _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
207208 if (__x->__right_ != nullptr)
208209 return static_cast<_EndNodePtr>(_VSTD::__tree_min(__x->__right_));
209210 while (!_VSTD::__tree_is_left_child(__x))
......@@ -218,7 +219,7 @@ inline _LIBCPP_INLINE_VISIBILITY
218219_NodePtr
219220__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT
220221{
221 _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
222 _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
222223 if (__x->__left_ != nullptr)
223224 return _VSTD::__tree_max(__x->__left_);
224225 _NodePtr __xx = static_cast<_NodePtr>(__x);
......@@ -232,7 +233,7 @@ template <class _NodePtr>
232233_LIBCPP_HIDE_FROM_ABI _NodePtr
233234__tree_leaf(_NodePtr __x) _NOEXCEPT
234235{
235 _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
236 _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
236237 while (true)
237238 {
238239 if (__x->__left_ != nullptr)
......@@ -256,8 +257,8 @@ template <class _NodePtr>
256257_LIBCPP_HIDE_FROM_ABI void
257258__tree_left_rotate(_NodePtr __x) _NOEXCEPT
258259{
259 _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
260 _LIBCPP_ASSERT(__x->__right_ != nullptr, "node should have a right child");
260 _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
261 _LIBCPP_ASSERT_INTERNAL(__x->__right_ != nullptr, "node should have a right child");
261262 _NodePtr __y = __x->__right_;
262263 __x->__right_ = __y->__left_;
263264 if (__x->__right_ != nullptr)
......@@ -277,8 +278,8 @@ template <class _NodePtr>
277278_LIBCPP_HIDE_FROM_ABI void
278279__tree_right_rotate(_NodePtr __x) _NOEXCEPT
279280{
280 _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
281 _LIBCPP_ASSERT(__x->__left_ != nullptr, "node should have a left child");
281 _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
282 _LIBCPP_ASSERT_INTERNAL(__x->__left_ != nullptr, "node should have a left child");
282283 _NodePtr __y = __x->__left_;
283284 __x->__left_ = __y->__right_;
284285 if (__x->__left_ != nullptr)
......@@ -303,8 +304,8 @@ template <class _NodePtr>
303304_LIBCPP_HIDE_FROM_ABI void
304305__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
305306{
306 _LIBCPP_ASSERT(__root != nullptr, "Root of the tree shouldn't be null");
307 _LIBCPP_ASSERT(__x != nullptr, "Can't attach null node to a leaf");
307 _LIBCPP_ASSERT_INTERNAL(__root != nullptr, "Root of the tree shouldn't be null");
308 _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Can't attach null node to a leaf");
308309 __x->__is_black_ = __x == __root;
309310 while (__x != __root && !__x->__parent_unsafe()->__is_black_)
310311 {
......@@ -373,9 +374,9 @@ template <class _NodePtr>
373374_LIBCPP_HIDE_FROM_ABI void
374375__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT
375376{
376 _LIBCPP_ASSERT(__root != nullptr, "Root node should not be null");
377 _LIBCPP_ASSERT(__z != nullptr, "The node to remove should not be null");
378 _LIBCPP_DEBUG_ASSERT(__tree_invariant(__root), "The tree invariants should hold");
377 _LIBCPP_ASSERT_INTERNAL(__root != nullptr, "Root node should not be null");
378 _LIBCPP_ASSERT_INTERNAL(__z != nullptr, "The node to remove should not be null");
379 _LIBCPP_ASSERT_INTERNAL(std::__tree_invariant(__root), "The tree invariants should hold");
379380 // __z will be removed from the tree. Client still needs to destruct/deallocate it
380381 // __y is either __z, or if __z has two children, __tree_next(__z).
381382 // __y will have at most one child.
......@@ -797,7 +798,7 @@ public:
797798 bool __value_constructed;
798799
799800
800 __tree_node_destructor(const __tree_node_destructor &) = default;
801 _LIBCPP_HIDE_FROM_ABI __tree_node_destructor(const __tree_node_destructor &) = default;
801802 __tree_node_destructor& operator=(const __tree_node_destructor&) = delete;
802803
803804 _LIBCPP_INLINE_VISIBILITY
......@@ -818,7 +819,7 @@ public:
818819 template <class> friend class __map_node_destructor;
819820};
820821
821#if _LIBCPP_STD_VER > 14
822#if _LIBCPP_STD_VER >= 17
822823template <class _NodeType, class _Alloc>
823824struct __generic_container_node_destructor;
824825template <class _Tp, class _VoidPtr, class _Alloc>
......@@ -849,7 +850,7 @@ public:
849850 typedef typename _NodeTypes::__node_value_type_pointer pointer;
850851
851852 _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT
852#if _LIBCPP_STD_VER > 11
853#if _LIBCPP_STD_VER >= 14
853854 : __ptr_(nullptr)
854855#endif
855856 {}
......@@ -922,7 +923,7 @@ public:
922923 typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
923924
924925 _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT
925#if _LIBCPP_STD_VER > 11
926#if _LIBCPP_STD_VER >= 14
926927 : __ptr_(nullptr)
927928#endif
928929 {}
......@@ -1100,36 +1101,36 @@ public:
11001101 __node_pointer __root() const _NOEXCEPT
11011102 {return static_cast<__node_pointer>(__end_node()->__left_);}
11021103
1103 __node_base_pointer* __root_ptr() const _NOEXCEPT {
1104 _LIBCPP_HIDE_FROM_ABI __node_base_pointer* __root_ptr() const _NOEXCEPT {
11041105 return _VSTD::addressof(__end_node()->__left_);
11051106 }
11061107
11071108 typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator;
11081109 typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
11091110
1110 explicit __tree(const value_compare& __comp)
1111 _LIBCPP_HIDE_FROM_ABI explicit __tree(const value_compare& __comp)
11111112 _NOEXCEPT_(
11121113 is_nothrow_default_constructible<__node_allocator>::value &&
11131114 is_nothrow_copy_constructible<value_compare>::value);
1114 explicit __tree(const allocator_type& __a);
1115 __tree(const value_compare& __comp, const allocator_type& __a);
1116 __tree(const __tree& __t);
1117 __tree& operator=(const __tree& __t);
1115 _LIBCPP_HIDE_FROM_ABI explicit __tree(const allocator_type& __a);
1116 _LIBCPP_HIDE_FROM_ABI __tree(const value_compare& __comp, const allocator_type& __a);
1117 _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __t);
1118 _LIBCPP_HIDE_FROM_ABI __tree& operator=(const __tree& __t);
11181119 template <class _ForwardIterator>
1119 void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
1120 _LIBCPP_HIDE_FROM_ABI void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
11201121 template <class _InputIterator>
1121 void __assign_multi(_InputIterator __first, _InputIterator __last);
1122 __tree(__tree&& __t)
1122 _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last);
1123 _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t)
11231124 _NOEXCEPT_(
11241125 is_nothrow_move_constructible<__node_allocator>::value &&
11251126 is_nothrow_move_constructible<value_compare>::value);
1126 __tree(__tree&& __t, const allocator_type& __a);
1127 __tree& operator=(__tree&& __t)
1127 _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t, const allocator_type& __a);
1128 _LIBCPP_HIDE_FROM_ABI __tree& operator=(__tree&& __t)
11281129 _NOEXCEPT_(
11291130 __node_traits::propagate_on_container_move_assignment::value &&
11301131 is_nothrow_move_assignable<value_compare>::value &&
11311132 is_nothrow_move_assignable<__node_allocator>::value);
1132 ~__tree();
1133 _LIBCPP_HIDE_FROM_ABI ~__tree();
11331134
11341135 _LIBCPP_INLINE_VISIBILITY
11351136 iterator begin() _NOEXCEPT {return iterator(__begin_node());}
......@@ -1146,9 +1147,9 @@ public:
11461147 __node_traits::max_size(__node_alloc()),
11471148 numeric_limits<difference_type >::max());}
11481149
1149 void clear() _NOEXCEPT;
1150 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
11501151
1151 void swap(__tree& __t)
1152 _LIBCPP_HIDE_FROM_ABI void swap(__tree& __t)
11521153#if _LIBCPP_STD_VER <= 11
11531154 _NOEXCEPT_(
11541155 __is_nothrow_swappable<value_compare>::value
......@@ -1160,23 +1161,23 @@ public:
11601161#endif
11611162
11621163 template <class _Key, class ..._Args>
1163 pair<iterator, bool>
1164 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool>
11641165 __emplace_unique_key_args(_Key const&, _Args&&... __args);
11651166 template <class _Key, class ..._Args>
1166 pair<iterator, bool>
1167 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool>
11671168 __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...);
11681169
11691170 template <class... _Args>
1170 pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
1171 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
11711172
11721173 template <class... _Args>
1173 iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
1174 _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
11741175
11751176 template <class... _Args>
1176 iterator __emplace_multi(_Args&&... __args);
1177 _LIBCPP_HIDE_FROM_ABI iterator __emplace_multi(_Args&&... __args);
11771178
11781179 template <class... _Args>
1179 iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
1180 _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
11801181
11811182 template <class _Pp>
11821183 _LIBCPP_INLINE_VISIBILITY
......@@ -1331,7 +1332,7 @@ public:
13311332 _LIBCPP_INLINE_VISIBILITY iterator
13321333 __remove_node_pointer(__node_pointer) _NOEXCEPT;
13331334
1334#if _LIBCPP_STD_VER > 14
1335#if _LIBCPP_STD_VER >= 17
13351336 template <class _NodeHandle, class _InsertReturnType>
13361337 _LIBCPP_INLINE_VISIBILITY
13371338 _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
......@@ -1361,33 +1362,33 @@ public:
13611362 _NodeHandle __node_handle_extract(const_iterator);
13621363#endif
13631364
1364 iterator erase(const_iterator __p);
1365 iterator erase(const_iterator __f, const_iterator __l);
1365 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
1366 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l);
13661367 template <class _Key>
1367 size_type __erase_unique(const _Key& __k);
1368 _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k);
13681369 template <class _Key>
1369 size_type __erase_multi(const _Key& __k);
1370 _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k);
13701371
1371 void __insert_node_at(__parent_pointer __parent,
1372 _LIBCPP_HIDE_FROM_ABI void __insert_node_at(__parent_pointer __parent,
13721373 __node_base_pointer& __child,
13731374 __node_base_pointer __new_node) _NOEXCEPT;
13741375
13751376 template <class _Key>
1376 iterator find(const _Key& __v);
1377 _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __v);
13771378 template <class _Key>
1378 const_iterator find(const _Key& __v) const;
1379 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __v) const;
13791380
13801381 template <class _Key>
1381 size_type __count_unique(const _Key& __k) const;
1382 _LIBCPP_HIDE_FROM_ABI size_type __count_unique(const _Key& __k) const;
13821383 template <class _Key>
1383 size_type __count_multi(const _Key& __k) const;
1384 _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const;
13841385
13851386 template <class _Key>
13861387 _LIBCPP_INLINE_VISIBILITY
13871388 iterator lower_bound(const _Key& __v)
13881389 {return __lower_bound(__v, __root(), __end_node());}
13891390 template <class _Key>
1390 iterator __lower_bound(const _Key& __v,
1391 _LIBCPP_HIDE_FROM_ABI iterator __lower_bound(const _Key& __v,
13911392 __node_pointer __root,
13921393 __iter_pointer __result);
13931394 template <class _Key>
......@@ -1395,7 +1396,7 @@ public:
13951396 const_iterator lower_bound(const _Key& __v) const
13961397 {return __lower_bound(__v, __root(), __end_node());}
13971398 template <class _Key>
1398 const_iterator __lower_bound(const _Key& __v,
1399 _LIBCPP_HIDE_FROM_ABI const_iterator __lower_bound(const _Key& __v,
13991400 __node_pointer __root,
14001401 __iter_pointer __result) const;
14011402 template <class _Key>
......@@ -1403,7 +1404,7 @@ public:
14031404 iterator upper_bound(const _Key& __v)
14041405 {return __upper_bound(__v, __root(), __end_node());}
14051406 template <class _Key>
1406 iterator __upper_bound(const _Key& __v,
1407 _LIBCPP_HIDE_FROM_ABI iterator __upper_bound(const _Key& __v,
14071408 __node_pointer __root,
14081409 __iter_pointer __result);
14091410 template <class _Key>
......@@ -1411,55 +1412,52 @@ public:
14111412 const_iterator upper_bound(const _Key& __v) const
14121413 {return __upper_bound(__v, __root(), __end_node());}
14131414 template <class _Key>
1414 const_iterator __upper_bound(const _Key& __v,
1415 _LIBCPP_HIDE_FROM_ABI const_iterator __upper_bound(const _Key& __v,
14151416 __node_pointer __root,
14161417 __iter_pointer __result) const;
14171418 template <class _Key>
1418 pair<iterator, iterator>
1419 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator>
14191420 __equal_range_unique(const _Key& __k);
14201421 template <class _Key>
1421 pair<const_iterator, const_iterator>
1422 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator>
14221423 __equal_range_unique(const _Key& __k) const;
14231424
14241425 template <class _Key>
1425 pair<iterator, iterator>
1426 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator>
14261427 __equal_range_multi(const _Key& __k);
14271428 template <class _Key>
1428 pair<const_iterator, const_iterator>
1429 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator>
14291430 __equal_range_multi(const _Key& __k) const;
14301431
14311432 typedef __tree_node_destructor<__node_allocator> _Dp;
14321433 typedef unique_ptr<__node, _Dp> __node_holder;
14331434
1434 __node_holder remove(const_iterator __p) _NOEXCEPT;
1435 _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT;
14351436private:
1436 __node_base_pointer&
1437 __find_leaf_low(__parent_pointer& __parent, const key_type& __v);
1438 __node_base_pointer&
1439 __find_leaf_high(__parent_pointer& __parent, const key_type& __v);
1440 __node_base_pointer&
1441 __find_leaf(const_iterator __hint,
1442 __parent_pointer& __parent, const key_type& __v);
1437 _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_leaf_low(__parent_pointer& __parent, const key_type& __v);
1438 _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_leaf_high(__parent_pointer& __parent, const key_type& __v);
1439 _LIBCPP_HIDE_FROM_ABI __node_base_pointer&
1440 __find_leaf(const_iterator __hint, __parent_pointer& __parent, const key_type& __v);
14431441 // FIXME: Make this function const qualified. Unfortunately doing so
14441442 // breaks existing code which uses non-const callable comparators.
14451443 template <class _Key>
1446 __node_base_pointer&
1447 __find_equal(__parent_pointer& __parent, const _Key& __v);
1444 _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_equal(__parent_pointer& __parent, const _Key& __v);
14481445 template <class _Key>
14491446 _LIBCPP_INLINE_VISIBILITY __node_base_pointer&
14501447 __find_equal(__parent_pointer& __parent, const _Key& __v) const {
14511448 return const_cast<__tree*>(this)->__find_equal(__parent, __v);
14521449 }
14531450 template <class _Key>
1454 __node_base_pointer&
1451 _LIBCPP_HIDE_FROM_ABI __node_base_pointer&
14551452 __find_equal(const_iterator __hint, __parent_pointer& __parent,
14561453 __node_base_pointer& __dummy,
14571454 const _Key& __v);
14581455
14591456 template <class ..._Args>
1460 __node_holder __construct_node(_Args&& ...__args);
1457 _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&& ...__args);
14611458
1462 void destroy(__node_pointer __nd) _NOEXCEPT;
1459 // TODO: Make this _LIBCPP_HIDE_FROM_ABI
1460 _LIBCPP_HIDDEN void destroy(__node_pointer __nd) _NOEXCEPT;
14631461
14641462 _LIBCPP_INLINE_VISIBILITY
14651463 void __copy_assign_alloc(const __tree& __t)
......@@ -1476,8 +1474,8 @@ private:
14761474 _LIBCPP_INLINE_VISIBILITY
14771475 void __copy_assign_alloc(const __tree&, false_type) {}
14781476
1479 void __move_assign(__tree& __t, false_type);
1480 void __move_assign(__tree& __t, true_type)
1477 _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, false_type);
1478 _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, true_type)
14811479 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
14821480 is_nothrow_move_assignable<__node_allocator>::value);
14831481
......@@ -1640,7 +1638,7 @@ __tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _Fo
16401638 typedef typename _ITraits::value_type _ItValueType;
16411639 static_assert((is_same<_ItValueType, __container_value_type>::value),
16421640 "__assign_unique may only be called with the containers value type");
1643 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
1641 static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
16441642 "__assign_unique requires a forward iterator");
16451643 if (size() != 0)
16461644 {
......@@ -2265,7 +2263,7 @@ __tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _
22652263 return __r;
22662264}
22672265
2268#if _LIBCPP_STD_VER > 14
2266#if _LIBCPP_STD_VER >= 17
22692267template <class _Tp, class _Compare, class _Allocator>
22702268template <class _NodeHandle, class _InsertReturnType>
22712269_LIBCPP_INLINE_VISIBILITY
......@@ -2422,7 +2420,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source)
24222420 }
24232421}
24242422
2425#endif // _LIBCPP_STD_VER > 14
2423#endif // _LIBCPP_STD_VER >= 17
24262424
24272425template <class _Tp, class _Compare, class _Allocator>
24282426typename __tree<_Tp, _Compare, _Allocator>::iterator
lib/libcxx/include/__tuple/make_tuple_types.h created+80
......@@ -0,0 +1,80 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_MAKE_TUPLE_TYPES_H
10#define _LIBCPP___TUPLE_MAKE_TUPLE_TYPES_H
11
12#include <__config>
13#include <__fwd/array.h>
14#include <__fwd/tuple.h>
15#include <__tuple/tuple_element.h>
16#include <__tuple/tuple_indices.h>
17#include <__tuple/tuple_size.h>
18#include <__tuple/tuple_types.h>
19#include <__type_traits/apply_cv.h>
20#include <__type_traits/remove_cv.h>
21#include <__type_traits/remove_reference.h>
22#include <cstddef>
23
24#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25# pragma GCC system_header
26#endif
27
28#ifndef _LIBCPP_CXX03_LANG
29
30_LIBCPP_BEGIN_NAMESPACE_STD
31
32// __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a
33// __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep).
34// _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>. If _Tuple is a
35// lvalue_reference type, then __tuple_types<_Types&...> is the result.
36
37template <class _TupleTypes, class _TupleIndices>
38struct __make_tuple_types_flat;
39
40template <template <class...> class _Tuple, class ..._Types, size_t ..._Idx>
41struct __make_tuple_types_flat<_Tuple<_Types...>, __tuple_indices<_Idx...>> {
42 // Specialization for pair, tuple, and __tuple_types
43 template <class _Tp>
44 using __apply_quals _LIBCPP_NODEBUG = __tuple_types<__apply_cv_t<_Tp, __type_pack_element<_Idx, _Types...>>...>;
45};
46
47template <class _Vt, size_t _Np, size_t ..._Idx>
48struct __make_tuple_types_flat<array<_Vt, _Np>, __tuple_indices<_Idx...>> {
49 template <size_t>
50 using __value_type = _Vt;
51 template <class _Tp>
52 using __apply_quals = __tuple_types<__apply_cv_t<_Tp, __value_type<_Idx>>...>;
53};
54
55template <class _Tp, size_t _Ep = tuple_size<__libcpp_remove_reference_t<_Tp> >::value,
56 size_t _Sp = 0,
57 bool _SameSize = (_Ep == tuple_size<__libcpp_remove_reference_t<_Tp> >::value)>
58struct __make_tuple_types
59{
60 static_assert(_Sp <= _Ep, "__make_tuple_types input error");
61 using _RawTp = __remove_cv_t<__libcpp_remove_reference_t<_Tp> >;
62 using _Maker = __make_tuple_types_flat<_RawTp, typename __make_tuple_indices<_Ep, _Sp>::type>;
63 using type = typename _Maker::template __apply_quals<_Tp>;
64};
65
66template <class ..._Types, size_t _Ep>
67struct __make_tuple_types<tuple<_Types...>, _Ep, 0, true> {
68 typedef _LIBCPP_NODEBUG __tuple_types<_Types...> type;
69};
70
71template <class ..._Types, size_t _Ep>
72struct __make_tuple_types<__tuple_types<_Types...>, _Ep, 0, true> {
73 typedef _LIBCPP_NODEBUG __tuple_types<_Types...> type;
74};
75
76_LIBCPP_END_NAMESPACE_STD
77
78#endif // _LIBCPP_CXX03_LANG
79
80#endif // _LIBCPP___TUPLE_MAKE_TUPLE_TYPES_H
lib/libcxx/include/__tuple/pair_like.h created+32
......@@ -0,0 +1,32 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_PAIR_LIKE_H
10#define _LIBCPP___TUPLE_PAIR_LIKE_H
11
12#include <__config>
13#include <__tuple/tuple_like.h>
14#include <__tuple/tuple_size.h>
15#include <__type_traits/remove_cvref.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18# pragma GCC system_header
19#endif
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23#if _LIBCPP_STD_VER >= 20
24
25template <class _Tp>
26concept __pair_like = __tuple_like<_Tp> && tuple_size<remove_cvref_t<_Tp>>::value == 2;
27
28#endif // _LIBCPP_STD_VER >= 20
29
30_LIBCPP_END_NAMESPACE_STD
31
32#endif // _LIBCPP___TUPLE_PAIR_LIKE_H
lib/libcxx/include/__tuple/sfinae_helpers.h created+183
......@@ -0,0 +1,183 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_SFINAE_HELPERS_H
10#define _LIBCPP___TUPLE_SFINAE_HELPERS_H
11
12#include <__config>
13#include <__fwd/tuple.h>
14#include <__tuple/make_tuple_types.h>
15#include <__tuple/tuple_element.h>
16#include <__tuple/tuple_like_ext.h>
17#include <__tuple/tuple_size.h>
18#include <__tuple/tuple_types.h>
19#include <__type_traits/enable_if.h>
20#include <__type_traits/integral_constant.h>
21#include <__type_traits/is_assignable.h>
22#include <__type_traits/is_constructible.h>
23#include <__type_traits/is_convertible.h>
24#include <__type_traits/is_same.h>
25#include <__type_traits/remove_cvref.h>
26#include <__type_traits/remove_reference.h>
27#include <cstddef>
28
29#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
30# pragma GCC system_header
31#endif
32
33_LIBCPP_BEGIN_NAMESPACE_STD
34
35#ifndef _LIBCPP_CXX03_LANG
36
37template <bool ..._Preds>
38struct __all_dummy;
39
40template <bool ..._Pred>
41struct __all : _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>> {};
42
43struct __tuple_sfinae_base {
44 template <template <class, class...> class _Trait,
45 class ..._LArgs, class ..._RArgs>
46 static auto __do_test(__tuple_types<_LArgs...>, __tuple_types<_RArgs...>)
47 -> __all<__enable_if_t<_Trait<_LArgs, _RArgs>::value, bool>{true}...>;
48 template <template <class...> class>
49 static auto __do_test(...) -> false_type;
50
51 template <class _FromArgs, class _ToArgs>
52 using __constructible = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{}));
53 template <class _FromArgs, class _ToArgs>
54 using __convertible = decltype(__do_test<is_convertible>(_FromArgs{}, _ToArgs{}));
55 template <class _FromArgs, class _ToArgs>
56 using __assignable = decltype(__do_test<is_assignable>(_ToArgs{}, _FromArgs{}));
57};
58
59// __tuple_convertible
60
61template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
62 bool = __tuple_like_ext<_Up>::value>
63struct __tuple_convertible
64 : public false_type {};
65
66template <class _Tp, class _Up>
67struct __tuple_convertible<_Tp, _Up, true, true>
68 : public __tuple_sfinae_base::__convertible<
69 typename __make_tuple_types<_Tp>::type
70 , typename __make_tuple_types<_Up>::type
71 >
72{};
73
74// __tuple_constructible
75
76template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
77 bool = __tuple_like_ext<_Up>::value>
78struct __tuple_constructible
79 : public false_type {};
80
81template <class _Tp, class _Up>
82struct __tuple_constructible<_Tp, _Up, true, true>
83 : public __tuple_sfinae_base::__constructible<
84 typename __make_tuple_types<_Tp>::type
85 , typename __make_tuple_types<_Up>::type
86 >
87{};
88
89// __tuple_assignable
90
91template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
92 bool = __tuple_like_ext<_Up>::value>
93struct __tuple_assignable
94 : public false_type {};
95
96template <class _Tp, class _Up>
97struct __tuple_assignable<_Tp, _Up, true, true>
98 : public __tuple_sfinae_base::__assignable<
99 typename __make_tuple_types<_Tp>::type
100 , typename __make_tuple_types<_Up&>::type
101 >
102{};
103
104
105template <size_t _Ip, class ..._Tp>
106struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, tuple<_Tp...> >
107{
108 typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
109};
110
111struct _LIBCPP_EXPORTED_FROM_ABI __check_tuple_constructor_fail {
112
113 static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() { return false; }
114 static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() { return false; }
115 template <class ...>
116 static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() { return false; }
117 template <class ...>
118 static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() { return false; }
119 template <class ...>
120 static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_assign() { return false; }
121};
122#endif // !defined(_LIBCPP_CXX03_LANG)
123
124#if _LIBCPP_STD_VER >= 17
125
126template <bool _CanCopy, bool _CanMove>
127struct __sfinae_ctor_base {};
128template <>
129struct __sfinae_ctor_base<false, false> {
130 __sfinae_ctor_base() = default;
131 __sfinae_ctor_base(__sfinae_ctor_base const&) = delete;
132 __sfinae_ctor_base(__sfinae_ctor_base &&) = delete;
133 __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
134 __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
135};
136template <>
137struct __sfinae_ctor_base<true, false> {
138 __sfinae_ctor_base() = default;
139 __sfinae_ctor_base(__sfinae_ctor_base const&) = default;
140 __sfinae_ctor_base(__sfinae_ctor_base &&) = delete;
141 __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
142 __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
143};
144template <>
145struct __sfinae_ctor_base<false, true> {
146 __sfinae_ctor_base() = default;
147 __sfinae_ctor_base(__sfinae_ctor_base const&) = delete;
148 __sfinae_ctor_base(__sfinae_ctor_base &&) = default;
149 __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
150 __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
151};
152
153template <bool _CanCopy, bool _CanMove>
154struct __sfinae_assign_base {};
155template <>
156struct __sfinae_assign_base<false, false> {
157 __sfinae_assign_base() = default;
158 __sfinae_assign_base(__sfinae_assign_base const&) = default;
159 __sfinae_assign_base(__sfinae_assign_base &&) = default;
160 __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
161 __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete;
162};
163template <>
164struct __sfinae_assign_base<true, false> {
165 __sfinae_assign_base() = default;
166 __sfinae_assign_base(__sfinae_assign_base const&) = default;
167 __sfinae_assign_base(__sfinae_assign_base &&) = default;
168 __sfinae_assign_base& operator=(__sfinae_assign_base const&) = default;
169 __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete;
170};
171template <>
172struct __sfinae_assign_base<false, true> {
173 __sfinae_assign_base() = default;
174 __sfinae_assign_base(__sfinae_assign_base const&) = default;
175 __sfinae_assign_base(__sfinae_assign_base &&) = default;
176 __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
177 __sfinae_assign_base& operator=(__sfinae_assign_base&&) = default;
178};
179#endif // _LIBCPP_STD_VER >= 17
180
181_LIBCPP_END_NAMESPACE_STD
182
183#endif // _LIBCPP___TUPLE_SFINAE_HELPERS_H
lib/libcxx/include/__tuple/tuple_element.h created+93
......@@ -0,0 +1,93 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_TUPLE_ELEMENT_H
10#define _LIBCPP___TUPLE_TUPLE_ELEMENT_H
11
12#include <__config>
13#include <__tuple/tuple_indices.h>
14#include <__tuple/tuple_types.h>
15#include <__type_traits/add_const.h>
16#include <__type_traits/add_cv.h>
17#include <__type_traits/add_volatile.h>
18#include <cstddef>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21# pragma GCC system_header
22#endif
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <size_t _Ip, class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_element;
27
28template <size_t _Ip, class _Tp>
29struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const _Tp>
30{
31 typedef _LIBCPP_NODEBUG typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type;
32};
33
34template <size_t _Ip, class _Tp>
35struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, volatile _Tp>
36{
37 typedef _LIBCPP_NODEBUG typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type;
38};
39
40template <size_t _Ip, class _Tp>
41struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp>
42{
43 typedef _LIBCPP_NODEBUG typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type;
44};
45
46#ifndef _LIBCPP_CXX03_LANG
47
48#if !__has_builtin(__type_pack_element)
49
50namespace __indexer_detail {
51
52template <size_t _Idx, class _Tp>
53struct __indexed { using type _LIBCPP_NODEBUG = _Tp; };
54
55template <class _Types, class _Indexes> struct __indexer;
56
57template <class ..._Types, size_t ..._Idx>
58struct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>>
59 : __indexed<_Idx, _Types>...
60{};
61
62template <size_t _Idx, class _Tp>
63__indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&);
64
65} // namespace __indexer_detail
66
67template <size_t _Idx, class ..._Types>
68using __type_pack_element _LIBCPP_NODEBUG = typename decltype(
69 __indexer_detail::__at_index<_Idx>(
70 __indexer_detail::__indexer<
71 __tuple_types<_Types...>,
72 typename __make_tuple_indices<sizeof...(_Types)>::type
73 >{})
74 )::type;
75#endif
76
77template <size_t _Ip, class ..._Types>
78struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...> >
79{
80 static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range");
81 typedef _LIBCPP_NODEBUG __type_pack_element<_Ip, _Types...> type;
82};
83
84#if _LIBCPP_STD_VER >= 14
85template <size_t _Ip, class ..._Tp>
86using tuple_element_t _LIBCPP_NODEBUG = typename tuple_element <_Ip, _Tp...>::type;
87#endif
88
89#endif // _LIBCPP_CXX03_LANG
90
91_LIBCPP_END_NAMESPACE_STD
92
93#endif // _LIBCPP___TUPLE_TUPLE_ELEMENT_H
lib/libcxx/include/__tuple/tuple_indices.h created+37
......@@ -0,0 +1,37 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_MAKE_TUPLE_INDICES_H
10#define _LIBCPP___TUPLE_MAKE_TUPLE_INDICES_H
11
12#include <__config>
13#include <__utility/integer_sequence.h>
14#include <cstddef>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20#ifndef _LIBCPP_CXX03_LANG
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <size_t...> struct __tuple_indices {};
25
26template <size_t _Ep, size_t _Sp = 0>
27struct __make_tuple_indices
28{
29 static_assert(_Sp <= _Ep, "__make_tuple_indices input error");
30 typedef __make_indices_imp<_Ep, _Sp> type;
31};
32
33_LIBCPP_END_NAMESPACE_STD
34
35#endif // _LIBCPP_CXX03_LANG
36
37#endif // _LIBCPP___TUPLE_MAKE_TUPLE_INDICES_H
lib/libcxx/include/__tuple/tuple_like.h created+51
......@@ -0,0 +1,51 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_TUPLE_LIKE_H
10#define _LIBCPP___TUPLE_TUPLE_LIKE_H
11
12#include <__config>
13#include <__fwd/array.h>
14#include <__fwd/pair.h>
15#include <__fwd/subrange.h>
16#include <__fwd/tuple.h>
17#include <__type_traits/integral_constant.h>
18#include <__type_traits/remove_cvref.h>
19#include <cstddef>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22# pragma GCC system_header
23#endif
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27#if _LIBCPP_STD_VER >= 20
28
29template <class _Tp>
30struct __tuple_like_impl : false_type {};
31
32template <class... _Tp>
33struct __tuple_like_impl<tuple<_Tp...> > : true_type {};
34
35template <class _T1, class _T2>
36struct __tuple_like_impl<pair<_T1, _T2> > : true_type {};
37
38template <class _Tp, size_t _Size>
39struct __tuple_like_impl<array<_Tp, _Size> > : true_type {};
40
41template <class _Ip, class _Sp, ranges::subrange_kind _Kp>
42struct __tuple_like_impl<ranges::subrange<_Ip, _Sp, _Kp> > : true_type {};
43
44template <class _Tp>
45concept __tuple_like = __tuple_like_impl<remove_cvref_t<_Tp>>::value;
46
47#endif // _LIBCPP_STD_VER >= 20
48
49_LIBCPP_END_NAMESPACE_STD
50
51#endif // _LIBCPP___TUPLE_TUPLE_LIKE_H
lib/libcxx/include/__tuple/tuple_like_ext.h created+44
......@@ -0,0 +1,44 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H
10#define _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H
11
12#include <__config>
13#include <__fwd/array.h>
14#include <__fwd/pair.h>
15#include <__fwd/tuple.h>
16#include <__tuple/tuple_types.h>
17#include <__type_traits/integral_constant.h>
18#include <cstddef>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21# pragma GCC system_header
22#endif
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _Tp> struct __tuple_like_ext : false_type {};
27
28template <class _Tp> struct __tuple_like_ext<const _Tp> : public __tuple_like_ext<_Tp> {};
29template <class _Tp> struct __tuple_like_ext<volatile _Tp> : public __tuple_like_ext<_Tp> {};
30template <class _Tp> struct __tuple_like_ext<const volatile _Tp> : public __tuple_like_ext<_Tp> {};
31
32#ifndef _LIBCPP_CXX03_LANG
33template <class... _Tp> struct __tuple_like_ext<tuple<_Tp...> > : true_type {};
34#endif
35
36template <class _T1, class _T2> struct __tuple_like_ext<pair<_T1, _T2> > : true_type {};
37
38template <class _Tp, size_t _Size> struct __tuple_like_ext<array<_Tp, _Size> > : true_type {};
39
40template <class... _Tp> struct __tuple_like_ext<__tuple_types<_Tp...> > : true_type {};
41
42_LIBCPP_END_NAMESPACE_STD
43
44#endif // _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H
lib/libcxx/include/__tuple/tuple_size.h created+75
......@@ -0,0 +1,75 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_TUPLE_SIZE_H
10#define _LIBCPP___TUPLE_TUPLE_SIZE_H
11
12#include <__config>
13#include <__fwd/tuple.h>
14#include <__tuple/tuple_types.h>
15#include <__type_traits/is_const.h>
16#include <__type_traits/is_volatile.h>
17#include <cstddef>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size;
26
27#if !defined(_LIBCPP_CXX03_LANG)
28template <class _Tp, class...>
29using __enable_if_tuple_size_imp = _Tp;
30
31template <class _Tp>
32struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
33 const _Tp,
34 __enable_if_t<!is_volatile<_Tp>::value>,
35 integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
36 : public integral_constant<size_t, tuple_size<_Tp>::value> {};
37
38template <class _Tp>
39struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
40 volatile _Tp,
41 __enable_if_t<!is_const<_Tp>::value>,
42 integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
43 : public integral_constant<size_t, tuple_size<_Tp>::value> {};
44
45template <class _Tp>
46struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
47 const volatile _Tp,
48 integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
49 : public integral_constant<size_t, tuple_size<_Tp>::value> {};
50
51#else
52template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {};
53template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {};
54template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {};
55#endif
56
57#ifndef _LIBCPP_CXX03_LANG
58
59template <class ..._Tp>
60struct _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> >
61 : public integral_constant<size_t, sizeof...(_Tp)>
62{
63};
64
65template <class ..._Tp>
66struct _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> >
67 : public integral_constant<size_t, sizeof...(_Tp)>
68{
69};
70
71#endif // _LIBCPP_CXX03_LANG
72
73_LIBCPP_END_NAMESPACE_STD
74
75#endif // _LIBCPP___TUPLE_TUPLE_SIZE_H
lib/libcxx/include/__tuple/tuple_types.h created+24
......@@ -0,0 +1,24 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_TUPLE_TYPES_H
10#define _LIBCPP___TUPLE_TUPLE_TYPES_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15# pragma GCC system_header
16#endif
17
18_LIBCPP_BEGIN_NAMESPACE_STD
19
20template <class ..._Tp> struct __tuple_types {};
21
22_LIBCPP_END_NAMESPACE_STD
23
24#endif // _LIBCPP___TUPLE_TUPLE_TYPES_H
lib/libcxx/include/__tuple_dir/apply_cv.h deleted-70
......@@ -1,70 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_APPLY_CV_H
10#define _LIBCPP___TUPLE_APPLY_CV_H
11
12#include <__config>
13#include <__type_traits/is_const.h>
14#include <__type_traits/is_reference.h>
15#include <__type_traits/is_volatile.h>
16#include <__type_traits/remove_reference.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19# pragma GCC system_header
20#endif
21
22#ifndef _LIBCPP_CXX03_LANG
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <bool _ApplyLV, bool _ApplyConst, bool _ApplyVolatile>
27struct __apply_cv_mf;
28template <>
29struct __apply_cv_mf<false, false, false> {
30 template <class _Tp> using __apply = _Tp;
31};
32template <>
33struct __apply_cv_mf<false, true, false> {
34 template <class _Tp> using __apply _LIBCPP_NODEBUG = const _Tp;
35};
36template <>
37struct __apply_cv_mf<false, false, true> {
38 template <class _Tp> using __apply _LIBCPP_NODEBUG = volatile _Tp;
39};
40template <>
41struct __apply_cv_mf<false, true, true> {
42 template <class _Tp> using __apply _LIBCPP_NODEBUG = const volatile _Tp;
43};
44template <>
45struct __apply_cv_mf<true, false, false> {
46 template <class _Tp> using __apply _LIBCPP_NODEBUG = _Tp&;
47};
48template <>
49struct __apply_cv_mf<true, true, false> {
50 template <class _Tp> using __apply _LIBCPP_NODEBUG = const _Tp&;
51};
52template <>
53struct __apply_cv_mf<true, false, true> {
54 template <class _Tp> using __apply _LIBCPP_NODEBUG = volatile _Tp&;
55};
56template <>
57struct __apply_cv_mf<true, true, true> {
58 template <class _Tp> using __apply _LIBCPP_NODEBUG = const volatile _Tp&;
59};
60template <class _Tp, class _RawTp = __libcpp_remove_reference_t<_Tp> >
61using __apply_cv_t _LIBCPP_NODEBUG = __apply_cv_mf<
62 is_lvalue_reference<_Tp>::value,
63 is_const<_RawTp>::value,
64 is_volatile<_RawTp>::value>;
65
66_LIBCPP_END_NAMESPACE_STD
67
68#endif // _LIBCPP_CXX03_LANG
69
70#endif // _LIBCPP___TUPLE_APPLY_CV_H
lib/libcxx/include/__tuple_dir/make_tuple_types.h deleted-84
......@@ -1,84 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_MAKE_TUPLE_TYPES_H
10#define _LIBCPP___TUPLE_MAKE_TUPLE_TYPES_H
11
12#include <__config>
13#include <__fwd/array.h>
14#include <__fwd/tuple.h>
15#include <__tuple_dir/apply_cv.h>
16#include <__tuple_dir/tuple_element.h>
17#include <__tuple_dir/tuple_indices.h>
18#include <__tuple_dir/tuple_size.h>
19#include <__tuple_dir/tuple_types.h>
20#include <__type_traits/remove_cv.h>
21#include <__type_traits/remove_reference.h>
22#include <cstddef>
23
24#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25# pragma GCC system_header
26#endif
27
28#ifndef _LIBCPP_CXX03_LANG
29
30_LIBCPP_BEGIN_NAMESPACE_STD
31
32// __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a
33// __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep).
34// _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>. If _Tuple is a
35// lvalue_reference type, then __tuple_types<_Types&...> is the result.
36
37template <class _TupleTypes, class _TupleIndices>
38struct __make_tuple_types_flat;
39
40template <template <class...> class _Tuple, class ..._Types, size_t ..._Idx>
41struct __make_tuple_types_flat<_Tuple<_Types...>, __tuple_indices<_Idx...>> {
42 // Specialization for pair, tuple, and __tuple_types
43 template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>>
44 using __apply_quals _LIBCPP_NODEBUG = __tuple_types<
45 typename _ApplyFn::template __apply<__type_pack_element<_Idx, _Types...>>...
46 >;
47};
48
49template <class _Vt, size_t _Np, size_t ..._Idx>
50struct __make_tuple_types_flat<array<_Vt, _Np>, __tuple_indices<_Idx...>> {
51 template <size_t>
52 using __value_type = _Vt;
53 template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>>
54 using __apply_quals = __tuple_types<
55 typename _ApplyFn::template __apply<__value_type<_Idx>>...
56 >;
57};
58
59template <class _Tp, size_t _Ep = tuple_size<__libcpp_remove_reference_t<_Tp> >::value,
60 size_t _Sp = 0,
61 bool _SameSize = (_Ep == tuple_size<__libcpp_remove_reference_t<_Tp> >::value)>
62struct __make_tuple_types
63{
64 static_assert(_Sp <= _Ep, "__make_tuple_types input error");
65 using _RawTp = __remove_cv_t<__libcpp_remove_reference_t<_Tp> >;
66 using _Maker = __make_tuple_types_flat<_RawTp, typename __make_tuple_indices<_Ep, _Sp>::type>;
67 using type = typename _Maker::template __apply_quals<_Tp>;
68};
69
70template <class ..._Types, size_t _Ep>
71struct __make_tuple_types<tuple<_Types...>, _Ep, 0, true> {
72 typedef _LIBCPP_NODEBUG __tuple_types<_Types...> type;
73};
74
75template <class ..._Types, size_t _Ep>
76struct __make_tuple_types<__tuple_types<_Types...>, _Ep, 0, true> {
77 typedef _LIBCPP_NODEBUG __tuple_types<_Types...> type;
78};
79
80_LIBCPP_END_NAMESPACE_STD
81
82#endif // _LIBCPP_CXX03_LANG
83
84#endif // _LIBCPP___TUPLE_MAKE_TUPLE_TYPES_H
lib/libcxx/include/__tuple_dir/pair_like.h deleted-32
......@@ -1,32 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_PAIR_LIKE_H
10#define _LIBCPP___TUPLE_PAIR_LIKE_H
11
12#include <__config>
13#include <__tuple_dir/tuple_like.h>
14#include <__tuple_dir/tuple_size.h>
15#include <__type_traits/remove_cvref.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18# pragma GCC system_header
19#endif
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23#if _LIBCPP_STD_VER >= 20
24
25template <class _Tp>
26concept __pair_like = __tuple_like<_Tp> && tuple_size<remove_cvref_t<_Tp>>::value == 2;
27
28#endif // _LIBCPP_STD_VER >= 20
29
30_LIBCPP_END_NAMESPACE_STD
31
32#endif // _LIBCPP___TUPLE_PAIR_LIKE_H
lib/libcxx/include/__tuple_dir/sfinae_helpers.h deleted-196
......@@ -1,196 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_SFINAE_HELPERS_H
10#define _LIBCPP___TUPLE_SFINAE_HELPERS_H
11
12#include <__config>
13#include <__fwd/tuple.h>
14#include <__tuple_dir/make_tuple_types.h>
15#include <__tuple_dir/tuple_element.h>
16#include <__tuple_dir/tuple_like_ext.h>
17#include <__tuple_dir/tuple_size.h>
18#include <__tuple_dir/tuple_types.h>
19#include <__type_traits/enable_if.h>
20#include <__type_traits/integral_constant.h>
21#include <__type_traits/is_assignable.h>
22#include <__type_traits/is_constructible.h>
23#include <__type_traits/is_convertible.h>
24#include <__type_traits/is_same.h>
25#include <__type_traits/remove_cvref.h>
26#include <__type_traits/remove_reference.h>
27#include <cstddef>
28
29#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
30# pragma GCC system_header
31#endif
32
33_LIBCPP_BEGIN_NAMESPACE_STD
34
35#ifndef _LIBCPP_CXX03_LANG
36
37template <bool ..._Preds>
38struct __all_dummy;
39
40template <bool ..._Pred>
41struct __all : _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>> {};
42
43struct __tuple_sfinae_base {
44 template <template <class, class...> class _Trait,
45 class ..._LArgs, class ..._RArgs>
46 static auto __do_test(__tuple_types<_LArgs...>, __tuple_types<_RArgs...>)
47 -> __all<__enable_if_t<_Trait<_LArgs, _RArgs>::value, bool>{true}...>;
48 template <template <class...> class>
49 static auto __do_test(...) -> false_type;
50
51 template <class _FromArgs, class _ToArgs>
52 using __constructible = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{}));
53 template <class _FromArgs, class _ToArgs>
54 using __convertible = decltype(__do_test<is_convertible>(_FromArgs{}, _ToArgs{}));
55 template <class _FromArgs, class _ToArgs>
56 using __assignable = decltype(__do_test<is_assignable>(_ToArgs{}, _FromArgs{}));
57};
58
59// __tuple_convertible
60
61template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
62 bool = __tuple_like_ext<_Up>::value>
63struct __tuple_convertible
64 : public false_type {};
65
66template <class _Tp, class _Up>
67struct __tuple_convertible<_Tp, _Up, true, true>
68 : public __tuple_sfinae_base::__convertible<
69 typename __make_tuple_types<_Tp>::type
70 , typename __make_tuple_types<_Up>::type
71 >
72{};
73
74// __tuple_constructible
75
76template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
77 bool = __tuple_like_ext<_Up>::value>
78struct __tuple_constructible
79 : public false_type {};
80
81template <class _Tp, class _Up>
82struct __tuple_constructible<_Tp, _Up, true, true>
83 : public __tuple_sfinae_base::__constructible<
84 typename __make_tuple_types<_Tp>::type
85 , typename __make_tuple_types<_Up>::type
86 >
87{};
88
89// __tuple_assignable
90
91template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
92 bool = __tuple_like_ext<_Up>::value>
93struct __tuple_assignable
94 : public false_type {};
95
96template <class _Tp, class _Up>
97struct __tuple_assignable<_Tp, _Up, true, true>
98 : public __tuple_sfinae_base::__assignable<
99 typename __make_tuple_types<_Tp>::type
100 , typename __make_tuple_types<_Up&>::type
101 >
102{};
103
104
105template <size_t _Ip, class ..._Tp>
106struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, tuple<_Tp...> >
107{
108 typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
109};
110
111template <bool _IsTuple, class _SizeTrait, size_t _Expected>
112struct __tuple_like_with_size_imp : false_type {};
113
114template <class _SizeTrait, size_t _Expected>
115struct __tuple_like_with_size_imp<true, _SizeTrait, _Expected>
116 : integral_constant<bool, _SizeTrait::value == _Expected> {};
117
118template <class _Tuple, size_t _ExpectedSize, class _RawTuple = __libcpp_remove_reference_t<_Tuple> >
119using __tuple_like_with_size _LIBCPP_NODEBUG = __tuple_like_with_size_imp<
120 __tuple_like_ext<_RawTuple>::value,
121 tuple_size<_RawTuple>, _ExpectedSize
122 >;
123
124struct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail {
125
126 static constexpr bool __enable_explicit_default() { return false; }
127 static constexpr bool __enable_implicit_default() { return false; }
128 template <class ...>
129 static constexpr bool __enable_explicit() { return false; }
130 template <class ...>
131 static constexpr bool __enable_implicit() { return false; }
132 template <class ...>
133 static constexpr bool __enable_assign() { return false; }
134};
135#endif // !defined(_LIBCPP_CXX03_LANG)
136
137#if _LIBCPP_STD_VER > 14
138
139template <bool _CanCopy, bool _CanMove>
140struct __sfinae_ctor_base {};
141template <>
142struct __sfinae_ctor_base<false, false> {
143 __sfinae_ctor_base() = default;
144 __sfinae_ctor_base(__sfinae_ctor_base const&) = delete;
145 __sfinae_ctor_base(__sfinae_ctor_base &&) = delete;
146 __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
147 __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
148};
149template <>
150struct __sfinae_ctor_base<true, false> {
151 __sfinae_ctor_base() = default;
152 __sfinae_ctor_base(__sfinae_ctor_base const&) = default;
153 __sfinae_ctor_base(__sfinae_ctor_base &&) = delete;
154 __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
155 __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
156};
157template <>
158struct __sfinae_ctor_base<false, true> {
159 __sfinae_ctor_base() = default;
160 __sfinae_ctor_base(__sfinae_ctor_base const&) = delete;
161 __sfinae_ctor_base(__sfinae_ctor_base &&) = default;
162 __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
163 __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
164};
165
166template <bool _CanCopy, bool _CanMove>
167struct __sfinae_assign_base {};
168template <>
169struct __sfinae_assign_base<false, false> {
170 __sfinae_assign_base() = default;
171 __sfinae_assign_base(__sfinae_assign_base const&) = default;
172 __sfinae_assign_base(__sfinae_assign_base &&) = default;
173 __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
174 __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete;
175};
176template <>
177struct __sfinae_assign_base<true, false> {
178 __sfinae_assign_base() = default;
179 __sfinae_assign_base(__sfinae_assign_base const&) = default;
180 __sfinae_assign_base(__sfinae_assign_base &&) = default;
181 __sfinae_assign_base& operator=(__sfinae_assign_base const&) = default;
182 __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete;
183};
184template <>
185struct __sfinae_assign_base<false, true> {
186 __sfinae_assign_base() = default;
187 __sfinae_assign_base(__sfinae_assign_base const&) = default;
188 __sfinae_assign_base(__sfinae_assign_base &&) = default;
189 __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
190 __sfinae_assign_base& operator=(__sfinae_assign_base&&) = default;
191};
192#endif // _LIBCPP_STD_VER > 14
193
194_LIBCPP_END_NAMESPACE_STD
195
196#endif // _LIBCPP___TUPLE_SFINAE_HELPERS_H
lib/libcxx/include/__tuple_dir/tuple_element.h deleted-93
......@@ -1,93 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_TUPLE_ELEMENT_H
10#define _LIBCPP___TUPLE_TUPLE_ELEMENT_H
11
12#include <__config>
13#include <__tuple_dir/tuple_indices.h>
14#include <__tuple_dir/tuple_types.h>
15#include <__type_traits/add_const.h>
16#include <__type_traits/add_cv.h>
17#include <__type_traits/add_volatile.h>
18#include <cstddef>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21# pragma GCC system_header
22#endif
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <size_t _Ip, class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_element;
27
28template <size_t _Ip, class _Tp>
29struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const _Tp>
30{
31 typedef _LIBCPP_NODEBUG typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type;
32};
33
34template <size_t _Ip, class _Tp>
35struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, volatile _Tp>
36{
37 typedef _LIBCPP_NODEBUG typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type;
38};
39
40template <size_t _Ip, class _Tp>
41struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp>
42{
43 typedef _LIBCPP_NODEBUG typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type;
44};
45
46#ifndef _LIBCPP_CXX03_LANG
47
48#if !__has_builtin(__type_pack_element)
49
50namespace __indexer_detail {
51
52template <size_t _Idx, class _Tp>
53struct __indexed { using type _LIBCPP_NODEBUG = _Tp; };
54
55template <class _Types, class _Indexes> struct __indexer;
56
57template <class ..._Types, size_t ..._Idx>
58struct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>>
59 : __indexed<_Idx, _Types>...
60{};
61
62template <size_t _Idx, class _Tp>
63__indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&);
64
65} // namespace __indexer_detail
66
67template <size_t _Idx, class ..._Types>
68using __type_pack_element _LIBCPP_NODEBUG = typename decltype(
69 __indexer_detail::__at_index<_Idx>(
70 __indexer_detail::__indexer<
71 __tuple_types<_Types...>,
72 typename __make_tuple_indices<sizeof...(_Types)>::type
73 >{})
74 )::type;
75#endif
76
77template <size_t _Ip, class ..._Types>
78struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...> >
79{
80 static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range");
81 typedef _LIBCPP_NODEBUG __type_pack_element<_Ip, _Types...> type;
82};
83
84#if _LIBCPP_STD_VER > 11
85template <size_t _Ip, class ..._Tp>
86using tuple_element_t _LIBCPP_NODEBUG = typename tuple_element <_Ip, _Tp...>::type;
87#endif
88
89#endif // _LIBCPP_CXX03_LANG
90
91_LIBCPP_END_NAMESPACE_STD
92
93#endif // _LIBCPP___TUPLE_TUPLE_ELEMENT_H
lib/libcxx/include/__tuple_dir/tuple_indices.h deleted-37
......@@ -1,37 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_MAKE_TUPLE_INDICES_H
10#define _LIBCPP___TUPLE_MAKE_TUPLE_INDICES_H
11
12#include <__config>
13#include <__utility/integer_sequence.h>
14#include <cstddef>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20#ifndef _LIBCPP_CXX03_LANG
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <size_t...> struct __tuple_indices {};
25
26template <size_t _Ep, size_t _Sp = 0>
27struct __make_tuple_indices
28{
29 static_assert(_Sp <= _Ep, "__make_tuple_indices input error");
30 typedef __make_indices_imp<_Ep, _Sp> type;
31};
32
33_LIBCPP_END_NAMESPACE_STD
34
35#endif // _LIBCPP_CXX03_LANG
36
37#endif // _LIBCPP___TUPLE_MAKE_TUPLE_INDICES_H
lib/libcxx/include/__tuple_dir/tuple_like.h deleted-51
......@@ -1,51 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_TUPLE_LIKE_H
10#define _LIBCPP___TUPLE_TUPLE_LIKE_H
11
12#include <__config>
13#include <__fwd/array.h>
14#include <__fwd/pair.h>
15#include <__fwd/subrange.h>
16#include <__fwd/tuple.h>
17#include <__type_traits/integral_constant.h>
18#include <__type_traits/remove_cvref.h>
19#include <cstddef>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22# pragma GCC system_header
23#endif
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27#if _LIBCPP_STD_VER >= 20
28
29template <class _Tp>
30struct __tuple_like_impl : false_type {};
31
32template <class... _Tp>
33struct __tuple_like_impl<tuple<_Tp...> > : true_type {};
34
35template <class _T1, class _T2>
36struct __tuple_like_impl<pair<_T1, _T2> > : true_type {};
37
38template <class _Tp, size_t _Size>
39struct __tuple_like_impl<array<_Tp, _Size> > : true_type {};
40
41template <class _Ip, class _Sp, ranges::subrange_kind _Kp>
42struct __tuple_like_impl<ranges::subrange<_Ip, _Sp, _Kp> > : true_type {};
43
44template <class _Tp>
45concept __tuple_like = __tuple_like_impl<remove_cvref_t<_Tp>>::value;
46
47#endif // _LIBCPP_STD_VER >= 20
48
49_LIBCPP_END_NAMESPACE_STD
50
51#endif // _LIBCPP___TUPLE_TUPLE_LIKE_H
lib/libcxx/include/__tuple_dir/tuple_like_ext.h deleted-44
......@@ -1,44 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H
10#define _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H
11
12#include <__config>
13#include <__fwd/array.h>
14#include <__fwd/pair.h>
15#include <__fwd/tuple.h>
16#include <__tuple_dir/tuple_types.h>
17#include <__type_traits/integral_constant.h>
18#include <cstddef>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21# pragma GCC system_header
22#endif
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _Tp> struct __tuple_like_ext : false_type {};
27
28template <class _Tp> struct __tuple_like_ext<const _Tp> : public __tuple_like_ext<_Tp> {};
29template <class _Tp> struct __tuple_like_ext<volatile _Tp> : public __tuple_like_ext<_Tp> {};
30template <class _Tp> struct __tuple_like_ext<const volatile _Tp> : public __tuple_like_ext<_Tp> {};
31
32#ifndef _LIBCPP_CXX03_LANG
33template <class... _Tp> struct __tuple_like_ext<tuple<_Tp...> > : true_type {};
34#endif
35
36template <class _T1, class _T2> struct __tuple_like_ext<pair<_T1, _T2> > : true_type {};
37
38template <class _Tp, size_t _Size> struct __tuple_like_ext<array<_Tp, _Size> > : true_type {};
39
40template <class... _Tp> struct __tuple_like_ext<__tuple_types<_Tp...> > : true_type {};
41
42_LIBCPP_END_NAMESPACE_STD
43
44#endif // _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H
lib/libcxx/include/__tuple_dir/tuple_size.h deleted-75
......@@ -1,75 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_TUPLE_SIZE_H
10#define _LIBCPP___TUPLE_TUPLE_SIZE_H
11
12#include <__config>
13#include <__fwd/tuple.h>
14#include <__tuple_dir/tuple_types.h>
15#include <__type_traits/is_const.h>
16#include <__type_traits/is_volatile.h>
17#include <cstddef>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size;
26
27#if !defined(_LIBCPP_CXX03_LANG)
28template <class _Tp, class...>
29using __enable_if_tuple_size_imp = _Tp;
30
31template <class _Tp>
32struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
33 const _Tp,
34 __enable_if_t<!is_volatile<_Tp>::value>,
35 integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
36 : public integral_constant<size_t, tuple_size<_Tp>::value> {};
37
38template <class _Tp>
39struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
40 volatile _Tp,
41 __enable_if_t<!is_const<_Tp>::value>,
42 integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
43 : public integral_constant<size_t, tuple_size<_Tp>::value> {};
44
45template <class _Tp>
46struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
47 const volatile _Tp,
48 integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
49 : public integral_constant<size_t, tuple_size<_Tp>::value> {};
50
51#else
52template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {};
53template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {};
54template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {};
55#endif
56
57#ifndef _LIBCPP_CXX03_LANG
58
59template <class ..._Tp>
60struct _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> >
61 : public integral_constant<size_t, sizeof...(_Tp)>
62{
63};
64
65template <class ..._Tp>
66struct _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> >
67 : public integral_constant<size_t, sizeof...(_Tp)>
68{
69};
70
71#endif // _LIBCPP_CXX03_LANG
72
73_LIBCPP_END_NAMESPACE_STD
74
75#endif // _LIBCPP___TUPLE_TUPLE_SIZE_H
lib/libcxx/include/__tuple_dir/tuple_types.h deleted-24
......@@ -1,24 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TUPLE_TUPLE_TYPES_H
10#define _LIBCPP___TUPLE_TUPLE_TYPES_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15# pragma GCC system_header
16#endif
17
18_LIBCPP_BEGIN_NAMESPACE_STD
19
20template <class ..._Tp> struct __tuple_types {};
21
22_LIBCPP_END_NAMESPACE_STD
23
24#endif // _LIBCPP___TUPLE_TUPLE_TYPES_H
lib/libcxx/include/__type_traits/add_const.h+5-3
......@@ -17,12 +17,14 @@
1717
1818_LIBCPP_BEGIN_NAMESPACE_STD
1919
20template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_const {
20template <class _Tp>
21struct _LIBCPP_TEMPLATE_VIS add_const {
2122 typedef _LIBCPP_NODEBUG const _Tp type;
2223};
2324
24#if _LIBCPP_STD_VER > 11
25template <class _Tp> using add_const_t = typename add_const<_Tp>::type;
25#if _LIBCPP_STD_VER >= 14
26template <class _Tp>
27using add_const_t = typename add_const<_Tp>::type;
2628#endif
2729
2830_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/add_cv.h+5-3
......@@ -17,12 +17,14 @@
1717
1818_LIBCPP_BEGIN_NAMESPACE_STD
1919
20template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_cv {
20template <class _Tp>
21struct _LIBCPP_TEMPLATE_VIS add_cv {
2122 typedef _LIBCPP_NODEBUG const volatile _Tp type;
2223};
2324
24#if _LIBCPP_STD_VER > 11
25template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type;
25#if _LIBCPP_STD_VER >= 14
26template <class _Tp>
27using add_cv_t = typename add_cv<_Tp>::type;
2628#endif
2729
2830_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/add_lvalue_reference.h+3-2
......@@ -44,8 +44,9 @@ struct add_lvalue_reference {
4444 using type _LIBCPP_NODEBUG = __add_lvalue_reference_t<_Tp>;
4545};
4646
47#if _LIBCPP_STD_VER > 11
48template <class _Tp> using add_lvalue_reference_t = __add_lvalue_reference_t<_Tp>;
47#if _LIBCPP_STD_VER >= 14
48template <class _Tp>
49using add_lvalue_reference_t = __add_lvalue_reference_t<_Tp>;
4950#endif
5051
5152_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/add_pointer.h+8-6
......@@ -28,13 +28,14 @@ template <class _Tp>
2828using __add_pointer_t = __add_pointer(_Tp);
2929
3030#else
31template <class _Tp,
32 bool = __libcpp_is_referenceable<_Tp>::value || is_void<_Tp>::value>
31template <class _Tp, bool = __libcpp_is_referenceable<_Tp>::value || is_void<_Tp>::value>
3332struct __add_pointer_impl {
3433 typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tp>* type;
3534};
36template <class _Tp> struct __add_pointer_impl<_Tp, false>
37 {typedef _LIBCPP_NODEBUG _Tp type;};
35template <class _Tp>
36struct __add_pointer_impl<_Tp, false> {
37 typedef _LIBCPP_NODEBUG _Tp type;
38};
3839
3940template <class _Tp>
4041using __add_pointer_t = typename __add_pointer_impl<_Tp>::type;
......@@ -46,8 +47,9 @@ struct add_pointer {
4647 using type _LIBCPP_NODEBUG = __add_pointer_t<_Tp>;
4748};
4849
49#if _LIBCPP_STD_VER > 11
50template <class _Tp> using add_pointer_t = __add_pointer_t<_Tp>;
50#if _LIBCPP_STD_VER >= 14
51template <class _Tp>
52using add_pointer_t = __add_pointer_t<_Tp>;
5153#endif
5254
5355_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/add_rvalue_reference.h+1-1
......@@ -44,7 +44,7 @@ struct add_rvalue_reference {
4444 using type = __add_rvalue_reference_t<_Tp>;
4545};
4646
47#if _LIBCPP_STD_VER > 11
47#if _LIBCPP_STD_VER >= 14
4848template <class _Tp>
4949using add_rvalue_reference_t = __add_rvalue_reference_t<_Tp>;
5050#endif
lib/libcxx/include/__type_traits/add_volatile.h+5-3
......@@ -17,12 +17,14 @@
1717
1818_LIBCPP_BEGIN_NAMESPACE_STD
1919
20template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_volatile {
20template <class _Tp>
21struct _LIBCPP_TEMPLATE_VIS add_volatile {
2122 typedef _LIBCPP_NODEBUG volatile _Tp type;
2223};
2324
24#if _LIBCPP_STD_VER > 11
25template <class _Tp> using add_volatile_t = typename add_volatile<_Tp>::type;
25#if _LIBCPP_STD_VER >= 14
26template <class _Tp>
27using add_volatile_t = typename add_volatile<_Tp>::type;
2628#endif
2729
2830_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/aligned_storage.h+54-54
......@@ -23,59 +23,63 @@
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
2525template <class _Tp>
26struct __align_type
27{
28 static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp);
29 typedef _Tp type;
26struct __align_type {
27 static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp);
28 typedef _Tp type;
3029};
3130
32struct __struct_double {long double __lx;};
33struct __struct_double4 {double __lx[4];};
34
35typedef
36 __type_list<__align_type<unsigned char>,
37 __type_list<__align_type<unsigned short>,
38 __type_list<__align_type<unsigned int>,
39 __type_list<__align_type<unsigned long>,
40 __type_list<__align_type<unsigned long long>,
41 __type_list<__align_type<double>,
42 __type_list<__align_type<long double>,
43 __type_list<__align_type<__struct_double>,
44 __type_list<__align_type<__struct_double4>,
45 __type_list<__align_type<int*>,
46 __nat
47 > > > > > > > > > > __all_types;
31struct __struct_double {
32 long double __lx;
33};
34struct __struct_double4 {
35 double __lx[4];
36};
37
38// clang-format off
39typedef __type_list<__align_type<unsigned char>,
40 __type_list<__align_type<unsigned short>,
41 __type_list<__align_type<unsigned int>,
42 __type_list<__align_type<unsigned long>,
43 __type_list<__align_type<unsigned long long>,
44 __type_list<__align_type<double>,
45 __type_list<__align_type<long double>,
46 __type_list<__align_type<__struct_double>,
47 __type_list<__align_type<__struct_double4>,
48 __type_list<__align_type<int*>,
49 __nat
50 > > > > > > > > > > __all_types;
51// clang-format on
4852
4953template <size_t _Align>
5054struct _ALIGNAS(_Align) __fallback_overaligned {};
5155
52template <class _TL, size_t _Align> struct __find_pod;
56template <class _TL, size_t _Align>
57struct __find_pod;
5358
5459template <class _Hp, size_t _Align>
55struct __find_pod<__type_list<_Hp, __nat>, _Align>
56{
57 typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, __fallback_overaligned<_Align> > type;
60struct __find_pod<__type_list<_Hp, __nat>, _Align> {
61 typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, __fallback_overaligned<_Align> > type;
5862};
5963
6064template <class _Hp, class _Tp, size_t _Align>
61struct __find_pod<__type_list<_Hp, _Tp>, _Align>
62{
63 typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, typename __find_pod<_Tp, _Align>::type> type;
65struct __find_pod<__type_list<_Hp, _Tp>, _Align> {
66 typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, typename __find_pod<_Tp, _Align>::type> type;
6467};
6568
66template <class _TL, size_t _Len> struct __find_max_align;
69template <class _TL, size_t _Len>
70struct __find_max_align;
6771
6872template <class _Hp, size_t _Len>
6973struct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant<size_t, _Hp::value> {};
7074
7175template <size_t _Len, size_t _A1, size_t _A2>
72struct __select_align
73{
76struct __select_align {
7477private:
75 static const size_t __min = _A2 < _A1 ? _A2 : _A1;
76 static const size_t __max = _A1 < _A2 ? _A2 : _A1;
78 static const size_t __min = _A2 < _A1 ? _A2 : _A1;
79 static const size_t __max = _A1 < _A2 ? _A2 : _A1;
80
7781public:
78 static const size_t value = _Len < __max ? __min : __max;
82 static const size_t value = _Len < __max ? __min : __max;
7983};
8084
8185template <class _Hp, class _Tp, size_t _Len>
......@@ -83,34 +87,30 @@ struct __find_max_align<__type_list<_Hp, _Tp>, _Len>
8387 : public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {};
8488
8589template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
86struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage
87{
88 typedef typename __find_pod<__all_types, _Align>::type _Aligner;
89 union type
90 {
91 _Aligner __align;
92 unsigned char __data[(_Len + _Align - 1)/_Align * _Align];
93 };
90struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage {
91 typedef typename __find_pod<__all_types, _Align>::type _Aligner;
92 union type {
93 _Aligner __align;
94 unsigned char __data[(_Len + _Align - 1) / _Align * _Align];
95 };
9496};
9597
96#if _LIBCPP_STD_VER > 11
98#if _LIBCPP_STD_VER >= 14
9799
98 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
100_LIBCPP_SUPPRESS_DEPRECATED_PUSH
99101template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
100 using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type;
101 _LIBCPP_SUPPRESS_DEPRECATED_POP
102using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type;
103_LIBCPP_SUPPRESS_DEPRECATED_POP
102104
103105#endif
104106
105#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \
106template <size_t _Len>\
107struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n>\
108{\
109 struct _ALIGNAS(n) type\
110 {\
111 unsigned char __lx[(_Len + n - 1)/n * n];\
112 };\
113}
107#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \
108 template <size_t _Len> \
109 struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n> { \
110 struct _ALIGNAS(n) type { \
111 unsigned char __lx[(_Len + n - 1) / n * n]; \
112 }; \
113 }
114114
115115_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1);
116116_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2);
lib/libcxx/include/__type_traits/aligned_union.h+13-18
......@@ -20,33 +20,28 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23template <size_t _I0, size_t ..._In>
23template <size_t _I0, size_t... _In>
2424struct __static_max;
2525
2626template <size_t _I0>
27struct __static_max<_I0>
28{
29 static const size_t value = _I0;
27struct __static_max<_I0> {
28 static const size_t value = _I0;
3029};
3130
32template <size_t _I0, size_t _I1, size_t ..._In>
33struct __static_max<_I0, _I1, _In...>
34{
35 static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value :
36 __static_max<_I1, _In...>::value;
31template <size_t _I0, size_t _I1, size_t... _In>
32struct __static_max<_I0, _I1, _In...> {
33 static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value : __static_max<_I1, _In...>::value;
3734};
3835
39template <size_t _Len, class _Type0, class ..._Types>
40struct _LIBCPP_DEPRECATED_IN_CXX23 aligned_union
41{
42 static const size_t alignment_value = __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0),
43 _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value;
44 static const size_t __len = __static_max<_Len, sizeof(_Type0),
45 sizeof(_Types)...>::value;
46 typedef typename aligned_storage<__len, alignment_value>::type type;
36template <size_t _Len, class _Type0, class... _Types>
37struct _LIBCPP_DEPRECATED_IN_CXX23 aligned_union {
38 static const size_t alignment_value =
39 __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0), _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value;
40 static const size_t __len = __static_max<_Len, sizeof(_Type0), sizeof(_Types)...>::value;
41 typedef typename aligned_storage<__len, alignment_value>::type type;
4742};
4843
49#if _LIBCPP_STD_VER > 11
44#if _LIBCPP_STD_VER >= 14
5045template <size_t _Len, class... _Types>
5146using aligned_union_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_union<_Len, _Types...>::type;
5247#endif
lib/libcxx/include/__type_traits/alignment_of.h+3-3
......@@ -19,10 +19,10 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22template <class _Tp> struct _LIBCPP_TEMPLATE_VIS alignment_of
23 : public integral_constant<size_t, _LIBCPP_ALIGNOF(_Tp)> {};
22template <class _Tp>
23struct _LIBCPP_TEMPLATE_VIS alignment_of : public integral_constant<size_t, _LIBCPP_ALIGNOF(_Tp)> {};
2424
25#if _LIBCPP_STD_VER > 14
25#if _LIBCPP_STD_VER >= 17
2626template <class _Tp>
2727inline constexpr size_t alignment_of_v = _LIBCPP_ALIGNOF(_Tp);
2828#endif
lib/libcxx/include/__type_traits/apply_cv.h+37-34
......@@ -13,7 +13,6 @@
1313#include <__type_traits/is_const.h>
1414#include <__type_traits/is_volatile.h>
1515#include <__type_traits/remove_reference.h>
16#include <cstddef>
1716
1817#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1918# pragma GCC system_header
......@@ -21,55 +20,59 @@
2120
2221_LIBCPP_BEGIN_NAMESPACE_STD
2322
24template <class _Tp, class _Up, bool = is_const<__libcpp_remove_reference_t<_Tp> >::value,
25 bool = is_volatile<__libcpp_remove_reference_t<_Tp> >::value>
26struct __apply_cv
27{
28 typedef _LIBCPP_NODEBUG _Up type;
23template <class _Tp,
24 bool = is_const<__libcpp_remove_reference_t<_Tp> >::value,
25 bool = is_volatile<__libcpp_remove_reference_t<_Tp> >::value>
26struct __apply_cv_impl {
27 template <class _Up>
28 using __apply _LIBCPP_NODEBUG = _Up;
2929};
3030
31template <class _Tp, class _Up>
32struct __apply_cv<_Tp, _Up, true, false>
33{
34 typedef _LIBCPP_NODEBUG const _Up type;
31template <class _Tp>
32struct __apply_cv_impl<_Tp, true, false> {
33 template <class _Up>
34 using __apply _LIBCPP_NODEBUG = const _Up;
3535};
3636
37template <class _Tp, class _Up>
38struct __apply_cv<_Tp, _Up, false, true>
39{
40 typedef volatile _Up type;
37template <class _Tp>
38struct __apply_cv_impl<_Tp, false, true> {
39 template <class _Up>
40 using __apply _LIBCPP_NODEBUG = volatile _Up;
4141};
4242
43template <class _Tp, class _Up>
44struct __apply_cv<_Tp, _Up, true, true>
45{
46 typedef const volatile _Up type;
43template <class _Tp>
44struct __apply_cv_impl<_Tp, true, true> {
45 template <class _Up>
46 using __apply _LIBCPP_NODEBUG = const volatile _Up;
4747};
4848
49template <class _Tp, class _Up>
50struct __apply_cv<_Tp&, _Up, false, false>
51{
52 typedef _Up& type;
49template <class _Tp>
50struct __apply_cv_impl<_Tp&, false, false> {
51 template <class _Up>
52 using __apply _LIBCPP_NODEBUG = _Up&;
5353};
5454
55template <class _Tp, class _Up>
56struct __apply_cv<_Tp&, _Up, true, false>
57{
58 typedef const _Up& type;
55template <class _Tp>
56struct __apply_cv_impl<_Tp&, true, false> {
57 template <class _Up>
58 using __apply _LIBCPP_NODEBUG = const _Up&;
5959};
6060
61template <class _Tp, class _Up>
62struct __apply_cv<_Tp&, _Up, false, true>
63{
64 typedef volatile _Up& type;
61template <class _Tp>
62struct __apply_cv_impl<_Tp&, false, true> {
63 template <class _Up>
64 using __apply _LIBCPP_NODEBUG = volatile _Up&;
6565};
6666
67template <class _Tp, class _Up>
68struct __apply_cv<_Tp&, _Up, true, true>
69{
70 typedef const volatile _Up& type;
67template <class _Tp>
68struct __apply_cv_impl<_Tp&, true, true> {
69 template <class _Up>
70 using __apply _LIBCPP_NODEBUG = const volatile _Up&;
7171};
7272
73template <class _Tp, class _Up>
74using __apply_cv_t _LIBCPP_NODEBUG = typename __apply_cv_impl<_Tp>::template __apply<_Up>;
75
7376_LIBCPP_END_NAMESPACE_STD
7477
7578#endif // _LIBCPP___TYPE_TRAITS_APPLY_CV_H
lib/libcxx/include/__type_traits/can_extract_key.h+3-6
......@@ -40,16 +40,13 @@ struct __can_extract_key<_Pair, _Key, pair<_First, _Second> >
4040// __can_extract_map_key uses true_type/false_type instead of the tags.
4141// It returns true if _Key != _ContainerValueTy (the container is a map not a set)
4242// and _ValTy == _Key.
43template <class _ValTy, class _Key, class _ContainerValueTy,
44 class _RawValTy = __remove_const_ref_t<_ValTy> >
45struct __can_extract_map_key
46 : integral_constant<bool, _IsSame<_RawValTy, _Key>::value> {};
43template <class _ValTy, class _Key, class _ContainerValueTy, class _RawValTy = __remove_const_ref_t<_ValTy> >
44struct __can_extract_map_key : integral_constant<bool, _IsSame<_RawValTy, _Key>::value> {};
4745
4846// This specialization returns __extract_key_fail_tag for non-map containers
4947// because _Key == _ContainerValueTy
5048template <class _ValTy, class _Key, class _RawValTy>
51struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy>
52 : false_type {};
49struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy> : false_type {};
5350
5451_LIBCPP_END_NAMESPACE_STD
5552
lib/libcxx/include/__type_traits/common_reference.h+67-62
......@@ -27,11 +27,10 @@
2727_LIBCPP_BEGIN_NAMESPACE_STD
2828
2929// common_reference
30#if _LIBCPP_STD_VER > 17
30#if _LIBCPP_STD_VER >= 20
3131// Let COND_RES(X, Y) be:
3232template <class _Xp, class _Yp>
33using __cond_res =
34 decltype(false ? std::declval<_Xp(&)()>()() : std::declval<_Yp(&)()>()());
33using __cond_res = decltype(false ? std::declval<_Xp (&)()>()() : std::declval<_Yp (&)()>()());
3534
3635// Let `XREF(A)` denote a unary alias template `T` such that `T<U>` denotes the same type as `U`
3736// with the addition of `A`'s cv and reference qualifiers, for a non-reference cv-unqualified type
......@@ -39,47 +38,49 @@ using __cond_res =
3938// [Note: `XREF(A)` is `__xref<A>::template __apply`]
4039template <class _Tp>
4140struct __xref {
42 template<class _Up>
41 template <class _Up>
4342 using __apply = __copy_cvref_t<_Tp, _Up>;
4443};
4544
4645// Given types A and B, let X be remove_reference_t<A>, let Y be remove_reference_t<B>,
4746// and let COMMON-REF(A, B) be:
48template<class _Ap, class _Bp, class _Xp = remove_reference_t<_Ap>, class _Yp = remove_reference_t<_Bp>>
47template <class _Ap, class _Bp, class _Xp = remove_reference_t<_Ap>, class _Yp = remove_reference_t<_Bp>>
4948struct __common_ref;
5049
51template<class _Xp, class _Yp>
50template <class _Xp, class _Yp>
5251using __common_ref_t = typename __common_ref<_Xp, _Yp>::__type;
5352
54template<class _Xp, class _Yp>
53template <class _Xp, class _Yp>
5554using __cv_cond_res = __cond_res<__copy_cv_t<_Xp, _Yp>&, __copy_cv_t<_Yp, _Xp>&>;
5655
57
5856// If A and B are both lvalue reference types, COMMON-REF(A, B) is
5957// COND-RES(COPYCV(X, Y)&, COPYCV(Y, X)&) if that type exists and is a reference type.
60template<class _Ap, class _Bp, class _Xp, class _Yp>
61requires requires { typename __cv_cond_res<_Xp, _Yp>; } && is_reference_v<__cv_cond_res<_Xp, _Yp>>
62struct __common_ref<_Ap&, _Bp&, _Xp, _Yp>
63{
64 using __type = __cv_cond_res<_Xp, _Yp>;
58// clang-format off
59template <class _Ap, class _Bp, class _Xp, class _Yp>
60 requires
61 requires { typename __cv_cond_res<_Xp, _Yp>; } &&
62 is_reference_v<__cv_cond_res<_Xp, _Yp>>
63struct __common_ref<_Ap&, _Bp&, _Xp, _Yp> {
64 using __type = __cv_cond_res<_Xp, _Yp>;
6565};
66// clang-format on
6667
6768// Otherwise, let C be remove_reference_t<COMMON-REF(X&, Y&)>&&. ...
6869template <class _Xp, class _Yp>
6970using __common_ref_C = remove_reference_t<__common_ref_t<_Xp&, _Yp&>>&&;
7071
71
7272// .... If A and B are both rvalue reference types, C is well-formed, and
7373// is_convertible_v<A, C> && is_convertible_v<B, C> is true, then COMMON-REF(A, B) is C.
74template<class _Ap, class _Bp, class _Xp, class _Yp>
75requires
76 requires { typename __common_ref_C<_Xp, _Yp>; } &&
77 is_convertible_v<_Ap&&, __common_ref_C<_Xp, _Yp>> &&
78 is_convertible_v<_Bp&&, __common_ref_C<_Xp, _Yp>>
79struct __common_ref<_Ap&&, _Bp&&, _Xp, _Yp>
80{
81 using __type = __common_ref_C<_Xp, _Yp>;
74// clang-format off
75template <class _Ap, class _Bp, class _Xp, class _Yp>
76 requires
77 requires { typename __common_ref_C<_Xp, _Yp>; } &&
78 is_convertible_v<_Ap&&, __common_ref_C<_Xp, _Yp>> &&
79 is_convertible_v<_Bp&&, __common_ref_C<_Xp, _Yp>>
80struct __common_ref<_Ap&&, _Bp&&, _Xp, _Yp> {
81 using __type = __common_ref_C<_Xp, _Yp>;
8282};
83// clang-format on
8384
8485// Otherwise, let D be COMMON-REF(const X&, Y&). ...
8586template <class _Tp, class _Up>
......@@ -87,21 +88,23 @@ using __common_ref_D = __common_ref_t<const _Tp&, _Up&>;
8788
8889// ... If A is an rvalue reference and B is an lvalue reference and D is well-formed and
8990// is_convertible_v<A, D> is true, then COMMON-REF(A, B) is D.
90template<class _Ap, class _Bp, class _Xp, class _Yp>
91requires requires { typename __common_ref_D<_Xp, _Yp>; } &&
92 is_convertible_v<_Ap&&, __common_ref_D<_Xp, _Yp>>
93struct __common_ref<_Ap&&, _Bp&, _Xp, _Yp>
94{
95 using __type = __common_ref_D<_Xp, _Yp>;
91// clang-format off
92template <class _Ap, class _Bp, class _Xp, class _Yp>
93 requires
94 requires { typename __common_ref_D<_Xp, _Yp>; } &&
95 is_convertible_v<_Ap&&, __common_ref_D<_Xp, _Yp>>
96struct __common_ref<_Ap&&, _Bp&, _Xp, _Yp> {
97 using __type = __common_ref_D<_Xp, _Yp>;
9698};
99// clang-format on
97100
98101// Otherwise, if A is an lvalue reference and B is an rvalue reference, then
99102// COMMON-REF(A, B) is COMMON-REF(B, A).
100template<class _Ap, class _Bp, class _Xp, class _Yp>
103template <class _Ap, class _Bp, class _Xp, class _Yp>
101104struct __common_ref<_Ap&, _Bp&&, _Xp, _Yp> : __common_ref<_Bp&&, _Ap&> {};
102105
103106// Otherwise, COMMON-REF(A, B) is ill-formed.
104template<class _Ap, class _Bp, class _Xp, class _Yp>
107template <class _Ap, class _Bp, class _Xp, class _Yp>
105108struct __common_ref {};
106109
107110// Note C: For the common_reference trait applied to a parameter pack [...]
......@@ -113,75 +116,77 @@ template <class... _Types>
113116using common_reference_t = typename common_reference<_Types...>::type;
114117
115118// bullet 1 - sizeof...(T) == 0
116template<>
119template <>
117120struct common_reference<> {};
118121
119122// bullet 2 - sizeof...(T) == 1
120123template <class _Tp>
121struct common_reference<_Tp>
122{
123 using type = _Tp;
124struct common_reference<_Tp> {
125 using type = _Tp;
124126};
125127
126128// bullet 3 - sizeof...(T) == 2
127template <class _Tp, class _Up> struct __common_reference_sub_bullet3;
128template <class _Tp, class _Up> struct __common_reference_sub_bullet2 : __common_reference_sub_bullet3<_Tp, _Up> {};
129template <class _Tp, class _Up> struct __common_reference_sub_bullet1 : __common_reference_sub_bullet2<_Tp, _Up> {};
129template <class _Tp, class _Up>
130struct __common_reference_sub_bullet3;
131template <class _Tp, class _Up>
132struct __common_reference_sub_bullet2 : __common_reference_sub_bullet3<_Tp, _Up> {};
133template <class _Tp, class _Up>
134struct __common_reference_sub_bullet1 : __common_reference_sub_bullet2<_Tp, _Up> {};
130135
131136// sub-bullet 1 - If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, then
132137// the member typedef `type` denotes that type.
133template <class _Tp, class _Up> struct common_reference<_Tp, _Up> : __common_reference_sub_bullet1<_Tp, _Up> {};
138template <class _Tp, class _Up>
139struct common_reference<_Tp, _Up> : __common_reference_sub_bullet1<_Tp, _Up> {};
134140
135141template <class _Tp, class _Up>
136requires is_reference_v<_Tp> && is_reference_v<_Up> && requires { typename __common_ref_t<_Tp, _Up>; }
137struct __common_reference_sub_bullet1<_Tp, _Up>
138{
139 using type = __common_ref_t<_Tp, _Up>;
142 requires is_reference_v<_Tp> && is_reference_v<_Up> && requires { typename __common_ref_t<_Tp, _Up>; }
143struct __common_reference_sub_bullet1<_Tp, _Up> {
144 using type = __common_ref_t<_Tp, _Up>;
140145};
141146
142147// sub-bullet 2 - Otherwise, if basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>, XREF(T1), XREF(T2)>::type
143148// is well-formed, then the member typedef `type` denotes that type.
144template <class, class, template <class> class, template <class> class> struct basic_common_reference {};
149template <class, class, template <class> class, template <class> class>
150struct basic_common_reference {};
145151
146152template <class _Tp, class _Up>
147using __basic_common_reference_t = typename basic_common_reference<
148 remove_cvref_t<_Tp>, remove_cvref_t<_Up>,
149 __xref<_Tp>::template __apply, __xref<_Up>::template __apply>::type;
153using __basic_common_reference_t =
154 typename basic_common_reference<remove_cvref_t<_Tp>,
155 remove_cvref_t<_Up>,
156 __xref<_Tp>::template __apply,
157 __xref<_Up>::template __apply>::type;
150158
151159template <class _Tp, class _Up>
152requires requires { typename __basic_common_reference_t<_Tp, _Up>; }
153struct __common_reference_sub_bullet2<_Tp, _Up>
154{
155 using type = __basic_common_reference_t<_Tp, _Up>;
160 requires requires { typename __basic_common_reference_t<_Tp, _Up>; }
161struct __common_reference_sub_bullet2<_Tp, _Up> {
162 using type = __basic_common_reference_t<_Tp, _Up>;
156163};
157164
158165// sub-bullet 3 - Otherwise, if COND-RES(T1, T2) is well-formed,
159166// then the member typedef `type` denotes that type.
160167template <class _Tp, class _Up>
161requires requires { typename __cond_res<_Tp, _Up>; }
162struct __common_reference_sub_bullet3<_Tp, _Up>
163{
164 using type = __cond_res<_Tp, _Up>;
168 requires requires { typename __cond_res<_Tp, _Up>; }
169struct __common_reference_sub_bullet3<_Tp, _Up> {
170 using type = __cond_res<_Tp, _Up>;
165171};
166172
167
168173// sub-bullet 4 & 5 - Otherwise, if common_type_t<T1, T2> is well-formed,
169174// then the member typedef `type` denotes that type.
170175// - Otherwise, there shall be no member `type`.
171template <class _Tp, class _Up> struct __common_reference_sub_bullet3 : common_type<_Tp, _Up> {};
176template <class _Tp, class _Up>
177struct __common_reference_sub_bullet3 : common_type<_Tp, _Up> {};
172178
173179// bullet 4 - If there is such a type `C`, the member typedef type shall denote the same type, if
174180// any, as `common_reference_t<C, Rest...>`.
175181template <class _Tp, class _Up, class _Vp, class... _Rest>
176requires requires { typename common_reference_t<_Tp, _Up>; }
177struct common_reference<_Tp, _Up, _Vp, _Rest...>
178 : common_reference<common_reference_t<_Tp, _Up>, _Vp, _Rest...>
179{};
182 requires requires { typename common_reference_t<_Tp, _Up>; }
183struct common_reference<_Tp, _Up, _Vp, _Rest...> : common_reference<common_reference_t<_Tp, _Up>, _Vp, _Rest...> {};
180184
181185// bullet 5 - Otherwise, there shall be no member `type`.
182template <class...> struct common_reference {};
186template <class...>
187struct common_reference {};
183188
184#endif // _LIBCPP_STD_VER > 17
189#endif // _LIBCPP_STD_VER >= 20
185190
186191_LIBCPP_END_NAMESPACE_STD
187192
lib/libcxx/include/__type_traits/common_type.h+19-51
......@@ -23,7 +23,7 @@
2323
2424_LIBCPP_BEGIN_NAMESPACE_STD
2525
26#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2727// Let COND_RES(X, Y) be:
2828template <class _Tp, class _Up>
2929using __cond_type = decltype(false ? std::declval<_Tp>() : std::declval<_Up>());
......@@ -33,9 +33,8 @@ struct __common_type3 {};
3333
3434// sub-bullet 4 - "if COND_RES(CREF(D1), CREF(D2)) denotes a type..."
3535template <class _Tp, class _Up>
36struct __common_type3<_Tp, _Up, void_t<__cond_type<const _Tp&, const _Up&>>>
37{
38 using type = remove_cvref_t<__cond_type<const _Tp&, const _Up&>>;
36struct __common_type3<_Tp, _Up, void_t<__cond_type<const _Tp&, const _Up&>>> {
37 using type = remove_cvref_t<__cond_type<const _Tp&, const _Up&>>;
3938};
4039
4140template <class _Tp, class _Up, class = void>
......@@ -47,50 +46,26 @@ struct __common_type2_imp {};
4746
4847// sub-bullet 3 - "if decay_t<decltype(false ? declval<D1>() : declval<D2>())> ..."
4948template <class _Tp, class _Up>
50struct __common_type2_imp<_Tp, _Up, __void_t<decltype(true ? std::declval<_Tp>() : std::declval<_Up>())> >
51{
52 typedef _LIBCPP_NODEBUG typename decay<decltype(
53 true ? std::declval<_Tp>() : std::declval<_Up>()
54 )>::type type;
49struct __common_type2_imp<_Tp, _Up, __void_t<decltype(true ? std::declval<_Tp>() : std::declval<_Up>())> > {
50 typedef _LIBCPP_NODEBUG __decay_t<decltype(true ? std::declval<_Tp>() : std::declval<_Up>())> type;
5551};
5652
5753template <class, class = void>
5854struct __common_type_impl {};
5955
60// Clang provides variadic templates in C++03 as an extension.
61#if !defined(_LIBCPP_CXX03_LANG) || defined(__clang__)
62# define _LIBCPP_OPTIONAL_PACK(...) , __VA_ARGS__
6356template <class... _Tp>
6457struct __common_types;
6558template <class... _Tp>
6659struct _LIBCPP_TEMPLATE_VIS common_type;
67#else
68# define _LIBCPP_OPTIONAL_PACK(...)
69struct __no_arg;
70template <class _Tp, class _Up, class = __no_arg>
71struct __common_types;
72template <class _Tp = __no_arg, class _Up = __no_arg, class _Vp = __no_arg,
73 class _Unused = __no_arg>
74struct common_type {
75 static_assert(sizeof(_Unused) == 0,
76 "common_type accepts at most 3 arguments in C++03");
77};
78#endif // _LIBCPP_CXX03_LANG
7960
8061template <class _Tp, class _Up>
81struct __common_type_impl<
82 __common_types<_Tp, _Up>, __void_t<typename common_type<_Tp, _Up>::type> >
83{
62struct __common_type_impl< __common_types<_Tp, _Up>, __void_t<typename common_type<_Tp, _Up>::type> > {
8463 typedef typename common_type<_Tp, _Up>::type type;
8564};
8665
87template <class _Tp, class _Up, class _Vp _LIBCPP_OPTIONAL_PACK(class... _Rest)>
88struct __common_type_impl<
89 __common_types<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)>,
90 __void_t<typename common_type<_Tp, _Up>::type> >
91 : __common_type_impl<__common_types<typename common_type<_Tp, _Up>::type,
92 _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> > {
93};
66template <class _Tp, class _Up, class _Vp, class... _Rest>
67struct __common_type_impl<__common_types<_Tp, _Up, _Vp, _Rest...>, __void_t<typename common_type<_Tp, _Up>::type> >
68 : __common_type_impl<__common_types<typename common_type<_Tp, _Up>::type, _Vp, _Rest...> > {};
9469
9570// bullet 1 - sizeof...(Tp) == 0
9671
......@@ -100,33 +75,26 @@ struct _LIBCPP_TEMPLATE_VIS common_type<> {};
10075// bullet 2 - sizeof...(Tp) == 1
10176
10277template <class _Tp>
103struct _LIBCPP_TEMPLATE_VIS common_type<_Tp>
104 : public common_type<_Tp, _Tp> {};
78struct _LIBCPP_TEMPLATE_VIS common_type<_Tp> : public common_type<_Tp, _Tp> {};
10579
10680// bullet 3 - sizeof...(Tp) == 2
10781
10882// sub-bullet 1 - "If is_same_v<T1, D1> is false or ..."
10983template <class _Tp, class _Up>
11084struct _LIBCPP_TEMPLATE_VIS common_type<_Tp, _Up>
111 : conditional<
112 _IsSame<_Tp, typename decay<_Tp>::type>::value && _IsSame<_Up, typename decay<_Up>::type>::value,
113 __common_type2_imp<_Tp, _Up>,
114 common_type<typename decay<_Tp>::type, typename decay<_Up>::type>
115 >::type
116{};
85 : conditional<_IsSame<_Tp, __decay_t<_Tp> >::value && _IsSame<_Up, __decay_t<_Up> >::value,
86 __common_type2_imp<_Tp, _Up>,
87 common_type<__decay_t<_Tp>, __decay_t<_Up> > >::type {};
11788
11889// bullet 4 - sizeof...(Tp) > 2
11990
120template <class _Tp, class _Up, class _Vp _LIBCPP_OPTIONAL_PACK(class... _Rest)>
121struct _LIBCPP_TEMPLATE_VIS
122 common_type<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)>
123 : __common_type_impl<
124 __common_types<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> > {};
125
126#undef _LIBCPP_OPTIONAL_PACK
91template <class _Tp, class _Up, class _Vp, class... _Rest>
92struct _LIBCPP_TEMPLATE_VIS common_type<_Tp, _Up, _Vp, _Rest...>
93 : __common_type_impl<__common_types<_Tp, _Up, _Vp, _Rest...> > {};
12794
128#if _LIBCPP_STD_VER > 11
129template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type;
95#if _LIBCPP_STD_VER >= 14
96template <class... _Tp>
97using common_type_t = typename common_type<_Tp...>::type;
13098#endif
13199
132100_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/conditional.h+1-1
......@@ -44,7 +44,7 @@ struct _LIBCPP_TEMPLATE_VIS conditional<false, _If, _Then> {
4444 using type _LIBCPP_NODEBUG = _Then;
4545};
4646
47#if _LIBCPP_STD_VER > 11
47#if _LIBCPP_STD_VER >= 14
4848template <bool _Bp, class _IfRes, class _ElseRes>
4949using conditional_t _LIBCPP_NODEBUG = typename conditional<_Bp, _IfRes, _ElseRes>::type;
5050#endif
lib/libcxx/include/__type_traits/conjunction.h+2-2
......@@ -37,7 +37,7 @@ false_type __and_helper(...);
3737template <class... _Pred>
3838using _And _LIBCPP_NODEBUG = decltype(std::__and_helper<_Pred...>(0));
3939
40#if _LIBCPP_STD_VER > 14
40#if _LIBCPP_STD_VER >= 17
4141
4242template <class...>
4343struct conjunction : true_type {};
......@@ -51,7 +51,7 @@ struct conjunction<_Arg, _Args...> : conditional_t<!bool(_Arg::value), _Arg, con
5151template <class... _Args>
5252inline constexpr bool conjunction_v = conjunction<_Args...>::value;
5353
54#endif // _LIBCPP_STD_VER > 14
54#endif // _LIBCPP_STD_VER >= 17
5555
5656_LIBCPP_END_NAMESPACE_STD
5757
lib/libcxx/include/__type_traits/copy_cv.h+8-12
......@@ -23,27 +23,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2323// Let COPYCV(FROM, TO) be an alias for type TO with the addition of FROM's
2424// top-level cv-qualifiers.
2525template <class _From, class _To>
26struct __copy_cv
27{
28 using type = _To;
26struct __copy_cv {
27 using type = _To;
2928};
3029
3130template <class _From, class _To>
32struct __copy_cv<const _From, _To>
33{
34 using type = typename add_const<_To>::type;
31struct __copy_cv<const _From, _To> {
32 using type = typename add_const<_To>::type;
3533};
3634
3735template <class _From, class _To>
38struct __copy_cv<volatile _From, _To>
39{
40 using type = typename add_volatile<_To>::type;
36struct __copy_cv<volatile _From, _To> {
37 using type = typename add_volatile<_To>::type;
4138};
4239
4340template <class _From, class _To>
44struct __copy_cv<const volatile _From, _To>
45{
46 using type = typename add_cv<_To>::type;
41struct __copy_cv<const volatile _From, _To> {
42 using type = typename add_cv<_To>::type;
4743};
4844
4945template <class _From, class _To>
lib/libcxx/include/__type_traits/copy_cvref.h+6-9
......@@ -21,21 +21,18 @@
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
2323template <class _From, class _To>
24struct __copy_cvref
25{
26 using type = __copy_cv_t<_From, _To>;
24struct __copy_cvref {
25 using type = __copy_cv_t<_From, _To>;
2726};
2827
2928template <class _From, class _To>
30struct __copy_cvref<_From&, _To>
31{
32 using type = __add_lvalue_reference_t<__copy_cv_t<_From, _To> >;
29struct __copy_cvref<_From&, _To> {
30 using type = __add_lvalue_reference_t<__copy_cv_t<_From, _To> >;
3331};
3432
3533template <class _From, class _To>
36struct __copy_cvref<_From&&, _To>
37{
38 using type = __add_rvalue_reference_t<__copy_cv_t<_From, _To> >;
34struct __copy_cvref<_From&&, _To> {
35 using type = __add_rvalue_reference_t<__copy_cv_t<_From, _To> >;
3936};
4037
4138template <class _From, class _To>
lib/libcxx/include/__type_traits/datasizeof.h created+55
......@@ -0,0 +1,55 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TYPE_TRAITS_DATASIZEOF_H
10#define _LIBCPP___TYPE_TRAITS_DATASIZEOF_H
11
12#include <__config>
13#include <__type_traits/is_class.h>
14#include <__type_traits/is_final.h>
15#include <cstddef>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18# pragma GCC system_header
19#endif
20
21// This trait provides the size of a type excluding any tail padding.
22//
23// It is useful in contexts where performing an operation using the full size of the class (including padding) may
24// have unintended side effects, such as overwriting a derived class' member when writing the tail padding of a class
25// through a pointer-to-base.
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29template <class _Tp>
30struct __libcpp_datasizeof {
31#if __has_cpp_attribute(__no_unique_address__)
32 template <class = char>
33 struct _FirstPaddingByte {
34 [[__no_unique_address__]] _Tp __v_;
35 char __first_padding_byte_;
36 };
37#else
38 template <bool = __libcpp_is_final<_Tp>::value || !is_class<_Tp>::value>
39 struct _FirstPaddingByte : _Tp {
40 char __first_padding_byte_;
41 };
42
43 template <>
44 struct _FirstPaddingByte<true> {
45 _Tp __v_;
46 char __first_padding_byte_;
47 };
48#endif
49
50 static const size_t value = offsetof(_FirstPaddingByte<>, __first_padding_byte_);
51};
52
53_LIBCPP_END_NAMESPACE_STD
54
55#endif // _LIBCPP___TYPE_TRAITS_DATASIZEOF_H
lib/libcxx/include/__type_traits/decay.h+20-18
......@@ -26,44 +26,46 @@
2626_LIBCPP_BEGIN_NAMESPACE_STD
2727
2828#if __has_builtin(__decay)
29template <class _Tp>
30using __decay_t _LIBCPP_NODEBUG = __decay(_Tp);
31
2932template <class _Tp>
3033struct decay {
31 using type _LIBCPP_NODEBUG = __decay(_Tp);
34 using type _LIBCPP_NODEBUG = __decay_t<_Tp>;
3235};
36
3337#else
3438template <class _Up, bool>
3539struct __decay {
36 typedef _LIBCPP_NODEBUG __remove_cv_t<_Up> type;
40 typedef _LIBCPP_NODEBUG __remove_cv_t<_Up> type;
3741};
3842
3943template <class _Up>
4044struct __decay<_Up, true> {
4145public:
42 typedef _LIBCPP_NODEBUG typename conditional
43 <
44 is_array<_Up>::value,
45 __add_pointer_t<__remove_extent_t<_Up> >,
46 typename conditional
47 <
48 is_function<_Up>::value,
49 typename add_pointer<_Up>::type,
50 __remove_cv_t<_Up>
51 >::type
52 >::type type;
46 typedef _LIBCPP_NODEBUG typename conditional<
47 is_array<_Up>::value,
48 __add_pointer_t<__remove_extent_t<_Up> >,
49 typename conditional<is_function<_Up>::value, typename add_pointer<_Up>::type, __remove_cv_t<_Up> >::type >::type
50 type;
5351};
5452
5553template <class _Tp>
56struct _LIBCPP_TEMPLATE_VIS decay
57{
54struct _LIBCPP_TEMPLATE_VIS decay {
5855private:
59 typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tp> _Up;
56 typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tp> _Up;
57
6058public:
6159 typedef _LIBCPP_NODEBUG typename __decay<_Up, __libcpp_is_referenceable<_Up>::value>::type type;
6260};
61
62template <class _Tp>
63using __decay_t = typename decay<_Tp>::type;
6364#endif // __has_builtin(__decay)
6465
65#if _LIBCPP_STD_VER > 11
66template <class _Tp> using decay_t = typename decay<_Tp>::type;
66#if _LIBCPP_STD_VER >= 14
67template <class _Tp>
68using decay_t = __decay_t<_Tp>;
6769#endif
6870
6971_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/disjunction.h+2-2
......@@ -43,7 +43,7 @@ struct _OrImpl<false> {
4343template <class... _Args>
4444using _Or _LIBCPP_NODEBUG = typename _OrImpl<sizeof...(_Args) != 0>::template _Result<false_type, _Args...>;
4545
46#if _LIBCPP_STD_VER > 14
46#if _LIBCPP_STD_VER >= 17
4747
4848template <class... _Args>
4949struct disjunction : _Or<_Args...> {};
......@@ -51,7 +51,7 @@ struct disjunction : _Or<_Args...> {};
5151template <class... _Args>
5252inline constexpr bool disjunction_v = _Or<_Args...>::value;
5353
54#endif // _LIBCPP_STD_VER > 14
54#endif // _LIBCPP_STD_VER >= 17
5555
5656_LIBCPP_END_NAMESPACE_STD
5757
lib/libcxx/include/__type_traits/enable_if.h+13-7
......@@ -17,13 +17,19 @@
1717
1818_LIBCPP_BEGIN_NAMESPACE_STD
1919
20template <bool, class _Tp = void> struct _LIBCPP_TEMPLATE_VIS enable_if {};
21template <class _Tp> struct _LIBCPP_TEMPLATE_VIS enable_if<true, _Tp> {typedef _Tp type;};
22
23template <bool _Bp, class _Tp = void> using __enable_if_t _LIBCPP_NODEBUG = typename enable_if<_Bp, _Tp>::type;
24
25#if _LIBCPP_STD_VER > 11
26template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
20template <bool, class _Tp = void>
21struct _LIBCPP_TEMPLATE_VIS enable_if {};
22template <class _Tp>
23struct _LIBCPP_TEMPLATE_VIS enable_if<true, _Tp> {
24 typedef _Tp type;
25};
26
27template <bool _Bp, class _Tp = void>
28using __enable_if_t _LIBCPP_NODEBUG = typename enable_if<_Bp, _Tp>::type;
29
30#if _LIBCPP_STD_VER >= 14
31template <bool _Bp, class _Tp = void>
32using enable_if_t = typename enable_if<_Bp, _Tp>::type;
2733#endif
2834
2935_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/extent.h+17-18
......@@ -21,32 +21,31 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121
2222#if __has_builtin(__array_extent)
2323
24template<class _Tp, size_t _Dim = 0>
25struct _LIBCPP_TEMPLATE_VIS extent
26 : integral_constant<size_t, __array_extent(_Tp, _Dim)> { };
24template <class _Tp, size_t _Dim = 0>
25struct _LIBCPP_TEMPLATE_VIS extent : integral_constant<size_t, __array_extent(_Tp, _Dim)> {};
2726
28#if _LIBCPP_STD_VER > 14
27# if _LIBCPP_STD_VER >= 17
2928template <class _Tp, unsigned _Ip = 0>
3029inline constexpr size_t extent_v = __array_extent(_Tp, _Ip);
31#endif
30# endif
3231
3332#else // __has_builtin(__array_extent)
3433
35template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TEMPLATE_VIS extent
36 : public integral_constant<size_t, 0> {};
37template <class _Tp> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], 0>
38 : public integral_constant<size_t, 0> {};
39template <class _Tp, unsigned _Ip> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], _Ip>
40 : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
41template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], 0>
42 : public integral_constant<size_t, _Np> {};
43template <class _Tp, size_t _Np, unsigned _Ip> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], _Ip>
44 : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
45
46#if _LIBCPP_STD_VER > 14
34template <class _Tp, unsigned _Ip = 0>
35struct _LIBCPP_TEMPLATE_VIS extent : public integral_constant<size_t, 0> {};
36template <class _Tp>
37struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], 0> : public integral_constant<size_t, 0> {};
38template <class _Tp, unsigned _Ip>
39struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], _Ip> : public integral_constant<size_t, extent<_Tp, _Ip - 1>::value> {};
40template <class _Tp, size_t _Np>
41struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], 0> : public integral_constant<size_t, _Np> {};
42template <class _Tp, size_t _Np, unsigned _Ip>
43struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], _Ip> : public integral_constant<size_t, extent<_Tp, _Ip - 1>::value> {};
44
45# if _LIBCPP_STD_VER >= 17
4746template <class _Tp, unsigned _Ip = 0>
4847inline constexpr size_t extent_v = extent<_Tp, _Ip>::value;
49#endif
48# endif
5049
5150#endif // __has_builtin(__array_extent)
5251
lib/libcxx/include/__type_traits/has_unique_object_representation.h+4-4
......@@ -20,11 +20,11 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 14
23#if _LIBCPP_STD_VER >= 17
2424
25template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_unique_object_representations
26 : public integral_constant<bool,
27 __has_unique_object_representations(remove_cv_t<remove_all_extents_t<_Tp>>)> {};
25template <class _Tp>
26struct _LIBCPP_TEMPLATE_VIS has_unique_object_representations
27 : public integral_constant<bool, __has_unique_object_representations(remove_cv_t<remove_all_extents_t<_Tp>>)> {};
2828
2929template <class _Tp>
3030inline constexpr bool has_unique_object_representations_v = has_unique_object_representations<_Tp>::value;
lib/libcxx/include/__type_traits/has_virtual_destructor.h+3-3
......@@ -18,10 +18,10 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_virtual_destructor
22 : public integral_constant<bool, __has_virtual_destructor(_Tp)> {};
21template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS has_virtual_destructor : public integral_constant<bool, __has_virtual_destructor(_Tp)> {};
2323
24#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2525template <class _Tp>
2626inline constexpr bool has_virtual_destructor_v = __has_virtual_destructor(_Tp);
2727#endif
lib/libcxx/include/__type_traits/integral_constant.h+8-11
......@@ -18,29 +18,26 @@
1818_LIBCPP_BEGIN_NAMESPACE_STD
1919
2020template <class _Tp, _Tp __v>
21struct _LIBCPP_TEMPLATE_VIS integral_constant
22{
23 static _LIBCPP_CONSTEXPR const _Tp value = __v;
24 typedef _Tp value_type;
21struct _LIBCPP_TEMPLATE_VIS integral_constant {
22 static _LIBCPP_CONSTEXPR const _Tp value = __v;
23 typedef _Tp value_type;
2524 typedef integral_constant type;
26 _LIBCPP_INLINE_VISIBILITY
27 _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT {return value;}
28#if _LIBCPP_STD_VER > 11
29 _LIBCPP_INLINE_VISIBILITY
30 constexpr value_type operator ()() const _NOEXCEPT {return value;}
25 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT { return value; }
26#if _LIBCPP_STD_VER >= 14
27 _LIBCPP_INLINE_VISIBILITY constexpr value_type operator()() const _NOEXCEPT { return value; }
3128#endif
3229};
3330
3431template <class _Tp, _Tp __v>
3532_LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value;
3633
37typedef integral_constant<bool, true> true_type;
34typedef integral_constant<bool, true> true_type;
3835typedef integral_constant<bool, false> false_type;
3936
4037template <bool _Val>
4138using _BoolConstant _LIBCPP_NODEBUG = integral_constant<bool, _Val>;
4239
43#if _LIBCPP_STD_VER > 14
40#if _LIBCPP_STD_VER >= 17
4441template <bool __b>
4542using bool_constant = integral_constant<bool, __b>;
4643#endif
lib/libcxx/include/__type_traits/invoke.h created+461
......@@ -0,0 +1,461 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___TYPE_TRAITS_INVOKE_H
11#define _LIBCPP___TYPE_TRAITS_INVOKE_H
12
13#include <__config>
14#include <__type_traits/add_lvalue_reference.h>
15#include <__type_traits/apply_cv.h>
16#include <__type_traits/conditional.h>
17#include <__type_traits/decay.h>
18#include <__type_traits/enable_if.h>
19#include <__type_traits/integral_constant.h>
20#include <__type_traits/is_base_of.h>
21#include <__type_traits/is_core_convertible.h>
22#include <__type_traits/is_member_function_pointer.h>
23#include <__type_traits/is_member_object_pointer.h>
24#include <__type_traits/is_reference_wrapper.h>
25#include <__type_traits/is_same.h>
26#include <__type_traits/is_void.h>
27#include <__type_traits/nat.h>
28#include <__type_traits/remove_cv.h>
29#include <__utility/declval.h>
30#include <__utility/forward.h>
31
32#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
33# pragma GCC system_header
34#endif
35
36_LIBCPP_BEGIN_NAMESPACE_STD
37
38struct __any {
39 __any(...);
40};
41
42template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
43struct __member_pointer_traits_imp {};
44
45template <class _Rp, class _Class, class... _Param>
46struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false> {
47 typedef _Class _ClassType;
48 typedef _Rp _ReturnType;
49 typedef _Rp(_FnType)(_Param...);
50};
51
52template <class _Rp, class _Class, class... _Param>
53struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false> {
54 typedef _Class _ClassType;
55 typedef _Rp _ReturnType;
56 typedef _Rp(_FnType)(_Param..., ...);
57};
58
59template <class _Rp, class _Class, class... _Param>
60struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false> {
61 typedef _Class const _ClassType;
62 typedef _Rp _ReturnType;
63 typedef _Rp(_FnType)(_Param...);
64};
65
66template <class _Rp, class _Class, class... _Param>
67struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false> {
68 typedef _Class const _ClassType;
69 typedef _Rp _ReturnType;
70 typedef _Rp(_FnType)(_Param..., ...);
71};
72
73template <class _Rp, class _Class, class... _Param>
74struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false> {
75 typedef _Class volatile _ClassType;
76 typedef _Rp _ReturnType;
77 typedef _Rp(_FnType)(_Param...);
78};
79
80template <class _Rp, class _Class, class... _Param>
81struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false> {
82 typedef _Class volatile _ClassType;
83 typedef _Rp _ReturnType;
84 typedef _Rp(_FnType)(_Param..., ...);
85};
86
87template <class _Rp, class _Class, class... _Param>
88struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false> {
89 typedef _Class const volatile _ClassType;
90 typedef _Rp _ReturnType;
91 typedef _Rp(_FnType)(_Param...);
92};
93
94template <class _Rp, class _Class, class... _Param>
95struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false> {
96 typedef _Class const volatile _ClassType;
97 typedef _Rp _ReturnType;
98 typedef _Rp(_FnType)(_Param..., ...);
99};
100
101template <class _Rp, class _Class, class... _Param>
102struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...)&, true, false> {
103 typedef _Class& _ClassType;
104 typedef _Rp _ReturnType;
105 typedef _Rp(_FnType)(_Param...);
106};
107
108template <class _Rp, class _Class, class... _Param>
109struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...)&, true, false> {
110 typedef _Class& _ClassType;
111 typedef _Rp _ReturnType;
112 typedef _Rp(_FnType)(_Param..., ...);
113};
114
115template <class _Rp, class _Class, class... _Param>
116struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false> {
117 typedef _Class const& _ClassType;
118 typedef _Rp _ReturnType;
119 typedef _Rp(_FnType)(_Param...);
120};
121
122template <class _Rp, class _Class, class... _Param>
123struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false> {
124 typedef _Class const& _ClassType;
125 typedef _Rp _ReturnType;
126 typedef _Rp(_FnType)(_Param..., ...);
127};
128
129template <class _Rp, class _Class, class... _Param>
130struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false> {
131 typedef _Class volatile& _ClassType;
132 typedef _Rp _ReturnType;
133 typedef _Rp(_FnType)(_Param...);
134};
135
136template <class _Rp, class _Class, class... _Param>
137struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false> {
138 typedef _Class volatile& _ClassType;
139 typedef _Rp _ReturnType;
140 typedef _Rp(_FnType)(_Param..., ...);
141};
142
143template <class _Rp, class _Class, class... _Param>
144struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false> {
145 typedef _Class const volatile& _ClassType;
146 typedef _Rp _ReturnType;
147 typedef _Rp(_FnType)(_Param...);
148};
149
150template <class _Rp, class _Class, class... _Param>
151struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false> {
152 typedef _Class const volatile& _ClassType;
153 typedef _Rp _ReturnType;
154 typedef _Rp(_FnType)(_Param..., ...);
155};
156
157template <class _Rp, class _Class, class... _Param>
158struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...)&&, true, false> {
159 typedef _Class&& _ClassType;
160 typedef _Rp _ReturnType;
161 typedef _Rp(_FnType)(_Param...);
162};
163
164template <class _Rp, class _Class, class... _Param>
165struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...)&&, true, false> {
166 typedef _Class&& _ClassType;
167 typedef _Rp _ReturnType;
168 typedef _Rp(_FnType)(_Param..., ...);
169};
170
171template <class _Rp, class _Class, class... _Param>
172struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false> {
173 typedef _Class const&& _ClassType;
174 typedef _Rp _ReturnType;
175 typedef _Rp(_FnType)(_Param...);
176};
177
178template <class _Rp, class _Class, class... _Param>
179struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false> {
180 typedef _Class const&& _ClassType;
181 typedef _Rp _ReturnType;
182 typedef _Rp(_FnType)(_Param..., ...);
183};
184
185template <class _Rp, class _Class, class... _Param>
186struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false> {
187 typedef _Class volatile&& _ClassType;
188 typedef _Rp _ReturnType;
189 typedef _Rp(_FnType)(_Param...);
190};
191
192template <class _Rp, class _Class, class... _Param>
193struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false> {
194 typedef _Class volatile&& _ClassType;
195 typedef _Rp _ReturnType;
196 typedef _Rp(_FnType)(_Param..., ...);
197};
198
199template <class _Rp, class _Class, class... _Param>
200struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false> {
201 typedef _Class const volatile&& _ClassType;
202 typedef _Rp _ReturnType;
203 typedef _Rp(_FnType)(_Param...);
204};
205
206template <class _Rp, class _Class, class... _Param>
207struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false> {
208 typedef _Class const volatile&& _ClassType;
209 typedef _Rp _ReturnType;
210 typedef _Rp(_FnType)(_Param..., ...);
211};
212
213template <class _Rp, class _Class>
214struct __member_pointer_traits_imp<_Rp _Class::*, false, true> {
215 typedef _Class _ClassType;
216 typedef _Rp _ReturnType;
217};
218
219template <class _MP>
220struct __member_pointer_traits
221 : public __member_pointer_traits_imp<__remove_cv_t<_MP>,
222 is_member_function_pointer<_MP>::value,
223 is_member_object_pointer<_MP>::value> {
224 // typedef ... _ClassType;
225 // typedef ... _ReturnType;
226 // typedef ... _FnType;
227};
228
229template <class _DecayedFp>
230struct __member_pointer_class_type {};
231
232template <class _Ret, class _ClassType>
233struct __member_pointer_class_type<_Ret _ClassType::*> {
234 typedef _ClassType type;
235};
236
237template <class _Fp,
238 class _A0,
239 class _DecayFp = __decay_t<_Fp>,
240 class _DecayA0 = __decay_t<_A0>,
241 class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
242using __enable_if_bullet1 =
243 typename enable_if<is_member_function_pointer<_DecayFp>::value && is_base_of<_ClassT, _DecayA0>::value >::type;
244
245template <class _Fp, class _A0, class _DecayFp = __decay_t<_Fp>, class _DecayA0 = __decay_t<_A0> >
246using __enable_if_bullet2 =
247 typename enable_if<is_member_function_pointer<_DecayFp>::value && __is_reference_wrapper<_DecayA0>::value >::type;
248
249template <class _Fp,
250 class _A0,
251 class _DecayFp = __decay_t<_Fp>,
252 class _DecayA0 = __decay_t<_A0>,
253 class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
254using __enable_if_bullet3 =
255 typename enable_if<is_member_function_pointer<_DecayFp>::value && !is_base_of<_ClassT, _DecayA0>::value &&
256 !__is_reference_wrapper<_DecayA0>::value >::type;
257
258template <class _Fp,
259 class _A0,
260 class _DecayFp = __decay_t<_Fp>,
261 class _DecayA0 = __decay_t<_A0>,
262 class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
263using __enable_if_bullet4 =
264 typename enable_if<is_member_object_pointer<_DecayFp>::value && is_base_of<_ClassT, _DecayA0>::value >::type;
265
266template <class _Fp, class _A0, class _DecayFp = __decay_t<_Fp>, class _DecayA0 = __decay_t<_A0> >
267using __enable_if_bullet5 =
268 typename enable_if<is_member_object_pointer<_DecayFp>::value && __is_reference_wrapper<_DecayA0>::value >::type;
269
270template <class _Fp,
271 class _A0,
272 class _DecayFp = __decay_t<_Fp>,
273 class _DecayA0 = __decay_t<_A0>,
274 class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
275using __enable_if_bullet6 =
276 typename enable_if<is_member_object_pointer<_DecayFp>::value && !is_base_of<_ClassT, _DecayA0>::value &&
277 !__is_reference_wrapper<_DecayA0>::value >::type;
278
279// __invoke forward declarations
280
281// fall back - none of the bullets
282
283template <class... _Args>
284__nat __invoke(__any, _Args&&... __args);
285
286// bullets 1, 2 and 3
287
288// clang-format off
289template <class _Fp, class _A0, class... _Args, class = __enable_if_bullet1<_Fp, _A0> >
290inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
291decltype((std::declval<_A0>().*std::declval<_Fp>())(std::declval<_Args>()...))
292__invoke(_Fp&& __f, _A0&& __a0, _Args&&... __args)
293 _NOEXCEPT_(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...)))
294 { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); }
295
296template <class _Fp, class _A0, class... _Args, class = __enable_if_bullet2<_Fp, _A0> >
297inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
298decltype((std::declval<_A0>().get().*std::declval<_Fp>())(std::declval<_Args>()...))
299__invoke(_Fp&& __f, _A0&& __a0, _Args&&... __args)
300 _NOEXCEPT_(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...)))
301 { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); }
302
303template <class _Fp, class _A0, class... _Args, class = __enable_if_bullet3<_Fp, _A0> >
304inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
305decltype(((*std::declval<_A0>()).*std::declval<_Fp>())(std::declval<_Args>()...))
306__invoke(_Fp&& __f, _A0&& __a0, _Args&&... __args)
307 _NOEXCEPT_(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...)))
308 { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); }
309
310// bullets 4, 5 and 6
311
312template <class _Fp, class _A0, class = __enable_if_bullet4<_Fp, _A0> >
313inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
314decltype(std::declval<_A0>().*std::declval<_Fp>())
315__invoke(_Fp&& __f, _A0&& __a0)
316 _NOEXCEPT_(noexcept(static_cast<_A0&&>(__a0).*__f))
317 { return static_cast<_A0&&>(__a0).*__f; }
318
319template <class _Fp, class _A0, class = __enable_if_bullet5<_Fp, _A0> >
320inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
321decltype(std::declval<_A0>().get().*std::declval<_Fp>())
322__invoke(_Fp&& __f, _A0&& __a0)
323 _NOEXCEPT_(noexcept(__a0.get().*__f))
324 { return __a0.get().*__f; }
325
326template <class _Fp, class _A0, class = __enable_if_bullet6<_Fp, _A0> >
327inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
328decltype((*std::declval<_A0>()).*std::declval<_Fp>())
329__invoke(_Fp&& __f, _A0&& __a0)
330 _NOEXCEPT_(noexcept((*static_cast<_A0&&>(__a0)).*__f))
331 { return (*static_cast<_A0&&>(__a0)).*__f; }
332
333// bullet 7
334
335template <class _Fp, class... _Args>
336inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
337decltype(std::declval<_Fp>()(std::declval<_Args>()...))
338__invoke(_Fp&& __f, _Args&&... __args)
339 _NOEXCEPT_(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...)))
340 { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); }
341// clang-format on
342
343// __invokable
344template <class _Ret, class _Fp, class... _Args>
345struct __invokable_r {
346 template <class _XFp, class... _XArgs>
347 static decltype(std::__invoke(std::declval<_XFp>(), std::declval<_XArgs>()...)) __try_call(int);
348 template <class _XFp, class... _XArgs>
349 static __nat __try_call(...);
350
351 // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void,
352 // or incomplete array types as required by the standard.
353 using _Result = decltype(__try_call<_Fp, _Args...>(0));
354
355 using type = __conditional_t<_IsNotSame<_Result, __nat>::value,
356 __conditional_t<is_void<_Ret>::value, true_type, __is_core_convertible<_Result, _Ret> >,
357 false_type>;
358 static const bool value = type::value;
359};
360template <class _Fp, class... _Args>
361using __invokable = __invokable_r<void, _Fp, _Args...>;
362
363template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class... _Args>
364struct __nothrow_invokable_r_imp {
365 static const bool value = false;
366};
367
368template <class _Ret, class _Fp, class... _Args>
369struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...> {
370 typedef __nothrow_invokable_r_imp _ThisT;
371
372 template <class _Tp>
373 static void __test_noexcept(_Tp) _NOEXCEPT;
374
375#ifdef _LIBCPP_CXX03_LANG
376 static const bool value = false;
377#else
378 static const bool value =
379 noexcept(_ThisT::__test_noexcept<_Ret>(_VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...)));
380#endif
381};
382
383template <class _Ret, class _Fp, class... _Args>
384struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...> {
385#ifdef _LIBCPP_CXX03_LANG
386 static const bool value = false;
387#else
388 static const bool value = noexcept(_VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...));
389#endif
390};
391
392template <class _Ret, class _Fp, class... _Args>
393using __nothrow_invokable_r =
394 __nothrow_invokable_r_imp<__invokable_r<_Ret, _Fp, _Args...>::value, is_void<_Ret>::value, _Ret, _Fp, _Args...>;
395
396template <class _Fp, class... _Args>
397using __nothrow_invokable = __nothrow_invokable_r_imp<__invokable<_Fp, _Args...>::value, true, void, _Fp, _Args...>;
398
399template <class _Fp, class... _Args>
400struct __invoke_of
401 : public enable_if<__invokable<_Fp, _Args...>::value, typename __invokable_r<void, _Fp, _Args...>::_Result> {};
402
403template <class _Ret, bool = is_void<_Ret>::value>
404struct __invoke_void_return_wrapper {
405 template <class... _Args>
406 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static _Ret __call(_Args&&... __args) {
407 return std::__invoke(std::forward<_Args>(__args)...);
408 }
409};
410
411template <class _Ret>
412struct __invoke_void_return_wrapper<_Ret, true> {
413 template <class... _Args>
414 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void __call(_Args&&... __args) {
415 std::__invoke(std::forward<_Args>(__args)...);
416 }
417};
418
419#if _LIBCPP_STD_VER >= 17
420
421// is_invocable
422
423template <class _Fn, class... _Args>
424struct _LIBCPP_TEMPLATE_VIS is_invocable : integral_constant<bool, __invokable<_Fn, _Args...>::value> {};
425
426template <class _Ret, class _Fn, class... _Args>
427struct _LIBCPP_TEMPLATE_VIS is_invocable_r : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {};
428
429template <class _Fn, class... _Args>
430inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
431
432template <class _Ret, class _Fn, class... _Args>
433inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value;
434
435// is_nothrow_invocable
436
437template <class _Fn, class... _Args>
438struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {
439};
440
441template <class _Ret, class _Fn, class... _Args>
442struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r
443 : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {};
444
445template <class _Fn, class... _Args>
446inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value;
447
448template <class _Ret, class _Fn, class... _Args>
449inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
450
451template <class _Fn, class... _Args>
452struct _LIBCPP_TEMPLATE_VIS invoke_result : __invoke_of<_Fn, _Args...> {};
453
454template <class _Fn, class... _Args>
455using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
456
457#endif // _LIBCPP_STD_VER >= 17
458
459_LIBCPP_END_NAMESPACE_STD
460
461#endif // _LIBCPP___TYPE_TRAITS_INVOKE_H
lib/libcxx/include/__type_traits/is_abstract.h+3-3
......@@ -18,10 +18,10 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_abstract
22 : public integral_constant<bool, __is_abstract(_Tp)> {};
21template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS is_abstract : public integral_constant<bool, __is_abstract(_Tp)> {};
2323
24#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2525template <class _Tp>
2626inline constexpr bool is_abstract_v = __is_abstract(_Tp);
2727#endif
lib/libcxx/include/__type_traits/is_aggregate.h+4-4
......@@ -18,15 +18,15 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21#if _LIBCPP_STD_VER > 14
21#if _LIBCPP_STD_VER >= 17
2222
23template <class _Tp> struct _LIBCPP_TEMPLATE_VIS
24is_aggregate : public integral_constant<bool, __is_aggregate(_Tp)> {};
23template <class _Tp>
24struct _LIBCPP_TEMPLATE_VIS is_aggregate : public integral_constant<bool, __is_aggregate(_Tp)> {};
2525
2626template <class _Tp>
2727inline constexpr bool is_aggregate_v = __is_aggregate(_Tp);
2828
29#endif // _LIBCPP_STD_VER > 14
29#endif // _LIBCPP_STD_VER >= 17
3030
3131_LIBCPP_END_NAMESPACE_STD
3232
lib/libcxx/include/__type_traits/is_allocator.h+4-6
......@@ -21,15 +21,13 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24template<typename _Alloc, typename = void, typename = void>
24template <typename _Alloc, typename = void, typename = void>
2525struct __is_allocator : false_type {};
2626
27template<typename _Alloc>
27template <typename _Alloc>
2828struct __is_allocator<_Alloc,
29 __void_t<typename _Alloc::value_type>,
30 __void_t<decltype(std::declval<_Alloc&>().allocate(size_t(0)))>
31 >
32 : true_type {};
29 __void_t<typename _Alloc::value_type>,
30 __void_t<decltype(std::declval<_Alloc&>().allocate(size_t(0)))> > : true_type {};
3331
3432_LIBCPP_END_NAMESPACE_STD
3533
lib/libcxx/include/__type_traits/is_always_bitcastable.h+43-40
......@@ -32,49 +32,52 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3232template <class _From, class _To>
3333struct __is_always_bitcastable {
3434 using _UnqualFrom = __remove_cv_t<_From>;
35 using _UnqualTo = __remove_cv_t<_To>;
35 using _UnqualTo = __remove_cv_t<_To>;
3636
37 // clang-format off
3738 static const bool value =
38 // First, the simple case -- `From` and `To` are the same object type.
39 (is_same<_UnqualFrom, _UnqualTo>::value && is_trivially_copyable<_UnqualFrom>::value) ||
39 // First, the simple case -- `From` and `To` are the same object type.
40 (is_same<_UnqualFrom, _UnqualTo>::value && is_trivially_copyable<_UnqualFrom>::value) ||
4041
41 // Beyond the simple case, we say that one type is "always bit-castable" to another if:
42 // - (1) `From` and `To` have the same value representation, and in addition every possible value of `From` has
43 // a corresponding value in the `To` type (in other words, the set of values of `To` is a superset of the set of
44 // values of `From`);
45 // - (2) When the corresponding values are not the same value (as, for example, between an unsigned and a signed
46 // integer, where a large positive value of the unsigned integer corresponds to a negative value in the signed
47 // integer type), the value of `To` that results from a bitwise copy of `From` is the same what would be produced
48 // by the built-in assignment (if it were defined for the two types, to which there are minor exceptions, e.g.
49 // built-in arrays).
50 //
51 // In practice, that means:
52 // - all integral types (except `bool`, see below) -- that is, character types and `int` types, both signed and
53 // unsigned...
54 // - as well as arrays of such types...
55 // - ...that have the same size.
56 //
57 // Other trivially-copyable types can't be validly bit-cast outside of their own type:
58 // - floating-point types normally have different sizes and thus aren't bit-castable between each other (fails #1);
59 // - integral types and floating-point types use different representations, so for example bit-casting an integral
60 // `1` to `float` results in a very small less-than-one value, unlike built-in assignment that produces `1.0`
61 // (fails #2);
62 // - booleans normally use only a single bit of their object representation; bit-casting an integer to a boolean
63 // will result in a boolean object with an incorrect representation, which is undefined behavior (fails #2).
64 // Bit-casting from a boolean into an integer, however, is valid;
65 // - enumeration types may have different ranges of possible values (fails #1);
66 // - for pointers, it is not guaranteed that pointers to different types use the same set of values to represent
67 // addresses, and the conversion results are explicitly unspecified for types with different alignments
68 // (fails #1);
69 // - for structs and unions it is impossible to determine whether the set of values of one of them is a subset of
70 // the other (fails #1);
71 // - there is no need to consider `nullptr_t` for practical purposes.
72 (
73 sizeof(_From) == sizeof(_To) &&
74 is_integral<_From>::value &&
75 is_integral<_To>::value &&
76 !is_same<_UnqualTo, bool>::value
77 );
42 // Beyond the simple case, we say that one type is "always bit-castable" to another if:
43 // - (1) `From` and `To` have the same value representation, and in addition every possible value of `From` has
44 // a corresponding value in the `To` type (in other words, the set of values of `To` is a superset of the set of
45 // values of `From`);
46 // - (2) When the corresponding values are not the same value (as, for example, between an unsigned and a signed
47 // integer, where a large positive value of the unsigned integer corresponds to a negative value in the signed
48 // integer type), the value of `To` that results from a bitwise copy of `From` is the same what would be
49 // produced by the built-in assignment (if it were defined for the two types, to which there are minor
50 // exceptions, e.g. built-in arrays).
51 //
52 // In practice, that means:
53 // - all integral types (except `bool`, see below) -- that is, character types and `int` types, both signed and
54 // unsigned...
55 // - as well as arrays of such types...
56 // - ...that have the same size.
57 //
58 // Other trivially-copyable types can't be validly bit-cast outside of their own type:
59 // - floating-point types normally have different sizes and thus aren't bit-castable between each other (fails
60 // #1);
61 // - integral types and floating-point types use different representations, so for example bit-casting an integral
62 // `1` to `float` results in a very small less-than-one value, unlike built-in assignment that produces `1.0`
63 // (fails #2);
64 // - booleans normally use only a single bit of their object representation; bit-casting an integer to a boolean
65 // will result in a boolean object with an incorrect representation, which is undefined behavior (fails #2).
66 // Bit-casting from a boolean into an integer, however, is valid;
67 // - enumeration types may have different ranges of possible values (fails #1);
68 // - for pointers, it is not guaranteed that pointers to different types use the same set of values to represent
69 // addresses, and the conversion results are explicitly unspecified for types with different alignments
70 // (fails #1);
71 // - for structs and unions it is impossible to determine whether the set of values of one of them is a subset of
72 // the other (fails #1);
73 // - there is no need to consider `nullptr_t` for practical purposes.
74 (
75 sizeof(_From) == sizeof(_To) &&
76 is_integral<_From>::value &&
77 is_integral<_To>::value &&
78 !is_same<_UnqualTo, bool>::value
79 );
80 // clang-format on
7881};
7982
8083_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/is_arithmetic.h+4-4
......@@ -20,11 +20,11 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_arithmetic
24 : public integral_constant<bool, is_integral<_Tp>::value ||
25 is_floating_point<_Tp>::value> {};
23template <class _Tp>
24struct _LIBCPP_TEMPLATE_VIS is_arithmetic
25 : public integral_constant<bool, is_integral<_Tp>::value || is_floating_point<_Tp>::value> {};
2626
27#if _LIBCPP_STD_VER > 14
27#if _LIBCPP_STD_VER >= 17
2828template <class _Tp>
2929inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
3030#endif
lib/libcxx/include/__type_traits/is_array.h+11-11
......@@ -24,26 +24,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2424#if __has_builtin(__is_array) && 0
2525
2626template <class _Tp>
27struct _LIBCPP_TEMPLATE_VIS is_array : _BoolConstant<__is_array(_Tp)> { };
27struct _LIBCPP_TEMPLATE_VIS is_array : _BoolConstant<__is_array(_Tp)> {};
2828
29#if _LIBCPP_STD_VER > 14
29# if _LIBCPP_STD_VER >= 17
3030template <class _Tp>
3131inline constexpr bool is_array_v = __is_array(_Tp);
32#endif
32# endif
3333
3434#else
3535
36template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array
37 : public false_type {};
38template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[]>
39 : public true_type {};
40template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[_Np]>
41 : public true_type {};
36template <class _Tp>
37struct _LIBCPP_TEMPLATE_VIS is_array : public false_type {};
38template <class _Tp>
39struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[]> : public true_type {};
40template <class _Tp, size_t _Np>
41struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[_Np]> : public true_type {};
4242
43#if _LIBCPP_STD_VER > 14
43# if _LIBCPP_STD_VER >= 17
4444template <class _Tp>
4545inline constexpr bool is_array_v = is_array<_Tp>::value;
46#endif
46# endif
4747
4848#endif // __has_builtin(__is_array)
4949
lib/libcxx/include/__type_traits/is_assignable.h+3-3
......@@ -18,10 +18,10 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template<class _Tp, class _Up>
22struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> { };
21template <class _Tp, class _Up>
22struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> {};
2323
24#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2525template <class _Tp, class _Arg>
2626inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Arg);
2727#endif
lib/libcxx/include/__type_traits/is_base_of.h+2-3
......@@ -19,10 +19,9 @@
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
2121template <class _Bp, class _Dp>
22struct _LIBCPP_TEMPLATE_VIS is_base_of
23 : public integral_constant<bool, __is_base_of(_Bp, _Dp)> {};
22struct _LIBCPP_TEMPLATE_VIS is_base_of : public integral_constant<bool, __is_base_of(_Bp, _Dp)> {};
2423
25#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2625template <class _Bp, class _Dp>
2726inline constexpr bool is_base_of_v = __is_base_of(_Bp, _Dp);
2827#endif
lib/libcxx/include/__type_traits/is_bounded_array.h+10-7
......@@ -19,17 +19,20 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22template <class> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array : false_type {};
23template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array<_Tp[_Np]> : true_type {};
22template <class>
23struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array : false_type {};
24template <class _Tp, size_t _Np>
25struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array<_Tp[_Np]> : true_type {};
2426
25#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2628
27template <class> struct _LIBCPP_TEMPLATE_VIS is_bounded_array : false_type {};
28template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS is_bounded_array<_Tp[_Np]> : true_type {};
29template <class>
30struct _LIBCPP_TEMPLATE_VIS is_bounded_array : false_type {};
31template <class _Tp, size_t _Np>
32struct _LIBCPP_TEMPLATE_VIS is_bounded_array<_Tp[_Np]> : true_type {};
2933
3034template <class _Tp>
31inline constexpr
32bool is_bounded_array_v = is_bounded_array<_Tp>::value;
35inline constexpr bool is_bounded_array_v = is_bounded_array<_Tp>::value;
3336
3437#endif
3538
lib/libcxx/include/__type_traits/is_callable.h+3-3
......@@ -19,12 +19,12 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22template<class _Func, class... _Args, class = decltype(std::declval<_Func>()(std::declval<_Args>()...))>
22template <class _Func, class... _Args, class = decltype(std::declval<_Func>()(std::declval<_Args>()...))>
2323true_type __is_callable_helper(int);
24template<class...>
24template <class...>
2525false_type __is_callable_helper(...);
2626
27template<class _Func, class... _Args>
27template <class _Func, class... _Args>
2828struct __is_callable : decltype(std::__is_callable_helper<_Func, _Args...>(0)) {};
2929
3030_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/is_class.h+3-3
......@@ -18,10 +18,10 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_class
22 : public integral_constant<bool, __is_class(_Tp)> {};
21template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS is_class : public integral_constant<bool, __is_class(_Tp)> {};
2323
24#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2525template <class _Tp>
2626inline constexpr bool is_class_v = __is_class(_Tp);
2727#endif
lib/libcxx/include/__type_traits/is_compound.h+8-8
......@@ -21,23 +21,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121
2222#if __has_builtin(__is_compound)
2323
24template<class _Tp>
25struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> { };
24template <class _Tp>
25struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> {};
2626
27#if _LIBCPP_STD_VER > 14
27# if _LIBCPP_STD_VER >= 17
2828template <class _Tp>
2929inline constexpr bool is_compound_v = __is_compound(_Tp);
30#endif
30# endif
3131
3232#else // __has_builtin(__is_compound)
3333
34template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_compound
35 : public integral_constant<bool, !is_fundamental<_Tp>::value> {};
34template <class _Tp>
35struct _LIBCPP_TEMPLATE_VIS is_compound : public integral_constant<bool, !is_fundamental<_Tp>::value> {};
3636
37#if _LIBCPP_STD_VER > 14
37# if _LIBCPP_STD_VER >= 17
3838template <class _Tp>
3939inline constexpr bool is_compound_v = is_compound<_Tp>::value;
40#endif
40# endif
4141
4242#endif // __has_builtin(__is_compound)
4343
lib/libcxx/include/__type_traits/is_const.h+9-7
......@@ -21,22 +21,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121#if __has_builtin(__is_const)
2222
2323template <class _Tp>
24struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> { };
24struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> {};
2525
26#if _LIBCPP_STD_VER > 14
26# if _LIBCPP_STD_VER >= 17
2727template <class _Tp>
2828inline constexpr bool is_const_v = __is_const(_Tp);
29#endif
29# endif
3030
3131#else
3232
33template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const : public false_type {};
34template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {};
33template <class _Tp>
34struct _LIBCPP_TEMPLATE_VIS is_const : public false_type {};
35template <class _Tp>
36struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {};
3537
36#if _LIBCPP_STD_VER > 14
38# if _LIBCPP_STD_VER >= 17
3739template <class _Tp>
3840inline constexpr bool is_const_v = is_const<_Tp>::value;
39#endif
41# endif
4042
4143#endif // __has_builtin(__is_const)
4244
lib/libcxx/include/__type_traits/is_constant_evaluated.h+5-5
......@@ -17,15 +17,15 @@
1717
1818_LIBCPP_BEGIN_NAMESPACE_STD
1919
20#if _LIBCPP_STD_VER > 17
21_LIBCPP_INLINE_VISIBILITY
22inline constexpr bool is_constant_evaluated() noexcept {
20#if _LIBCPP_STD_VER >= 20
21_LIBCPP_INLINE_VISIBILITY inline constexpr bool is_constant_evaluated() noexcept {
2322 return __builtin_is_constant_evaluated();
2423}
2524#endif
2625
27_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR
28bool __libcpp_is_constant_evaluated() _NOEXCEPT { return __builtin_is_constant_evaluated(); }
26_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR bool __libcpp_is_constant_evaluated() _NOEXCEPT {
27 return __builtin_is_constant_evaluated();
28}
2929
3030_LIBCPP_END_NAMESPACE_STD
3131
lib/libcxx/include/__type_traits/is_constructible.h+4-6
......@@ -18,13 +18,11 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp, class ..._Args>
22struct _LIBCPP_TEMPLATE_VIS is_constructible
23 : public integral_constant<bool, __is_constructible(_Tp, _Args...)>
24{ };
21template <class _Tp, class... _Args>
22struct _LIBCPP_TEMPLATE_VIS is_constructible : public integral_constant<bool, __is_constructible(_Tp, _Args...)> {};
2523
26#if _LIBCPP_STD_VER > 14
27template <class _Tp, class ..._Args>
24#if _LIBCPP_STD_VER >= 17
25template <class _Tp, class... _Args>
2826inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
2927#endif
3028
lib/libcxx/include/__type_traits/is_convertible.h+61-55
......@@ -24,81 +24,87 @@
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
27#if __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
27#if __has_builtin(__is_convertible) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
2828
29template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS is_convertible
30 : public integral_constant<bool, __is_convertible_to(_T1, _T2)> {};
29template <class _T1, class _T2>
30struct _LIBCPP_TEMPLATE_VIS is_convertible : public integral_constant<bool, __is_convertible(_T1, _T2)> {};
3131
32#else // __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
32#elif __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
3333
34namespace __is_convertible_imp
35{
36template <class _Tp> void __test_convert(_Tp);
34template <class _T1, class _T2>
35struct _LIBCPP_TEMPLATE_VIS is_convertible : public integral_constant<bool, __is_convertible_to(_T1, _T2)> {};
36
37// TODO: Remove this fallback when GCC < 13 support is no longer required.
38// GCC 13 has the __is_convertible built-in.
39#else // __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
40
41namespace __is_convertible_imp {
42template <class _Tp>
43void __test_convert(_Tp);
3744
3845template <class _From, class _To, class = void>
3946struct __is_convertible_test : public false_type {};
4047
4148template <class _From, class _To>
42struct __is_convertible_test<_From, _To,
43 decltype(__is_convertible_imp::__test_convert<_To>(std::declval<_From>()))> : public true_type
44{};
45
46template <class _Tp, bool _IsArray = is_array<_Tp>::value,
47 bool _IsFunction = is_function<_Tp>::value,
48 bool _IsVoid = is_void<_Tp>::value>
49 struct __is_array_function_or_void {enum {value = 0};};
50template <class _Tp> struct __is_array_function_or_void<_Tp, true, false, false> {enum {value = 1};};
51template <class _Tp> struct __is_array_function_or_void<_Tp, false, true, false> {enum {value = 2};};
52template <class _Tp> struct __is_array_function_or_void<_Tp, false, false, true> {enum {value = 3};};
53}
49struct __is_convertible_test<_From, _To, decltype(__is_convertible_imp::__test_convert<_To>(std::declval<_From>()))>
50 : public true_type {};
51
52// clang-format off
53template <class _Tp,
54 bool _IsArray = is_array<_Tp>::value,
55 bool _IsFunction = is_function<_Tp>::value,
56 bool _IsVoid = is_void<_Tp>::value>
57 struct __is_array_function_or_void { enum { value = 0 }; };
58template <class _Tp> struct __is_array_function_or_void<_Tp, true, false, false> { enum { value = 1 }; };
59template <class _Tp> struct __is_array_function_or_void<_Tp, false, true, false> { enum { value = 2 }; };
60template <class _Tp> struct __is_array_function_or_void<_Tp, false, false, true> { enum { value = 3 }; };
61// clang-format on
62} // namespace __is_convertible_imp
5463
5564template <class _Tp,
56 unsigned = __is_convertible_imp::__is_array_function_or_void<__libcpp_remove_reference_t<_Tp> >::value>
57struct __is_convertible_check
58{
59 static const size_t __v = 0;
65 unsigned = __is_convertible_imp::__is_array_function_or_void<__libcpp_remove_reference_t<_Tp> >::value>
66struct __is_convertible_check {
67 static const size_t __v = 0;
6068};
6169
6270template <class _Tp>
63struct __is_convertible_check<_Tp, 0>
64{
65 static const size_t __v = sizeof(_Tp);
71struct __is_convertible_check<_Tp, 0> {
72 static const size_t __v = sizeof(_Tp);
6673};
6774
68template <class _T1, class _T2,
69 unsigned _T1_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T1>::value,
70 unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value>
75template <class _T1,
76 class _T2,
77 unsigned _T1_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T1>::value,
78 unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value>
7179struct __is_convertible
72 : public integral_constant<bool,
73 __is_convertible_imp::__is_convertible_test<_T1, _T2>::value
74 >
75{};
76
77template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type {};
78template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type {};
79template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type {};
80template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 1> : public false_type {};
81
82template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 2> : public false_type {};
83template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 2> : public false_type {};
84template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 2> : public false_type {};
85template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 2> : public false_type {};
86
87template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 3> : public false_type {};
88template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 3> : public false_type {};
89template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 3> : public false_type {};
90template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 3> : public true_type {};
91
92template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS is_convertible
93 : public __is_convertible<_T1, _T2>
94{
95 static const size_t __complete_check1 = __is_convertible_check<_T1>::__v;
96 static const size_t __complete_check2 = __is_convertible_check<_T2>::__v;
80 : public integral_constant<bool, __is_convertible_imp::__is_convertible_test<_T1, _T2>::value >{};
81
82// clang-format off
83template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type{};
84template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type{};
85template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type{};
86template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 1> : public false_type{};
87
88template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 2> : public false_type{};
89template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 2> : public false_type{};
90template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 2> : public false_type{};
91template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 2> : public false_type{};
92
93template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 3> : public false_type{};
94template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 3> : public false_type{};
95template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 3> : public false_type{};
96template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 3> : public true_type{};
97// clang-format on
98
99template <class _T1, class _T2>
100struct _LIBCPP_TEMPLATE_VIS is_convertible : public __is_convertible<_T1, _T2> {
101 static const size_t __complete_check1 = __is_convertible_check<_T1>::__v;
102 static const size_t __complete_check2 = __is_convertible_check<_T2>::__v;
97103};
98104
99105#endif // __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
100106
101#if _LIBCPP_STD_VER > 14
107#if _LIBCPP_STD_VER >= 17
102108template <class _From, class _To>
103109inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value;
104110#endif
lib/libcxx/include/__type_traits/is_copy_assignable.h+2-3
......@@ -24,10 +24,9 @@ template <class _Tp>
2424struct _LIBCPP_TEMPLATE_VIS is_copy_assignable
2525 : public integral_constant<
2626 bool,
27 __is_assignable(__add_lvalue_reference_t<_Tp>,
28 __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
27 __is_assignable(__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
2928
30#if _LIBCPP_STD_VER > 14
29#if _LIBCPP_STD_VER >= 17
3130template <class _Tp>
3231inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value;
3332#endif
lib/libcxx/include/__type_traits/is_copy_constructible.h+3-4
......@@ -22,11 +22,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222
2323template <class _Tp>
2424struct _LIBCPP_TEMPLATE_VIS is_copy_constructible
25 : public integral_constant<
26 bool,
27 __is_constructible(_Tp, __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
25 : public integral_constant<bool, __is_constructible(_Tp, __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {
26};
2827
29#if _LIBCPP_STD_VER > 14
28#if _LIBCPP_STD_VER >= 17
3029template <class _Tp>
3130inline constexpr bool is_copy_constructible_v = is_copy_constructible<_Tp>::value;
3231#endif
lib/libcxx/include/__type_traits/is_core_convertible.h+2-3
......@@ -27,9 +27,8 @@ template <class _Tp, class _Up, class = void>
2727struct __is_core_convertible : public false_type {};
2828
2929template <class _Tp, class _Up>
30struct __is_core_convertible<_Tp, _Up, decltype(
31 static_cast<void(*)(_Up)>(0) ( static_cast<_Tp(*)()>(0)() )
32)> : public true_type {};
30struct __is_core_convertible<_Tp, _Up, decltype(static_cast<void (*)(_Up)>(0)(static_cast<_Tp (*)()>(0)()))>
31 : public true_type {};
3332
3433_LIBCPP_END_NAMESPACE_STD
3534
lib/libcxx/include/__type_traits/is_default_constructible.h+2-4
......@@ -19,11 +19,9 @@
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
2121template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS is_default_constructible
23 : public integral_constant<bool, __is_constructible(_Tp)>
24 {};
22struct _LIBCPP_TEMPLATE_VIS is_default_constructible : public integral_constant<bool, __is_constructible(_Tp)> {};
2523
26#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2725template <class _Tp>
2826inline constexpr bool is_default_constructible_v = __is_constructible(_Tp);
2927#endif
lib/libcxx/include/__type_traits/is_destructible.h+19-24
......@@ -24,13 +24,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2424
2525#if __has_builtin(__is_destructible)
2626
27template<class _Tp>
28struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> { };
27template <class _Tp>
28struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> {};
2929
30#if _LIBCPP_STD_VER > 14
30# if _LIBCPP_STD_VER >= 17
3131template <class _Tp>
3232inline constexpr bool is_destructible_v = __is_destructible(_Tp);
33#endif
33# endif
3434
3535#else // __has_builtin(__is_destructible)
3636
......@@ -42,19 +42,19 @@ inline constexpr bool is_destructible_v = __is_destructible(_Tp);
4242// where _Up is remove_all_extents<_Tp>::type
4343
4444template <class>
45struct __is_destructible_apply { typedef int type; };
45struct __is_destructible_apply {
46 typedef int type;
47};
4648
4749template <typename _Tp>
4850struct __is_destructor_wellformed {
49 template <typename _Tp1>
50 static true_type __test (
51 typename __is_destructible_apply<decltype(std::declval<_Tp1&>().~_Tp1())>::type
52 );
51 template <typename _Tp1>
52 static true_type __test(typename __is_destructible_apply<decltype(std::declval<_Tp1&>().~_Tp1())>::type);
5353
54 template <typename _Tp1>
55 static false_type __test (...);
54 template <typename _Tp1>
55 static false_type __test(...);
5656
57 static const bool value = decltype(__test<_Tp>(12))::value;
57 static const bool value = decltype(__test<_Tp>(12))::value;
5858};
5959
6060template <class _Tp, bool>
......@@ -62,12 +62,10 @@ struct __destructible_imp;
6262
6363template <class _Tp>
6464struct __destructible_imp<_Tp, false>
65 : public integral_constant<bool,
66 __is_destructor_wellformed<__remove_all_extents_t<_Tp> >::value> {};
65 : public integral_constant<bool, __is_destructor_wellformed<__remove_all_extents_t<_Tp> >::value> {};
6766
6867template <class _Tp>
69struct __destructible_imp<_Tp, true>
70 : public true_type {};
68struct __destructible_imp<_Tp, true> : public true_type {};
7169
7270template <class _Tp, bool>
7371struct __destructible_false;
......@@ -79,21 +77,18 @@ template <class _Tp>
7977struct __destructible_false<_Tp, true> : public false_type {};
8078
8179template <class _Tp>
82struct is_destructible
83 : public __destructible_false<_Tp, is_function<_Tp>::value> {};
80struct is_destructible : public __destructible_false<_Tp, is_function<_Tp>::value> {};
8481
8582template <class _Tp>
86struct is_destructible<_Tp[]>
87 : public false_type {};
83struct is_destructible<_Tp[]> : public false_type {};
8884
8985template <>
90struct is_destructible<void>
91 : public false_type {};
86struct is_destructible<void> : public false_type {};
9287
93#if _LIBCPP_STD_VER > 14
88# if _LIBCPP_STD_VER >= 17
9489template <class _Tp>
9590inline constexpr bool is_destructible_v = is_destructible<_Tp>::value;
96#endif
91# endif
9792
9893#endif // __has_builtin(__is_destructible)
9994
lib/libcxx/include/__type_traits/is_empty.h+2-3
......@@ -19,10 +19,9 @@
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
2121template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS is_empty
23 : public integral_constant<bool, __is_empty(_Tp)> {};
22struct _LIBCPP_TEMPLATE_VIS is_empty : public integral_constant<bool, __is_empty(_Tp)> {};
2423
25#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2625template <class _Tp>
2726inline constexpr bool is_empty_v = __is_empty(_Tp);
2827#endif
lib/libcxx/include/__type_traits/is_enum.h+3-3
......@@ -18,10 +18,10 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum
22 : public integral_constant<bool, __is_enum(_Tp)> {};
21template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS is_enum : public integral_constant<bool, __is_enum(_Tp)> {};
2323
24#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2525template <class _Tp>
2626inline constexpr bool is_enum_v = __is_enum(_Tp);
2727#endif
lib/libcxx/include/__type_traits/is_equality_comparable.h created+78
......@@ -0,0 +1,78 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TYPE_TRAITS_IS_EQUALITY_COMPARABLE_H
10#define _LIBCPP___TYPE_TRAITS_IS_EQUALITY_COMPARABLE_H
11
12#include <__config>
13#include <__type_traits/integral_constant.h>
14#include <__type_traits/is_integral.h>
15#include <__type_traits/is_same.h>
16#include <__type_traits/is_void.h>
17#include <__type_traits/remove_cv.h>
18#include <__type_traits/remove_cvref.h>
19#include <__type_traits/void_t.h>
20#include <__utility/declval.h>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23# pragma GCC system_header
24#endif
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _Tp, class _Up, class = void>
29struct __is_equality_comparable : false_type {};
30
31template <class _Tp, class _Up>
32struct __is_equality_comparable<_Tp, _Up, __void_t<decltype(std::declval<_Tp>() == std::declval<_Up>())> > : true_type {
33};
34
35// A type is_trivially_equality_comparable if the expression `a == b` is equivalent to `std::memcmp(&a, &b, sizeof(T))`
36// (with `a` and `b` being of type `T`). For the case where we compare two object of the same type, we can use
37// __is_trivially_equality_comparable. We have special-casing for pointers which point to the same type ignoring
38// cv-qualifications and comparing to void-pointers.
39//
40// The following types are not trivially equality comparable:
41// floating-point types: different bit-patterns can compare equal. (e.g 0.0 and -0.0)
42// enums: The user is allowed to specialize operator== for enums
43// pointers that don't have the same type (ignoring cv-qualifiers): pointers to virtual bases are equality comparable,
44// but don't have the same bit-pattern. An exception to this is comparing to a void-pointer. There the bit-pattern is
45// always compared.
46
47template <class _Tp, class _Up>
48struct __libcpp_is_trivially_equality_comparable_impl : false_type {};
49
50template <class _Tp>
51struct __libcpp_is_trivially_equality_comparable_impl<_Tp, _Tp>
52#if __has_builtin(__is_trivially_equality_comparable)
53 : integral_constant<bool, __is_trivially_equality_comparable(_Tp) && __is_equality_comparable<_Tp, _Tp>::value> {
54};
55#else
56 : is_integral<_Tp> {
57};
58#endif // __has_builtin(__is_trivially_equality_comparable)
59
60template <class _Tp>
61struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Tp*> : true_type {};
62
63// TODO: Use is_pointer_inverconvertible_base_of
64template <class _Tp, class _Up>
65struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Up*>
66 : integral_constant<
67 bool,
68 __is_equality_comparable<_Tp*, _Up*>::value &&
69 (is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value || is_void<_Tp>::value || is_void<_Up>::value)> {
70};
71
72template <class _Tp, class _Up>
73using __libcpp_is_trivially_equality_comparable =
74 __libcpp_is_trivially_equality_comparable_impl<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >;
75
76_LIBCPP_END_NAMESPACE_STD
77
78#endif // _LIBCPP___TYPE_TRAITS_IS_EQUALITY_COMPARABLE_H
lib/libcxx/include/__type_traits/is_execution_policy.h created+59
......@@ -0,0 +1,59 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H
10#define _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H
11
12#include <__config>
13#include <__type_traits/remove_cvref.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19#if _LIBCPP_STD_VER >= 17
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class>
24inline constexpr bool is_execution_policy_v = false;
25
26template <class>
27inline constexpr bool __is_unsequenced_execution_policy_impl = false;
28
29template <class _Tp>
30inline constexpr bool __is_unsequenced_execution_policy_v =
31 __is_unsequenced_execution_policy_impl<__remove_cvref_t<_Tp>>;
32
33template <class>
34inline constexpr bool __is_parallel_execution_policy_impl = false;
35
36template <class _Tp>
37inline constexpr bool __is_parallel_execution_policy_v = __is_parallel_execution_policy_impl<__remove_cvref_t<_Tp>>;
38
39namespace execution {
40struct __disable_user_instantiations_tag {
41 explicit __disable_user_instantiations_tag() = default;
42};
43} // namespace execution
44
45// TODO: Remove default argument once algorithms are using the new backend dispatching
46template <class _ExecutionPolicy>
47_LIBCPP_HIDE_FROM_ABI auto
48__remove_parallel_policy(const _ExecutionPolicy& = _ExecutionPolicy{execution::__disable_user_instantiations_tag{}});
49
50// Removes the "parallel" part of an execution policy.
51// For example, turns par_unseq into unseq, and par into seq.
52template <class _ExecutionPolicy>
53using __remove_parallel_policy_t = decltype(std::__remove_parallel_policy<_ExecutionPolicy>());
54
55_LIBCPP_END_NAMESPACE_STD
56
57#endif // _LIBCPP_STD_VER >= 17
58
59#endif // _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H
lib/libcxx/include/__type_traits/is_final.h+6-6
......@@ -18,15 +18,15 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp> struct _LIBCPP_TEMPLATE_VIS
22__libcpp_is_final : public integral_constant<bool, __is_final(_Tp)> {};
21template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS __libcpp_is_final : public integral_constant<bool, __is_final(_Tp)> {};
2323
24#if _LIBCPP_STD_VER > 11
25template <class _Tp> struct _LIBCPP_TEMPLATE_VIS
26is_final : public integral_constant<bool, __is_final(_Tp)> {};
24#if _LIBCPP_STD_VER >= 14
25template <class _Tp>
26struct _LIBCPP_TEMPLATE_VIS is_final : public integral_constant<bool, __is_final(_Tp)> {};
2727#endif
2828
29#if _LIBCPP_STD_VER > 14
29#if _LIBCPP_STD_VER >= 17
3030template <class _Tp>
3131inline constexpr bool is_final_v = __is_final(_Tp);
3232#endif
lib/libcxx/include/__type_traits/is_floating_point.h+5-3
......@@ -19,15 +19,17 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22// clang-format off
2223template <class _Tp> struct __libcpp_is_floating_point : public false_type {};
2324template <> struct __libcpp_is_floating_point<float> : public true_type {};
2425template <> struct __libcpp_is_floating_point<double> : public true_type {};
2526template <> struct __libcpp_is_floating_point<long double> : public true_type {};
27// clang-format on
2628
27template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_floating_point
28 : public __libcpp_is_floating_point<__remove_cv_t<_Tp> > {};
29template <class _Tp>
30struct _LIBCPP_TEMPLATE_VIS is_floating_point : public __libcpp_is_floating_point<__remove_cv_t<_Tp> > {};
2931
30#if _LIBCPP_STD_VER > 14
32#if _LIBCPP_STD_VER >= 17
3133template <class _Tp>
3234inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
3335#endif
lib/libcxx/include/__type_traits/is_function.h+1-1
......@@ -33,7 +33,7 @@ struct _LIBCPP_TEMPLATE_VIS is_function
3333
3434#endif // __has_builtin(__is_function)
3535
36#if _LIBCPP_STD_VER > 14
36#if _LIBCPP_STD_VER >= 17
3737template <class _Tp>
3838inline constexpr bool is_function_v = is_function<_Tp>::value;
3939#endif
lib/libcxx/include/__type_traits/is_fundamental.h+9-10
......@@ -22,25 +22,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222
2323#if __has_builtin(__is_fundamental)
2424
25template<class _Tp>
26struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> { };
25template <class _Tp>
26struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> {};
2727
28#if _LIBCPP_STD_VER > 14
28# if _LIBCPP_STD_VER >= 17
2929template <class _Tp>
3030inline constexpr bool is_fundamental_v = __is_fundamental(_Tp);
31#endif
31# endif
3232
3333#else // __has_builtin(__is_fundamental)
3434
35template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_fundamental
36 : public integral_constant<bool, is_void<_Tp>::value ||
37 __is_nullptr_t<_Tp>::value ||
38 is_arithmetic<_Tp>::value> {};
35template <class _Tp>
36struct _LIBCPP_TEMPLATE_VIS is_fundamental
37 : public integral_constant<bool, is_void<_Tp>::value || __is_nullptr_t<_Tp>::value || is_arithmetic<_Tp>::value> {};
3938
40#if _LIBCPP_STD_VER > 14
39# if _LIBCPP_STD_VER >= 17
4140template <class _Tp>
4241inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
43#endif
42# endif
4443
4544#endif // __has_builtin(__is_fundamental)
4645
lib/libcxx/include/__type_traits/is_implicitly_default_constructible.h+7-9
......@@ -28,19 +28,17 @@ template <class _Tp>
2828void __test_implicit_default_constructible(_Tp);
2929
3030template <class _Tp, class = void, class = typename is_default_constructible<_Tp>::type>
31struct __is_implicitly_default_constructible
32 : false_type
33{ };
31struct __is_implicitly_default_constructible : false_type {};
3432
3533template <class _Tp>
36struct __is_implicitly_default_constructible<_Tp, decltype(std::__test_implicit_default_constructible<_Tp const&>({})), true_type>
37 : true_type
38{ };
34struct __is_implicitly_default_constructible<_Tp,
35 decltype(std::__test_implicit_default_constructible<_Tp const&>({})),
36 true_type> : true_type {};
3937
4038template <class _Tp>
41struct __is_implicitly_default_constructible<_Tp, decltype(std::__test_implicit_default_constructible<_Tp const&>({})), false_type>
42 : false_type
43{ };
39struct __is_implicitly_default_constructible<_Tp,
40 decltype(std::__test_implicit_default_constructible<_Tp const&>({})),
41 false_type> : false_type {};
4442#endif // !C++03
4543
4644_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/is_integral.h+9-7
......@@ -19,6 +19,7 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22// clang-format off
2223template <class _Tp> struct __libcpp_is_integral { enum { value = 0 }; };
2324template <> struct __libcpp_is_integral<bool> { enum { value = 1 }; };
2425template <> struct __libcpp_is_integral<char> { enum { value = 1 }; };
......@@ -44,26 +45,27 @@ template <> struct __libcpp_is_integral<unsigned long long> { enum { va
4445template <> struct __libcpp_is_integral<__int128_t> { enum { value = 1 }; };
4546template <> struct __libcpp_is_integral<__uint128_t> { enum { value = 1 }; };
4647#endif
48// clang-format on
4749
4850#if __has_builtin(__is_integral)
4951
5052template <class _Tp>
51struct _LIBCPP_TEMPLATE_VIS is_integral : _BoolConstant<__is_integral(_Tp)> { };
53struct _LIBCPP_TEMPLATE_VIS is_integral : _BoolConstant<__is_integral(_Tp)> {};
5254
53#if _LIBCPP_STD_VER > 14
55# if _LIBCPP_STD_VER >= 17
5456template <class _Tp>
5557inline constexpr bool is_integral_v = __is_integral(_Tp);
56#endif
58# endif
5759
5860#else
5961
60template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_integral
61 : public _BoolConstant<__libcpp_is_integral<__remove_cv_t<_Tp> >::value> {};
62template <class _Tp>
63struct _LIBCPP_TEMPLATE_VIS is_integral : public _BoolConstant<__libcpp_is_integral<__remove_cv_t<_Tp> >::value> {};
6264
63#if _LIBCPP_STD_VER > 14
65# if _LIBCPP_STD_VER >= 17
6466template <class _Tp>
6567inline constexpr bool is_integral_v = is_integral<_Tp>::value;
66#endif
68# endif
6769
6870#endif // __has_builtin(__is_integral)
6971
lib/libcxx/include/__type_traits/is_literal_type.h+6-6
......@@ -19,15 +19,15 @@
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
2121#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
22template <class _Tp> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 is_literal_type
23 : public integral_constant<bool, __is_literal_type(_Tp)>
24 {};
22template <class _Tp>
23struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 is_literal_type
24 : public integral_constant<bool, __is_literal_type(_Tp)> {};
2525
26#if _LIBCPP_STD_VER > 14
26# if _LIBCPP_STD_VER >= 17
2727template <class _Tp>
2828_LIBCPP_DEPRECATED_IN_CXX17 inline constexpr bool is_literal_type_v = __is_literal_type(_Tp);
29#endif // _LIBCPP_STD_VER > 14
30#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
29# endif // _LIBCPP_STD_VER >= 17
30#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
3131
3232_LIBCPP_END_NAMESPACE_STD
3333
lib/libcxx/include/__type_traits/is_member_function_pointer.h+16-18
......@@ -21,41 +21,39 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24template <class _Tp> struct __libcpp_is_member_pointer {
25 enum {
26 __is_member = false,
27 __is_func = false,
28 __is_obj = false
29 };
24template <class _Tp>
25struct __libcpp_is_member_pointer {
26 enum { __is_member = false, __is_func = false, __is_obj = false };
3027};
31template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> {
28template <class _Tp, class _Up>
29struct __libcpp_is_member_pointer<_Tp _Up::*> {
3230 enum {
3331 __is_member = true,
34 __is_func = is_function<_Tp>::value,
35 __is_obj = !__is_func,
32 __is_func = is_function<_Tp>::value,
33 __is_obj = !__is_func,
3634 };
3735};
3836
3937#if __has_builtin(__is_member_function_pointer)
4038
41template<class _Tp>
42struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
43 : _BoolConstant<__is_member_function_pointer(_Tp)> { };
39template <class _Tp>
40struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer : _BoolConstant<__is_member_function_pointer(_Tp)> {};
4441
45#if _LIBCPP_STD_VER > 14
42# if _LIBCPP_STD_VER >= 17
4643template <class _Tp>
4744inline constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Tp);
48#endif
45# endif
4946
5047#else // __has_builtin(__is_member_function_pointer)
5148
52template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
53 : public _BoolConstant< __libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_func > {};
49template <class _Tp>
50struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
51 : public _BoolConstant<__libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_func> {};
5452
55#if _LIBCPP_STD_VER > 14
53# if _LIBCPP_STD_VER >= 17
5654template <class _Tp>
5755inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value;
58#endif
56# endif
5957
6058#endif // __has_builtin(__is_member_function_pointer)
6159
lib/libcxx/include/__type_traits/is_member_object_pointer.h+9-9
......@@ -20,24 +20,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2020
2121#if __has_builtin(__is_member_object_pointer)
2222
23template<class _Tp>
24struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
25 : _BoolConstant<__is_member_object_pointer(_Tp)> { };
23template <class _Tp>
24struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer : _BoolConstant<__is_member_object_pointer(_Tp)> {};
2625
27#if _LIBCPP_STD_VER > 14
26# if _LIBCPP_STD_VER >= 17
2827template <class _Tp>
2928inline constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Tp);
30#endif
29# endif
3130
3231#else // __has_builtin(__is_member_object_pointer)
3332
34template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
35 : public _BoolConstant< __libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_obj > {};
33template <class _Tp>
34struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
35 : public _BoolConstant<__libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_obj> {};
3636
37#if _LIBCPP_STD_VER > 14
37# if _LIBCPP_STD_VER >= 17
3838template <class _Tp>
3939inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value;
40#endif
40# endif
4141
4242#endif // __has_builtin(__is_member_object_pointer)
4343
lib/libcxx/include/__type_traits/is_member_pointer.h+9-8
......@@ -21,23 +21,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121
2222#if __has_builtin(__is_member_pointer)
2323
24template<class _Tp>
25struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> { };
24template <class _Tp>
25struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> {};
2626
27#if _LIBCPP_STD_VER > 14
27# if _LIBCPP_STD_VER >= 17
2828template <class _Tp>
2929inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
30#endif
30# endif
3131
3232#else // __has_builtin(__is_member_pointer)
3333
34template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_pointer
35 : public _BoolConstant< __libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_member > {};
34template <class _Tp>
35struct _LIBCPP_TEMPLATE_VIS is_member_pointer
36 : public _BoolConstant<__libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_member> {};
3637
37#if _LIBCPP_STD_VER > 14
38# if _LIBCPP_STD_VER >= 17
3839template <class _Tp>
3940inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
40#endif
41# endif
4142
4243#endif // __has_builtin(__is_member_pointer)
4344
lib/libcxx/include/__type_traits/is_move_assignable.h+2-4
......@@ -22,11 +22,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222
2323template <class _Tp>
2424struct _LIBCPP_TEMPLATE_VIS is_move_assignable
25 : public integral_constant<
26 bool,
27 __is_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {};
25 : public integral_constant<bool, __is_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {};
2826
29#if _LIBCPP_STD_VER > 14
27#if _LIBCPP_STD_VER >= 17
3028template <class _Tp>
3129inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value;
3230#endif
lib/libcxx/include/__type_traits/is_move_constructible.h+2-3
......@@ -21,10 +21,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121
2222template <class _Tp>
2323struct _LIBCPP_TEMPLATE_VIS is_move_constructible
24 : public integral_constant<bool, __is_constructible(_Tp, __add_rvalue_reference_t<_Tp>)>
25 {};
24 : public integral_constant<bool, __is_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {};
2625
27#if _LIBCPP_STD_VER > 14
26#if _LIBCPP_STD_VER >= 17
2827template <class _Tp>
2928inline constexpr bool is_move_constructible_v = is_move_constructible<_Tp>::value;
3029#endif
lib/libcxx/include/__type_traits/is_nothrow_assignable.h+3-3
......@@ -19,10 +19,10 @@
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
2121template <class _Tp, class _Arg>
22struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable
23 : public integral_constant<bool, __is_nothrow_assignable(_Tp, _Arg)> {};
22struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable : public integral_constant<bool, __is_nothrow_assignable(_Tp, _Arg)> {
23};
2424
25#if _LIBCPP_STD_VER > 14
25#if _LIBCPP_STD_VER >= 17
2626template <class _Tp, class _Arg>
2727inline constexpr bool is_nothrow_assignable_v = __is_nothrow_assignable(_Tp, _Arg);
2828#endif
lib/libcxx/include/__type_traits/is_nothrow_constructible.h+18-25
......@@ -22,54 +22,47 @@
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
25#if __has_builtin(__is_nothrow_constructible)
25// GCC is disabled due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611
26#if __has_builtin(__is_nothrow_constructible) && !defined(_LIBCPP_COMPILER_GCC)
2627
27template <
28 class _Tp, class... _Args>
28template < class _Tp, class... _Args>
2929struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible
3030 : public integral_constant<bool, __is_nothrow_constructible(_Tp, _Args...)> {};
3131#else
3232
33template <bool, bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible;
33template <bool, bool, class _Tp, class... _Args>
34struct __libcpp_is_nothrow_constructible;
3435
3536template <class _Tp, class... _Args>
36struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/false, _Tp, _Args...>
37 : public integral_constant<bool, noexcept(_Tp(std::declval<_Args>()...))>
38{
39};
37struct __libcpp_is_nothrow_constructible</*is constructible*/ true, /*is reference*/ false, _Tp, _Args...>
38 : public integral_constant<bool, noexcept(_Tp(std::declval<_Args>()...))> {};
4039
4140template <class _Tp>
42void __implicit_conversion_to(_Tp) noexcept { }
41void __implicit_conversion_to(_Tp) noexcept {}
4342
4443template <class _Tp, class _Arg>
45struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/true, _Tp, _Arg>
46 : public integral_constant<bool, noexcept(_VSTD::__implicit_conversion_to<_Tp>(std::declval<_Arg>()))>
47{
48};
44struct __libcpp_is_nothrow_constructible</*is constructible*/ true, /*is reference*/ true, _Tp, _Arg>
45 : public integral_constant<bool, noexcept(_VSTD::__implicit_conversion_to<_Tp>(std::declval<_Arg>()))> {};
4946
5047template <class _Tp, bool _IsReference, class... _Args>
51struct __libcpp_is_nothrow_constructible</*is constructible*/false, _IsReference, _Tp, _Args...>
52 : public false_type
53{
48struct __libcpp_is_nothrow_constructible</*is constructible*/ false, _IsReference, _Tp, _Args...> : public false_type {
5449};
5550
5651template <class _Tp, class... _Args>
5752struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible
58 : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, is_reference<_Tp>::value, _Tp, _Args...>
59{
60};
53 : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value,
54 is_reference<_Tp>::value,
55 _Tp,
56 _Args...> {};
6157
6258template <class _Tp, size_t _Ns>
6359struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp[_Ns]>
64 : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp>
65{
66};
60 : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp> {};
6761
6862#endif // __has_builtin(__is_nothrow_constructible)
6963
70
71#if _LIBCPP_STD_VER > 14
72template <class _Tp, class ..._Args>
64#if _LIBCPP_STD_VER >= 17
65template <class _Tp, class... _Args>
7366inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<_Tp, _Args...>::value;
7467#endif
7568
lib/libcxx/include/__type_traits/is_nothrow_convertible.h+9-12
......@@ -24,29 +24,26 @@
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
27#if _LIBCPP_STD_VER > 17
27#if _LIBCPP_STD_VER >= 20
2828
2929template <typename _Tp>
30static void __test_noexcept(_Tp) noexcept;
30void __test_noexcept(_Tp) noexcept;
3131
32template<typename _Fm, typename _To>
33static bool_constant<noexcept(_VSTD::__test_noexcept<_To>(std::declval<_Fm>()))>
34__is_nothrow_convertible_test();
32template <typename _Fm, typename _To>
33bool_constant<noexcept(_VSTD::__test_noexcept<_To>(std::declval<_Fm>()))> __is_nothrow_convertible_test();
3534
3635template <typename _Fm, typename _To>
37struct __is_nothrow_convertible_helper: decltype(__is_nothrow_convertible_test<_Fm, _To>())
38{ };
36struct __is_nothrow_convertible_helper : decltype(__is_nothrow_convertible_test<_Fm, _To>()) {};
3937
4038template <typename _Fm, typename _To>
41struct is_nothrow_convertible : _Or<
42 _And<is_void<_To>, is_void<_Fm>>,
43 _Lazy<_And, is_convertible<_Fm, _To>, __is_nothrow_convertible_helper<_Fm, _To>>
44>::type { };
39struct is_nothrow_convertible
40 : _Or<_And<is_void<_To>, is_void<_Fm>>,
41 _Lazy<_And, is_convertible<_Fm, _To>, __is_nothrow_convertible_helper<_Fm, _To> > >::type {};
4542
4643template <typename _Fm, typename _To>
4744inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<_Fm, _To>::value;
4845
49#endif // _LIBCPP_STD_VER > 17
46#endif // _LIBCPP_STD_VER >= 20
5047
5148_LIBCPP_END_NAMESPACE_STD
5249
lib/libcxx/include/__type_traits/is_nothrow_copy_assignable.h+4-6
......@@ -22,13 +22,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222
2323template <class _Tp>
2424struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_assignable
25 : public integral_constant<
26 bool,
27 __is_nothrow_assignable(
28 __add_lvalue_reference_t<_Tp>,
29 __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
25 : public integral_constant<bool,
26 __is_nothrow_assignable(__add_lvalue_reference_t<_Tp>,
27 __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
3028
31#if _LIBCPP_STD_VER > 14
29#if _LIBCPP_STD_VER >= 17
3230template <class _Tp>
3331inline constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<_Tp>::value;
3432#endif
lib/libcxx/include/__type_traits/is_nothrow_copy_constructible.h+4-4
......@@ -24,9 +24,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2424// TODO: remove this implementation once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 is fixed
2525#ifdef _LIBCPP_COMPILER_GCC
2626
27template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible
28 : public is_nothrow_constructible<_Tp,
29 __add_lvalue_reference_t<typename add_const<_Tp>::type> > {};
27template <class _Tp>
28struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible
29 : public is_nothrow_constructible<_Tp, __add_lvalue_reference_t<typename add_const<_Tp>::type> > {};
3030
3131#else // _LIBCPP_COMPILER_GCC
3232
......@@ -38,7 +38,7 @@ struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible
3838
3939#endif // _LIBCPP_COMPILER_GCC
4040
41#if _LIBCPP_STD_VER > 14
41#if _LIBCPP_STD_VER >= 17
4242template <class _Tp>
4343inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<_Tp>::value;
4444#endif
lib/libcxx/include/__type_traits/is_nothrow_default_constructible.h+4-4
......@@ -18,11 +18,11 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_default_constructible
22 : public integral_constant<bool, __is_nothrow_constructible(_Tp)>
23 {};
21template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS is_nothrow_default_constructible
23 : public integral_constant<bool, __is_nothrow_constructible(_Tp)> {};
2424
25#if _LIBCPP_STD_VER > 14
25#if _LIBCPP_STD_VER >= 17
2626template <class _Tp>
2727inline constexpr bool is_nothrow_default_constructible_v = __is_nothrow_constructible(_Tp);
2828#endif
lib/libcxx/include/__type_traits/is_nothrow_destructible.h+16-31
......@@ -26,60 +26,45 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2626
2727#if !defined(_LIBCPP_CXX03_LANG)
2828
29template <bool, class _Tp> struct __libcpp_is_nothrow_destructible;
29template <bool, class _Tp>
30struct __libcpp_is_nothrow_destructible;
3031
3132template <class _Tp>
32struct __libcpp_is_nothrow_destructible<false, _Tp>
33 : public false_type
34{
35};
33struct __libcpp_is_nothrow_destructible<false, _Tp> : public false_type {};
3634
3735template <class _Tp>
3836struct __libcpp_is_nothrow_destructible<true, _Tp>
39 : public integral_constant<bool, noexcept(std::declval<_Tp>().~_Tp()) >
40{
41};
37 : public integral_constant<bool, noexcept(std::declval<_Tp>().~_Tp()) > {};
4238
4339template <class _Tp>
4440struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible
45 : public __libcpp_is_nothrow_destructible<is_destructible<_Tp>::value, _Tp>
46{
47};
41 : public __libcpp_is_nothrow_destructible<is_destructible<_Tp>::value, _Tp> {};
4842
4943template <class _Tp, size_t _Ns>
50struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[_Ns]>
51 : public is_nothrow_destructible<_Tp>
52{
53};
44struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[_Ns]> : public is_nothrow_destructible<_Tp> {};
5445
5546template <class _Tp>
56struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&>
57 : public true_type
58{
59};
47struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&> : public true_type {};
6048
6149template <class _Tp>
62struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&&>
63 : public true_type
64{
65};
50struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&&> : public true_type {};
6651
6752#else
6853
69template <class _Tp> struct __libcpp_nothrow_destructor
70 : public integral_constant<bool, is_scalar<_Tp>::value ||
71 is_reference<_Tp>::value> {};
54template <class _Tp>
55struct __libcpp_nothrow_destructor : public integral_constant<bool, is_scalar<_Tp>::value || is_reference<_Tp>::value> {
56};
7257
73template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible
74 : public __libcpp_nothrow_destructor<__remove_all_extents_t<_Tp> > {};
58template <class _Tp>
59struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible : public __libcpp_nothrow_destructor<__remove_all_extents_t<_Tp> > {
60};
7561
7662template <class _Tp>
77struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[]>
78 : public false_type {};
63struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[]> : public false_type {};
7964
8065#endif
8166
82#if _LIBCPP_STD_VER > 14
67#if _LIBCPP_STD_VER >= 17
8368template <class _Tp>
8469inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<_Tp>::value;
8570#endif
lib/libcxx/include/__type_traits/is_nothrow_move_assignable.h+3-4
......@@ -22,12 +22,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222
2323template <class _Tp>
2424struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_assignable
25 : public integral_constant<
26 bool,
27 __is_nothrow_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {
25 : public integral_constant<bool,
26 __is_nothrow_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {
2827};
2928
30#if _LIBCPP_STD_VER > 14
29#if _LIBCPP_STD_VER >= 17
3130template <class _Tp>
3231inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<_Tp>::value;
3332#endif
lib/libcxx/include/__type_traits/is_nothrow_move_constructible.h+7-7
......@@ -23,19 +23,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2323// TODO: remove this implementation once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 is fixed
2424#ifndef _LIBCPP_COMPILER_GCC
2525
26template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible
27 : public integral_constant<bool, __is_nothrow_constructible(_Tp, __add_rvalue_reference_t<_Tp>)>
28 {};
26template <class _Tp>
27struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible
28 : public integral_constant<bool, __is_nothrow_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {};
2929
3030#else // _LIBCPP_COMPILER_GCC
3131
32template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible
33 : public is_nothrow_constructible<_Tp, __add_rvalue_reference_t<_Tp> >
34 {};
32template <class _Tp>
33struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible
34 : public is_nothrow_constructible<_Tp, __add_rvalue_reference_t<_Tp> > {};
3535
3636#endif // _LIBCPP_COMPILER_GCC
3737
38#if _LIBCPP_STD_VER > 14
38#if _LIBCPP_STD_VER >= 17
3939template <class _Tp>
4040inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<_Tp>::value;
4141#endif
lib/libcxx/include/__type_traits/is_null_pointer.h+12-10
......@@ -20,21 +20,23 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23template <class _Tp> struct __is_nullptr_t_impl : public false_type {};
24template <> struct __is_nullptr_t_impl<nullptr_t> : public true_type {};
23template <class _Tp>
24struct __is_nullptr_t_impl : public false_type {};
25template <>
26struct __is_nullptr_t_impl<nullptr_t> : public true_type {};
2527
26template <class _Tp> struct _LIBCPP_TEMPLATE_VIS __is_nullptr_t
27 : public __is_nullptr_t_impl<__remove_cv_t<_Tp> > {};
28template <class _Tp>
29struct _LIBCPP_TEMPLATE_VIS __is_nullptr_t : public __is_nullptr_t_impl<__remove_cv_t<_Tp> > {};
2830
29#if _LIBCPP_STD_VER > 11
30template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_null_pointer
31 : public __is_nullptr_t_impl<__remove_cv_t<_Tp> > {};
31#if _LIBCPP_STD_VER >= 14
32template <class _Tp>
33struct _LIBCPP_TEMPLATE_VIS is_null_pointer : public __is_nullptr_t_impl<__remove_cv_t<_Tp> > {};
3234
33#if _LIBCPP_STD_VER > 14
35# if _LIBCPP_STD_VER >= 17
3436template <class _Tp>
3537inline constexpr bool is_null_pointer_v = is_null_pointer<_Tp>::value;
36#endif
37#endif // _LIBCPP_STD_VER > 11
38# endif
39#endif // _LIBCPP_STD_VER >= 14
3840
3941_LIBCPP_END_NAMESPACE_STD
4042
lib/libcxx/include/__type_traits/is_object.h+11-11
......@@ -24,26 +24,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2424
2525#if __has_builtin(__is_object)
2626
27template<class _Tp>
28struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> { };
27template <class _Tp>
28struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> {};
2929
30#if _LIBCPP_STD_VER > 14
30# if _LIBCPP_STD_VER >= 17
3131template <class _Tp>
3232inline constexpr bool is_object_v = __is_object(_Tp);
33#endif
33# endif
3434
3535#else // __has_builtin(__is_object)
3636
37template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_object
38 : public integral_constant<bool, is_scalar<_Tp>::value ||
39 is_array<_Tp>::value ||
40 is_union<_Tp>::value ||
41 is_class<_Tp>::value > {};
37template <class _Tp>
38struct _LIBCPP_TEMPLATE_VIS is_object
39 : public integral_constant<bool,
40 is_scalar<_Tp>::value || is_array<_Tp>::value || is_union<_Tp>::value ||
41 is_class<_Tp>::value > {};
4242
43#if _LIBCPP_STD_VER > 14
43# if _LIBCPP_STD_VER >= 17
4444template <class _Tp>
4545inline constexpr bool is_object_v = is_object<_Tp>::value;
46#endif
46# endif
4747
4848#endif // __has_builtin(__is_object)
4949
lib/libcxx/include/__type_traits/is_pod.h+3-3
......@@ -18,10 +18,10 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pod
22 : public integral_constant<bool, __is_pod(_Tp)> {};
21template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS is_pod : public integral_constant<bool, __is_pod(_Tp)> {};
2323
24#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2525template <class _Tp>
2626inline constexpr bool is_pod_v = __is_pod(_Tp);
2727#endif
lib/libcxx/include/__type_traits/is_pointer.h+20-12
......@@ -21,34 +21,42 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121
2222#if __has_builtin(__is_pointer)
2323
24template<class _Tp>
25struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { };
24template <class _Tp>
25struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> {};
2626
27#if _LIBCPP_STD_VER > 14
27# if _LIBCPP_STD_VER >= 17
2828template <class _Tp>
2929inline constexpr bool is_pointer_v = __is_pointer(_Tp);
30#endif
30# endif
3131
3232#else // __has_builtin(__is_pointer)
3333
34template <class _Tp> struct __libcpp_is_pointer : public false_type {};
35template <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {};
34template <class _Tp>
35struct __libcpp_is_pointer : public false_type {};
36template <class _Tp>
37struct __libcpp_is_pointer<_Tp*> : public true_type {};
3638
37template <class _Tp> struct __libcpp_remove_objc_qualifiers { typedef _Tp type; };
38#if defined(_LIBCPP_HAS_OBJC_ARC)
39template <class _Tp>
40struct __libcpp_remove_objc_qualifiers {
41 typedef _Tp type;
42};
43# if defined(_LIBCPP_HAS_OBJC_ARC)
44// clang-format off
3945template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __strong> { typedef _Tp type; };
4046template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __weak> { typedef _Tp type; };
4147template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __autoreleasing> { typedef _Tp type; };
4248template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __unsafe_unretained> { typedef _Tp type; };
43#endif
49// clang-format on
50# endif
4451
45template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pointer
52template <class _Tp>
53struct _LIBCPP_TEMPLATE_VIS is_pointer
4654 : public __libcpp_is_pointer<typename __libcpp_remove_objc_qualifiers<__remove_cv_t<_Tp> >::type> {};
4755
48#if _LIBCPP_STD_VER > 14
56# if _LIBCPP_STD_VER >= 17
4957template <class _Tp>
5058inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
51#endif
59# endif
5260
5361#endif // __has_builtin(__is_pointer)
5462
lib/libcxx/include/__type_traits/is_polymorphic.h+2-3
......@@ -19,10 +19,9 @@
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
2121template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS is_polymorphic
23 : public integral_constant<bool, __is_polymorphic(_Tp)> {};
22struct _LIBCPP_TEMPLATE_VIS is_polymorphic : public integral_constant<bool, __is_polymorphic(_Tp)> {};
2423
25#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2625template <class _Tp>
2726inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp);
2827#endif
lib/libcxx/include/__type_traits/is_primary_template.h+3-6
......@@ -21,13 +21,10 @@
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
2323template <class _Tp>
24using __test_for_primary_template = __enable_if_t<
25 _IsSame<_Tp, typename _Tp::__primary_template>::value
26 >;
24using __test_for_primary_template = __enable_if_t<_IsSame<_Tp, typename _Tp::__primary_template>::value>;
25
2726template <class _Tp>
28using __is_primary_template = _IsValidExpansion<
29 __test_for_primary_template, _Tp
30 >;
27using __is_primary_template = _IsValidExpansion<__test_for_primary_template, _Tp>;
3128
3229_LIBCPP_END_NAMESPACE_STD
3330
lib/libcxx/include/__type_traits/is_reference.h+25-20
......@@ -18,41 +18,46 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21#if __has_builtin(__is_lvalue_reference) && \
22 __has_builtin(__is_rvalue_reference) && \
23 __has_builtin(__is_reference)
21#if __has_builtin(__is_lvalue_reference) && __has_builtin(__is_rvalue_reference) && __has_builtin(__is_reference)
2422
25template<class _Tp>
26struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> { };
23template <class _Tp>
24struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> {};
2725
28template<class _Tp>
29struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> { };
26template <class _Tp>
27struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> {};
3028
31template<class _Tp>
32struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> { };
29template <class _Tp>
30struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> {};
3331
34#if _LIBCPP_STD_VER > 14
32# if _LIBCPP_STD_VER >= 17
3533template <class _Tp>
3634inline constexpr bool is_reference_v = __is_reference(_Tp);
3735template <class _Tp>
3836inline constexpr bool is_lvalue_reference_v = __is_lvalue_reference(_Tp);
3937template <class _Tp>
4038inline constexpr bool is_rvalue_reference_v = __is_rvalue_reference(_Tp);
41#endif
39# endif
4240
4341#else // __has_builtin(__is_lvalue_reference) && etc...
4442
45template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {};
46template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {};
43template <class _Tp>
44struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {};
45template <class _Tp>
46struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {};
4747
48template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : public false_type {};
49template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference<_Tp&&> : public true_type {};
48template <class _Tp>
49struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : public false_type {};
50template <class _Tp>
51struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference<_Tp&&> : public true_type {};
5052
51template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference : public false_type {};
52template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&> : public true_type {};
53template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&&> : public true_type {};
53template <class _Tp>
54struct _LIBCPP_TEMPLATE_VIS is_reference : public false_type {};
55template <class _Tp>
56struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&> : public true_type {};
57template <class _Tp>
58struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&&> : public true_type {};
5459
55#if _LIBCPP_STD_VER > 14
60# if _LIBCPP_STD_VER >= 17
5661template <class _Tp>
5762inline constexpr bool is_reference_v = is_reference<_Tp>::value;
5863
......@@ -61,7 +66,7 @@ inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<_Tp>::value;
6166
6267template <class _Tp>
6368inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value;
64#endif
69# endif
6570
6671#endif // __has_builtin(__is_lvalue_reference) && etc...
6772
lib/libcxx/include/__type_traits/is_reference_wrapper.h+9-6
......@@ -19,12 +19,15 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22template <class _Tp> class _LIBCPP_TEMPLATE_VIS reference_wrapper;
23
24template <class _Tp> struct __is_reference_wrapper_impl : public false_type {};
25template <class _Tp> struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {};
26template <class _Tp> struct __is_reference_wrapper
27 : public __is_reference_wrapper_impl<__remove_cv_t<_Tp> > {};
22template <class _Tp>
23class _LIBCPP_TEMPLATE_VIS reference_wrapper;
24
25template <class _Tp>
26struct __is_reference_wrapper_impl : public false_type {};
27template <class _Tp>
28struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {};
29template <class _Tp>
30struct __is_reference_wrapper : public __is_reference_wrapper_impl<__remove_cv_t<_Tp> > {};
2831
2932_LIBCPP_END_NAMESPACE_STD
3033
lib/libcxx/include/__type_traits/is_same.h+2-2
......@@ -19,9 +19,9 @@
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
2121template <class _Tp, class _Up>
22struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> { };
22struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> {};
2323
24#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2525template <class _Tp, class _Up>
2626inline constexpr bool is_same_v = __is_same(_Tp, _Up);
2727#endif
lib/libcxx/include/__type_traits/is_scalar.h+25-18
......@@ -25,35 +25,42 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2525
2626#if __has_builtin(__is_scalar)
2727
28template<class _Tp>
29struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> { };
28template <class _Tp>
29struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> {};
3030
31#if _LIBCPP_STD_VER > 14
31# if _LIBCPP_STD_VER >= 17
3232template <class _Tp>
3333inline constexpr bool is_scalar_v = __is_scalar(_Tp);
34#endif
34# endif
3535
3636#else // __has_builtin(__is_scalar)
3737
38template <class _Tp> struct __is_block : false_type {};
39#if defined(_LIBCPP_HAS_EXTENSION_BLOCKS)
40template <class _Rp, class ..._Args> struct __is_block<_Rp (^)(_Args...)> : true_type {};
41#endif
38template <class _Tp>
39struct __is_block : false_type {};
40# if defined(_LIBCPP_HAS_EXTENSION_BLOCKS)
41template <class _Rp, class... _Args>
42struct __is_block<_Rp (^)(_Args...)> : true_type {};
43# endif
4244
43template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_scalar
44 : public integral_constant<bool, is_arithmetic<_Tp>::value ||
45 is_member_pointer<_Tp>::value ||
46 is_pointer<_Tp>::value ||
47 __is_nullptr_t<_Tp>::value ||
48 __is_block<_Tp>::value ||
49 is_enum<_Tp>::value > {};
45// clang-format off
46template <class _Tp>
47struct _LIBCPP_TEMPLATE_VIS is_scalar
48 : public integral_constant<
49 bool, is_arithmetic<_Tp>::value ||
50 is_member_pointer<_Tp>::value ||
51 is_pointer<_Tp>::value ||
52 __is_nullptr_t<_Tp>::value ||
53 __is_block<_Tp>::value ||
54 is_enum<_Tp>::value> {};
55// clang-format on
5056
51template <> struct _LIBCPP_TEMPLATE_VIS is_scalar<nullptr_t> : public true_type {};
57template <>
58struct _LIBCPP_TEMPLATE_VIS is_scalar<nullptr_t> : public true_type {};
5259
53#if _LIBCPP_STD_VER > 14
60# if _LIBCPP_STD_VER >= 17
5461template <class _Tp>
5562inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
56#endif
63# endif
5764
5865#endif // __has_builtin(__is_scalar)
5966
lib/libcxx/include/__type_traits/is_scoped_enum.h+3-5
......@@ -21,17 +21,15 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24#if _LIBCPP_STD_VER > 20
24#if _LIBCPP_STD_VER >= 23
2525template <class _Tp, bool = is_enum_v<_Tp> >
2626struct __is_scoped_enum_helper : false_type {};
2727
2828template <class _Tp>
29struct __is_scoped_enum_helper<_Tp, true>
30 : public bool_constant<!is_convertible_v<_Tp, underlying_type_t<_Tp> > > {};
29struct __is_scoped_enum_helper<_Tp, true> : public bool_constant<!is_convertible_v<_Tp, underlying_type_t<_Tp> > > {};
3130
3231template <class _Tp>
33struct _LIBCPP_TEMPLATE_VIS is_scoped_enum
34 : public __is_scoped_enum_helper<_Tp> {};
32struct _LIBCPP_TEMPLATE_VIS is_scoped_enum : public __is_scoped_enum_helper<_Tp> {};
3533
3634template <class _Tp>
3735inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
lib/libcxx/include/__type_traits/is_signed.h+11-9
......@@ -22,13 +22,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222
2323#if __has_builtin(__is_signed)
2424
25template<class _Tp>
26struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> { };
25template <class _Tp>
26struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> {};
2727
28#if _LIBCPP_STD_VER > 14
28# if _LIBCPP_STD_VER >= 17
2929template <class _Tp>
3030inline constexpr bool is_signed_v = __is_signed(_Tp);
31#endif
31# endif
3232
3333#else // __has_builtin(__is_signed)
3434
......@@ -36,19 +36,21 @@ template <class _Tp, bool = is_integral<_Tp>::value>
3636struct __libcpp_is_signed_impl : public _BoolConstant<(_Tp(-1) < _Tp(0))> {};
3737
3838template <class _Tp>
39struct __libcpp_is_signed_impl<_Tp, false> : public true_type {}; // floating point
39struct __libcpp_is_signed_impl<_Tp, false> : public true_type {}; // floating point
4040
4141template <class _Tp, bool = is_arithmetic<_Tp>::value>
4242struct __libcpp_is_signed : public __libcpp_is_signed_impl<_Tp> {};
4343
44template <class _Tp> struct __libcpp_is_signed<_Tp, false> : public false_type {};
44template <class _Tp>
45struct __libcpp_is_signed<_Tp, false> : public false_type {};
4546
46template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_signed : public __libcpp_is_signed<_Tp> {};
47template <class _Tp>
48struct _LIBCPP_TEMPLATE_VIS is_signed : public __libcpp_is_signed<_Tp> {};
4749
48#if _LIBCPP_STD_VER > 14
50# if _LIBCPP_STD_VER >= 17
4951template <class _Tp>
5052inline constexpr bool is_signed_v = is_signed<_Tp>::value;
51#endif
53# endif
5254
5355#endif // __has_builtin(__is_signed)
5456
lib/libcxx/include/__type_traits/is_signed_integer.h+9-7
......@@ -18,15 +18,17 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp> struct __libcpp_is_signed_integer : public false_type {};
22template <> struct __libcpp_is_signed_integer<signed char> : public true_type {};
23template <> struct __libcpp_is_signed_integer<signed short> : public true_type {};
24template <> struct __libcpp_is_signed_integer<signed int> : public true_type {};
25template <> struct __libcpp_is_signed_integer<signed long> : public true_type {};
26template <> struct __libcpp_is_signed_integer<signed long long> : public true_type {};
21// clang-format off
22template <class _Tp> struct __libcpp_is_signed_integer : public false_type {};
23template <> struct __libcpp_is_signed_integer<signed char> : public true_type {};
24template <> struct __libcpp_is_signed_integer<signed short> : public true_type {};
25template <> struct __libcpp_is_signed_integer<signed int> : public true_type {};
26template <> struct __libcpp_is_signed_integer<signed long> : public true_type {};
27template <> struct __libcpp_is_signed_integer<signed long long> : public true_type {};
2728#ifndef _LIBCPP_HAS_NO_INT128
28template <> struct __libcpp_is_signed_integer<__int128_t> : public true_type {};
29template <> struct __libcpp_is_signed_integer<__int128_t> : public true_type {};
2930#endif
31// clang-format on
3032
3133_LIBCPP_END_NAMESPACE_STD
3234
lib/libcxx/include/__type_traits/is_specialization.h+2-2
......@@ -30,7 +30,7 @@
3030
3131_LIBCPP_BEGIN_NAMESPACE_STD
3232
33#if _LIBCPP_STD_VER > 14
33#if _LIBCPP_STD_VER >= 17
3434
3535template <class _Tp, template <class...> class _Template>
3636inline constexpr bool __is_specialization_v = false; // true if and only if _Tp is a specialization of _Template
......@@ -38,7 +38,7 @@ inline constexpr bool __is_specialization_v = false; // true if and only if _Tp
3838template <template <class...> class _Template, class... _Args>
3939inline constexpr bool __is_specialization_v<_Template<_Args...>, _Template> = true;
4040
41#endif // _LIBCPP_STD_VER > 14
41#endif // _LIBCPP_STD_VER >= 17
4242
4343_LIBCPP_END_NAMESPACE_STD
4444
lib/libcxx/include/__type_traits/is_standard_layout.h+3-4
......@@ -18,11 +18,10 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_standard_layout
22 : public integral_constant<bool, __is_standard_layout(_Tp)>
23 {};
21template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS is_standard_layout : public integral_constant<bool, __is_standard_layout(_Tp)> {};
2423
25#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2625template <class _Tp>
2726inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp);
2827#endif
lib/libcxx/include/__type_traits/is_swappable.h+37-67
......@@ -30,9 +30,10 @@
3030
3131_LIBCPP_BEGIN_NAMESPACE_STD
3232
33template <class _Tp> struct __is_swappable;
34template <class _Tp> struct __is_nothrow_swappable;
35
33template <class _Tp>
34struct __is_swappable;
35template <class _Tp>
36struct __is_nothrow_swappable;
3637
3738#ifndef _LIBCPP_CXX03_LANG
3839template <class _Tp>
......@@ -43,49 +44,40 @@ using __swap_result_t = void;
4344#endif
4445
4546template <class _Tp>
46inline _LIBCPP_INLINE_VISIBILITY
47_LIBCPP_CONSTEXPR_SINCE_CXX20 __swap_result_t<_Tp>
48swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value &&
49 is_nothrow_move_assignable<_Tp>::value);
47inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __swap_result_t<_Tp> swap(_Tp& __x, _Tp& __y)
48 _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value&& is_nothrow_move_assignable<_Tp>::value);
5049
51template<class _Tp, size_t _Np>
50template <class _Tp, size_t _Np>
5251inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
53typename enable_if<
54 __is_swappable<_Tp>::value
55>::type
56swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value);
52 typename enable_if<__is_swappable<_Tp>::value>::type swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np])
53 _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value);
5754
58namespace __detail
59{
55namespace __detail {
6056// ALL generic swap overloads MUST already have a declaration available at this point.
6157
62template <class _Tp, class _Up = _Tp,
63 bool _NotVoid = !is_void<_Tp>::value && !is_void<_Up>::value>
64struct __swappable_with
65{
66 template <class _LHS, class _RHS>
67 static decltype(swap(std::declval<_LHS>(), std::declval<_RHS>()))
68 __test_swap(int);
69 template <class, class>
70 static __nat __test_swap(long);
71
72 // Extra parens are needed for the C++03 definition of decltype.
73 typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1;
74 typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2;
75
76 static const bool value = _IsNotSame<__swap1, __nat>::value
77 && _IsNotSame<__swap2, __nat>::value;
58template <class _Tp, class _Up = _Tp, bool _NotVoid = !is_void<_Tp>::value && !is_void<_Up>::value>
59struct __swappable_with {
60 template <class _LHS, class _RHS>
61 static decltype(swap(std::declval<_LHS>(), std::declval<_RHS>())) __test_swap(int);
62 template <class, class>
63 static __nat __test_swap(long);
64
65 // Extra parens are needed for the C++03 definition of decltype.
66 typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1;
67 typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2;
68
69 static const bool value = _IsNotSame<__swap1, __nat>::value && _IsNotSame<__swap2, __nat>::value;
7870};
7971
8072template <class _Tp, class _Up>
81struct __swappable_with<_Tp, _Up, false> : false_type {};
73struct __swappable_with<_Tp, _Up, false> : false_type {};
8274
8375template <class _Tp, class _Up = _Tp, bool _Swappable = __swappable_with<_Tp, _Up>::value>
8476struct __nothrow_swappable_with {
8577 static const bool value =
8678#ifndef _LIBCPP_HAS_NO_NOEXCEPT
87 noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()))
88 && noexcept(swap(std::declval<_Up>(), std::declval<_Tp>()));
79 noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()))&& noexcept(
80 swap(std::declval<_Up>(), std::declval<_Tp>()));
8981#else
9082 false;
9183#endif
......@@ -97,54 +89,32 @@ struct __nothrow_swappable_with<_Tp, _Up, false> : false_type {};
9789} // namespace __detail
9890
9991template <class _Tp>
100struct __is_swappable
101 : public integral_constant<bool, __detail::__swappable_with<_Tp&>::value>
102{
103};
92struct __is_swappable : public integral_constant<bool, __detail::__swappable_with<_Tp&>::value> {};
10493
10594template <class _Tp>
106struct __is_nothrow_swappable
107 : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp&>::value>
108{
109};
95struct __is_nothrow_swappable : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp&>::value> {};
11096
111#if _LIBCPP_STD_VER > 14
97#if _LIBCPP_STD_VER >= 17
11298
11399template <class _Tp, class _Up>
114100struct _LIBCPP_TEMPLATE_VIS is_swappable_with
115 : public integral_constant<bool, __detail::__swappable_with<_Tp, _Up>::value>
116{
117};
101 : public integral_constant<bool, __detail::__swappable_with<_Tp, _Up>::value> {};
118102
119103template <class _Tp>
120104struct _LIBCPP_TEMPLATE_VIS is_swappable
121 : public __conditional_t<
122 __libcpp_is_referenceable<_Tp>::value,
123 is_swappable_with<
124 __add_lvalue_reference_t<_Tp>,
125 __add_lvalue_reference_t<_Tp> >,
126 false_type
127 >
128{
129};
105 : public __conditional_t<__libcpp_is_referenceable<_Tp>::value,
106 is_swappable_with<__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<_Tp> >,
107 false_type> {};
130108
131109template <class _Tp, class _Up>
132110struct _LIBCPP_TEMPLATE_VIS is_nothrow_swappable_with
133 : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp, _Up>::value>
134{
135};
111 : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp, _Up>::value> {};
136112
137113template <class _Tp>
138114struct _LIBCPP_TEMPLATE_VIS is_nothrow_swappable
139 : public __conditional_t<
140 __libcpp_is_referenceable<_Tp>::value,
141 is_nothrow_swappable_with<
142 __add_lvalue_reference_t<_Tp>,
143 __add_lvalue_reference_t<_Tp> >,
144 false_type
145 >
146{
147};
115 : public __conditional_t<__libcpp_is_referenceable<_Tp>::value,
116 is_nothrow_swappable_with<__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<_Tp> >,
117 false_type> {};
148118
149119template <class _Tp, class _Up>
150120inline constexpr bool is_swappable_with_v = is_swappable_with<_Tp, _Up>::value;
......@@ -158,7 +128,7 @@ inline constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<_T
158128template <class _Tp>
159129inline constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Tp>::value;
160130
161#endif // _LIBCPP_STD_VER > 14
131#endif // _LIBCPP_STD_VER >= 17
162132
163133_LIBCPP_END_NAMESPACE_STD
164134
lib/libcxx/include/__type_traits/is_trivial.h+3-4
......@@ -18,11 +18,10 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivial
22 : public integral_constant<bool, __is_trivial(_Tp)>
23 {};
21template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS is_trivial : public integral_constant<bool, __is_trivial(_Tp)> {};
2423
25#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2625template <class _Tp>
2726inline constexpr bool is_trivial_v = __is_trivial(_Tp);
2827#endif
lib/libcxx/include/__type_traits/is_trivially_assignable.h+2-4
......@@ -19,11 +19,9 @@
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
2121template <class _Tp, class _Arg>
22struct is_trivially_assignable
23 : integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)>
24{ };
22struct is_trivially_assignable : integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)> {};
2523
26#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2725template <class _Tp, class _Arg>
2826inline constexpr bool is_trivially_assignable_v = __is_trivially_assignable(_Tp, _Arg);
2927#endif
lib/libcxx/include/__type_traits/is_trivially_constructible.h+2-4
......@@ -20,11 +20,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2020
2121template <class _Tp, class... _Args>
2222struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible
23 : integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)>
24{
25};
23 : integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)> {};
2624
27#if _LIBCPP_STD_VER > 14
25#if _LIBCPP_STD_VER >= 17
2826template <class _Tp, class... _Args>
2927inline constexpr bool is_trivially_constructible_v = __is_trivially_constructible(_Tp, _Args...);
3028#endif
lib/libcxx/include/__type_traits/is_trivially_copy_assignable.h+4-6
......@@ -22,13 +22,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222
2323template <class _Tp>
2424struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_assignable
25 : public integral_constant<
26 bool,
27 __is_trivially_assignable(
28 __add_lvalue_reference_t<_Tp>,
29 __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
25 : public integral_constant<bool,
26 __is_trivially_assignable(__add_lvalue_reference_t<_Tp>,
27 __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {};
3028
31#if _LIBCPP_STD_VER > 14
29#if _LIBCPP_STD_VER >= 17
3230template <class _Tp>
3331inline constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<_Tp>::value;
3432#endif
lib/libcxx/include/__type_traits/is_trivially_copy_constructible.h+4-4
......@@ -19,11 +19,11 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_constructible
23 : public integral_constant<bool, __is_trivially_constructible(_Tp, __add_lvalue_reference_t<const _Tp>)>
24 {};
22template <class _Tp>
23struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_constructible
24 : public integral_constant<bool, __is_trivially_constructible(_Tp, __add_lvalue_reference_t<const _Tp>)> {};
2525
26#if _LIBCPP_STD_VER > 14
26#if _LIBCPP_STD_VER >= 17
2727template <class _Tp>
2828inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<_Tp>::value;
2929#endif
lib/libcxx/include/__type_traits/is_trivially_copyable.h+9-4
......@@ -11,6 +11,7 @@
1111
1212#include <__config>
1313#include <__type_traits/integral_constant.h>
14#include <cstdint>
1415
1516#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1617# pragma GCC system_header
......@@ -18,15 +19,19 @@
1819
1920_LIBCPP_BEGIN_NAMESPACE_STD
2021
21template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_copyable
22 : public integral_constant<bool, __is_trivially_copyable(_Tp)>
23 {};
22template <class _Tp>
23struct _LIBCPP_TEMPLATE_VIS is_trivially_copyable : public integral_constant<bool, __is_trivially_copyable(_Tp)> {};
2424
25#if _LIBCPP_STD_VER > 14
25#if _LIBCPP_STD_VER >= 17
2626template <class _Tp>
2727inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp);
2828#endif
2929
30#if _LIBCPP_STD_VER >= 20
31template <class _Tp>
32inline constexpr bool __is_cheap_to_copy = is_trivially_copyable_v<_Tp> && sizeof(_Tp) <= sizeof(std::intmax_t);
33#endif
34
3035_LIBCPP_END_NAMESPACE_STD
3136
3237#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_COPYABLE_H
lib/libcxx/include/__type_traits/is_trivially_default_constructible.h+4-4
......@@ -18,11 +18,11 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_default_constructible
22 : public integral_constant<bool, __is_trivially_constructible(_Tp)>
23 {};
21template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS is_trivially_default_constructible
23 : public integral_constant<bool, __is_trivially_constructible(_Tp)> {};
2424
25#if _LIBCPP_STD_VER > 14
25#if _LIBCPP_STD_VER >= 17
2626template <class _Tp>
2727inline constexpr bool is_trivially_default_constructible_v = __is_trivially_constructible(_Tp);
2828#endif
lib/libcxx/include/__type_traits/is_trivially_destructible.h+7-5
......@@ -21,21 +21,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121
2222#if __has_builtin(__is_trivially_destructible)
2323
24template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
24template <class _Tp>
25struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
2526 : public integral_constant<bool, __is_trivially_destructible(_Tp)> {};
2627
2728#elif __has_builtin(__has_trivial_destructor)
2829
29template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
30 : public integral_constant<bool, is_destructible<_Tp>::value && __has_trivial_destructor(_Tp)> {};
30template <class _Tp>
31struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
32 : public integral_constant<bool, is_destructible<_Tp>::value&& __has_trivial_destructor(_Tp)> {};
3133
3234#else
3335
34#error is_trivially_destructible is not implemented
36# error is_trivially_destructible is not implemented
3537
3638#endif // __has_builtin(__is_trivially_destructible)
3739
38#if _LIBCPP_STD_VER > 14
40#if _LIBCPP_STD_VER >= 17
3941template <class _Tp>
4042inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<_Tp>::value;
4143#endif
lib/libcxx/include/__type_traits/is_trivially_lexicographically_comparable.h created+53
......@@ -0,0 +1,53 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_LEXICOGRAPHICALLY_COMPARABLE_H
10#define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_LEXICOGRAPHICALLY_COMPARABLE_H
11
12#include <__config>
13#include <__type_traits/integral_constant.h>
14#include <__type_traits/is_same.h>
15#include <__type_traits/is_unsigned.h>
16#include <__type_traits/remove_cv.h>
17#include <__type_traits/void_t.h>
18#include <__utility/declval.h>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21# pragma GCC system_header
22#endif
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26// A type is_trivially_lexicographically_comparable if the expression `a <=> b` (or their pre-C++20 equivalents) is
27// equivalent to `std::memcmp(&a, &b, sizeof(T))` (with `a` and `b` being of type `T`). There is currently no builtin to
28// tell us whether that's the case for arbitrary types, so we can only do this for known types. Specifically, these are
29// currently unsigned integer types with a sizeof(T) == 1.
30//
31// bool is trivially lexicographically comparable, because e.g. false <=> true is valid code. Furthermore, the standard
32// says that [basic.fundamental] "Type bool is a distinct type that has the same object representation, value
33// representation, and alignment requirements as an implementation-defined unsigned integer type. The values of type
34// bool are true and false."
35// This means that bool has to be unsigned and has exactly two values. This means that having anything other than the
36// `true` or `false` value representations in a bool is UB.
37//
38// The following types are not trivially lexicographically comparable:
39// signed integer types: `char(-1) < char(1)`, but memcmp compares `unsigned char`s
40// unsigned integer types with sizeof(T) > 1: depending on the endianness, the LSB might be the first byte to be
41// compared. This means that when comparing unsigned(129) and unsigned(2)
42// using memcmp(), the result would be that 2 > 129.
43// TODO: Do we want to enable this on big-endian systems?
44
45template <class _Tp, class _Up>
46struct __libcpp_is_trivially_lexicographically_comparable
47 : integral_constant<bool,
48 is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value && sizeof(_Tp) == 1 &&
49 is_unsigned<_Tp>::value> {};
50
51_LIBCPP_END_NAMESPACE_STD
52
53#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_LEXICOGRAPHICALLY_COMPARABLE_H
lib/libcxx/include/__type_traits/is_trivially_move_assignable.h+1-1
......@@ -26,7 +26,7 @@ struct _LIBCPP_TEMPLATE_VIS is_trivially_move_assignable
2626 bool,
2727 __is_trivially_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {};
2828
29#if _LIBCPP_STD_VER > 14
29#if _LIBCPP_STD_VER >= 17
3030template <class _Tp>
3131inline constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable<_Tp>::value;
3232#endif
lib/libcxx/include/__type_traits/is_trivially_move_constructible.h+1-1
......@@ -23,7 +23,7 @@ template <class _Tp>
2323struct _LIBCPP_TEMPLATE_VIS is_trivially_move_constructible
2424 : public integral_constant<bool, __is_trivially_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {};
2525
26#if _LIBCPP_STD_VER > 14
26#if _LIBCPP_STD_VER >= 17
2727template <class _Tp>
2828inline constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<_Tp>::value;
2929#endif
lib/libcxx/include/__type_traits/is_unbounded_array.h+10-7
......@@ -18,17 +18,20 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array : false_type {};
22template <class _Tp> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array<_Tp[]> : true_type {};
21template <class>
22struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array : false_type {};
23template <class _Tp>
24struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array<_Tp[]> : true_type {};
2325
24#if _LIBCPP_STD_VER > 17
26#if _LIBCPP_STD_VER >= 20
2527
26template <class> struct _LIBCPP_TEMPLATE_VIS is_unbounded_array : false_type {};
27template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_unbounded_array<_Tp[]> : true_type {};
28template <class>
29struct _LIBCPP_TEMPLATE_VIS is_unbounded_array : false_type {};
30template <class _Tp>
31struct _LIBCPP_TEMPLATE_VIS is_unbounded_array<_Tp[]> : true_type {};
2832
2933template <class _Tp>
30inline constexpr
31bool is_unbounded_array_v = is_unbounded_array<_Tp>::value;
34inline constexpr bool is_unbounded_array_v = is_unbounded_array<_Tp>::value;
3235
3336#endif
3437
lib/libcxx/include/__type_traits/is_union.h+3-3
......@@ -18,10 +18,10 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_union
22 : public integral_constant<bool, __is_union(_Tp)> {};
21template <class _Tp>
22struct _LIBCPP_TEMPLATE_VIS is_union : public integral_constant<bool, __is_union(_Tp)> {};
2323
24#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2525template <class _Tp>
2626inline constexpr bool is_union_v = __is_union(_Tp);
2727#endif
lib/libcxx/include/__type_traits/is_unsigned.h+11-9
......@@ -22,13 +22,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222
2323#if __has_builtin(__is_unsigned)
2424
25template<class _Tp>
26struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> { };
25template <class _Tp>
26struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> {};
2727
28#if _LIBCPP_STD_VER > 14
28# if _LIBCPP_STD_VER >= 17
2929template <class _Tp>
3030inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
31#endif
31# endif
3232
3333#else // __has_builtin(__is_unsigned)
3434
......@@ -36,19 +36,21 @@ template <class _Tp, bool = is_integral<_Tp>::value>
3636struct __libcpp_is_unsigned_impl : public _BoolConstant<(_Tp(0) < _Tp(-1))> {};
3737
3838template <class _Tp>
39struct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {}; // floating point
39struct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {}; // floating point
4040
4141template <class _Tp, bool = is_arithmetic<_Tp>::value>
4242struct __libcpp_is_unsigned : public __libcpp_is_unsigned_impl<_Tp> {};
4343
44template <class _Tp> struct __libcpp_is_unsigned<_Tp, false> : public false_type {};
44template <class _Tp>
45struct __libcpp_is_unsigned<_Tp, false> : public false_type {};
4546
46template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_unsigned : public __libcpp_is_unsigned<_Tp> {};
47template <class _Tp>
48struct _LIBCPP_TEMPLATE_VIS is_unsigned : public __libcpp_is_unsigned<_Tp> {};
4749
48#if _LIBCPP_STD_VER > 14
50# if _LIBCPP_STD_VER >= 17
4951template <class _Tp>
5052inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
51#endif
53# endif
5254
5355#endif // __has_builtin(__is_unsigned)
5456
lib/libcxx/include/__type_traits/is_unsigned_integer.h+9-7
......@@ -18,15 +18,17 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp> struct __libcpp_is_unsigned_integer : public false_type {};
22template <> struct __libcpp_is_unsigned_integer<unsigned char> : public true_type {};
23template <> struct __libcpp_is_unsigned_integer<unsigned short> : public true_type {};
24template <> struct __libcpp_is_unsigned_integer<unsigned int> : public true_type {};
25template <> struct __libcpp_is_unsigned_integer<unsigned long> : public true_type {};
26template <> struct __libcpp_is_unsigned_integer<unsigned long long> : public true_type {};
21// clang-format off
22template <class _Tp> struct __libcpp_is_unsigned_integer : public false_type {};
23template <> struct __libcpp_is_unsigned_integer<unsigned char> : public true_type {};
24template <> struct __libcpp_is_unsigned_integer<unsigned short> : public true_type {};
25template <> struct __libcpp_is_unsigned_integer<unsigned int> : public true_type {};
26template <> struct __libcpp_is_unsigned_integer<unsigned long> : public true_type {};
27template <> struct __libcpp_is_unsigned_integer<unsigned long long> : public true_type {};
2728#ifndef _LIBCPP_HAS_NO_INT128
28template <> struct __libcpp_is_unsigned_integer<__uint128_t> : public true_type {};
29template <> struct __libcpp_is_unsigned_integer<__uint128_t> : public true_type {};
2930#endif
31// clang-format on
3032
3133_LIBCPP_END_NAMESPACE_STD
3234
lib/libcxx/include/__type_traits/is_valid_expansion.h+3-3
......@@ -18,12 +18,12 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <template <class...> class _Templ, class ..._Args, class = _Templ<_Args...> >
21template <template <class...> class _Templ, class... _Args, class = _Templ<_Args...> >
2222true_type __sfinae_test_impl(int);
23template <template <class...> class, class ...>
23template <template <class...> class, class...>
2424false_type __sfinae_test_impl(...);
2525
26template <template <class ...> class _Templ, class ..._Args>
26template <template <class...> class _Templ, class... _Args>
2727using _IsValidExpansion _LIBCPP_NODEBUG = decltype(std::__sfinae_test_impl<_Templ, _Args...>(0));
2828
2929_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/is_void.h+7-7
......@@ -23,22 +23,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2323#if __has_builtin(__is_void)
2424
2525template <class _Tp>
26struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> { };
26struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> {};
2727
28#if _LIBCPP_STD_VER > 14
28# if _LIBCPP_STD_VER >= 17
2929template <class _Tp>
3030inline constexpr bool is_void_v = __is_void(_Tp);
31#endif
31# endif
3232
3333#else
3434
35template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_void
36 : public is_same<__remove_cv_t<_Tp>, void> {};
35template <class _Tp>
36struct _LIBCPP_TEMPLATE_VIS is_void : public is_same<__remove_cv_t<_Tp>, void> {};
3737
38#if _LIBCPP_STD_VER > 14
38# if _LIBCPP_STD_VER >= 17
3939template <class _Tp>
4040inline constexpr bool is_void_v = is_void<_Tp>::value;
41#endif
41# endif
4242
4343#endif // __has_builtin(__is_void)
4444
lib/libcxx/include/__type_traits/is_volatile.h+9-7
......@@ -21,22 +21,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121#if __has_builtin(__is_volatile)
2222
2323template <class _Tp>
24struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> { };
24struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> {};
2525
26#if _LIBCPP_STD_VER > 14
26# if _LIBCPP_STD_VER >= 17
2727template <class _Tp>
2828inline constexpr bool is_volatile_v = __is_volatile(_Tp);
29#endif
29# endif
3030
3131#else
3232
33template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile : public false_type {};
34template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {};
33template <class _Tp>
34struct _LIBCPP_TEMPLATE_VIS is_volatile : public false_type {};
35template <class _Tp>
36struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {};
3537
36#if _LIBCPP_STD_VER > 14
38# if _LIBCPP_STD_VER >= 17
3739template <class _Tp>
3840inline constexpr bool is_volatile_v = is_volatile<_Tp>::value;
39#endif
41# endif
4042
4143#endif // __has_builtin(__is_volatile)
4244
lib/libcxx/include/__type_traits/lazy.h+1-1
......@@ -17,7 +17,7 @@
1717
1818_LIBCPP_BEGIN_NAMESPACE_STD
1919
20template <template <class...> class _Func, class ..._Args>
20template <template <class...> class _Func, class... _Args>
2121struct _Lazy : _Func<_Args...> {};
2222
2323_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/make_32_64_or_128_bit.h+11-10
......@@ -27,21 +27,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2727///
2828/// The restriction is the same as the integral version of to_char.
2929template <class _Tp>
30#if _LIBCPP_STD_VER > 17
31 requires (is_signed_v<_Tp> || is_unsigned_v<_Tp> || is_same_v<_Tp, char>)
30#if _LIBCPP_STD_VER >= 20
31 requires(is_signed_v<_Tp> || is_unsigned_v<_Tp> || is_same_v<_Tp, char>)
3232#endif
33// clang-format off
3334using __make_32_64_or_128_bit_t =
34 __copy_unsigned_t<_Tp,
35 __conditional_t<sizeof(_Tp) <= sizeof(int32_t), int32_t,
36 __conditional_t<sizeof(_Tp) <= sizeof(int64_t), int64_t,
35 __copy_unsigned_t<_Tp,
36 __conditional_t<sizeof(_Tp) <= sizeof(int32_t), int32_t,
37 __conditional_t<sizeof(_Tp) <= sizeof(int64_t), int64_t,
3738#ifndef _LIBCPP_HAS_NO_INT128
38 __conditional_t<sizeof(_Tp) <= sizeof(__int128_t), __int128_t,
39 /* else */ void>
39 __conditional_t<sizeof(_Tp) <= sizeof(__int128_t), __int128_t,
40 /* else */ void>
4041#else
41 /* else */ void
42 /* else */ void
4243#endif
43 > >
44 >;
44 > > >;
45// clang-format on
4546
4647_LIBCPP_END_NAMESPACE_STD
4748
lib/libcxx/include/__type_traits/make_const_lvalue_ref.h+1-1
......@@ -18,7 +18,7 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template<class _Tp>
21template <class _Tp>
2222using __make_const_lvalue_ref = const __libcpp_remove_reference_t<_Tp>&;
2323
2424_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/make_signed.h+20-17
......@@ -29,30 +29,31 @@ template <class _Tp>
2929using __make_signed_t = __make_signed(_Tp);
3030
3131#else
32typedef
33 __type_list<signed char,
34 __type_list<signed short,
35 __type_list<signed int,
36 __type_list<signed long,
37 __type_list<signed long long,
32// clang-format off
33typedef __type_list<signed char,
34 __type_list<signed short,
35 __type_list<signed int,
36 __type_list<signed long,
37 __type_list<signed long long,
3838# ifndef _LIBCPP_HAS_NO_INT128
39 __type_list<__int128_t,
39 __type_list<__int128_t,
4040# endif
41 __nat
41 __nat
4242# ifndef _LIBCPP_HAS_NO_INT128
43 >
43 >
4444# endif
45 > > > > > __signed_types;
45 > > > > > __signed_types;
46// clang-format on
4647
4748template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
48struct __make_signed {};
49struct __make_signed{};
4950
5051template <class _Tp>
51struct __make_signed<_Tp, true>
52{
53 typedef typename __find_first<__signed_types, sizeof(_Tp)>::type type;
52struct __make_signed<_Tp, true> {
53 typedef typename __find_first<__signed_types, sizeof(_Tp)>::type type;
5454};
5555
56// clang-format off
5657template <> struct __make_signed<bool, true> {};
5758template <> struct __make_signed< signed short, true> {typedef short type;};
5859template <> struct __make_signed<unsigned short, true> {typedef short type;};
......@@ -66,9 +67,10 @@ template <> struct __make_signed<unsigned long long, true> {typedef long long ty
6667template <> struct __make_signed<__int128_t, true> {typedef __int128_t type;};
6768template <> struct __make_signed<__uint128_t, true> {typedef __int128_t type;};
6869# endif
70// clang-format on
6971
7072template <class _Tp>
71using __make_signed_t = typename __apply_cv<_Tp, typename __make_signed<__remove_cv_t<_Tp> >::type>::type;
73using __make_signed_t = __apply_cv_t<_Tp, typename __make_signed<__remove_cv_t<_Tp> >::type>;
7274
7375#endif // __has_builtin(__make_signed)
7476
......@@ -77,8 +79,9 @@ struct make_signed {
7779 using type _LIBCPP_NODEBUG = __make_signed_t<_Tp>;
7880};
7981
80#if _LIBCPP_STD_VER > 11
81template <class _Tp> using make_signed_t = __make_signed_t<_Tp>;
82#if _LIBCPP_STD_VER >= 14
83template <class _Tp>
84using make_signed_t = __make_signed_t<_Tp>;
8285#endif
8386
8487_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/make_unsigned.h+22-20
......@@ -31,30 +31,31 @@ template <class _Tp>
3131using __make_unsigned_t = __make_unsigned(_Tp);
3232
3333#else
34typedef
35 __type_list<unsigned char,
36 __type_list<unsigned short,
37 __type_list<unsigned int,
38 __type_list<unsigned long,
39 __type_list<unsigned long long,
34// clang-format off
35typedef __type_list<unsigned char,
36 __type_list<unsigned short,
37 __type_list<unsigned int,
38 __type_list<unsigned long,
39 __type_list<unsigned long long,
4040# ifndef _LIBCPP_HAS_NO_INT128
41 __type_list<__uint128_t,
41 __type_list<__uint128_t,
4242# endif
43 __nat
43 __nat
4444# ifndef _LIBCPP_HAS_NO_INT128
45 >
45 >
4646# endif
47 > > > > > __unsigned_types;
47 > > > > > __unsigned_types;
48// clang-format on
4849
4950template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
50struct __make_unsigned {};
51struct __make_unsigned{};
5152
5253template <class _Tp>
53struct __make_unsigned<_Tp, true>
54{
55 typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type;
54struct __make_unsigned<_Tp, true> {
55 typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type;
5656};
5757
58// clang-format off
5859template <> struct __make_unsigned<bool, true> {};
5960template <> struct __make_unsigned< signed short, true> {typedef unsigned short type;};
6061template <> struct __make_unsigned<unsigned short, true> {typedef unsigned short type;};
......@@ -68,9 +69,10 @@ template <> struct __make_unsigned<unsigned long long, true> {typedef unsigned l
6869template <> struct __make_unsigned<__int128_t, true> {typedef __uint128_t type;};
6970template <> struct __make_unsigned<__uint128_t, true> {typedef __uint128_t type;};
7071# endif
72// clang-format on
7173
7274template <class _Tp>
73using __make_unsigned_t = typename __apply_cv<_Tp, typename __make_unsigned<__remove_cv_t<_Tp> >::type>::type;
75using __make_unsigned_t = __apply_cv_t<_Tp, typename __make_unsigned<__remove_cv_t<_Tp> >::type>;
7476
7577#endif // __has_builtin(__make_unsigned)
7678
......@@ -79,15 +81,15 @@ struct make_unsigned {
7981 using type _LIBCPP_NODEBUG = __make_unsigned_t<_Tp>;
8082};
8183
82#if _LIBCPP_STD_VER > 11
83template <class _Tp> using make_unsigned_t = __make_unsigned_t<_Tp>;
84#if _LIBCPP_STD_VER >= 14
85template <class _Tp>
86using make_unsigned_t = __make_unsigned_t<_Tp>;
8487#endif
8588
8689#ifndef _LIBCPP_CXX03_LANG
8790template <class _Tp>
88_LIBCPP_HIDE_FROM_ABI constexpr
89__make_unsigned_t<_Tp> __to_unsigned_like(_Tp __x) noexcept {
90 return static_cast<__make_unsigned_t<_Tp> >(__x);
91_LIBCPP_HIDE_FROM_ABI constexpr __make_unsigned_t<_Tp> __to_unsigned_like(_Tp __x) noexcept {
92 return static_cast<__make_unsigned_t<_Tp> >(__x);
9193}
9294#endif
9395
lib/libcxx/include/__type_traits/maybe_const.h+1-1
......@@ -18,7 +18,7 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template<bool _Const, class _Tp>
21template <bool _Const, class _Tp>
2222using __maybe_const = __conditional_t<_Const, const _Tp, _Tp>;
2323
2424_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/nat.h+5-6
......@@ -17,13 +17,12 @@
1717
1818_LIBCPP_BEGIN_NAMESPACE_STD
1919
20struct __nat
21{
20struct __nat {
2221#ifndef _LIBCPP_CXX03_LANG
23 __nat() = delete;
24 __nat(const __nat&) = delete;
25 __nat& operator=(const __nat&) = delete;
26 ~__nat() = delete;
22 __nat() = delete;
23 __nat(const __nat&) = delete;
24 __nat& operator=(const __nat&) = delete;
25 ~__nat() = delete;
2726#endif
2827};
2928
lib/libcxx/include/__type_traits/negation.h+3-3
......@@ -21,12 +21,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121template <class _Pred>
2222struct _Not : _BoolConstant<!_Pred::value> {};
2323
24#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2525template <class _Tp>
2626struct negation : _Not<_Tp> {};
27template<class _Tp>
27template <class _Tp>
2828inline constexpr bool negation_v = !_Tp::value;
29#endif // _LIBCPP_STD_VER > 14
29#endif // _LIBCPP_STD_VER >= 17
3030
3131_LIBCPP_END_NAMESPACE_STD
3232
lib/libcxx/include/__type_traits/noexcept_move_assign_container.h+9-7
......@@ -20,15 +20,17 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23template <typename _Alloc, typename _Traits=allocator_traits<_Alloc> >
24struct __noexcept_move_assign_container : public integral_constant<bool,
25 _Traits::propagate_on_container_move_assignment::value
26#if _LIBCPP_STD_VER > 14
27 || _Traits::is_always_equal::value
23template <typename _Alloc, typename _Traits = allocator_traits<_Alloc> >
24struct __noexcept_move_assign_container
25 : public integral_constant<bool,
26 _Traits::propagate_on_container_move_assignment::value
27#if _LIBCPP_STD_VER >= 17
28 || _Traits::is_always_equal::value
2829#else
29 && is_nothrow_move_assignable<_Alloc>::value
30 && is_nothrow_move_assignable<_Alloc>::value
3031#endif
31 > {};
32 > {
33};
3234
3335_LIBCPP_END_NAMESPACE_STD
3436
lib/libcxx/include/__type_traits/operation_traits.h created+26
......@@ -0,0 +1,26 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TYPE_TRAITS_OPERATION_TRAITS_H
10#define _LIBCPP___TYPE_TRAITS_OPERATION_TRAITS_H
11
12#include <__config>
13#include <__type_traits/integral_constant.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21template <class _Pred, class _Lhs, class _Rhs>
22struct __is_trivial_plus_operation : false_type {};
23
24_LIBCPP_END_NAMESPACE_STD
25
26#endif // _LIBCPP___TYPE_TRAITS_OPERATION_TRAITS_H
lib/libcxx/include/__type_traits/predicate_traits.h created+26
......@@ -0,0 +1,26 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS
10#define _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS
11
12#include <__config>
13#include <__type_traits/integral_constant.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21template <class _Pred, class _Lhs, class _Rhs>
22struct __is_trivial_equality_predicate : false_type {};
23
24_LIBCPP_END_NAMESPACE_STD
25
26#endif // _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS
lib/libcxx/include/__type_traits/promote.h+40-45
......@@ -13,7 +13,6 @@
1313#include <__type_traits/integral_constant.h>
1414#include <__type_traits/is_same.h>
1515#include <__utility/declval.h>
16#include <cstddef>
1716
1817#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1918# pragma GCC system_header
......@@ -22,73 +21,69 @@
2221_LIBCPP_BEGIN_NAMESPACE_STD
2322
2423template <class _Tp>
25struct __numeric_type
26{
27 static void __test(...);
28 static float __test(float);
29 static double __test(char);
30 static double __test(int);
31 static double __test(unsigned);
32 static double __test(long);
33 static double __test(unsigned long);
34 static double __test(long long);
35 static double __test(unsigned long long);
24struct __numeric_type {
25 static void __test(...);
26 static float __test(float);
27 static double __test(char);
28 static double __test(int);
29 static double __test(unsigned);
30 static double __test(long);
31 static double __test(unsigned long);
32 static double __test(long long);
33 static double __test(unsigned long long);
3634#ifndef _LIBCPP_HAS_NO_INT128
37 static double __test(__int128_t);
38 static double __test(__uint128_t);
35 static double __test(__int128_t);
36 static double __test(__uint128_t);
3937#endif
40 static double __test(double);
41 static long double __test(long double);
38 static double __test(double);
39 static long double __test(long double);
4240
43 typedef decltype(__test(std::declval<_Tp>())) type;
44 static const bool value = _IsNotSame<type, void>::value;
41 typedef decltype(__test(std::declval<_Tp>())) type;
42 static const bool value = _IsNotSame<type, void>::value;
4543};
4644
4745template <>
48struct __numeric_type<void>
49{
50 static const bool value = true;
46struct __numeric_type<void> {
47 static const bool value = true;
5148};
5249
53template <class _A1, class _A2 = void, class _A3 = void,
54 bool = __numeric_type<_A1>::value &&
55 __numeric_type<_A2>::value &&
56 __numeric_type<_A3>::value>
57class __promote_imp
58{
50template <class _A1,
51 class _A2 = void,
52 class _A3 = void,
53 bool = __numeric_type<_A1>::value&& __numeric_type<_A2>::value&& __numeric_type<_A3>::value>
54class __promote_imp {
5955public:
60 static const bool value = false;
56 static const bool value = false;
6157};
6258
6359template <class _A1, class _A2, class _A3>
64class __promote_imp<_A1, _A2, _A3, true>
65{
60class __promote_imp<_A1, _A2, _A3, true> {
6661private:
67 typedef typename __promote_imp<_A1>::type __type1;
68 typedef typename __promote_imp<_A2>::type __type2;
69 typedef typename __promote_imp<_A3>::type __type3;
62 typedef typename __promote_imp<_A1>::type __type1;
63 typedef typename __promote_imp<_A2>::type __type2;
64 typedef typename __promote_imp<_A3>::type __type3;
65
7066public:
71 typedef decltype(__type1() + __type2() + __type3()) type;
72 static const bool value = true;
67 typedef decltype(__type1() + __type2() + __type3()) type;
68 static const bool value = true;
7369};
7470
7571template <class _A1, class _A2>
76class __promote_imp<_A1, _A2, void, true>
77{
72class __promote_imp<_A1, _A2, void, true> {
7873private:
79 typedef typename __promote_imp<_A1>::type __type1;
80 typedef typename __promote_imp<_A2>::type __type2;
74 typedef typename __promote_imp<_A1>::type __type1;
75 typedef typename __promote_imp<_A2>::type __type2;
76
8177public:
82 typedef decltype(__type1() + __type2()) type;
83 static const bool value = true;
78 typedef decltype(__type1() + __type2()) type;
79 static const bool value = true;
8480};
8581
8682template <class _A1>
87class __promote_imp<_A1, void, void, true>
88{
83class __promote_imp<_A1, void, void, true> {
8984public:
90 typedef typename __numeric_type<_A1>::type type;
91 static const bool value = true;
85 typedef typename __numeric_type<_A1>::type type;
86 static const bool value = true;
9287};
9388
9489template <class _A1, class _A2 = void, class _A3 = void>
lib/libcxx/include/__type_traits/rank.h+7-7
......@@ -27,16 +27,16 @@ struct rank : integral_constant<size_t, __array_rank(_Tp)> {};
2727
2828#else
2929
30template <class _Tp> struct _LIBCPP_TEMPLATE_VIS rank
31 : public integral_constant<size_t, 0> {};
32template <class _Tp> struct _LIBCPP_TEMPLATE_VIS rank<_Tp[]>
33 : public integral_constant<size_t, rank<_Tp>::value + 1> {};
34template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS rank<_Tp[_Np]>
35 : public integral_constant<size_t, rank<_Tp>::value + 1> {};
30template <class _Tp>
31struct _LIBCPP_TEMPLATE_VIS rank : public integral_constant<size_t, 0> {};
32template <class _Tp>
33struct _LIBCPP_TEMPLATE_VIS rank<_Tp[]> : public integral_constant<size_t, rank<_Tp>::value + 1> {};
34template <class _Tp, size_t _Np>
35struct _LIBCPP_TEMPLATE_VIS rank<_Tp[_Np]> : public integral_constant<size_t, rank<_Tp>::value + 1> {};
3636
3737#endif // __has_builtin(__array_rank)
3838
39#if _LIBCPP_STD_VER > 14
39#if _LIBCPP_STD_VER >= 17
4040template <class _Tp>
4141inline constexpr size_t rank_v = rank<_Tp>::value;
4242#endif
lib/libcxx/include/__type_traits/remove_all_extents.h+15-8
......@@ -27,19 +27,26 @@ struct remove_all_extents {
2727template <class _Tp>
2828using __remove_all_extents_t = __remove_all_extents(_Tp);
2929#else
30template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_all_extents
31 {typedef _Tp type;};
32template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[]>
33 {typedef typename remove_all_extents<_Tp>::type type;};
34template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[_Np]>
35 {typedef typename remove_all_extents<_Tp>::type type;};
30template <class _Tp>
31struct _LIBCPP_TEMPLATE_VIS remove_all_extents {
32 typedef _Tp type;
33};
34template <class _Tp>
35struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[]> {
36 typedef typename remove_all_extents<_Tp>::type type;
37};
38template <class _Tp, size_t _Np>
39struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[_Np]> {
40 typedef typename remove_all_extents<_Tp>::type type;
41};
3642
3743template <class _Tp>
3844using __remove_all_extents_t = typename remove_all_extents<_Tp>::type;
3945#endif // __has_builtin(__remove_all_extents)
4046
41#if _LIBCPP_STD_VER > 11
42template <class _Tp> using remove_all_extents_t = __remove_all_extents_t<_Tp>;
47#if _LIBCPP_STD_VER >= 14
48template <class _Tp>
49using remove_all_extents_t = __remove_all_extents_t<_Tp>;
4350#endif
4451
4552_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_const.h+11-4
......@@ -26,15 +26,22 @@ struct remove_const {
2626template <class _Tp>
2727using __remove_const_t = __remove_const(_Tp);
2828#else
29template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const {typedef _Tp type;};
30template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const<const _Tp> {typedef _Tp type;};
29template <class _Tp>
30struct _LIBCPP_TEMPLATE_VIS remove_const {
31 typedef _Tp type;
32};
33template <class _Tp>
34struct _LIBCPP_TEMPLATE_VIS remove_const<const _Tp> {
35 typedef _Tp type;
36};
3137
3238template <class _Tp>
3339using __remove_const_t = typename remove_const<_Tp>::type;
3440#endif // __has_builtin(__remove_const)
3541
36#if _LIBCPP_STD_VER > 11
37template <class _Tp> using remove_const_t = __remove_const_t<_Tp>;
42#if _LIBCPP_STD_VER >= 14
43template <class _Tp>
44using remove_const_t = __remove_const_t<_Tp>;
3845#endif
3946
4047_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_cv.h+8-5
......@@ -19,7 +19,7 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if __has_builtin(__remove_cv)
22#if __has_builtin(__remove_cv) && !defined(_LIBCPP_COMPILER_GCC)
2323template <class _Tp>
2424struct remove_cv {
2525 using type _LIBCPP_NODEBUG = __remove_cv(_Tp);
......@@ -28,15 +28,18 @@ struct remove_cv {
2828template <class _Tp>
2929using __remove_cv_t = __remove_cv(_Tp);
3030#else
31template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_cv
32{typedef __remove_volatile_t<__remove_const_t<_Tp> > type;};
31template <class _Tp>
32struct _LIBCPP_TEMPLATE_VIS remove_cv {
33 typedef __remove_volatile_t<__remove_const_t<_Tp> > type;
34};
3335
3436template <class _Tp>
3537using __remove_cv_t = __remove_volatile_t<__remove_const_t<_Tp> >;
3638#endif // __has_builtin(__remove_cv)
3739
38#if _LIBCPP_STD_VER > 11
39template <class _Tp> using remove_cv_t = __remove_cv_t<_Tp>;
40#if _LIBCPP_STD_VER >= 14
41template <class _Tp>
42using remove_cv_t = __remove_cv_t<_Tp>;
4043#endif
4144
4245_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_cvref.h+5-4
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if __has_builtin(__remove_cvref)
23#if __has_builtin(__remove_cvref) && !defined(_LIBCPP_COMPILER_GCC)
2424template <class _Tp>
2525using __remove_cvref_t _LIBCPP_NODEBUG = __remove_cvref(_Tp);
2626#else
......@@ -31,13 +31,14 @@ using __remove_cvref_t _LIBCPP_NODEBUG = __remove_cv_t<__libcpp_remove_reference
3131template <class _Tp, class _Up>
3232struct __is_same_uncvref : _IsSame<__remove_cvref_t<_Tp>, __remove_cvref_t<_Up> > {};
3333
34#if _LIBCPP_STD_VER > 17
34#if _LIBCPP_STD_VER >= 20
3535template <class _Tp>
3636struct remove_cvref {
37 using type _LIBCPP_NODEBUG = __remove_cvref_t<_Tp>;
37 using type _LIBCPP_NODEBUG = __remove_cvref_t<_Tp>;
3838};
3939
40template <class _Tp> using remove_cvref_t = __remove_cvref_t<_Tp>;
40template <class _Tp>
41using remove_cvref_t = __remove_cvref_t<_Tp>;
4142#endif
4243
4344_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_extent.h+15-8
......@@ -27,19 +27,26 @@ struct remove_extent {
2727template <class _Tp>
2828using __remove_extent_t = __remove_extent(_Tp);
2929#else
30template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent
31 {typedef _Tp type;};
32template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[]>
33 {typedef _Tp type;};
34template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[_Np]>
35 {typedef _Tp type;};
30template <class _Tp>
31struct _LIBCPP_TEMPLATE_VIS remove_extent {
32 typedef _Tp type;
33};
34template <class _Tp>
35struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[]> {
36 typedef _Tp type;
37};
38template <class _Tp, size_t _Np>
39struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[_Np]> {
40 typedef _Tp type;
41};
3642
3743template <class _Tp>
3844using __remove_extent_t = typename remove_extent<_Tp>::type;
3945#endif // __has_builtin(__remove_extent)
4046
41#if _LIBCPP_STD_VER > 11
42template <class _Tp> using remove_extent_t = __remove_extent_t<_Tp>;
47#if _LIBCPP_STD_VER >= 14
48template <class _Tp>
49using remove_extent_t = __remove_extent_t<_Tp>;
4350#endif
4451
4552_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_pointer.h+5-2
......@@ -26,18 +26,21 @@ struct remove_pointer {
2626template <class _Tp>
2727using __remove_pointer_t = __remove_pointer(_Tp);
2828#else
29// clang-format off
2930template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer {typedef _LIBCPP_NODEBUG _Tp type;};
3031template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp*> {typedef _LIBCPP_NODEBUG _Tp type;};
3132template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const> {typedef _LIBCPP_NODEBUG _Tp type;};
3233template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* volatile> {typedef _LIBCPP_NODEBUG _Tp type;};
3334template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const volatile> {typedef _LIBCPP_NODEBUG _Tp type;};
35// clang-format on
3436
3537template <class _Tp>
3638using __remove_pointer_t = typename remove_pointer<_Tp>::type;
3739#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer)
3840
39#if _LIBCPP_STD_VER > 11
40template <class _Tp> using remove_pointer_t = __remove_pointer_t<_Tp>;
41#if _LIBCPP_STD_VER >= 14
42template <class _Tp>
43using remove_pointer_t = __remove_pointer_t<_Tp>;
4144#endif
4245
4346_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_reference.h+5-2
......@@ -27,16 +27,19 @@ struct remove_reference {
2727template <class _Tp>
2828using __libcpp_remove_reference_t = __remove_reference_t(_Tp);
2929#else
30// clang-format off
3031template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference {typedef _LIBCPP_NODEBUG _Tp type;};
3132template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&> {typedef _LIBCPP_NODEBUG _Tp type;};
3233template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typedef _LIBCPP_NODEBUG _Tp type;};
34// clang-format on
3335
3436template <class _Tp>
3537using __libcpp_remove_reference_t = typename remove_reference<_Tp>::type;
3638#endif // __has_builtin(__remove_reference_t)
3739
38#if _LIBCPP_STD_VER > 11
39template <class _Tp> using remove_reference_t = __libcpp_remove_reference_t<_Tp>;
40#if _LIBCPP_STD_VER >= 14
41template <class _Tp>
42using remove_reference_t = __libcpp_remove_reference_t<_Tp>;
4043#endif
4144
4245_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/remove_volatile.h+11-4
......@@ -26,15 +26,22 @@ struct remove_volatile {
2626template <class _Tp>
2727using __remove_volatile_t = __remove_volatile(_Tp);
2828#else
29template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef _Tp type;};
30template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile<volatile _Tp> {typedef _Tp type;};
29template <class _Tp>
30struct _LIBCPP_TEMPLATE_VIS remove_volatile {
31 typedef _Tp type;
32};
33template <class _Tp>
34struct _LIBCPP_TEMPLATE_VIS remove_volatile<volatile _Tp> {
35 typedef _Tp type;
36};
3137
3238template <class _Tp>
3339using __remove_volatile_t = typename remove_volatile<_Tp>::type;
3440#endif // __has_builtin(__remove_volatile)
3541
36#if _LIBCPP_STD_VER > 11
37template <class _Tp> using remove_volatile_t = __remove_volatile_t<_Tp>;
42#if _LIBCPP_STD_VER >= 14
43template <class _Tp>
44using remove_volatile_t = __remove_volatile_t<_Tp>;
3845#endif
3946
4047_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/result_of.h+11-12
......@@ -21,18 +21,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121// result_of
2222
2323#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
24template <class _Callable> class _LIBCPP_DEPRECATED_IN_CXX17 result_of;
25
26template <class _Fp, class ..._Args>
27class _LIBCPP_TEMPLATE_VIS result_of<_Fp(_Args...)>
28 : public __invoke_of<_Fp, _Args...>
29{
30};
31
32#if _LIBCPP_STD_VER > 11
33template <class _Tp> using result_of_t _LIBCPP_DEPRECATED_IN_CXX17 = typename result_of<_Tp>::type;
34#endif // _LIBCPP_STD_VER > 11
35#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
24template <class _Callable>
25class _LIBCPP_DEPRECATED_IN_CXX17 result_of;
26
27template <class _Fp, class... _Args>
28class _LIBCPP_TEMPLATE_VIS result_of<_Fp(_Args...)> : public __invoke_of<_Fp, _Args...> {};
29
30# if _LIBCPP_STD_VER >= 14
31template <class _Tp>
32using result_of_t _LIBCPP_DEPRECATED_IN_CXX17 = typename result_of<_Tp>::type;
33# endif // _LIBCPP_STD_VER >= 14
34#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
3635
3736_LIBCPP_END_NAMESPACE_STD
3837
lib/libcxx/include/__type_traits/strip_signature.h+5-3
......@@ -19,23 +19,24 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22template<class _Fp>
22template <class _Fp>
2323struct __strip_signature;
2424
2525# if defined(__cpp_static_call_operator) && __cpp_static_call_operator >= 202207L
2626
2727template <class _Rp, class... _Args>
28struct __strip_signature<_Rp(*)(_Args...)> {
28struct __strip_signature<_Rp (*)(_Args...)> {
2929 using type = _Rp(_Args...);
3030};
3131
3232template <class _Rp, class... _Args>
33struct __strip_signature<_Rp(*)(_Args...) noexcept> {
33struct __strip_signature<_Rp (*)(_Args...) noexcept> {
3434 using type = _Rp(_Args...);
3535};
3636
3737# endif // defined(__cpp_static_call_operator) && __cpp_static_call_operator >= 202207L
3838
39// clang-format off
3940template<class _Rp, class _Gp, class ..._Ap>
4041struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); };
4142template<class _Rp, class _Gp, class ..._Ap>
......@@ -71,6 +72,7 @@ template<class _Rp, class _Gp, class ..._Ap>
7172struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); };
7273template<class _Rp, class _Gp, class ..._Ap>
7374struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); };
75// clang-format on
7476
7577_LIBCPP_END_NAMESPACE_STD
7678
lib/libcxx/include/__type_traits/type_identity.h+10-4
......@@ -18,14 +18,20 @@
1818_LIBCPP_BEGIN_NAMESPACE_STD
1919
2020template <class _Tp>
21struct __type_identity { typedef _Tp type; };
21struct __type_identity {
22 typedef _Tp type;
23};
2224
2325template <class _Tp>
2426using __type_identity_t _LIBCPP_NODEBUG = typename __type_identity<_Tp>::type;
2527
26#if _LIBCPP_STD_VER > 17
27template<class _Tp> struct type_identity { typedef _Tp type; };
28template<class _Tp> using type_identity_t = typename type_identity<_Tp>::type;
28#if _LIBCPP_STD_VER >= 20
29template <class _Tp>
30struct type_identity {
31 typedef _Tp type;
32};
33template <class _Tp>
34using type_identity_t = typename type_identity<_Tp>::type;
2935#endif
3036
3137_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/type_list.h+9-11
......@@ -19,24 +19,22 @@
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
2121template <class _Hp, class _Tp>
22struct __type_list
23{
24 typedef _Hp _Head;
25 typedef _Tp _Tail;
22struct __type_list {
23 typedef _Hp _Head;
24 typedef _Tp _Tail;
2625};
2726
28template <class _TypeList, size_t _Size, bool = _Size <= sizeof(typename _TypeList::_Head)> struct __find_first;
27template <class _TypeList, size_t _Size, bool = _Size <= sizeof(typename _TypeList::_Head)>
28struct __find_first;
2929
3030template <class _Hp, class _Tp, size_t _Size>
31struct __find_first<__type_list<_Hp, _Tp>, _Size, true>
32{
33 typedef _LIBCPP_NODEBUG _Hp type;
31struct __find_first<__type_list<_Hp, _Tp>, _Size, true> {
32 typedef _LIBCPP_NODEBUG _Hp type;
3433};
3534
3635template <class _Hp, class _Tp, size_t _Size>
37struct __find_first<__type_list<_Hp, _Tp>, _Size, false>
38{
39 typedef _LIBCPP_NODEBUG typename __find_first<_Tp, _Size>::type type;
36struct __find_first<__type_list<_Hp, _Tp>, _Size, false> {
37 typedef _LIBCPP_NODEBUG typename __find_first<_Tp, _Size>::type type;
4038};
4139
4240_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/underlying_type.h+7-6
......@@ -18,22 +18,23 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21template <class _Tp, bool = is_enum<_Tp>::value> struct __underlying_type_impl;
21template <class _Tp, bool = is_enum<_Tp>::value>
22struct __underlying_type_impl;
2223
2324template <class _Tp>
2425struct __underlying_type_impl<_Tp, false> {};
2526
2627template <class _Tp>
27struct __underlying_type_impl<_Tp, true>
28{
29 typedef __underlying_type(_Tp) type;
28struct __underlying_type_impl<_Tp, true> {
29 typedef __underlying_type(_Tp) type;
3030};
3131
3232template <class _Tp>
3333struct underlying_type : __underlying_type_impl<_Tp, is_enum<_Tp>::value> {};
3434
35#if _LIBCPP_STD_VER > 11
36template <class _Tp> using underlying_type_t = typename underlying_type<_Tp>::type;
35#if _LIBCPP_STD_VER >= 14
36template <class _Tp>
37using underlying_type_t = typename underlying_type<_Tp>::type;
3738#endif
3839
3940_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/unwrap_ref.h created+63
......@@ -0,0 +1,63 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TYPE_TRAITS_UNWRAP_REF_H
10#define _LIBCPP___TYPE_TRAITS_UNWRAP_REF_H
11
12#include <__config>
13#include <__type_traits/decay.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21template <class _Tp>
22struct __unwrap_reference {
23 typedef _LIBCPP_NODEBUG _Tp type;
24};
25
26template <class _Tp>
27class reference_wrapper;
28
29template <class _Tp>
30struct __unwrap_reference<reference_wrapper<_Tp> > {
31 typedef _LIBCPP_NODEBUG _Tp& type;
32};
33
34template <class _Tp>
35struct decay;
36
37#if _LIBCPP_STD_VER >= 20
38template <class _Tp>
39struct unwrap_reference : __unwrap_reference<_Tp> {};
40
41template <class _Tp>
42using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
43
44template <class _Tp>
45struct unwrap_ref_decay : unwrap_reference<__decay_t<_Tp> > {};
46
47template <class _Tp>
48using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
49#endif // _LIBCPP_STD_VER >= 20
50
51template <class _Tp>
52struct __unwrap_ref_decay
53#if _LIBCPP_STD_VER >= 20
54 : unwrap_ref_decay<_Tp>
55#else
56 : __unwrap_reference<__decay_t<_Tp> >
57#endif
58{
59};
60
61_LIBCPP_END_NAMESPACE_STD
62
63#endif // _LIBCPP___TYPE_TRAITS_UNWRAP_REF_H
lib/libcxx/include/__type_traits/void_t.h+3-2
......@@ -17,8 +17,9 @@
1717
1818_LIBCPP_BEGIN_NAMESPACE_STD
1919
20#if _LIBCPP_STD_VER > 14
21template <class...> using void_t = void;
20#if _LIBCPP_STD_VER >= 17
21template <class...>
22using void_t = void;
2223#endif
2324
2425template <class...>
lib/libcxx/include/__undef_macros+12
......@@ -14,3 +14,15 @@
1414#ifdef max
1515# undef max
1616#endif
17
18#ifdef refresh
19# undef refresh
20#endif
21
22#ifdef move
23# undef move
24#endif
25
26#ifdef erase
27# undef erase
28#endif
lib/libcxx/include/__utility/as_const.h+1-1
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#if _LIBCPP_STD_VER > 14
23#if _LIBCPP_STD_VER >= 17
2424template <class _Tp>
2525_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; }
2626
lib/libcxx/include/__utility/auto_cast.h+1-1
......@@ -17,6 +17,6 @@
1717# pragma GCC system_header
1818#endif
1919
20#define _LIBCPP_AUTO_CAST(expr) static_cast<typename decay<decltype((expr))>::type>(expr)
20#define _LIBCPP_AUTO_CAST(expr) static_cast<::std::__decay_t<decltype((expr))> >(expr)
2121
2222#endif // _LIBCPP___UTILITY_AUTO_CAST_H
lib/libcxx/include/__utility/cmp.h+2-2
......@@ -28,7 +28,7 @@ _LIBCPP_PUSH_MACROS
2828
2929_LIBCPP_BEGIN_NAMESPACE_STD
3030
31#if _LIBCPP_STD_VER > 17
31#if _LIBCPP_STD_VER >= 20
3232template<class _Tp, class... _Up>
3333struct _IsSameAsAny : _Or<_IsSame<_Tp, _Up>...> {};
3434
......@@ -102,7 +102,7 @@ bool in_range(_Up __u) noexcept
102102 return _VSTD::cmp_less_equal(__u, numeric_limits<_Tp>::max()) &&
103103 _VSTD::cmp_greater_equal(__u, numeric_limits<_Tp>::min());
104104}
105#endif // _LIBCPP_STD_VER > 17
105#endif // _LIBCPP_STD_VER >= 20
106106
107107_LIBCPP_END_NAMESPACE_STD
108108
lib/libcxx/include/__utility/exception_guard.h+12-7
......@@ -19,6 +19,9 @@
1919# pragma GCC system_header
2020#endif
2121
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
2225_LIBCPP_BEGIN_NAMESPACE_STD
2326
2427// __exception_guard is a helper class for writing code with the strong exception guarantee.
......@@ -41,7 +44,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
4144// less common, especially one that tries to catch an exception through -fno-exceptions code.
4245//
4346// __exception_guard can help greatly simplify code that would normally be cluttered by
44// `#if _LIBCPP_NO_EXCEPTIONS`. For example:
47// `#if _LIBCPP_HAS_NO_EXCEPTIONS`. For example:
4548//
4649// template <class Iterator, class Size, class OutputIterator>
4750// Iterator uninitialized_copy_n(Iterator iter, Size n, OutputIterator out) {
......@@ -58,7 +61,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
5861// }
5962//
6063
61#ifndef _LIBCPP_NO_EXCEPTIONS
6264template <class _Rollback>
6365struct __exception_guard_exceptions {
6466 __exception_guard_exceptions() = delete;
......@@ -91,9 +93,6 @@ private:
9193
9294_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__exception_guard_exceptions);
9395
94template <class _Rollback>
95using __exception_guard = __exception_guard_exceptions<_Rollback>;
96#else // _LIBCPP_NO_EXCEPTIONS
9796template <class _Rollback>
9897struct __exception_guard_noexceptions {
9998 __exception_guard_noexceptions() = delete;
......@@ -116,7 +115,7 @@ struct __exception_guard_noexceptions {
116115 }
117116
118117 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODEBUG ~__exception_guard_noexceptions() {
119 _LIBCPP_ASSERT(__completed_, "__exception_guard not completed with exceptions disabled");
118 _LIBCPP_ASSERT_UNCATEGORIZED(__completed_, "__exception_guard not completed with exceptions disabled");
120119 }
121120
122121private:
......@@ -125,9 +124,13 @@ private:
125124
126125_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__exception_guard_noexceptions);
127126
127#ifdef _LIBCPP_HAS_NO_EXCEPTIONS
128128template <class _Rollback>
129129using __exception_guard = __exception_guard_noexceptions<_Rollback>;
130#endif // _LIBCPP_NO_EXCEPTIONS
130#else
131template <class _Rollback>
132using __exception_guard = __exception_guard_exceptions<_Rollback>;
133#endif
131134
132135template <class _Rollback>
133136_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __exception_guard<_Rollback> __make_exception_guard(_Rollback __rollback) {
......@@ -136,4 +139,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __exception_guard<_Rollback> __make_exce
136139
137140_LIBCPP_END_NAMESPACE_STD
138141
142_LIBCPP_POP_MACROS
143
139144#endif // _LIBCPP___UTILITY_TRANSACTION_H
lib/libcxx/include/__utility/exchange.h+7-2
......@@ -19,9 +19,12 @@
1919# pragma GCC system_header
2020#endif
2121
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
2225_LIBCPP_BEGIN_NAMESPACE_STD
2326
24#if _LIBCPP_STD_VER > 11
27#if _LIBCPP_STD_VER >= 14
2528template<class _T1, class _T2 = _T1>
2629inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
2730_T1 exchange(_T1& __obj, _T2&& __new_value)
......@@ -31,8 +34,10 @@ _T1 exchange(_T1& __obj, _T2&& __new_value)
3134 __obj = _VSTD::forward<_T2>(__new_value);
3235 return __old_value;
3336}
34#endif // _LIBCPP_STD_VER > 11
37#endif // _LIBCPP_STD_VER >= 14
3538
3639_LIBCPP_END_NAMESPACE_STD
3740
41_LIBCPP_POP_MACROS
42
3843#endif // _LIBCPP___UTILITY_EXCHANGE_H
lib/libcxx/include/__utility/forward_like.h+2-2
......@@ -22,7 +22,7 @@
2222
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
25#if _LIBCPP_STD_VER > 20
25#if _LIBCPP_STD_VER >= 23
2626
2727template <class _Ap, class _Bp>
2828using _CopyConst = _If<is_const_v<_Ap>, const _Bp, _Bp>;
......@@ -39,7 +39,7 @@ template <class _Tp, class _Up>
3939 return static_cast<_ForwardLike<_Tp, _Up>>(__ux);
4040}
4141
42#endif // _LIBCPP_STD_VER > 20
42#endif // _LIBCPP_STD_VER >= 23
4343
4444_LIBCPP_END_NAMESPACE_STD
4545
lib/libcxx/include/__utility/in_place.h+6-6
......@@ -19,23 +19,23 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if _LIBCPP_STD_VER > 14
22#if _LIBCPP_STD_VER >= 17
2323
24struct _LIBCPP_TYPE_VIS in_place_t {
25 explicit in_place_t() = default;
24struct _LIBCPP_EXPORTED_FROM_ABI in_place_t {
25 explicit in_place_t() = default;
2626};
2727inline constexpr in_place_t in_place{};
2828
2929template <class _Tp>
3030struct _LIBCPP_TEMPLATE_VIS in_place_type_t {
31 explicit in_place_type_t() = default;
31 _LIBCPP_HIDE_FROM_ABI explicit in_place_type_t() = default;
3232};
3333template <class _Tp>
3434inline constexpr in_place_type_t<_Tp> in_place_type{};
3535
3636template <size_t _Idx>
3737struct _LIBCPP_TEMPLATE_VIS in_place_index_t {
38 explicit in_place_index_t() = default;
38 _LIBCPP_HIDE_FROM_ABI explicit in_place_index_t() = default;
3939};
4040template <size_t _Idx>
4141inline constexpr in_place_index_t<_Idx> in_place_index{};
......@@ -52,7 +52,7 @@ template <size_t _Idx> struct __is_inplace_index_imp<in_place_index_t<_Idx>> : t
5252template <class _Tp>
5353using __is_inplace_index = __is_inplace_index_imp<__remove_cvref_t<_Tp>>;
5454
55#endif // _LIBCPP_STD_VER > 14
55#endif // _LIBCPP_STD_VER >= 17
5656
5757_LIBCPP_END_NAMESPACE_STD
5858
lib/libcxx/include/__utility/integer_sequence.h+4-4
......@@ -85,7 +85,7 @@ using __make_indices_imp =
8585
8686#endif
8787
88#if _LIBCPP_STD_VER > 11
88#if _LIBCPP_STD_VER >= 14
8989
9090template<class _Tp, _Tp... _Ip>
9191struct _LIBCPP_TEMPLATE_VIS integer_sequence
......@@ -138,15 +138,15 @@ template<size_t _Np>
138138template<class... _Tp>
139139 using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
140140
141# if _LIBCPP_STD_VER > 17
141# if _LIBCPP_STD_VER >= 20
142142// Executes __func for every element in an index_sequence.
143143template <size_t... _Index, class _Function>
144144_LIBCPP_HIDE_FROM_ABI constexpr void __for_each_index_sequence(index_sequence<_Index...>, _Function __func) {
145145 (__func.template operator()<_Index>(), ...);
146146}
147# endif // _LIBCPP_STD_VER > 17
147# endif // _LIBCPP_STD_VER >= 20
148148
149#endif // _LIBCPP_STD_VER > 11
149#endif // _LIBCPP_STD_VER >= 14
150150
151151_LIBCPP_END_NAMESPACE_STD
152152
lib/libcxx/include/__utility/is_pointer_in_range.h created+62
......@@ -0,0 +1,62 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_IS_POINTER_IN_RANGE_H
10#define _LIBCPP___UTILITY_IS_POINTER_IN_RANGE_H
11
12#include <__algorithm/comp.h>
13#include <__assert>
14#include <__config>
15#include <__type_traits/enable_if.h>
16#include <__type_traits/integral_constant.h>
17#include <__type_traits/is_constant_evaluated.h>
18#include <__type_traits/void_t.h>
19#include <__utility/declval.h>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22# pragma GCC system_header
23#endif
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Tp, class _Up, class = void>
28struct __is_less_than_comparable : false_type {};
29
30template <class _Tp, class _Up>
31struct __is_less_than_comparable<_Tp, _Up, __void_t<decltype(std::declval<_Tp>() < std::declval<_Up>())> > : true_type {
32};
33
34template <class _Tp, class _Up, __enable_if_t<__is_less_than_comparable<const _Tp*, const _Up*>::value, int> = 0>
35_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_SANITIZE("address") bool __is_pointer_in_range(
36 const _Tp* __begin, const _Tp* __end, const _Up* __ptr) {
37 if (__libcpp_is_constant_evaluated()) {
38 _LIBCPP_ASSERT_UNCATEGORIZED(__builtin_constant_p(__begin <= __end), "__begin and __end do not form a range");
39
40 // If this is not a constant during constant evaluation we know that __ptr is not part of the allocation where
41 // [__begin, __end) is.
42 if (!__builtin_constant_p(__begin <= __ptr && __ptr < __end))
43 return false;
44 }
45
46 // Checking this for unrelated pointers is technically UB, but no compiler optimizes based on it (currently).
47 return !__less<>()(__ptr, __begin) && __less<>()(__ptr, __end);
48}
49
50template <class _Tp, class _Up, __enable_if_t<!__is_less_than_comparable<const _Tp*, const _Up*>::value, int> = 0>
51_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_SANITIZE("address") bool __is_pointer_in_range(
52 const _Tp* __begin, const _Tp* __end, const _Up* __ptr) {
53 if (__libcpp_is_constant_evaluated())
54 return false;
55
56 return reinterpret_cast<const char*>(__begin) <= reinterpret_cast<const char*>(__ptr) &&
57 reinterpret_cast<const char*>(__ptr) < reinterpret_cast<const char*>(__end);
58}
59
60_LIBCPP_END_NAMESPACE_STD
61
62#endif // _LIBCPP___UTILITY_IS_POINTER_IN_RANGE_H
lib/libcxx/include/__utility/move.h+5
......@@ -20,6 +20,9 @@
2020# pragma GCC system_header
2121#endif
2222
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
2326_LIBCPP_BEGIN_NAMESPACE_STD
2427
2528template <class _Tp>
......@@ -41,4 +44,6 @@ move_if_noexcept(_LIBCPP_LIFETIMEBOUND _Tp& __x) _NOEXCEPT {
4144
4245_LIBCPP_END_NAMESPACE_STD
4346
47_LIBCPP_POP_MACROS
48
4449#endif // _LIBCPP___UTILITY_MOVE_H
lib/libcxx/include/__utility/pair.h+349-168
......@@ -11,17 +11,23 @@
1111
1212#include <__compare/common_comparison_category.h>
1313#include <__compare/synth_three_way.h>
14#include <__concepts/different_from.h>
1415#include <__config>
15#include <__functional/unwrap_ref.h>
16#include <__fwd/array.h>
1617#include <__fwd/get.h>
18#include <__fwd/pair.h>
19#include <__fwd/subrange.h>
1720#include <__fwd/tuple.h>
18#include <__tuple_dir/sfinae_helpers.h>
19#include <__tuple_dir/tuple_element.h>
20#include <__tuple_dir/tuple_indices.h>
21#include <__tuple_dir/tuple_size.h>
21#include <__tuple/pair_like.h>
22#include <__tuple/sfinae_helpers.h>
23#include <__tuple/tuple_element.h>
24#include <__tuple/tuple_indices.h>
25#include <__tuple/tuple_size.h>
2226#include <__type_traits/common_reference.h>
2327#include <__type_traits/common_type.h>
2428#include <__type_traits/conditional.h>
29#include <__type_traits/decay.h>
30#include <__type_traits/integral_constant.h>
2531#include <__type_traits/is_assignable.h>
2632#include <__type_traits/is_constructible.h>
2733#include <__type_traits/is_convertible.h>
......@@ -38,6 +44,9 @@
3844#include <__type_traits/is_same.h>
3945#include <__type_traits/is_swappable.h>
4046#include <__type_traits/nat.h>
47#include <__type_traits/remove_cvref.h>
48#include <__type_traits/unwrap_ref.h>
49#include <__utility/declval.h>
4150#include <__utility/forward.h>
4251#include <__utility/move.h>
4352#include <__utility/piecewise_construct.h>
......@@ -47,16 +56,25 @@
4756# pragma GCC system_header
4857#endif
4958
59_LIBCPP_PUSH_MACROS
60#include <__undef_macros>
61
5062_LIBCPP_BEGIN_NAMESPACE_STD
5163
52#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
5364template <class, class>
5465struct __non_trivially_copyable_base {
55 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
66 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI
5667 __non_trivially_copyable_base() _NOEXCEPT {}
57 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
68 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
5869 __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
5970};
71
72#if _LIBCPP_STD_VER >= 23
73template <class _Tp>
74struct __is_specialization_of_subrange : false_type {};
75
76template <class _Iter, class _Sent, ranges::subrange_kind _Kind>
77struct __is_specialization_of_subrange<ranges::subrange<_Iter, _Sent, _Kind>> : true_type {};
6078#endif
6179
6280template <class _T1, class _T2>
......@@ -65,66 +83,80 @@ struct _LIBCPP_TEMPLATE_VIS pair
6583: private __non_trivially_copyable_base<_T1, _T2>
6684#endif
6785{
68 typedef _T1 first_type;
69 typedef _T2 second_type;
86 using first_type = _T1;
87 using second_type = _T2;
7088
7189 _T1 first;
7290 _T2 second;
7391
74 pair(pair const&) = default;
75 pair(pair&&) = default;
92 _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
93 _LIBCPP_HIDE_FROM_ABI pair(pair&&) = default;
7694
7795#ifdef _LIBCPP_CXX03_LANG
78 _LIBCPP_INLINE_VISIBILITY
96 _LIBCPP_HIDE_FROM_ABI
7997 pair() : first(), second() {}
8098
81 _LIBCPP_INLINE_VISIBILITY
99 _LIBCPP_HIDE_FROM_ABI
82100 pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
83101
84102 template <class _U1, class _U2>
85 _LIBCPP_INLINE_VISIBILITY
103 _LIBCPP_HIDE_FROM_ABI
86104 pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
87105
88 _LIBCPP_INLINE_VISIBILITY
106 _LIBCPP_HIDE_FROM_ABI
89107 pair& operator=(pair const& __p) {
90108 first = __p.first;
91109 second = __p.second;
92110 return *this;
93111 }
112
113 // Extension: This is provided in C++03 because it allows properly handling the
114 // assignment to a pair containing references, which would be a hard
115 // error otherwise.
116 template <class _U1, class _U2, class = __enable_if_t<
117 is_assignable<first_type&, _U1 const&>::value &&
118 is_assignable<second_type&, _U2 const&>::value
119 > >
120 _LIBCPP_HIDE_FROM_ABI
121 pair& operator=(pair<_U1, _U2> const& __p) {
122 first = __p.first;
123 second = __p.second;
124 return *this;
125 }
94126#else
95127 struct _CheckArgs {
96128 template <int&...>
97 static constexpr bool __enable_explicit_default() {
129 static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() {
98130 return is_default_constructible<_T1>::value
99131 && is_default_constructible<_T2>::value
100132 && !__enable_implicit_default<>();
101133 }
102134
103135 template <int&...>
104 static constexpr bool __enable_implicit_default() {
136 static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() {
105137 return __is_implicitly_default_constructible<_T1>::value
106138 && __is_implicitly_default_constructible<_T2>::value;
107139 }
108140
109141 template <class _U1, class _U2>
110 static constexpr bool __is_pair_constructible() {
142 static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_pair_constructible() {
111143 return is_constructible<first_type, _U1>::value
112144 && is_constructible<second_type, _U2>::value;
113145 }
114146
115147 template <class _U1, class _U2>
116 static constexpr bool __is_implicit() {
148 static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_implicit() {
117149 return is_convertible<_U1, first_type>::value
118150 && is_convertible<_U2, second_type>::value;
119151 }
120152
121153 template <class _U1, class _U2>
122 static constexpr bool __enable_explicit() {
154 static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() {
123155 return __is_pair_constructible<_U1, _U2>() && !__is_implicit<_U1, _U2>();
124156 }
125157
126158 template <class _U1, class _U2>
127 static constexpr bool __enable_implicit() {
159 static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() {
128160 return __is_pair_constructible<_U1, _U2>() && __is_implicit<_U1, _U2>();
129161 }
130162 };
......@@ -133,36 +165,10 @@ struct _LIBCPP_TEMPLATE_VIS pair
133165 using _CheckArgsDep _LIBCPP_NODEBUG = typename conditional<
134166 _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type;
135167
136 struct _CheckTupleLikeConstructor {
137 template <class _Tuple>
138 static constexpr bool __enable_implicit() {
139 return __tuple_convertible<_Tuple, pair>::value;
140 }
141
142 template <class _Tuple>
143 static constexpr bool __enable_explicit() {
144 return __tuple_constructible<_Tuple, pair>::value
145 && !__tuple_convertible<_Tuple, pair>::value;
146 }
147
148 template <class _Tuple>
149 static constexpr bool __enable_assign() {
150 return __tuple_assignable<_Tuple, pair>::value;
151 }
152 };
153
154 template <class _Tuple>
155 using _CheckTLC _LIBCPP_NODEBUG = __conditional_t<
156 __tuple_like_with_size<_Tuple, 2>::value
157 && !is_same<typename decay<_Tuple>::type, pair>::value,
158 _CheckTupleLikeConstructor,
159 __check_tuple_constructor_fail
160 >;
161
162168 template<bool _Dummy = true, typename enable_if<
163169 _CheckArgsDep<_Dummy>::__enable_explicit_default()
164170 >::type* = nullptr>
165 explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
171 explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
166172 pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
167173 is_nothrow_default_constructible<second_type>::value)
168174 : first(), second() {}
......@@ -170,7 +176,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
170176 template<bool _Dummy = true, typename enable_if<
171177 _CheckArgsDep<_Dummy>::__enable_implicit_default()
172178 >::type* = nullptr>
173 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
179 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
174180 pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
175181 is_nothrow_default_constructible<second_type>::value)
176182 : first(), second() {}
......@@ -178,7 +184,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
178184 template <bool _Dummy = true, typename enable_if<
179185 _CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>()
180186 >::type* = nullptr>
181 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
187 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
182188 explicit pair(_T1 const& __t1, _T2 const& __t2)
183189 _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
184190 is_nothrow_copy_constructible<second_type>::value)
......@@ -187,41 +193,41 @@ struct _LIBCPP_TEMPLATE_VIS pair
187193 template<bool _Dummy = true, typename enable_if<
188194 _CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>()
189195 >::type* = nullptr>
190 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
196 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
191197 pair(_T1 const& __t1, _T2 const& __t2)
192198 _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
193199 is_nothrow_copy_constructible<second_type>::value)
194200 : first(__t1), second(__t2) {}
195201
196202 template <
197#if _LIBCPP_STD_VER > 20 // http://wg21.link/P1951
203#if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
198204 class _U1 = _T1, class _U2 = _T2,
199205#else
200206 class _U1, class _U2,
201207#endif
202208 typename enable_if<_CheckArgs::template __enable_explicit<_U1, _U2>()>::type* = nullptr
203209 >
204 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
210 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
205211 explicit pair(_U1&& __u1, _U2&& __u2)
206212 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
207213 is_nothrow_constructible<second_type, _U2>::value))
208 : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
214 : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {}
209215
210216 template <
211#if _LIBCPP_STD_VER > 20 // http://wg21.link/P1951
217#if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
212218 class _U1 = _T1, class _U2 = _T2,
213219#else
214220 class _U1, class _U2,
215221#endif
216222 typename enable_if<_CheckArgs::template __enable_implicit<_U1, _U2>()>::type* = nullptr
217223 >
218 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
224 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
219225 pair(_U1&& __u1, _U2&& __u2)
220226 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
221227 is_nothrow_constructible<second_type, _U2>::value))
222 : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
228 : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {}
223229
224#if _LIBCPP_STD_VER > 20
230#if _LIBCPP_STD_VER >= 23
225231 template<class _U1, class _U2, __enable_if_t<
226232 _CheckArgs::template __is_pair_constructible<_U1&, _U2&>()
227233 >* = nullptr>
......@@ -235,7 +241,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
235241 template<class _U1, class _U2, typename enable_if<
236242 _CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>()
237243 >::type* = nullptr>
238 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
244 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
239245 explicit pair(pair<_U1, _U2> const& __p)
240246 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
241247 is_nothrow_constructible<second_type, _U2 const&>::value))
......@@ -244,7 +250,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
244250 template<class _U1, class _U2, typename enable_if<
245251 _CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>()
246252 >::type* = nullptr>
247 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
253 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
248254 pair(pair<_U1, _U2> const& __p)
249255 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
250256 is_nothrow_constructible<second_type, _U2 const&>::value))
......@@ -253,22 +259,22 @@ struct _LIBCPP_TEMPLATE_VIS pair
253259 template<class _U1, class _U2, typename enable_if<
254260 _CheckArgs::template __enable_explicit<_U1, _U2>()
255261 >::type* = nullptr>
256 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
262 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
257263 explicit pair(pair<_U1, _U2>&&__p)
258264 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
259265 is_nothrow_constructible<second_type, _U2&&>::value))
260 : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
266 : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}
261267
262268 template<class _U1, class _U2, typename enable_if<
263269 _CheckArgs::template __enable_implicit<_U1, _U2>()
264270 >::type* = nullptr>
265 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
271 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
266272 pair(pair<_U1, _U2>&& __p)
267273 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
268274 is_nothrow_constructible<second_type, _U2&&>::value))
269 : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
275 : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}
270276
271#if _LIBCPP_STD_VER > 20
277#if _LIBCPP_STD_VER >= 23
272278 template<class _U1, class _U2, __enable_if_t<
273279 _CheckArgs::template __is_pair_constructible<const _U1&&, const _U2&&>()
274280 >* = nullptr>
......@@ -280,24 +286,27 @@ struct _LIBCPP_TEMPLATE_VIS pair
280286 : first(std::move(__p.first)), second(std::move(__p.second)) {}
281287#endif
282288
283 template<class _Tuple, typename enable_if<
284 _CheckTLC<_Tuple>::template __enable_explicit<_Tuple>()
285 >::type* = nullptr>
286 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
287 explicit pair(_Tuple&& __p)
288 : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
289 second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
289# if _LIBCPP_STD_VER >= 23
290 // This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed.
291 template <class _PairLike, bool _Enable = tuple_size<remove_cvref_t<_PairLike>>::value == 2>
292 _LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() {
293 if constexpr (tuple_size<remove_cvref_t<_PairLike>>::value == 2) {
294 return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> ||
295 !is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>;
296 }
297 return false;
298 }
290299
291 template<class _Tuple, typename enable_if<
292 _CheckTLC<_Tuple>::template __enable_implicit<_Tuple>()
293 >::type* = nullptr>
294 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
295 pair(_Tuple&& __p)
296 : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
297 second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
300 template <__pair_like _PairLike>
301 requires(is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike&&>()))> &&
302 is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike&&>()))>)
303 _LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>())
304 pair(_PairLike&& __p)
305 : first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {}
306# endif
298307
299308 template <class... _Args1, class... _Args2>
300 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
309 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
301310 pair(piecewise_construct_t __pc,
302311 tuple<_Args1...> __first_args, tuple<_Args2...> __second_args)
303312 _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value &&
......@@ -306,7 +315,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
306315 typename __make_tuple_indices<sizeof...(_Args1)>::type(),
307316 typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
308317
309 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
318 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
310319 pair& operator=(__conditional_t<
311320 is_copy_assignable<first_type>::value &&
312321 is_copy_assignable<second_type>::value,
......@@ -319,7 +328,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
319328 return *this;
320329 }
321330
322 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
331 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
323332 pair& operator=(__conditional_t<
324333 is_move_assignable<first_type>::value &&
325334 is_move_assignable<second_type>::value,
......@@ -327,12 +336,34 @@ struct _LIBCPP_TEMPLATE_VIS pair
327336 _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&
328337 is_nothrow_move_assignable<second_type>::value)
329338 {
330 first = _VSTD::forward<first_type>(__p.first);
331 second = _VSTD::forward<second_type>(__p.second);
339 first = std::forward<first_type>(__p.first);
340 second = std::forward<second_type>(__p.second);
332341 return *this;
333342 }
334343
335#if _LIBCPP_STD_VER > 20
344 template <class _U1, class _U2, __enable_if_t<
345 is_assignable<first_type&, _U1 const&>::value &&
346 is_assignable<second_type&, _U2 const&>::value
347 >* = nullptr>
348 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
349 pair& operator=(pair<_U1, _U2> const& __p) {
350 first = __p.first;
351 second = __p.second;
352 return *this;
353 }
354
355 template <class _U1, class _U2, __enable_if_t<
356 is_assignable<first_type&, _U1>::value &&
357 is_assignable<second_type&, _U2>::value
358 >* = nullptr>
359 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
360 pair& operator=(pair<_U1, _U2>&& __p) {
361 first = std::forward<_U1>(__p.first);
362 second = std::forward<_U2>(__p.second);
363 return *this;
364 }
365
366# if _LIBCPP_STD_VER >= 23
336367 _LIBCPP_HIDE_FROM_ABI constexpr
337368 const pair& operator=(pair const& __p) const
338369 noexcept(is_nothrow_copy_assignable_v<const first_type> &&
......@@ -374,30 +405,178 @@ struct _LIBCPP_TEMPLATE_VIS pair
374405 second = std::forward<_U2>(__p.second);
375406 return *this;
376407 }
377#endif // _LIBCPP_STD_VER > 20
378
379 template <class _Tuple, typename enable_if<
380 _CheckTLC<_Tuple>::template __enable_assign<_Tuple>()
381 >::type* = nullptr>
382 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
383 pair& operator=(_Tuple&& __p) {
384 first = _VSTD::get<0>(_VSTD::forward<_Tuple>(__p));
385 second = _VSTD::get<1>(_VSTD::forward<_Tuple>(__p));
408
409 template <__pair_like _PairLike>
410 requires(__different_from<_PairLike, pair> &&
411 !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
412 is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
413 is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>)
414 _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) {
415 first = std::get<0>(std::forward<_PairLike>(__p));
416 second = std::get<1>(std::forward<_PairLike>(__p));
386417 return *this;
387418 }
388#endif
389419
390 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
420 template <__pair_like _PairLike>
421 requires(__different_from<_PairLike, pair> &&
422 !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
423 is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
424 is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>)
425 _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const {
426 first = std::get<0>(std::forward<_PairLike>(__p));
427 second = std::get<1>(std::forward<_PairLike>(__p));
428 return *this;
429 }
430# endif // _LIBCPP_STD_VER >= 23
431
432 // Prior to C++23, we provide an approximation of constructors and assignment operators from
433 // pair-like types. This was historically provided as an extension.
434#if _LIBCPP_STD_VER < 23
435 // from std::tuple
436 template<class _U1, class _U2, __enable_if_t<
437 is_convertible<_U1 const&, _T1>::value &&
438 is_convertible<_U2 const&, _T2>::value
439 >* = nullptr>
440 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
441 pair(tuple<_U1, _U2> const& __p)
442 : first(std::get<0>(__p)),
443 second(std::get<1>(__p)) {}
444
445 template<class _U1, class _U2, __enable_if_t<
446 is_constructible<_T1, _U1 const&>::value &&
447 is_constructible<_T2, _U2 const&>::value &&
448 !(is_convertible<_U1 const&, _T1>::value &&
449 is_convertible<_U2 const&, _T2>::value)
450 >* = nullptr>
451 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
452 explicit
453 pair(tuple<_U1, _U2> const& __p)
454 : first(std::get<0>(__p)),
455 second(std::get<1>(__p)) {}
456
457 template<class _U1, class _U2, __enable_if_t<
458 is_convertible<_U1, _T1>::value &&
459 is_convertible<_U2, _T2>::value
460 >* = nullptr>
461 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
462 pair(tuple<_U1, _U2>&& __p)
463 : first(std::get<0>(std::move(__p))),
464 second(std::get<1>(std::move(__p))) {}
465
466 template<class _U1, class _U2, __enable_if_t<
467 is_constructible<_T1, _U1>::value &&
468 is_constructible<_T2, _U2>::value &&
469 !(is_convertible<_U1, _T1>::value &&
470 is_convertible<_U2, _T2>::value)
471 >* = nullptr>
472 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
473 explicit
474 pair(tuple<_U1, _U2>&& __p)
475 : first(std::get<0>(std::move(__p))),
476 second(std::get<1>(std::move(__p))) {}
477
478
479 template<class _U1, class _U2, __enable_if_t<
480 is_assignable<_T1&, _U1 const&>::value &&
481 is_assignable<_T2&, _U2 const&>::value
482 >* = nullptr>
483 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
484 pair& operator=(tuple<_U1, _U2> const& __p) {
485 first = std::get<0>(__p);
486 second = std::get<1>(__p);
487 return *this;
488 }
489
490 template<class _U1, class _U2, __enable_if_t<
491 is_assignable<_T1&, _U1&&>::value &&
492 is_assignable<_T2&, _U2&&>::value
493 >* = nullptr>
494 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
495 pair& operator=(tuple<_U1, _U2>&& __p) {
496 first = std::get<0>(std::move(__p));
497 second = std::get<1>(std::move(__p));
498 return *this;
499 }
500
501 // from std::array
502 template<class _Up, __enable_if_t<
503 is_convertible<_Up const&, _T1>::value &&
504 is_convertible<_Up const&, _T2>::value
505 >* = nullptr>
506 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
507 pair(array<_Up, 2> const& __p)
508 : first(__p[0]),
509 second(__p[1]) {}
510
511 template<class _Up, __enable_if_t<
512 is_constructible<_T1, _Up const&>::value &&
513 is_constructible<_T2, _Up const&>::value &&
514 !(is_convertible<_Up const&, _T1>::value &&
515 is_convertible<_Up const&, _T2>::value)
516 >* = nullptr>
517 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
518 explicit
519 pair(array<_Up, 2> const& __p)
520 : first(__p[0]),
521 second(__p[1]) {}
522
523 template<class _Up, __enable_if_t<
524 is_convertible<_Up, _T1>::value &&
525 is_convertible<_Up, _T2>::value
526 >* = nullptr>
527 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
528 pair(array<_Up, 2>&& __p)
529 : first(std::move(__p)[0]),
530 second(std::move(__p)[1]) {}
531
532 template<class _Up, __enable_if_t<
533 is_constructible<_T1, _Up>::value &&
534 is_constructible<_T2, _Up>::value &&
535 !(is_convertible<_Up, _T1>::value &&
536 is_convertible<_Up, _T2>::value)
537 >* = nullptr>
538 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
539 explicit
540 pair(array<_Up, 2>&& __p)
541 : first(std::move(__p)[0]),
542 second(std::move(__p)[1]) {}
543
544
545 template<class _Up, __enable_if_t<
546 is_assignable<_T1&, _Up const&>::value &&
547 is_assignable<_T2&, _Up const&>::value
548 >* = nullptr>
549 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
550 pair& operator=(array<_Up, 2> const& __p) {
551 first = std::get<0>(__p);
552 second = std::get<1>(__p);
553 return *this;
554 }
555
556 template<class _Up, __enable_if_t<
557 is_assignable<_T1&, _Up>::value &&
558 is_assignable<_T2&, _Up>::value
559 >* = nullptr>
560 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
561 pair& operator=(array<_Up, 2>&& __p) {
562 first = std::get<0>(std::move(__p));
563 second = std::get<1>(std::move(__p));
564 return *this;
565 }
566#endif // _LIBCPP_STD_VER < 23
567#endif // _LIBCPP_CXX03_LANG
568
569 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
391570 void
392571 swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&
393572 __is_nothrow_swappable<second_type>::value)
394573 {
395 using _VSTD::swap;
574 using std::swap;
396575 swap(first, __p.first);
397576 swap(second, __p.second);
398577 }
399578
400#if _LIBCPP_STD_VER > 20
579#if _LIBCPP_STD_VER >= 23
401580 _LIBCPP_HIDE_FROM_ABI constexpr
402581 void swap(const pair& __p) const
403582 noexcept(__is_nothrow_swappable<const first_type>::value &&
......@@ -412,88 +591,88 @@ private:
412591
413592#ifndef _LIBCPP_CXX03_LANG
414593 template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
415 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
594 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
416595 pair(piecewise_construct_t,
417596 tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
418597 __tuple_indices<_I1...>, __tuple_indices<_I2...>);
419598#endif
420599};
421600
422#if _LIBCPP_STD_VER > 14
601#if _LIBCPP_STD_VER >= 17
423602template<class _T1, class _T2>
424603pair(_T1, _T2) -> pair<_T1, _T2>;
425604#endif
426605
427606// [pairs.spec], specialized algorithms
428607
429template <class _T1, class _T2>
430inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
608template <class _T1, class _T2, class _U1, class _U2>
609inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
431610bool
432operator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
611operator==(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
433612{
434613 return __x.first == __y.first && __x.second == __y.second;
435614}
436615
437#if _LIBCPP_STD_VER > 17
616#if _LIBCPP_STD_VER >= 20
438617
439template <class _T1, class _T2>
618template <class _T1, class _T2, class _U1, class _U2>
440619_LIBCPP_HIDE_FROM_ABI constexpr
441620common_comparison_category_t<
442 __synth_three_way_result<_T1>,
443 __synth_three_way_result<_T2> >
444operator<=>(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
621 __synth_three_way_result<_T1, _U1>,
622 __synth_three_way_result<_T2, _U2> >
623operator<=>(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
445624{
446 if (auto __c = _VSTD::__synth_three_way(__x.first, __y.first); __c != 0) {
625 if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) {
447626 return __c;
448627 }
449 return _VSTD::__synth_three_way(__x.second, __y.second);
628 return std::__synth_three_way(__x.second, __y.second);
450629}
451630
452#else // _LIBCPP_STD_VER > 17
631#else // _LIBCPP_STD_VER >= 20
453632
454template <class _T1, class _T2>
455inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
633template <class _T1, class _T2, class _U1, class _U2>
634inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
456635bool
457operator!=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
636operator!=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
458637{
459638 return !(__x == __y);
460639}
461640
462template <class _T1, class _T2>
463inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
641template <class _T1, class _T2, class _U1, class _U2>
642inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
464643bool
465operator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
644operator< (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
466645{
467646 return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
468647}
469648
470template <class _T1, class _T2>
471inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
649template <class _T1, class _T2, class _U1, class _U2>
650inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
472651bool
473operator> (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
652operator> (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
474653{
475654 return __y < __x;
476655}
477656
478template <class _T1, class _T2>
479inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
657template <class _T1, class _T2, class _U1, class _U2>
658inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
480659bool
481operator>=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
660operator>=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
482661{
483662 return !(__x < __y);
484663}
485664
486template <class _T1, class _T2>
487inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
665template <class _T1, class _T2, class _U1, class _U2>
666inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
488667bool
489operator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
668operator<=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
490669{
491670 return !(__y < __x);
492671}
493672
494#endif // _LIBCPP_STD_VER > 17
673#endif // _LIBCPP_STD_VER >= 20
495674
496#if _LIBCPP_STD_VER > 20
675#if _LIBCPP_STD_VER >= 23
497676template <class _T1, class _T2, class _U1, class _U2, template<class> class _TQual, template<class> class _UQual>
498677 requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
499678 common_reference_t<_TQual<_T2>, _UQual<_U2>>>; }
......@@ -507,10 +686,10 @@ template <class _T1, class _T2, class _U1, class _U2>
507686struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> {
508687 using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>;
509688};
510#endif // _LIBCPP_STD_VER > 20
689#endif // _LIBCPP_STD_VER >= 23
511690
512691template <class _T1, class _T2>
513inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
692inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
514693typename enable_if
515694<
516695 __is_swappable<_T1>::value &&
......@@ -524,7 +703,7 @@ swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
524703 __x.swap(__y);
525704}
526705
527#if _LIBCPP_STD_VER > 20
706#if _LIBCPP_STD_VER >= 23
528707template <class _T1, class _T2>
529708 requires (__is_swappable<const _T1>::value &&
530709 __is_swappable<const _T2>::value)
......@@ -537,12 +716,12 @@ void swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
537716#endif
538717
539718template <class _T1, class _T2>
540inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
719inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
541720pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
542721make_pair(_T1&& __t1, _T2&& __t2)
543722{
544723 return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
545 (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
724 (std::forward<_T1>(__t1), std::forward<_T2>(__t2));
546725}
547726
548727template <class _T1, class _T2>
......@@ -558,13 +737,13 @@ struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> >
558737template <class _T1, class _T2>
559738struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> >
560739{
561 typedef _LIBCPP_NODEBUG _T1 type;
740 using type _LIBCPP_NODEBUG = _T1;
562741};
563742
564743template <class _T1, class _T2>
565744struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> >
566745{
567 typedef _LIBCPP_NODEBUG _T2 type;
746 using type _LIBCPP_NODEBUG = _T2;
568747};
569748
570749template <size_t _Ip> struct __get_pair;
......@@ -574,27 +753,27 @@ struct __get_pair<0>
574753{
575754 template <class _T1, class _T2>
576755 static
577 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
756 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
578757 _T1&
579758 get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
580759
581760 template <class _T1, class _T2>
582761 static
583 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
762 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
584763 const _T1&
585764 get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
586765
587766 template <class _T1, class _T2>
588767 static
589 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
768 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
590769 _T1&&
591 get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);}
770 get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T1>(__p.first);}
592771
593772 template <class _T1, class _T2>
594773 static
595 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
774 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
596775 const _T1&&
597 get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T1>(__p.first);}
776 get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T1>(__p.first);}
598777};
599778
600779template <>
......@@ -602,31 +781,31 @@ struct __get_pair<1>
602781{
603782 template <class _T1, class _T2>
604783 static
605 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
784 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
606785 _T2&
607786 get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
608787
609788 template <class _T1, class _T2>
610789 static
611 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
790 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
612791 const _T2&
613792 get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
614793
615794 template <class _T1, class _T2>
616795 static
617 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
796 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
618797 _T2&&
619 get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);}
798 get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T2>(__p.second);}
620799
621800 template <class _T1, class _T2>
622801 static
623 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
802 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
624803 const _T2&&
625 get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T2>(__p.second);}
804 get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T2>(__p.second);}
626805};
627806
628807template <size_t _Ip, class _T1, class _T2>
629inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
808inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
630809typename tuple_element<_Ip, pair<_T1, _T2> >::type&
631810get(pair<_T1, _T2>& __p) _NOEXCEPT
632811{
......@@ -634,7 +813,7 @@ get(pair<_T1, _T2>& __p) _NOEXCEPT
634813}
635814
636815template <size_t _Ip, class _T1, class _T2>
637inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
816inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
638817const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
639818get(const pair<_T1, _T2>& __p) _NOEXCEPT
640819{
......@@ -642,80 +821,82 @@ get(const pair<_T1, _T2>& __p) _NOEXCEPT
642821}
643822
644823template <size_t _Ip, class _T1, class _T2>
645inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
824inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
646825typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
647826get(pair<_T1, _T2>&& __p) _NOEXCEPT
648827{
649 return __get_pair<_Ip>::get(_VSTD::move(__p));
828 return __get_pair<_Ip>::get(std::move(__p));
650829}
651830
652831template <size_t _Ip, class _T1, class _T2>
653inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
832inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
654833const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
655834get(const pair<_T1, _T2>&& __p) _NOEXCEPT
656835{
657 return __get_pair<_Ip>::get(_VSTD::move(__p));
836 return __get_pair<_Ip>::get(std::move(__p));
658837}
659838
660#if _LIBCPP_STD_VER > 11
839#if _LIBCPP_STD_VER >= 14
661840template <class _T1, class _T2>
662inline _LIBCPP_INLINE_VISIBILITY
841inline _LIBCPP_HIDE_FROM_ABI
663842constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT
664843{
665844 return __get_pair<0>::get(__p);
666845}
667846
668847template <class _T1, class _T2>
669inline _LIBCPP_INLINE_VISIBILITY
848inline _LIBCPP_HIDE_FROM_ABI
670849constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT
671850{
672851 return __get_pair<0>::get(__p);
673852}
674853
675854template <class _T1, class _T2>
676inline _LIBCPP_INLINE_VISIBILITY
855inline _LIBCPP_HIDE_FROM_ABI
677856constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT
678857{
679 return __get_pair<0>::get(_VSTD::move(__p));
858 return __get_pair<0>::get(std::move(__p));
680859}
681860
682861template <class _T1, class _T2>
683inline _LIBCPP_INLINE_VISIBILITY
862inline _LIBCPP_HIDE_FROM_ABI
684863constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT
685864{
686 return __get_pair<0>::get(_VSTD::move(__p));
865 return __get_pair<0>::get(std::move(__p));
687866}
688867
689868template <class _T1, class _T2>
690inline _LIBCPP_INLINE_VISIBILITY
869inline _LIBCPP_HIDE_FROM_ABI
691870constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT
692871{
693872 return __get_pair<1>::get(__p);
694873}
695874
696875template <class _T1, class _T2>
697inline _LIBCPP_INLINE_VISIBILITY
876inline _LIBCPP_HIDE_FROM_ABI
698877constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT
699878{
700879 return __get_pair<1>::get(__p);
701880}
702881
703882template <class _T1, class _T2>
704inline _LIBCPP_INLINE_VISIBILITY
883inline _LIBCPP_HIDE_FROM_ABI
705884constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT
706885{
707 return __get_pair<1>::get(_VSTD::move(__p));
886 return __get_pair<1>::get(std::move(__p));
708887}
709888
710889template <class _T1, class _T2>
711inline _LIBCPP_INLINE_VISIBILITY
890inline _LIBCPP_HIDE_FROM_ABI
712891constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT
713892{
714 return __get_pair<1>::get(_VSTD::move(__p));
893 return __get_pair<1>::get(std::move(__p));
715894}
716895
717#endif // _LIBCPP_STD_VER > 11
896#endif // _LIBCPP_STD_VER >= 14
718897
719898_LIBCPP_END_NAMESPACE_STD
720899
900_LIBCPP_POP_MACROS
901
721902#endif // _LIBCPP___UTILITY_PAIR_H
lib/libcxx/include/__utility/piecewise_construct.h+5-4
......@@ -18,10 +18,11 @@
1818_LIBCPP_BEGIN_NAMESPACE_STD
1919
2020struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { explicit piecewise_construct_t() = default; };
21#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
22extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
23#else
24/* inline */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
21
22#if _LIBCPP_STD_VER >= 17
23inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
24#elif !defined(_LIBCPP_CXX03_LANG)
25constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
2526#endif
2627
2728_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__utility/swap.h+5
......@@ -23,6 +23,9 @@
2323# pragma GCC system_header
2424#endif
2525
26_LIBCPP_PUSH_MACROS
27#include <__undef_macros>
28
2629_LIBCPP_BEGIN_NAMESPACE_STD
2730
2831#ifndef _LIBCPP_CXX03_LANG
......@@ -51,4 +54,6 @@ swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::v
5154
5255_LIBCPP_END_NAMESPACE_STD
5356
57_LIBCPP_POP_MACROS
58
5459#endif // _LIBCPP___UTILITY_SWAP_H
lib/libcxx/include/__utility/terminate_on_exception.h created+48
......@@ -0,0 +1,48 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_TERMINATE_ON_EXCEPTION_H
10#define _LIBCPP___UTILITY_TERMINATE_ON_EXCEPTION_H
11
12#include <__config>
13#include <__exception/terminate.h>
14#include <new>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20#if _LIBCPP_STD_VER >= 17
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
25
26template <class _Func>
27_LIBCPP_HIDE_FROM_ABI auto __terminate_on_exception(_Func __func) {
28 try {
29 return __func();
30 } catch (...) {
31 std::terminate();
32 }
33}
34
35# else // _LIBCPP_HAS_NO_EXCEPTIONS
36
37template <class _Func>
38_LIBCPP_HIDE_FROM_ABI auto __terminate_on_exception(_Func __func) {
39 return __func();
40}
41
42# endif // _LIBCPP_HAS_NO_EXCEPTIONS
43
44_LIBCPP_END_NAMESPACE_STD
45
46#endif // _LIBCPP_STD_VER >= 17
47
48#endif // _LIBCPP___UTILITY_TERMINATE_ON_EXCEPTION_H
lib/libcxx/include/__utility/to_underlying.h+1-1
......@@ -27,7 +27,7 @@ __to_underlying(_Tp __val) noexcept {
2727}
2828#endif // !_LIBCPP_CXX03_LANG
2929
30#if _LIBCPP_STD_VER > 20
30#if _LIBCPP_STD_VER >= 23
3131template <class _Tp>
3232_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY constexpr underlying_type_t<_Tp>
3333to_underlying(_Tp __val) noexcept {
lib/libcxx/include/__utility/unreachable.h+2-2
......@@ -19,11 +19,11 @@
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
2121_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void __libcpp_unreachable() {
22 _LIBCPP_ASSERT(false, "std::unreachable() was reached");
22 _LIBCPP_ASSERT_UNCATEGORIZED(false, "std::unreachable() was reached");
2323 __builtin_unreachable();
2424}
2525
26#if _LIBCPP_STD_VER > 20
26#if _LIBCPP_STD_VER >= 23
2727
2828[[noreturn]] _LIBCPP_HIDE_FROM_ABI inline void unreachable() { __libcpp_unreachable(); }
2929
lib/libcxx/include/__variant/monostate.h+5-5
......@@ -21,19 +21,19 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_STD
2323
24#if _LIBCPP_STD_VER > 14
24#if _LIBCPP_STD_VER >= 17
2525
2626struct _LIBCPP_TEMPLATE_VIS monostate {};
2727
2828_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(monostate, monostate) noexcept { return true; }
2929
30# if _LIBCPP_STD_VER > 17
30# if _LIBCPP_STD_VER >= 20
3131
3232_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(monostate, monostate) noexcept {
3333 return strong_ordering::equal;
3434}
3535
36# else // _LIBCPP_STD_VER > 17
36# else // _LIBCPP_STD_VER >= 20
3737
3838_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(monostate, monostate) noexcept { return false; }
3939
......@@ -45,7 +45,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(monostate, monostate) noexcept {
4545
4646_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(monostate, monostate) noexcept { return true; }
4747
48# endif // _LIBCPP_STD_VER > 17
48# endif // _LIBCPP_STD_VER >= 20
4949
5050template <>
5151struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
......@@ -57,7 +57,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
5757 }
5858};
5959
60#endif // _LIBCPP_STD_VER > 14
60#endif // _LIBCPP_STD_VER >= 17
6161
6262_LIBCPP_END_NAMESPACE_STD
6363
lib/libcxx/include/__verbose_abort+8-5
......@@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121
2222// This function should never be called directly from the code -- it should only be called through
2323// the _LIBCPP_VERBOSE_ABORT macro.
24_LIBCPP_NORETURN _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
24_LIBCPP_NORETURN _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
2525void __libcpp_verbose_abort(const char *__format, ...);
2626
2727// _LIBCPP_VERBOSE_ABORT(format, args...)
......@@ -40,16 +40,19 @@ void __libcpp_verbose_abort(const char *__format, ...);
4040
4141// Support _LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED until LLVM 18, but tell people
4242// to move to customizing _LIBCPP_VERBOSE_ABORT instead.
43# if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY) && defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED)
44# undef _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
43# if defined(_LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT) && defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED)
44# undef _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT
4545# warning _LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED is deprecated, please customize _LIBCPP_VERBOSE_ABORT instead
4646# endif
4747
48# if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY)
49# define _LIBCPP_VERBOSE_ABORT(...) __builtin_abort()
48# if defined(_LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT)
49// The decltype is there to suppress -Wunused warnings in this configuration.
50void __use(const char*, ...);
51# define _LIBCPP_VERBOSE_ABORT(...) (decltype(::std::__use(__VA_ARGS__))(), __builtin_abort())
5052# else
5153# define _LIBCPP_VERBOSE_ABORT(...) ::std::__libcpp_verbose_abort(__VA_ARGS__)
5254# endif
55
5356#endif // !defined(_LIBCPP_VERBOSE_ABORT)
5457
5558_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/algorithm+162-121
......@@ -22,41 +22,41 @@ namespace ranges {
2222
2323 // [algorithms.results], algorithm result types
2424 template <class I, class F>
25 struct in_fun_result; // since C++20
25 struct in_fun_result; // since C++20
2626
2727 template <class I1, class I2>
28 struct in_in_result; // since C++20
28 struct in_in_result; // since C++20
2929
3030 template <class I, class O>
31 struct in_out_result; // since C++20
31 struct in_out_result; // since C++20
3232
3333 template <class I1, class I2, class O>
34 struct in_in_out_result; // since C++20
34 struct in_in_out_result; // since C++20
3535
3636 template <class I, class O1, class O2>
37 struct in_out_out_result; // since C++20
37 struct in_out_out_result; // since C++20
3838
3939 template <class I1, class I2>
40 struct min_max_result; // since C++20
40 struct min_max_result; // since C++20
4141
4242 template <class I>
43 struct in_found_result; // since C++20
43 struct in_found_result; // since C++20
4444
4545 template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
46 indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> // since C++20
46 indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> // since C++20
4747 constexpr I min_element(I first, S last, Comp comp = {}, Proj proj = {});
4848
4949 template<forward_range R, class Proj = identity,
50 indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> // since C++20
50 indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> // since C++20
5151 constexpr borrowed_iterator_t<R> min_element(R&& r, Comp comp = {}, Proj proj = {});
5252
5353 template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
5454 indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
55 constexpr I ranges::max_element(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
55 constexpr I ranges::max_element(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
5656
5757 template<forward_range R, class Proj = identity,
5858 indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
59 constexpr borrowed_iterator_t<R> ranges::max_element(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
59 constexpr borrowed_iterator_t<R> ranges::max_element(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
6060
6161 template<class I1, class I2>
6262 using mismatch_result = in_in_result<I1, I2>;
......@@ -64,86 +64,86 @@ namespace ranges {
6464 template <input_iterator I1, sentinel_for<_I1> S1, input_iterator I2, sentinel_for<_I2> S2,
6565 class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
6666 requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
67 constexpr mismatch_result<_I1, _I2>
68 mismatch()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) // since C++20
67 constexpr mismatch_result<_I1, _I2> // since C++20
68 mismatch()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
6969
7070 template <input_range R1, input_range R2,
7171 class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
7272 requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
7373 constexpr mismatch_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
74 mismatch(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) // since C++20
74 mismatch(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) // since C++20
7575
7676 requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
77 constexpr I find(I first, S last, const T& value, Proj proj = {}); // since C++20
77 constexpr I find(I first, S last, const T& value, Proj proj = {}); // since C++20
7878
7979 template<input_range R, class T, class Proj = identity>
8080 requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T*>
8181 constexpr borrowed_iterator_t<R>
82 find(R&& r, const T& value, Proj proj = {}); // since C++20
82 find(R&& r, const T& value, Proj proj = {}); // since C++20
8383
8484 template<input_iterator I, sentinel_for<I> S, class Proj = identity,
8585 indirect_unary_predicate<projected<I, Proj>> Pred>
86 constexpr I find_if(I first, S last, Pred pred, Proj proj = {}); // since C++20
86 constexpr I find_if(I first, S last, Pred pred, Proj proj = {}); // since C++20
8787
8888 template<input_range R, class Proj = identity,
8989 indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
9090 constexpr borrowed_iterator_t<R>
91 find_if(R&& r, Pred pred, Proj proj = {}); // since C++20
91 find_if(R&& r, Pred pred, Proj proj = {}); // since C++20
9292
9393 template<input_iterator I, sentinel_for<I> S, class Proj = identity,
9494 indirect_unary_predicate<projected<I, Proj>> Pred>
95 constexpr I find_if_not(I first, S last, Pred pred, Proj proj = {}); // since C++20
95 constexpr I find_if_not(I first, S last, Pred pred, Proj proj = {}); // since C++20
9696
9797 template<input_range R, class Proj = identity,
9898 indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
9999 constexpr borrowed_iterator_t<R>
100 find_if_not(R&& r, Pred pred, Proj proj = {}); // since C++20
100 find_if_not(R&& r, Pred pred, Proj proj = {}); // since C++20
101101
102102 template<class T, class Proj = identity,
103103 indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
104 constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20
104 constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20
105105
106106 template<copyable T, class Proj = identity,
107107 indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
108 constexpr T min(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20
108 constexpr T min(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20
109109
110110 template<input_range R, class Proj = identity,
111111 indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
112112 requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*>
113113 constexpr range_value_t<R>
114 min(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
114 min(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
115115
116116 template<class T, class Proj = identity,
117117 indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
118 constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20
118 constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20
119119
120120 template<copyable T, class Proj = identity,
121121 indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
122 constexpr T max(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20
122 constexpr T max(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20
123123
124124 template<input_range R, class Proj = identity,
125125 indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
126126 requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*>
127127 constexpr range_value_t<R>
128 max(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
128 max(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
129129
130130 template<class I, class O>
131 using unary_transform_result = in_out_result<I, O>; // since C++20
131 using unary_transform_result = in_out_result<I, O>; // since C++20
132132
133133 template<class I1, class I2, class O>
134 using binary_transform_result = in_in_out_result<I1, I2, O>; // since C++20
134 using binary_transform_result = in_in_out_result<I1, I2, O>; // since C++20
135135
136136 template<input_iterator I, sentinel_for<I> S, weakly_incrementable O,
137137 copy_constructible F, class Proj = identity>
138138 requires indirectly_writable<O, indirect_result_t<F&, projected<I, Proj>>>
139139 constexpr ranges::unary_transform_result<I, O>
140 transform(I first1, S last1, O result, F op, Proj proj = {}); // since C++20
140 transform(I first1, S last1, O result, F op, Proj proj = {}); // since C++20
141141
142142 template<input_range R, weakly_incrementable O, copy_constructible F,
143143 class Proj = identity>
144144 requires indirectly_writable<O, indirect_result_t<F&, projected<iterator_t<R>, Proj>>>
145145 constexpr ranges::unary_transform_result<borrowed_iterator_t<R>, O>
146 transform(R&& r, O result, F op, Proj proj = {}); // since C++20
146 transform(R&& r, O result, F op, Proj proj = {}); // since C++20
147147
148148 template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
149149 weakly_incrementable O, copy_constructible F, class Proj1 = identity,
......@@ -152,7 +152,7 @@ namespace ranges {
152152 projected<I2, Proj2>>>
153153 constexpr ranges::binary_transform_result<I1, I2, O>
154154 transform(I1 first1, S1 last1, I2 first2, S2 last2, O result,
155 F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
155 F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
156156
157157 template<input_range R1, input_range R2, weakly_incrementable O,
158158 copy_constructible F, class Proj1 = identity, class Proj2 = identity>
......@@ -160,27 +160,27 @@ namespace ranges {
160160 projected<iterator_t<R2>, Proj2>>>
161161 constexpr ranges::binary_transform_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O>
162162 transform(R1&& r1, R2&& r2, O result,
163 F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
163 F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
164164
165165 template<input_iterator I, sentinel_for<I> S, class T, class Proj = identity>
166166 requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
167167 constexpr iter_difference_t<I>
168 count(I first, S last, const T& value, Proj proj = {}); // since C++20
168 count(I first, S last, const T& value, Proj proj = {}); // since C++20
169169
170170 template<input_range R, class T, class Proj = identity>
171171 requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T*>
172172 constexpr range_difference_t<R>
173 count(R&& r, const T& value, Proj proj = {}); // since C++20
173 count(R&& r, const T& value, Proj proj = {}); // since C++20
174174
175175 template<input_iterator I, sentinel_for<I> S, class Proj = identity,
176176 indirect_unary_predicate<projected<I, Proj>> Pred>
177177 constexpr iter_difference_t<I>
178 count_if(I first, S last, Pred pred, Proj proj = {}); // since C++20
178 count_if(I first, S last, Pred pred, Proj proj = {}); // since C++20
179179
180180 template<input_range R, class Proj = identity,
181181 indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
182182 constexpr range_difference_t<R>
183 count_if(R&& r, Pred pred, Proj proj = {}); // since C++20
183 count_if(R&& r, Pred pred, Proj proj = {}); // since C++20
184184
185185 template<class T>
186186 using minmax_result = min_max_result<T>;
......@@ -188,18 +188,18 @@ namespace ranges {
188188 template<class T, class Proj = identity,
189189 indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
190190 constexpr ranges::minmax_result<const T&>
191 minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20
191 minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20
192192
193193 template<copyable T, class Proj = identity,
194194 indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
195195 constexpr ranges::minmax_result<T>
196 minmax(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20
196 minmax(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20
197197
198198 template<input_range R, class Proj = identity,
199199 indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
200200 requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*>
201201 constexpr ranges::minmax_result<range_value_t<R>>
202 minmax(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
202 minmax(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
203203
204204 template<class I>
205205 using minmax_element_result = min_max_result<I>;
......@@ -207,18 +207,18 @@ namespace ranges {
207207 template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
208208 indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
209209 constexpr ranges::minmax_element_result<I>
210 minmax_element(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
210 minmax_element(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
211211
212212 template<forward_range R, class Proj = identity,
213213 indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
214214 constexpr ranges::minmax_element_result<borrowed_iterator_t<R>>
215 minmax_element(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
215 minmax_element(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
216216
217217 template<class I, class O>
218 using copy_result = in_out_result<I, O>; // since C++20
218 using copy_result = in_out_result<I, O>; // since C++20
219219
220220 template<class I, class O>
221 using copy_n_result = in_out_result<I, O>; // since C++20
221 using copy_n_result = in_out_result<I, O>; // since C++20
222222
223223 template<class I, class O>
224224 using copy_if_result = in_out_result<I, O>; // since C++20
......@@ -333,20 +333,20 @@ namespace ranges {
333333
334334 template<random_access_iterator I, sentinel_for<I> S, class Proj = identity,
335335 indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
336 constexpr bool is_heap(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20
336 constexpr bool is_heap(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
337337
338338 template<random_access_range R, class Proj = identity,
339339 indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
340 constexpr bool is_heap(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20
340 constexpr bool is_heap(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
341341
342342 template<random_access_iterator I, sentinel_for<I> S, class Proj = identity,
343343 indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
344 constexpr I is_heap_until(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20
344 constexpr I is_heap_until(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
345345
346346 template<random_access_range R, class Proj = identity,
347347 indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
348348 constexpr borrowed_iterator_t<R>
349 is_heap_until(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20
349 is_heap_until(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
350350
351351 template<bidirectional_iterator I, sentinel_for<I> S>
352352 requires permutable<I>
......@@ -399,15 +399,24 @@ namespace ranges {
399399
400400 template<input_or_output_iterator O, sentinel_for<O> S, copy_constructible F>
401401 requires invocable<F&> && indirectly_writable<O, invoke_result_t<F&>>
402 constexpr O generate(O first, S last, F gen); // Since C++20
402 constexpr O generate(O first, S last, F gen); // since C++20
403
404 template<class ExecutionPolicy, class ForwardIterator, class Generator>
405 void generate(ExecutionPolicy&& exec,
406 ForwardIterator first, ForwardIterator last,
407 Generator gen); // since C++17
403408
404409 template<class R, copy_constructible F>
405410 requires invocable<F&> && output_range<R, invoke_result_t<F&>>
406 constexpr borrowed_iterator_t<R> generate(R&& r, F gen); // Since C++20
411 constexpr borrowed_iterator_t<R> generate(R&& r, F gen); // since C++20
407412
408413 template<input_or_output_iterator O, copy_constructible F>
409414 requires invocable<F&> && indirectly_writable<O, invoke_result_t<F&>>
410 constexpr O generate_n(O first, iter_difference_t<O> n, F gen); // Since C++20
415 constexpr O generate_n(O first, iter_difference_t<O> n, F gen); // since C++20
416
417 template<class ExecutionPolicy, class ForwardIterator, class Size, class Generator>
418 ForwardIterator generate_n(ExecutionPolicy&& exec,
419 ForwardIterator first, Size n, Generator gen); // since C++17
411420
412421 template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
413422 class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
......@@ -424,27 +433,39 @@ namespace ranges {
424433
425434 template<input_iterator I, sentinel_for<I> S, class Proj = identity,
426435 indirect_unary_predicate<projected<I, Proj>> Pred>
427 constexpr bool ranges::all_of(I first, S last, Pred pred, Proj proj = {}); // since C++20
436 constexpr bool ranges::all_of(I first, S last, Pred pred, Proj proj = {}); // since C++20
428437
429438 template<input_range R, class Proj = identity,
430439 indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
431 constexpr bool ranges::all_of(R&& r, Pred pred, Proj proj = {}); // since C++20
440 constexpr bool ranges::all_of(R&& r, Pred pred, Proj proj = {}); // since C++20
432441
433442 template<input_iterator I, sentinel_for<I> S, class Proj = identity,
434443 indirect_unary_predicate<projected<I, Proj>> Pred>
435 constexpr bool ranges::any_of(I first, S last, Pred pred, Proj proj = {}); // since C++20
444 constexpr bool ranges::any_of(I first, S last, Pred pred, Proj proj = {}); // since C++20
436445
437446 template<input_range R, class Proj = identity,
438447 indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
439 constexpr bool ranges::any_of(R&& r, Pred pred, Proj proj = {}); // since C++20
448 constexpr bool ranges::any_of(R&& r, Pred pred, Proj proj = {}); // since C++20
440449
441450 template<input_iterator I, sentinel_for<I> S, class Proj = identity,
442451 indirect_unary_predicate<projected<I, Proj>> Pred>
443 constexpr bool ranges::none_of(I first, S last, Pred pred, Proj proj = {}); // since C++20
452 constexpr bool ranges::none_of(I first, S last, Pred pred, Proj proj = {}); // since C++20
444453
445454 template<input_range R, class Proj = identity,
446455 indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
447 constexpr bool ranges::none_of(R&& r, Pred pred, Proj proj = {}); // since C++20
456 constexpr bool ranges::none_of(R&& r, Pred pred, Proj proj = {}); // since C++20
457
458 template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
459 class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
460 requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
461 constexpr bool ranges::starts_with(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
462 Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++23
463
464 template<input_range R1, input_range R2, class Pred = ranges::equal_to, class Proj1 = identity,
465 class Proj2 = identity>
466 requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
467 constexpr bool ranges::starts_with(R1&& r1, R2&& r2, Pred pred = {},
468 Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++23
448469
449470 template<input_iterator I1, sentinel_for<I1> S1,
450471 random_access_iterator I2, sentinel_for<I2> S2,
......@@ -453,7 +474,7 @@ namespace ranges {
453474 indirect_strict_weak_order<Comp, projected<I1, Proj1>, projected<I2, Proj2>>
454475 constexpr partial_sort_copy_result<I1, I2>
455476 partial_sort_copy(I1 first, S1 last, I2 result_first, S2 result_last,
456 Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
477 Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
457478
458479 template<input_range R1, random_access_range R2, class Comp = ranges::less,
459480 class Proj1 = identity, class Proj2 = identity>
......@@ -463,7 +484,7 @@ namespace ranges {
463484 projected<iterator_t<R2>, Proj2>>
464485 constexpr partial_sort_copy_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
465486 partial_sort_copy(R1&& r, R2&& result_r, Comp comp = {},
466 Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
487 Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
467488
468489 template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
469490 indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
......@@ -486,64 +507,64 @@ namespace ranges {
486507 class Proj = identity>
487508 requires sortable<I, Comp, Proj>
488509 constexpr I
489 ranges::nth_element(I first, I nth, S last, Comp comp = {}, Proj proj = {}); // since C++20
510 ranges::nth_element(I first, I nth, S last, Comp comp = {}, Proj proj = {}); // since C++20
490511
491512 template<random_access_range R, class Comp = ranges::less, class Proj = identity>
492513 requires sortable<iterator_t<R>, Comp, Proj>
493514 constexpr borrowed_iterator_t<R>
494 ranges::nth_element(R&& r, iterator_t<R> nth, Comp comp = {}, Proj proj = {}); // since C++20
515 ranges::nth_element(R&& r, iterator_t<R> nth, Comp comp = {}, Proj proj = {}); // since C++20
495516
496517 template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
497 indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less>
498 constexpr I upper_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); // since C++20
518 indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less> // since C++20
519 constexpr I upper_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {});
499520
500521 template<forward_range R, class T, class Proj = identity,
501522 indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Comp =
502523 ranges::less>
503524 constexpr borrowed_iterator_t<R>
504 upper_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); // since C++20
525 upper_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); // since C++20
505526
506527 template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
507528 indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less>
508529 constexpr I lower_bound(I first, S last, const T& value, Comp comp = {},
509 Proj proj = {}); // since C++20
530 Proj proj = {}); // since C++20
510531 template<forward_range R, class T, class Proj = identity,
511532 indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Comp =
512533 ranges::less>
513534 constexpr borrowed_iterator_t<R>
514 lower_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); // since C++20
535 lower_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); // since C++20
515536
516537 template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
517538 indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less>
518539 constexpr bool binary_search(I first, S last, const T& value, Comp comp = {},
519 Proj proj = {}); // since C++20
540 Proj proj = {}); // since C++20
520541
521542 template<forward_range R, class T, class Proj = identity,
522543 indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Comp =
523544 ranges::less>
524545 constexpr bool binary_search(R&& r, const T& value, Comp comp = {},
525 Proj proj = {}); // since C++20
546 Proj proj = {}); // since C++20
526547
527548 template<permutable I, sentinel_for<I> S, class Proj = identity,
528549 indirect_unary_predicate<projected<I, Proj>> Pred>
529550 constexpr subrange<I>
530 partition(I first, S last, Pred pred, Proj proj = {}); // Since C++20
551 partition(I first, S last, Pred pred, Proj proj = {}); // since C++20
531552
532553 template<forward_range R, class Proj = identity,
533554 indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
534555 requires permutable<iterator_t<R>>
535556 constexpr borrowed_subrange_t<R>
536 partition(R&& r, Pred pred, Proj proj = {}); // Since C++20
557 partition(R&& r, Pred pred, Proj proj = {}); // since C++20
537558
538559 template<bidirectional_iterator I, sentinel_for<I> S, class Proj = identity,
539560 indirect_unary_predicate<projected<I, Proj>> Pred>
540561 requires permutable<I>
541 subrange<I> stable_partition(I first, S last, Pred pred, Proj proj = {}); // Since C++20
562 subrange<I> stable_partition(I first, S last, Pred pred, Proj proj = {}); // since C++20
542563
543564 template<bidirectional_range R, class Proj = identity,
544565 indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
545566 requires permutable<iterator_t<R>>
546 borrowed_subrange_t<R> stable_partition(R&& r, Pred pred, Proj proj = {}); // Since C++20
567 borrowed_subrange_t<R> stable_partition(R&& r, Pred pred, Proj proj = {}); // since C++20
547568
548569 template<input_iterator I1, sentinel_for<I1> S1, forward_iterator I2, sentinel_for<I2> S2,
549570 class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
......@@ -563,7 +584,7 @@ namespace ranges {
563584 template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
564585 indirect_binary_predicate<projected<I, Proj>,
565586 projected<I, Proj>> Pred = ranges::equal_to>
566 constexpr I ranges::adjacent_find(I first, S last, Pred pred = {}, Proj proj = {}); // since C+20
587 constexpr I ranges::adjacent_find(I first, S last, Pred pred = {}, Proj proj = {}); // since C++20
567588
568589 template<forward_range R, class Proj = identity,
569590 indirect_binary_predicate<projected<iterator_t<R>, Proj>,
......@@ -604,7 +625,7 @@ namespace ranges {
604625 projected<I2, Proj2>> Comp = ranges::less>
605626 constexpr bool
606627 ranges::lexicographical_compare(I1 first1, S1 last1, I2 first2, S2 last2,
607 Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
628 Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
608629
609630 template<input_range R1, input_range R2, class Proj1 = identity,
610631 class Proj2 = identity,
......@@ -612,7 +633,7 @@ namespace ranges {
612633 projected<iterator_t<R2>, Proj2>> Comp = ranges::less>
613634 constexpr bool
614635 ranges::lexicographical_compare(R1&& r1, R2&& r2, Comp comp = {},
615 Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
636 Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
616637
617638 template<bidirectional_iterator I1, sentinel_for<I1> S1, bidirectional_iterator I2>
618639 requires indirectly_movable<I1, I2>
......@@ -643,7 +664,7 @@ namespace ranges {
643664 requires indirectly_copyable<I, O1> && indirectly_copyable<I, O2>
644665 constexpr partition_copy_result<I, O1, O2>
645666 partition_copy(I first, S last, O1 out_true, O2 out_false, Pred pred,
646 Proj proj = {}); // Since C++20
667 Proj proj = {}); // since C++20
647668
648669 template<input_range R, weakly_incrementable O1, weakly_incrementable O2,
649670 class Proj = identity,
......@@ -651,16 +672,16 @@ namespace ranges {
651672 requires indirectly_copyable<iterator_t<R>, O1> &&
652673 indirectly_copyable<iterator_t<R>, O2>
653674 constexpr partition_copy_result<borrowed_iterator_t<R>, O1, O2>
654 partition_copy(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {}); // Since C++20
675 partition_copy(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {}); // since C++20
655676
656677 template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
657678 indirect_unary_predicate<projected<I, Proj>> Pred>
658 constexpr I partition_point(I first, S last, Pred pred, Proj proj = {}); // Since C++20
679 constexpr I partition_point(I first, S last, Pred pred, Proj proj = {}); // since C++20
659680
660681 template<forward_range R, class Proj = identity,
661682 indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
662683 constexpr borrowed_iterator_t<R>
663 partition_point(R&& r, Pred pred, Proj proj = {}); // Since C++20
684 partition_point(R&& r, Pred pred, Proj proj = {}); // since C++20
664685
665686 template<class I1, class I2, class O>
666687 using merge_result = in_in_out_result<I1, I2, O>; // since C++20
......@@ -755,7 +776,7 @@ namespace ranges {
755776
756777 template<forward_range R>
757778 requires permutable<iterator_t<R>>
758 constexpr borrowed_subrange_t<R> rotate(R&& r, iterator_t<R> middle); // Since C++20
779 constexpr borrowed_subrange_t<R> rotate(R&& r, iterator_t<R> middle); // since C++20
759780
760781 template <class _InIter, class _OutIter>
761782 using rotate_copy_result = in_out_result<_InIter, _OutIter>; // since C++20
......@@ -774,23 +795,23 @@ namespace ranges {
774795 requires (forward_iterator<I> || random_access_iterator<O>) &&
775796 indirectly_copyable<I, O> &&
776797 uniform_random_bit_generator<remove_reference_t<Gen>>
777 O sample(I first, S last, O out, iter_difference_t<I> n, Gen&& g); // Since C++20
798 O sample(I first, S last, O out, iter_difference_t<I> n, Gen&& g); // since C++20
778799
779800 template<input_range R, weakly_incrementable O, class Gen>
780801 requires (forward_range<R> || random_access_iterator<O>) &&
781802 indirectly_copyable<iterator_t<R>, O> &&
782803 uniform_random_bit_generator<remove_reference_t<Gen>>
783 O sample(R&& r, O out, range_difference_t<R> n, Gen&& g); // Since C++20
804 O sample(R&& r, O out, range_difference_t<R> n, Gen&& g); // since C++20
784805
785806 template<random_access_iterator I, sentinel_for<I> S, class Gen>
786807 requires permutable<I> &&
787808 uniform_random_bit_generator<remove_reference_t<Gen>>
788 I shuffle(I first, S last, Gen&& g); // Since C++20
809 I shuffle(I first, S last, Gen&& g); // since C++20
789810
790811 template<random_access_range R, class Gen>
791812 requires permutable<iterator_t<R>> &&
792813 uniform_random_bit_generator<remove_reference_t<Gen>>
793 borrowed_iterator_t<R> shuffle(R&& r, Gen&& g); // Since C++20
814 borrowed_iterator_t<R> shuffle(R&& r, Gen&& g); // since C++20
794815
795816 template<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2,
796817 sentinel_for<I2> S2, class Proj1 = identity, class Proj2 = identity,
......@@ -798,14 +819,14 @@ namespace ranges {
798819 projected<I2, Proj2>> Pred = ranges::equal_to>
799820 constexpr bool ranges::is_permutation(I1 first1, S1 last1, I2 first2, S2 last2,
800821 Pred pred = {},
801 Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
822 Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
802823
803824 template<forward_range R1, forward_range R2,
804825 class Proj1 = identity, class Proj2 = identity,
805826 indirect_equivalence_relation<projected<iterator_t<R1>, Proj1>,
806827 projected<iterator_t<R2>, Proj2>> Pred = ranges::equal_to>
807828 constexpr bool ranges::is_permutation(R1&& r1, R2&& r2, Pred pred = {},
808 Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
829 Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
809830
810831 template<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2,
811832 sentinel_for<I2> S2, class Pred = ranges::equal_to,
......@@ -904,35 +925,35 @@ namespace ranges {
904925 indirect_strict_weak_order<projected<I1, Proj1>, projected<I2, Proj2>> Comp =
905926 ranges::less>
906927 constexpr bool includes(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {},
907 Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
928 Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
908929
909930 template<input_range R1, input_range R2, class Proj1 = identity,
910931 class Proj2 = identity,
911932 indirect_strict_weak_order<projected<iterator_t<R1>, Proj1>,
912933 projected<iterator_t<R2>, Proj2>> Comp = ranges::less>
913934 constexpr bool includes(R1&& r1, R2&& r2, Comp comp = {},
914 Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
935 Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
915936
916937 template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less,
917938 class Proj = identity>
918939 requires sortable<I, Comp, Proj>
919 I inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); // Since C++20
940 I inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); // since C++20
920941
921942 template<bidirectional_range R, class Comp = ranges::less, class Proj = identity>
922943 requires sortable<iterator_t<R>, Comp, Proj>
923944 borrowed_iterator_t<R>
924945 inplace_merge(R&& r, iterator_t<R> middle, Comp comp = {},
925 Proj proj = {}); // Since C++20
946 Proj proj = {}); // since C++20
926947
927948 template<permutable I, sentinel_for<I> S, class Proj = identity,
928949 indirect_equivalence_relation<projected<I, Proj>> C = ranges::equal_to>
929 constexpr subrange<I> unique(I first, S last, C comp = {}, Proj proj = {}); // Since C++20
950 constexpr subrange<I> unique(I first, S last, C comp = {}, Proj proj = {}); // since C++20
930951
931952 template<forward_range R, class Proj = identity,
932953 indirect_equivalence_relation<projected<iterator_t<R>, Proj>> C = ranges::equal_to>
933954 requires permutable<iterator_t<R>>
934955 constexpr borrowed_subrange_t<R>
935 unique(R&& r, C comp = {}, Proj proj = {}); // Since C++20
956 unique(R&& r, C comp = {}, Proj proj = {}); // since C++20
936957
937958 template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class Proj = identity,
938959 indirect_equivalence_relation<projected<I, Proj>> C = ranges::equal_to>
......@@ -941,7 +962,7 @@ namespace ranges {
941962 (input_iterator<O> && same_as<iter_value_t<I>, iter_value_t<O>>) ||
942963 indirectly_copyable_storable<I, O>)
943964 constexpr unique_copy_result<I, O>
944 unique_copy(I first, S last, O result, C comp = {}, Proj proj = {}); // Since C++20
965 unique_copy(I first, S last, O result, C comp = {}, Proj proj = {}); // since C++20
945966
946967 template<input_range R, weakly_incrementable O, class Proj = identity,
947968 indirect_equivalence_relation<projected<iterator_t<R>, Proj>> C = ranges::equal_to>
......@@ -950,41 +971,41 @@ namespace ranges {
950971 (input_iterator<O> && same_as<range_value_t<R>, iter_value_t<O>>) ||
951972 indirectly_copyable_storable<iterator_t<R>, O>)
952973 constexpr unique_copy_result<borrowed_iterator_t<R>, O>
953 unique_copy(R&& r, O result, C comp = {}, Proj proj = {}); // Since C++20
974 unique_copy(R&& r, O result, C comp = {}, Proj proj = {}); // since C++20
954975
955976 template<class I, class O>
956 using remove_copy_result = in_out_result<I, O>; // Since C++20
977 using remove_copy_result = in_out_result<I, O>; // since C++20
957978
958979 template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class T,
959980 class Proj = identity>
960981 indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
961982 constexpr remove_copy_result<I, O>
962 remove_copy(I first, S last, O result, const T& value, Proj proj = {}); // Since C++20
983 remove_copy(I first, S last, O result, const T& value, Proj proj = {}); // since C++20
963984
964985 template<input_range R, weakly_incrementable O, class T, class Proj = identity>
965986 requires indirectly_copyable<iterator_t<R>, O> &&
966987 indirect_binary_predicate<ranges::equal_to,
967988 projected<iterator_t<R>, Proj>, const T*>
968989 constexpr remove_copy_result<borrowed_iterator_t<R>, O>
969 remove_copy(R&& r, O result, const T& value, Proj proj = {}); // Since C++20
990 remove_copy(R&& r, O result, const T& value, Proj proj = {}); // since C++20
970991
971992 template<class I, class O>
972 using remove_copy_if_result = in_out_result<I, O>; // Since C++20
993 using remove_copy_if_result = in_out_result<I, O>; // since C++20
973994
974995 template<input_iterator I, sentinel_for<I> S, weakly_incrementable O,
975996 class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred>
976997 requires indirectly_copyable<I, O>
977998 constexpr remove_copy_if_result<I, O>
978 remove_copy_if(I first, S last, O result, Pred pred, Proj proj = {}); // Since C++20
999 remove_copy_if(I first, S last, O result, Pred pred, Proj proj = {}); // since C++20
9791000
9801001 template<input_range R, weakly_incrementable O, class Proj = identity,
9811002 indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
9821003 requires indirectly_copyable<iterator_t<R>, O>
9831004 constexpr remove_copy_if_result<borrowed_iterator_t<R>, O>
984 remove_copy_if(R&& r, O result, Pred pred, Proj proj = {}); // Since C++20
1005 remove_copy_if(R&& r, O result, Pred pred, Proj proj = {}); // since C++20
9851006
9861007 template<class I, class O>
987 using replace_copy_result = in_out_result<I, O>; // Since C++20
1008 using replace_copy_result = in_out_result<I, O>; // since C++20
9881009
9891010 template<input_iterator I, sentinel_for<I> S, class T1, class T2,
9901011 output_iterator<const T2&> O, class Proj = identity>
......@@ -992,7 +1013,7 @@ namespace ranges {
9921013 indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T1*>
9931014 constexpr replace_copy_result<I, O>
9941015 replace_copy(I first, S last, O result, const T1& old_value, const T2& new_value,
995 Proj proj = {}); // Since C++20
1016 Proj proj = {}); // since C++20
9961017
9971018 template<input_range R, class T1, class T2, output_iterator<const T2&> O,
9981019 class Proj = identity>
......@@ -1001,54 +1022,54 @@ namespace ranges {
10011022 projected<iterator_t<R>, Proj>, const T1*>
10021023 constexpr replace_copy_result<borrowed_iterator_t<R>, O>
10031024 replace_copy(R&& r, O result, const T1& old_value, const T2& new_value,
1004 Proj proj = {}); // Since C++20
1025 Proj proj = {}); // since C++20
10051026
10061027 template<class I, class O>
1007 using replace_copy_if_result = in_out_result<I, O>; // Since C++20
1028 using replace_copy_if_result = in_out_result<I, O>; // since C++20
10081029
10091030 template<input_iterator I, sentinel_for<I> S, class T, output_iterator<const T&> O,
10101031 class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred>
10111032 requires indirectly_copyable<I, O>
10121033 constexpr replace_copy_if_result<I, O>
10131034 replace_copy_if(I first, S last, O result, Pred pred, const T& new_value,
1014 Proj proj = {}); // Since C++20
1035 Proj proj = {}); // since C++20
10151036
10161037 template<input_range R, class T, output_iterator<const T&> O, class Proj = identity,
10171038 indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
10181039 requires indirectly_copyable<iterator_t<R>, O>
10191040 constexpr replace_copy_if_result<borrowed_iterator_t<R>, O>
10201041 replace_copy_if(R&& r, O result, Pred pred, const T& new_value,
1021 Proj proj = {}); // Since C++20
1042 Proj proj = {}); // since C++20
10221043
10231044 template<class I>
1024 using prev_permutation_result = in_found_result<I>; // Since C++20
1045 using prev_permutation_result = in_found_result<I>; // since C++20
10251046
10261047 template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less,
10271048 class Proj = identity>
10281049 requires sortable<I, Comp, Proj>
10291050 constexpr ranges::prev_permutation_result<I>
1030 ranges::prev_permutation(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20
1051 ranges::prev_permutation(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
10311052
10321053 template<bidirectional_range R, class Comp = ranges::less,
10331054 class Proj = identity>
10341055 requires sortable<iterator_t<R>, Comp, Proj>
10351056 constexpr ranges::prev_permutation_result<borrowed_iterator_t<R>>
1036 ranges::prev_permutation(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20
1057 ranges::prev_permutation(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
10371058
10381059 template<class I>
1039 using next_permutation_result = in_found_result<I>; // Since C++20
1060 using next_permutation_result = in_found_result<I>; // since C++20
10401061
10411062 template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less,
10421063 class Proj = identity>
10431064 requires sortable<I, Comp, Proj>
10441065 constexpr ranges::next_permutation_result<I>
1045 ranges::next_permutation(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20
1066 ranges::next_permutation(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
10461067
10471068 template<bidirectional_range R, class Comp = ranges::less,
10481069 class Proj = identity>
10491070 requires sortable<iterator_t<R>, Comp, Proj>
10501071 constexpr ranges::next_permutation_result<borrowed_iterator_t<R>>
1051 ranges::next_permutation(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20
1072 ranges::next_permutation(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
10521073
10531074}
10541075
......@@ -1684,6 +1705,18 @@ template <class InputIterator1, class InputIterator2, class Compare>
16841705 lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
16851706 InputIterator2 first2, InputIterator2 last2, Compare comp);
16861707
1708template<class InputIterator1, class InputIterator2, class Cmp>
1709 constexpr auto
1710 lexicographical_compare_three_way(InputIterator1 first1, InputIterator1 last1,
1711 InputIterator2 first2, InputIterator2 last2,
1712 Cmp comp)
1713 -> decltype(comp(*b1, *b2)); // since C++20
1714
1715template<class InputIterator1, class InputIterator2>
1716 constexpr auto
1717 lexicographical_compare_three_way(InputIterator1 first1, InputIterator1 last1,
1718 InputIterator2 first2, InputIterator2 last2); // since C++20
1719
16871720template <class BidirectionalIterator>
16881721 constexpr bool // constexpr in C++20
16891722 next_permutation(BidirectionalIterator first, BidirectionalIterator last);
......@@ -1705,9 +1738,7 @@ template <class BidirectionalIterator, class Compare>
17051738
17061739#include <__assert> // all public C++ headers provide the assertion handler
17071740#include <__config>
1708#include <__debug>
17091741#include <cstddef>
1710#include <type_traits>
17111742#include <version>
17121743
17131744#include <__algorithm/adjacent_find.h>
......@@ -1753,6 +1784,7 @@ template <class BidirectionalIterator, class Compare>
17531784#include <__algorithm/is_sorted_until.h>
17541785#include <__algorithm/iter_swap.h>
17551786#include <__algorithm/lexicographical_compare.h>
1787#include <__algorithm/lexicographical_compare_three_way.h>
17561788#include <__algorithm/lower_bound.h>
17571789#include <__algorithm/make_heap.h>
17581790#include <__algorithm/max.h>
......@@ -1776,6 +1808,19 @@ template <class BidirectionalIterator, class Compare>
17761808#include <__algorithm/partition_point.h>
17771809#include <__algorithm/pop_heap.h>
17781810#include <__algorithm/prev_permutation.h>
1811#include <__algorithm/pstl_any_all_none_of.h>
1812#include <__algorithm/pstl_copy.h>
1813#include <__algorithm/pstl_count.h>
1814#include <__algorithm/pstl_fill.h>
1815#include <__algorithm/pstl_find.h>
1816#include <__algorithm/pstl_for_each.h>
1817#include <__algorithm/pstl_generate.h>
1818#include <__algorithm/pstl_is_partitioned.h>
1819#include <__algorithm/pstl_merge.h>
1820#include <__algorithm/pstl_replace.h>
1821#include <__algorithm/pstl_sort.h>
1822#include <__algorithm/pstl_stable_sort.h>
1823#include <__algorithm/pstl_transform.h>
17791824#include <__algorithm/push_heap.h>
17801825#include <__algorithm/ranges_adjacent_find.h>
17811826#include <__algorithm/ranges_all_of.h>
......@@ -1857,6 +1902,7 @@ template <class BidirectionalIterator, class Compare>
18571902#include <__algorithm/ranges_sort_heap.h>
18581903#include <__algorithm/ranges_stable_partition.h>
18591904#include <__algorithm/ranges_stable_sort.h>
1905#include <__algorithm/ranges_starts_with.h>
18601906#include <__algorithm/ranges_swap_ranges.h>
18611907#include <__algorithm/ranges_transform.h>
18621908#include <__algorithm/ranges_unique.h>
......@@ -1905,21 +1951,16 @@ template <class BidirectionalIterator, class Compare>
19051951# pragma GCC system_header
19061952#endif
19071953
1908#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
1909# include <__pstl_algorithm>
1910#endif
1911
1912#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
1913# include <chrono>
1914#endif
1915
19161954#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
19171955# include <atomic>
1956# include <bit>
19181957# include <concepts>
1958# include <cstdlib>
19191959# include <cstring>
19201960# include <iterator>
19211961# include <memory>
19221962# include <stdexcept>
1963# include <type_traits>
19231964# include <utility>
19241965#endif
19251966
lib/libcxx/include/any+30-8
......@@ -87,13 +87,27 @@ namespace std {
8787#include <__memory/allocator_destructor.h>
8888#include <__memory/allocator_traits.h>
8989#include <__memory/unique_ptr.h>
90#include <__type_traits/add_const.h>
91#include <__type_traits/add_pointer.h>
92#include <__type_traits/aligned_storage.h>
93#include <__type_traits/alignment_of.h>
94#include <__type_traits/conditional.h>
95#include <__type_traits/decay.h>
96#include <__type_traits/is_constructible.h>
97#include <__type_traits/is_copy_constructible.h>
98#include <__type_traits/is_function.h>
99#include <__type_traits/is_nothrow_move_constructible.h>
100#include <__type_traits/is_reference.h>
101#include <__type_traits/is_same.h>
102#include <__type_traits/remove_cv.h>
103#include <__type_traits/remove_cvref.h>
104#include <__type_traits/remove_reference.h>
90105#include <__utility/forward.h>
91106#include <__utility/in_place.h>
92107#include <__utility/move.h>
93108#include <__utility/unreachable.h>
94#include <cstdlib>
109#include <__verbose_abort>
95110#include <initializer_list>
96#include <type_traits>
97111#include <typeinfo>
98112#include <version>
99113
......@@ -101,8 +115,11 @@ namespace std {
101115# pragma GCC system_header
102116#endif
103117
118_LIBCPP_PUSH_MACROS
119#include <__undef_macros>
120
104121namespace std {
105class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
122class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
106123{
107124public:
108125 const char* what() const _NOEXCEPT override;
......@@ -111,16 +128,16 @@ public:
111128
112129_LIBCPP_BEGIN_NAMESPACE_STD
113130
114#if _LIBCPP_STD_VER > 14
131#if _LIBCPP_STD_VER >= 17
115132
116133_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
117134_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
118135void __throw_bad_any_cast()
119136{
120#ifndef _LIBCPP_NO_EXCEPTIONS
137#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
121138 throw bad_any_cast();
122139#else
123 _VSTD::abort();
140 _LIBCPP_VERBOSE_ABORT("bad_any_cast was thrown in -fno-exceptions mode");
124141#endif
125142}
126143
......@@ -311,7 +328,7 @@ private:
311328 const void* __fallback_info);
312329
313330 union _Storage {
314 constexpr _Storage() : __ptr(nullptr) {}
331 _LIBCPP_HIDE_FROM_ABI constexpr _Storage() : __ptr(nullptr) {}
315332 void * __ptr;
316333 __any_imp::_Buffer __buf;
317334 };
......@@ -692,10 +709,12 @@ any_cast(any * __any) _NOEXCEPT
692709 return nullptr;
693710}
694711
695#endif // _LIBCPP_STD_VER > 14
712#endif // _LIBCPP_STD_VER >= 17
696713
697714_LIBCPP_END_NAMESPACE_STD
698715
716_LIBCPP_POP_MACROS
717
699718#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
700719# include <chrono>
701720#endif
......@@ -703,9 +722,12 @@ _LIBCPP_END_NAMESPACE_STD
703722#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
704723# include <atomic>
705724# include <concepts>
725# include <cstdlib>
706726# include <iosfwd>
707727# include <iterator>
708728# include <memory>
729# include <stdexcept>
730# include <type_traits>
709731# include <variant>
710732#endif
711733
lib/libcxx/include/array+57-44
......@@ -77,15 +77,18 @@ template <class T, class... U>
7777template <class T, size_t N>
7878 bool operator==(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
7979template <class T, size_t N>
80 bool operator!=(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
80 bool operator!=(const array<T,N>& x, const array<T,N>& y); // removed in C++20
8181template <class T, size_t N>
82 bool operator<(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
82 bool operator<(const array<T,N>& x, const array<T,N>& y); // removed in C++20
8383template <class T, size_t N>
84 bool operator>(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
84 bool operator>(const array<T,N>& x, const array<T,N>& y); // removed in C++20
8585template <class T, size_t N>
86 bool operator<=(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
86 bool operator<=(const array<T,N>& x, const array<T,N>& y); // removed in C++20
8787template <class T, size_t N>
88 bool operator>=(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
88 bool operator>=(const array<T,N>& x, const array<T,N>& y); // removed in C++20
89template<class T, size_t N>
90 constexpr synth-three-way-result<T>
91 operator<=>(const array<T, N>& x, const array<T, N>& y); // since C++20
8992
9093template <class T, size_t N >
9194 void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20
......@@ -111,16 +114,27 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
111114#include <__algorithm/equal.h>
112115#include <__algorithm/fill_n.h>
113116#include <__algorithm/lexicographical_compare.h>
117#include <__algorithm/lexicographical_compare_three_way.h>
114118#include <__algorithm/swap_ranges.h>
115119#include <__assert> // all public C++ headers provide the assertion handler
116120#include <__config>
121#include <__fwd/array.h>
117122#include <__iterator/reverse_iterator.h>
118#include <__tuple_dir/sfinae_helpers.h>
123#include <__tuple/sfinae_helpers.h>
124#include <__type_traits/conditional.h>
125#include <__type_traits/is_array.h>
126#include <__type_traits/is_const.h>
127#include <__type_traits/is_constructible.h>
128#include <__type_traits/is_move_constructible.h>
129#include <__type_traits/is_nothrow_constructible.h>
130#include <__type_traits/is_nothrow_move_constructible.h>
131#include <__type_traits/is_same.h>
132#include <__type_traits/is_swappable.h>
133#include <__type_traits/remove_cv.h>
119134#include <__utility/integer_sequence.h>
120135#include <__utility/move.h>
121136#include <__utility/unreachable.h>
122137#include <stdexcept>
123#include <type_traits>
124138#include <version>
125139
126140// standard-mandated includes
......@@ -137,8 +151,8 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
137151#include <initializer_list>
138152
139153// [tuple.helper]
140#include <__tuple_dir/tuple_element.h>
141#include <__tuple_dir/tuple_size.h>
154#include <__tuple/tuple_element.h>
155#include <__tuple/tuple_size.h>
142156
143157#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
144158# pragma GCC system_header
......@@ -215,23 +229,23 @@ struct _LIBCPP_TEMPLATE_VIS array
215229 // element access:
216230 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
217231 reference operator[](size_type __n) _NOEXCEPT {
218 _LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array<T, N>");
232 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
219233 return __elems_[__n];
220234 }
221235 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
222236 const_reference operator[](size_type __n) const _NOEXCEPT {
223 _LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array<T, N>");
237 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
224238 return __elems_[__n];
225239 }
226240
227 _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n)
241 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n)
228242 {
229243 if (__n >= _Size)
230244 __throw_out_of_range("array::at");
231245 return __elems_[__n];
232246 }
233247
234 _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const
248 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const
235249 {
236250 if (__n >= _Size)
237251 __throw_out_of_range("array::at");
......@@ -328,13 +342,13 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
328342 // element access:
329343 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
330344 reference operator[](size_type) _NOEXCEPT {
331 _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
345 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
332346 __libcpp_unreachable();
333347 }
334348
335349 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
336350 const_reference operator[](size_type) const _NOEXCEPT {
337 _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
351 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
338352 __libcpp_unreachable();
339353 }
340354
......@@ -352,31 +366,31 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
352366
353367 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
354368 reference front() _NOEXCEPT {
355 _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
369 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array");
356370 __libcpp_unreachable();
357371 }
358372
359373 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
360374 const_reference front() const _NOEXCEPT {
361 _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
375 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array");
362376 __libcpp_unreachable();
363377 }
364378
365379 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
366380 reference back() _NOEXCEPT {
367 _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
381 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array");
368382 __libcpp_unreachable();
369383 }
370384
371385 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
372386 const_reference back() const _NOEXCEPT {
373 _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
387 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array");
374388 __libcpp_unreachable();
375389 }
376390};
377391
378392
379#if _LIBCPP_STD_VER > 14
393#if _LIBCPP_STD_VER >= 17
380394template<class _Tp, class... _Args,
381395 class = enable_if_t<__all<_IsSame<_Tp, _Args>::value...>::value>
382396 >
......@@ -392,47 +406,44 @@ operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
392406 return _VSTD::equal(__x.begin(), __x.end(), __y.begin());
393407}
394408
409#if _LIBCPP_STD_VER <= 17
410
395411template <class _Tp, size_t _Size>
396inline _LIBCPP_INLINE_VISIBILITY
397_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
398operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
399{
412inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
400413 return !(__x == __y);
401414}
402415
403416template <class _Tp, size_t _Size>
404inline _LIBCPP_INLINE_VISIBILITY
405_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
406operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
407{
408 return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
409 __y.begin(), __y.end());
417inline _LIBCPP_HIDE_FROM_ABI bool operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
418 return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
410419}
411420
412421template <class _Tp, size_t _Size>
413inline _LIBCPP_INLINE_VISIBILITY
414_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
415operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
416{
422inline _LIBCPP_HIDE_FROM_ABI bool operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
417423 return __y < __x;
418424}
419425
420426template <class _Tp, size_t _Size>
421inline _LIBCPP_INLINE_VISIBILITY
422_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
423operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
424{
427inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
425428 return !(__y < __x);
426429}
427430
428431template <class _Tp, size_t _Size>
429inline _LIBCPP_INLINE_VISIBILITY
430_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
431operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
432{
432inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
433433 return !(__x < __y);
434434}
435435
436#else // _LIBCPP_STD_VER <= 17
437
438template <class _Tp, size_t _Size>
439_LIBCPP_HIDE_FROM_ABI constexpr __synth_three_way_result<_Tp>
440operator<=>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
441 return std::lexicographical_compare_three_way(
442 __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>);
443}
444
445#endif // _LIBCPP_STD_VER <= 17
446
436447template <class _Tp, size_t _Size>
437448inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
438449__enable_if_t<_Size == 0 || __is_swappable<_Tp>::value, void>
......@@ -489,7 +500,7 @@ get(const array<_Tp, _Size>&& __a) _NOEXCEPT
489500 return _VSTD::move(__a.__elems_[_Ip]);
490501}
491502
492#if _LIBCPP_STD_VER > 17
503#if _LIBCPP_STD_VER >= 20
493504
494505template <typename _Tp, size_t _Size, size_t... _Index>
495506_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
......@@ -528,14 +539,16 @@ to_array(_Tp(&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) {
528539 make_index_sequence<_Size>());
529540}
530541
531#endif // _LIBCPP_STD_VER > 17
542#endif // _LIBCPP_STD_VER >= 20
532543
533544_LIBCPP_END_NAMESPACE_STD
534545
535546#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
536547# include <algorithm>
537548# include <concepts>
549# include <cstdlib>
538550# include <iterator>
551# include <type_traits>
539552# include <utility>
540553#endif
541554
lib/libcxx/include/atomic+18-2133
......@@ -519,2154 +519,39 @@ template <class T>
519519*/
520520
521521#include <__assert> // all public C++ headers provide the assertion handler
522#include <__availability>
523#include <__chrono/duration.h>
522#include <__atomic/aliases.h>
523#include <__atomic/atomic.h>
524#include <__atomic/atomic_base.h>
525#include <__atomic/atomic_flag.h>
526#include <__atomic/atomic_init.h>
527#include <__atomic/atomic_lock_free.h>
528#include <__atomic/atomic_sync.h>
529#include <__atomic/check_memory_order.h>
530#include <__atomic/contention_t.h>
531#include <__atomic/cxx_atomic_impl.h>
532#include <__atomic/fence.h>
533#include <__atomic/is_always_lock_free.h>
534#include <__atomic/kill_dependency.h>
535#include <__atomic/memory_order.h>
524536#include <__config>
525#include <__thread/poll_with_backoff.h>
526#include <__thread/timed_backoff_policy.h>
527#include <__type_traits/conditional.h>
528#include <__type_traits/decay.h>
529#include <__type_traits/is_assignable.h>
530#include <__type_traits/is_function.h>
531#include <__type_traits/is_nothrow_default_constructible.h>
532#include <__type_traits/is_same.h>
533#include <__type_traits/is_trivially_copyable.h>
534#include <__type_traits/remove_const.h>
535#include <__type_traits/remove_pointer.h>
536#include <__type_traits/underlying_type.h>
537#include <cstddef>
538#include <cstdint>
539#include <cstring>
540537#include <version>
541538
542#ifndef _LIBCPP_HAS_NO_THREADS
543# include <__threading_support>
544#endif
545
546539#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
547540# pragma GCC system_header
548541#endif
549542
550543#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
551# error <atomic> is not implemented
552#endif
553#ifdef kill_dependency
554# error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23.
544# error <atomic> is not implemented
555545#endif
556546
557#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
558 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
559 __m == memory_order_acquire || \
560 __m == memory_order_acq_rel, \
561 "memory order argument to atomic operation is invalid")
562
563#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
564 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
565 __m == memory_order_acq_rel, \
566 "memory order argument to atomic operation is invalid")
567
568#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
569 _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
570 __f == memory_order_acq_rel, \
571 "memory order argument to atomic operation is invalid")
572
573_LIBCPP_BEGIN_NAMESPACE_STD
574
575// Figure out what the underlying type for `memory_order` would be if it were
576// declared as an unscoped enum (accounting for -fshort-enums). Use this result
577// to pin the underlying type in C++20.
578enum __legacy_memory_order {
579 __mo_relaxed,
580 __mo_consume,
581 __mo_acquire,
582 __mo_release,
583 __mo_acq_rel,
584 __mo_seq_cst
585};
586
587typedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
588
589#if _LIBCPP_STD_VER > 17
590
591enum class memory_order : __memory_order_underlying_t {
592 relaxed = __mo_relaxed,
593 consume = __mo_consume,
594 acquire = __mo_acquire,
595 release = __mo_release,
596 acq_rel = __mo_acq_rel,
597 seq_cst = __mo_seq_cst
598};
599
600inline constexpr auto memory_order_relaxed = memory_order::relaxed;
601inline constexpr auto memory_order_consume = memory_order::consume;
602inline constexpr auto memory_order_acquire = memory_order::acquire;
603inline constexpr auto memory_order_release = memory_order::release;
604inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
605inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
606
607#else
608
609typedef enum memory_order {
610 memory_order_relaxed = __mo_relaxed,
611 memory_order_consume = __mo_consume,
612 memory_order_acquire = __mo_acquire,
613 memory_order_release = __mo_release,
614 memory_order_acq_rel = __mo_acq_rel,
615 memory_order_seq_cst = __mo_seq_cst,
616} memory_order;
617
618#endif // _LIBCPP_STD_VER > 17
619
620template <typename _Tp> _LIBCPP_INLINE_VISIBILITY
621bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
622 return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
623}
624
625static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
626 "unexpected underlying type for std::memory_order");
627
628#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
629 defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
630
631// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
632// the default operator= in an object is not volatile, a byte-by-byte copy
633// is required.
634template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
635typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
636__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
637 __a_value = __val;
638}
639template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
640typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
641__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
642 volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
643 volatile char* __end = __to + sizeof(_Tp);
644 volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
645 while (__to != __end)
646 *__to++ = *__from++;
647}
648
649#endif
650
651#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
652
653template <typename _Tp>
654struct __cxx_atomic_base_impl {
655
656 _LIBCPP_INLINE_VISIBILITY
657#ifndef _LIBCPP_CXX03_LANG
658 __cxx_atomic_base_impl() _NOEXCEPT = default;
659#else
660 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
661#endif // _LIBCPP_CXX03_LANG
662 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
663 : __a_value(value) {}
664 _Tp __a_value;
665};
666
667_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
668 // Avoid switch statement to make this a constexpr.
669 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
670 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
671 (__order == memory_order_release ? __ATOMIC_RELEASE:
672 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
673 (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
674 __ATOMIC_CONSUME))));
675}
676
677_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
678 // Avoid switch statement to make this a constexpr.
679 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
680 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
681 (__order == memory_order_release ? __ATOMIC_RELAXED:
682 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
683 (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
684 __ATOMIC_CONSUME))));
685}
686
687template <typename _Tp>
688_LIBCPP_INLINE_VISIBILITY
689void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
690 __cxx_atomic_assign_volatile(__a->__a_value, __val);
691}
692
693template <typename _Tp>
694_LIBCPP_INLINE_VISIBILITY
695void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
696 __a->__a_value = __val;
697}
698
699_LIBCPP_INLINE_VISIBILITY inline
700void __cxx_atomic_thread_fence(memory_order __order) {
701 __atomic_thread_fence(__to_gcc_order(__order));
702}
703
704_LIBCPP_INLINE_VISIBILITY inline
705void __cxx_atomic_signal_fence(memory_order __order) {
706 __atomic_signal_fence(__to_gcc_order(__order));
707}
708
709template <typename _Tp>
710_LIBCPP_INLINE_VISIBILITY
711void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
712 memory_order __order) {
713 __atomic_store(&__a->__a_value, &__val,
714 __to_gcc_order(__order));
715}
716
717template <typename _Tp>
718_LIBCPP_INLINE_VISIBILITY
719void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
720 memory_order __order) {
721 __atomic_store(&__a->__a_value, &__val,
722 __to_gcc_order(__order));
723}
724
725template <typename _Tp>
726_LIBCPP_INLINE_VISIBILITY
727_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
728 memory_order __order) {
729 _Tp __ret;
730 __atomic_load(&__a->__a_value, &__ret,
731 __to_gcc_order(__order));
732 return __ret;
733}
734
735template <typename _Tp>
736_LIBCPP_INLINE_VISIBILITY
737_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
738 _Tp __ret;
739 __atomic_load(&__a->__a_value, &__ret,
740 __to_gcc_order(__order));
741 return __ret;
742}
743
744template <typename _Tp>
745_LIBCPP_INLINE_VISIBILITY
746_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
747 _Tp __value, memory_order __order) {
748 _Tp __ret;
749 __atomic_exchange(&__a->__a_value, &__value, &__ret,
750 __to_gcc_order(__order));
751 return __ret;
752}
753
754template <typename _Tp>
755_LIBCPP_INLINE_VISIBILITY
756_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
757 memory_order __order) {
758 _Tp __ret;
759 __atomic_exchange(&__a->__a_value, &__value, &__ret,
760 __to_gcc_order(__order));
761 return __ret;
762}
763
764template <typename _Tp>
765_LIBCPP_INLINE_VISIBILITY
766bool __cxx_atomic_compare_exchange_strong(
767 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
768 memory_order __success, memory_order __failure) {
769 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
770 false,
771 __to_gcc_order(__success),
772 __to_gcc_failure_order(__failure));
773}
774
775template <typename _Tp>
776_LIBCPP_INLINE_VISIBILITY
777bool __cxx_atomic_compare_exchange_strong(
778 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
779 memory_order __failure) {
780 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
781 false,
782 __to_gcc_order(__success),
783 __to_gcc_failure_order(__failure));
784}
785
786template <typename _Tp>
787_LIBCPP_INLINE_VISIBILITY
788bool __cxx_atomic_compare_exchange_weak(
789 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
790 memory_order __success, memory_order __failure) {
791 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
792 true,
793 __to_gcc_order(__success),
794 __to_gcc_failure_order(__failure));
795}
796
797template <typename _Tp>
798_LIBCPP_INLINE_VISIBILITY
799bool __cxx_atomic_compare_exchange_weak(
800 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
801 memory_order __failure) {
802 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
803 true,
804 __to_gcc_order(__success),
805 __to_gcc_failure_order(__failure));
806}
807
808template <typename _Tp>
809struct __skip_amt { enum {value = 1}; };
810
811template <typename _Tp>
812struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
813
814// FIXME: Haven't figured out what the spec says about using arrays with
815// atomic_fetch_add. Force a failure rather than creating bad behavior.
816template <typename _Tp>
817struct __skip_amt<_Tp[]> { };
818template <typename _Tp, int n>
819struct __skip_amt<_Tp[n]> { };
820
821template <typename _Tp, typename _Td>
822_LIBCPP_INLINE_VISIBILITY
823_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
824 _Td __delta, memory_order __order) {
825 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
826 __to_gcc_order(__order));
827}
828
829template <typename _Tp, typename _Td>
830_LIBCPP_INLINE_VISIBILITY
831_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
832 memory_order __order) {
833 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
834 __to_gcc_order(__order));
835}
836
837template <typename _Tp, typename _Td>
838_LIBCPP_INLINE_VISIBILITY
839_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
840 _Td __delta, memory_order __order) {
841 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
842 __to_gcc_order(__order));
843}
844
845template <typename _Tp, typename _Td>
846_LIBCPP_INLINE_VISIBILITY
847_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
848 memory_order __order) {
849 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
850 __to_gcc_order(__order));
851}
852
853template <typename _Tp>
854_LIBCPP_INLINE_VISIBILITY
855_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
856 _Tp __pattern, memory_order __order) {
857 return __atomic_fetch_and(&__a->__a_value, __pattern,
858 __to_gcc_order(__order));
859}
860
861template <typename _Tp>
862_LIBCPP_INLINE_VISIBILITY
863_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
864 _Tp __pattern, memory_order __order) {
865 return __atomic_fetch_and(&__a->__a_value, __pattern,
866 __to_gcc_order(__order));
867}
868
869template <typename _Tp>
870_LIBCPP_INLINE_VISIBILITY
871_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
872 _Tp __pattern, memory_order __order) {
873 return __atomic_fetch_or(&__a->__a_value, __pattern,
874 __to_gcc_order(__order));
875}
876
877template <typename _Tp>
878_LIBCPP_INLINE_VISIBILITY
879_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
880 memory_order __order) {
881 return __atomic_fetch_or(&__a->__a_value, __pattern,
882 __to_gcc_order(__order));
883}
884
885template <typename _Tp>
886_LIBCPP_INLINE_VISIBILITY
887_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
888 _Tp __pattern, memory_order __order) {
889 return __atomic_fetch_xor(&__a->__a_value, __pattern,
890 __to_gcc_order(__order));
891}
892
893template <typename _Tp>
894_LIBCPP_INLINE_VISIBILITY
895_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
896 memory_order __order) {
897 return __atomic_fetch_xor(&__a->__a_value, __pattern,
898 __to_gcc_order(__order));
899}
900
901#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
902
903#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
904
905template <typename _Tp>
906struct __cxx_atomic_base_impl {
907
908 _LIBCPP_INLINE_VISIBILITY
909#ifndef _LIBCPP_CXX03_LANG
910 __cxx_atomic_base_impl() _NOEXCEPT = default;
911#else
912 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
913#endif // _LIBCPP_CXX03_LANG
914 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT
915 : __a_value(__value) {}
916 _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
917};
918
919#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
920
921_LIBCPP_INLINE_VISIBILITY inline
922void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
923 __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
924}
925
926_LIBCPP_INLINE_VISIBILITY inline
927void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
928 __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
929}
930
931template<class _Tp>
932_LIBCPP_INLINE_VISIBILITY
933void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
934 __c11_atomic_init(&__a->__a_value, __val);
935}
936template<class _Tp>
937_LIBCPP_INLINE_VISIBILITY
938void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
939 __c11_atomic_init(&__a->__a_value, __val);
940}
941
942template<class _Tp>
943_LIBCPP_INLINE_VISIBILITY
944void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
945 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
946}
947template<class _Tp>
948_LIBCPP_INLINE_VISIBILITY
949void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
950 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
951}
952
953template<class _Tp>
954_LIBCPP_INLINE_VISIBILITY
955_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
956 using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
957 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
958}
959template<class _Tp>
960_LIBCPP_INLINE_VISIBILITY
961_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
962 using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
963 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
964}
965
966template<class _Tp>
967_LIBCPP_INLINE_VISIBILITY
968_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
969 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
970}
971template<class _Tp>
972_LIBCPP_INLINE_VISIBILITY
973_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
974 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
975}
976
977_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
978 // Avoid switch statement to make this a constexpr.
979 return __order == memory_order_release ? memory_order_relaxed:
980 (__order == memory_order_acq_rel ? memory_order_acquire:
981 __order);
982}
983
984template<class _Tp>
985_LIBCPP_INLINE_VISIBILITY
986bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
987 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
988}
989template<class _Tp>
990_LIBCPP_INLINE_VISIBILITY
991bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
992 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
993}
994
995template<class _Tp>
996_LIBCPP_INLINE_VISIBILITY
997bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
998 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
999}
1000template<class _Tp>
1001_LIBCPP_INLINE_VISIBILITY
1002bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
1003 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
1004}
1005
1006template<class _Tp>
1007_LIBCPP_INLINE_VISIBILITY
1008_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
1009 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1010}
1011template<class _Tp>
1012_LIBCPP_INLINE_VISIBILITY
1013_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
1014 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1015}
1016
1017template<class _Tp>
1018_LIBCPP_INLINE_VISIBILITY
1019_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
1020 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1021}
1022template<class _Tp>
1023_LIBCPP_INLINE_VISIBILITY
1024_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
1025 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1026}
1027
1028template<class _Tp>
1029_LIBCPP_INLINE_VISIBILITY
1030_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
1031 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1032}
1033template<class _Tp>
1034_LIBCPP_INLINE_VISIBILITY
1035_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
1036 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1037}
1038template<class _Tp>
1039_LIBCPP_INLINE_VISIBILITY
1040_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
1041 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1042}
1043template<class _Tp>
1044_LIBCPP_INLINE_VISIBILITY
1045_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
1046 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1047}
1048
1049template<class _Tp>
1050_LIBCPP_INLINE_VISIBILITY
1051_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
1052 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1053}
1054template<class _Tp>
1055_LIBCPP_INLINE_VISIBILITY
1056_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
1057 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1058}
1059
1060template<class _Tp>
1061_LIBCPP_INLINE_VISIBILITY
1062_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
1063 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1064}
1065template<class _Tp>
1066_LIBCPP_INLINE_VISIBILITY
1067_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
1068 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1069}
1070
1071template<class _Tp>
1072_LIBCPP_INLINE_VISIBILITY
1073_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
1074 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1075}
1076template<class _Tp>
1077_LIBCPP_INLINE_VISIBILITY
1078_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
1079 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1080}
1081
1082#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
1083
1084template <class _Tp>
1085_LIBCPP_INLINE_VISIBILITY
1086_Tp kill_dependency(_Tp __y) _NOEXCEPT
1087{
1088 return __y;
1089}
1090
1091#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
1092# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
1093# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
1094#ifndef _LIBCPP_HAS_NO_CHAR8_T
1095# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
1096#endif
1097# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
1098# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
1099# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
1100# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
1101# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
1102# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
1103# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
1104# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
1105#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
1106# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
1107# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
1108#ifndef _LIBCPP_HAS_NO_CHAR8_T
1109# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
1110#endif
1111# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1112# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1113# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1114# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
1115# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
1116# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
1117# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
1118# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
1119#endif
1120
1121template <class _Tp>
1122struct __libcpp_is_always_lock_free {
1123 // __atomic_always_lock_free is available in all Standard modes
1124 static const bool __value = __atomic_always_lock_free(sizeof(_Tp), 0);
1125};
1126
1127#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1128
1129template<typename _Tp>
1130struct __cxx_atomic_lock_impl {
1131
1132 _LIBCPP_INLINE_VISIBILITY
1133 __cxx_atomic_lock_impl() _NOEXCEPT
1134 : __a_value(), __a_lock(0) {}
1135 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
1136 __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
1137 : __a_value(value), __a_lock(0) {}
1138
1139 _Tp __a_value;
1140 mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
1141
1142 _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
1143 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1144 /*spin*/;
1145 }
1146 _LIBCPP_INLINE_VISIBILITY void __lock() const {
1147 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1148 /*spin*/;
1149 }
1150 _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
1151 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1152 }
1153 _LIBCPP_INLINE_VISIBILITY void __unlock() const {
1154 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1155 }
1156 _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
1157 __lock();
1158 _Tp __old;
1159 __cxx_atomic_assign_volatile(__old, __a_value);
1160 __unlock();
1161 return __old;
1162 }
1163 _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
1164 __lock();
1165 _Tp __old = __a_value;
1166 __unlock();
1167 return __old;
1168 }
1169};
1170
1171template <typename _Tp>
1172_LIBCPP_INLINE_VISIBILITY
1173void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1174 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1175}
1176template <typename _Tp>
1177_LIBCPP_INLINE_VISIBILITY
1178void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1179 __a->__a_value = __val;
1180}
1181
1182template <typename _Tp>
1183_LIBCPP_INLINE_VISIBILITY
1184void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1185 __a->__lock();
1186 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1187 __a->__unlock();
1188}
1189template <typename _Tp>
1190_LIBCPP_INLINE_VISIBILITY
1191void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1192 __a->__lock();
1193 __a->__a_value = __val;
1194 __a->__unlock();
1195}
1196
1197template <typename _Tp>
1198_LIBCPP_INLINE_VISIBILITY
1199_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1200 return __a->__read();
1201}
1202template <typename _Tp>
1203_LIBCPP_INLINE_VISIBILITY
1204_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1205 return __a->__read();
1206}
1207
1208template <typename _Tp>
1209_LIBCPP_INLINE_VISIBILITY
1210_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1211 __a->__lock();
1212 _Tp __old;
1213 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1214 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1215 __a->__unlock();
1216 return __old;
1217}
1218template <typename _Tp>
1219_LIBCPP_INLINE_VISIBILITY
1220_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1221 __a->__lock();
1222 _Tp __old = __a->__a_value;
1223 __a->__a_value = __value;
1224 __a->__unlock();
1225 return __old;
1226}
1227
1228template <typename _Tp>
1229_LIBCPP_INLINE_VISIBILITY
1230bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1231 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1232 _Tp __temp;
1233 __a->__lock();
1234 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
1235 bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
1236 if(__ret)
1237 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1238 else
1239 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1240 __a->__unlock();
1241 return __ret;
1242}
1243template <typename _Tp>
1244_LIBCPP_INLINE_VISIBILITY
1245bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
1246 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1247 __a->__lock();
1248 bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
1249 if(__ret)
1250 _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
1251 else
1252 _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
1253 __a->__unlock();
1254 return __ret;
1255}
1256
1257template <typename _Tp>
1258_LIBCPP_INLINE_VISIBILITY
1259bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1260 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1261 _Tp __temp;
1262 __a->__lock();
1263 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
1264 bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
1265 if(__ret)
1266 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1267 else
1268 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1269 __a->__unlock();
1270 return __ret;
1271}
1272template <typename _Tp>
1273_LIBCPP_INLINE_VISIBILITY
1274bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
1275 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1276 __a->__lock();
1277 bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
1278 if(__ret)
1279 _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
1280 else
1281 _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
1282 __a->__unlock();
1283 return __ret;
1284}
1285
1286template <typename _Tp, typename _Td>
1287_LIBCPP_INLINE_VISIBILITY
1288_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1289 _Td __delta, memory_order) {
1290 __a->__lock();
1291 _Tp __old;
1292 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1293 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
1294 __a->__unlock();
1295 return __old;
1296}
1297template <typename _Tp, typename _Td>
1298_LIBCPP_INLINE_VISIBILITY
1299_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
1300 _Td __delta, memory_order) {
1301 __a->__lock();
1302 _Tp __old = __a->__a_value;
1303 __a->__a_value += __delta;
1304 __a->__unlock();
1305 return __old;
1306}
1307
1308template <typename _Tp, typename _Td>
1309_LIBCPP_INLINE_VISIBILITY
1310_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
1311 ptrdiff_t __delta, memory_order) {
1312 __a->__lock();
1313 _Tp* __old;
1314 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1315 __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
1316 __a->__unlock();
1317 return __old;
1318}
1319template <typename _Tp, typename _Td>
1320_LIBCPP_INLINE_VISIBILITY
1321_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
1322 ptrdiff_t __delta, memory_order) {
1323 __a->__lock();
1324 _Tp* __old = __a->__a_value;
1325 __a->__a_value += __delta;
1326 __a->__unlock();
1327 return __old;
1328}
1329
1330template <typename _Tp, typename _Td>
1331_LIBCPP_INLINE_VISIBILITY
1332_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1333 _Td __delta, memory_order) {
1334 __a->__lock();
1335 _Tp __old;
1336 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1337 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
1338 __a->__unlock();
1339 return __old;
1340}
1341template <typename _Tp, typename _Td>
1342_LIBCPP_INLINE_VISIBILITY
1343_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
1344 _Td __delta, memory_order) {
1345 __a->__lock();
1346 _Tp __old = __a->__a_value;
1347 __a->__a_value -= __delta;
1348 __a->__unlock();
1349 return __old;
1350}
1351
1352template <typename _Tp>
1353_LIBCPP_INLINE_VISIBILITY
1354_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1355 _Tp __pattern, memory_order) {
1356 __a->__lock();
1357 _Tp __old;
1358 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1359 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
1360 __a->__unlock();
1361 return __old;
1362}
1363template <typename _Tp>
1364_LIBCPP_INLINE_VISIBILITY
1365_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
1366 _Tp __pattern, memory_order) {
1367 __a->__lock();
1368 _Tp __old = __a->__a_value;
1369 __a->__a_value &= __pattern;
1370 __a->__unlock();
1371 return __old;
1372}
1373
1374template <typename _Tp>
1375_LIBCPP_INLINE_VISIBILITY
1376_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1377 _Tp __pattern, memory_order) {
1378 __a->__lock();
1379 _Tp __old;
1380 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1381 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
1382 __a->__unlock();
1383 return __old;
1384}
1385template <typename _Tp>
1386_LIBCPP_INLINE_VISIBILITY
1387_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
1388 _Tp __pattern, memory_order) {
1389 __a->__lock();
1390 _Tp __old = __a->__a_value;
1391 __a->__a_value |= __pattern;
1392 __a->__unlock();
1393 return __old;
1394}
1395
1396template <typename _Tp>
1397_LIBCPP_INLINE_VISIBILITY
1398_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1399 _Tp __pattern, memory_order) {
1400 __a->__lock();
1401 _Tp __old;
1402 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1403 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
1404 __a->__unlock();
1405 return __old;
1406}
1407template <typename _Tp>
1408_LIBCPP_INLINE_VISIBILITY
1409_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
1410 _Tp __pattern, memory_order) {
1411 __a->__lock();
1412 _Tp __old = __a->__a_value;
1413 __a->__a_value ^= __pattern;
1414 __a->__unlock();
1415 return __old;
1416}
1417
1418template <typename _Tp,
1419 typename _Base = typename conditional<__libcpp_is_always_lock_free<_Tp>::__value,
1420 __cxx_atomic_base_impl<_Tp>,
1421 __cxx_atomic_lock_impl<_Tp> >::type>
1422#else
1423template <typename _Tp,
1424 typename _Base = __cxx_atomic_base_impl<_Tp> >
1425#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1426struct __cxx_atomic_impl : public _Base {
1427 static_assert(is_trivially_copyable<_Tp>::value,
1428 "std::atomic<T> requires that 'T' be a trivially copyable type");
1429
1430 _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT = default;
1431 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT
1432 : _Base(__value) {}
1433};
1434
1435#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
1436 using __cxx_contention_t = int32_t;
1437#else
1438 using __cxx_contention_t = int64_t;
1439#endif // __linux__ || (_AIX && !__64BIT__)
1440
1441using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
1442
1443#ifndef _LIBCPP_HAS_NO_THREADS
1444
1445_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
1446_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
1447_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
1448_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
1449
1450_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
1451_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
1452_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
1453_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
1454
1455template <class _Atp, class _Fn>
1456struct __libcpp_atomic_wait_backoff_impl {
1457 _Atp* __a;
1458 _Fn __test_fn;
1459 _LIBCPP_AVAILABILITY_SYNC
1460 _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
1461 {
1462 if(__elapsed > chrono::microseconds(64))
1463 {
1464 auto const __monitor = std::__libcpp_atomic_monitor(__a);
1465 if(__test_fn())
1466 return true;
1467 std::__libcpp_atomic_wait(__a, __monitor);
1468 }
1469 else if(__elapsed > chrono::microseconds(4))
1470 __libcpp_thread_yield();
1471 else
1472 {} // poll
1473 return false;
1474 }
1475};
1476
1477template <class _Atp, class _Fn>
1478_LIBCPP_AVAILABILITY_SYNC
1479_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
1480{
1481 __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
1482 return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
1483}
1484
1485#else // _LIBCPP_HAS_NO_THREADS
1486
1487template <class _Tp>
1488_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
1489template <class _Tp>
1490_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
1491template <class _Atp, class _Fn>
1492_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
1493{
1494 return __libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy());
1495}
1496
1497#endif // _LIBCPP_HAS_NO_THREADS
1498
1499template <class _Atp, class _Tp>
1500struct __cxx_atomic_wait_test_fn_impl {
1501 _Atp* __a;
1502 _Tp __val;
1503 memory_order __order;
1504 _LIBCPP_INLINE_VISIBILITY bool operator()() const
1505 {
1506 return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val);
1507 }
1508};
1509
1510template <class _Atp, class _Tp>
1511_LIBCPP_AVAILABILITY_SYNC
1512_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
1513{
1514 __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
1515 return std::__cxx_atomic_wait(__a, __test_fn);
1516}
1517
1518// general atomic<T>
1519
1520template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1521struct __atomic_base // false
1522{
1523 mutable __cxx_atomic_impl<_Tp> __a_;
1524
1525#if defined(__cpp_lib_atomic_is_always_lock_free)
1526 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value;
1527#endif
1528
1529 _LIBCPP_INLINE_VISIBILITY
1530 bool is_lock_free() const volatile _NOEXCEPT
1531 {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
1532 _LIBCPP_INLINE_VISIBILITY
1533 bool is_lock_free() const _NOEXCEPT
1534 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
1535 _LIBCPP_INLINE_VISIBILITY
1536 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1537 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
1538 {std::__cxx_atomic_store(&__a_, __d, __m);}
1539 _LIBCPP_INLINE_VISIBILITY
1540 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1541 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
1542 {std::__cxx_atomic_store(&__a_, __d, __m);}
1543 _LIBCPP_INLINE_VISIBILITY
1544 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
1545 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
1546 {return std::__cxx_atomic_load(&__a_, __m);}
1547 _LIBCPP_INLINE_VISIBILITY
1548 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
1549 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
1550 {return std::__cxx_atomic_load(&__a_, __m);}
1551 _LIBCPP_INLINE_VISIBILITY
1552 operator _Tp() const volatile _NOEXCEPT {return load();}
1553 _LIBCPP_INLINE_VISIBILITY
1554 operator _Tp() const _NOEXCEPT {return load();}
1555 _LIBCPP_INLINE_VISIBILITY
1556 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1557 {return std::__cxx_atomic_exchange(&__a_, __d, __m);}
1558 _LIBCPP_INLINE_VISIBILITY
1559 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1560 {return std::__cxx_atomic_exchange(&__a_, __d, __m);}
1561 _LIBCPP_INLINE_VISIBILITY
1562 bool compare_exchange_weak(_Tp& __e, _Tp __d,
1563 memory_order __s, memory_order __f) volatile _NOEXCEPT
1564 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1565 {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
1566 _LIBCPP_INLINE_VISIBILITY
1567 bool compare_exchange_weak(_Tp& __e, _Tp __d,
1568 memory_order __s, memory_order __f) _NOEXCEPT
1569 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1570 {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
1571 _LIBCPP_INLINE_VISIBILITY
1572 bool compare_exchange_strong(_Tp& __e, _Tp __d,
1573 memory_order __s, memory_order __f) volatile _NOEXCEPT
1574 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1575 {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
1576 _LIBCPP_INLINE_VISIBILITY
1577 bool compare_exchange_strong(_Tp& __e, _Tp __d,
1578 memory_order __s, memory_order __f) _NOEXCEPT
1579 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1580 {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
1581 _LIBCPP_INLINE_VISIBILITY
1582 bool compare_exchange_weak(_Tp& __e, _Tp __d,
1583 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1584 {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
1585 _LIBCPP_INLINE_VISIBILITY
1586 bool compare_exchange_weak(_Tp& __e, _Tp __d,
1587 memory_order __m = memory_order_seq_cst) _NOEXCEPT
1588 {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
1589 _LIBCPP_INLINE_VISIBILITY
1590 bool compare_exchange_strong(_Tp& __e, _Tp __d,
1591 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1592 {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
1593 _LIBCPP_INLINE_VISIBILITY
1594 bool compare_exchange_strong(_Tp& __e, _Tp __d,
1595 memory_order __m = memory_order_seq_cst) _NOEXCEPT
1596 {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
1597
1598 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
1599 {std::__cxx_atomic_wait(&__a_, __v, __m);}
1600 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
1601 {std::__cxx_atomic_wait(&__a_, __v, __m);}
1602 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
1603 {std::__cxx_atomic_notify_one(&__a_);}
1604 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
1605 {std::__cxx_atomic_notify_one(&__a_);}
1606 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
1607 {std::__cxx_atomic_notify_all(&__a_);}
1608 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
1609 {std::__cxx_atomic_notify_all(&__a_);}
1610
1611#if _LIBCPP_STD_VER > 17
1612 _LIBCPP_INLINE_VISIBILITY constexpr
1613 __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
1614#else
1615 _LIBCPP_INLINE_VISIBILITY
1616 __atomic_base() _NOEXCEPT = default;
1617#endif
1618
1619 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1620 __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
1621
1622 __atomic_base(const __atomic_base&) = delete;
1623};
1624
1625#if defined(__cpp_lib_atomic_is_always_lock_free)
1626template <class _Tp, bool __b>
1627_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1628#endif
1629
1630// atomic<Integral>
1631
1632template <class _Tp>
1633struct __atomic_base<_Tp, true>
1634 : public __atomic_base<_Tp, false>
1635{
1636 typedef __atomic_base<_Tp, false> __base;
1637
1638 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1639 __atomic_base() _NOEXCEPT = default;
1640
1641 _LIBCPP_INLINE_VISIBILITY
1642 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
1643
1644 _LIBCPP_INLINE_VISIBILITY
1645 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1646 {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);}
1647 _LIBCPP_INLINE_VISIBILITY
1648 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1649 {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);}
1650 _LIBCPP_INLINE_VISIBILITY
1651 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1652 {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
1653 _LIBCPP_INLINE_VISIBILITY
1654 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1655 {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
1656 _LIBCPP_INLINE_VISIBILITY
1657 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1658 {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);}
1659 _LIBCPP_INLINE_VISIBILITY
1660 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1661 {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);}
1662 _LIBCPP_INLINE_VISIBILITY
1663 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1664 {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);}
1665 _LIBCPP_INLINE_VISIBILITY
1666 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1667 {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);}
1668 _LIBCPP_INLINE_VISIBILITY
1669 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1670 {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
1671 _LIBCPP_INLINE_VISIBILITY
1672 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1673 {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
1674
1675 _LIBCPP_INLINE_VISIBILITY
1676 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
1677 _LIBCPP_INLINE_VISIBILITY
1678 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
1679 _LIBCPP_INLINE_VISIBILITY
1680 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
1681 _LIBCPP_INLINE_VISIBILITY
1682 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
1683 _LIBCPP_INLINE_VISIBILITY
1684 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
1685 _LIBCPP_INLINE_VISIBILITY
1686 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
1687 _LIBCPP_INLINE_VISIBILITY
1688 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
1689 _LIBCPP_INLINE_VISIBILITY
1690 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
1691 _LIBCPP_INLINE_VISIBILITY
1692 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
1693 _LIBCPP_INLINE_VISIBILITY
1694 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
1695 _LIBCPP_INLINE_VISIBILITY
1696 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
1697 _LIBCPP_INLINE_VISIBILITY
1698 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
1699 _LIBCPP_INLINE_VISIBILITY
1700 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
1701 _LIBCPP_INLINE_VISIBILITY
1702 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
1703 _LIBCPP_INLINE_VISIBILITY
1704 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
1705 _LIBCPP_INLINE_VISIBILITY
1706 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
1707 _LIBCPP_INLINE_VISIBILITY
1708 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
1709 _LIBCPP_INLINE_VISIBILITY
1710 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
1711};
1712
1713// atomic<T>
1714
1715template <class _Tp>
1716struct atomic
1717 : public __atomic_base<_Tp>
1718{
1719 typedef __atomic_base<_Tp> __base;
1720 typedef _Tp value_type;
1721 typedef value_type difference_type;
1722
1723#if _LIBCPP_STD_VER > 17
1724 _LIBCPP_INLINE_VISIBILITY
1725 atomic() = default;
1726#else
1727 _LIBCPP_INLINE_VISIBILITY
1728 atomic() _NOEXCEPT = default;
1729#endif
1730
1731 _LIBCPP_INLINE_VISIBILITY
1732 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
1733
1734 _LIBCPP_INLINE_VISIBILITY
1735 _Tp operator=(_Tp __d) volatile _NOEXCEPT
1736 {__base::store(__d); return __d;}
1737 _LIBCPP_INLINE_VISIBILITY
1738 _Tp operator=(_Tp __d) _NOEXCEPT
1739 {__base::store(__d); return __d;}
1740
1741 atomic& operator=(const atomic&) = delete;
1742 atomic& operator=(const atomic&) volatile = delete;
1743};
1744
1745// atomic<T*>
1746
1747template <class _Tp>
1748struct atomic<_Tp*>
1749 : public __atomic_base<_Tp*>
1750{
1751 typedef __atomic_base<_Tp*> __base;
1752 typedef _Tp* value_type;
1753 typedef ptrdiff_t difference_type;
1754
1755 _LIBCPP_INLINE_VISIBILITY
1756 atomic() _NOEXCEPT = default;
1757
1758 _LIBCPP_INLINE_VISIBILITY
1759 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
1760
1761 _LIBCPP_INLINE_VISIBILITY
1762 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
1763 {__base::store(__d); return __d;}
1764 _LIBCPP_INLINE_VISIBILITY
1765 _Tp* operator=(_Tp* __d) _NOEXCEPT
1766 {__base::store(__d); return __d;}
1767
1768 _LIBCPP_INLINE_VISIBILITY
1769 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1770 // __atomic_fetch_add accepts function pointers, guard against them.
1771 static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
1772 return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);
1773 }
1774
1775 _LIBCPP_INLINE_VISIBILITY
1776 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1777 // __atomic_fetch_add accepts function pointers, guard against them.
1778 static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
1779 return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);
1780 }
1781
1782 _LIBCPP_INLINE_VISIBILITY
1783 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1784 // __atomic_fetch_add accepts function pointers, guard against them.
1785 static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
1786 return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1787 }
1788
1789 _LIBCPP_INLINE_VISIBILITY
1790 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1791 // __atomic_fetch_add accepts function pointers, guard against them.
1792 static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
1793 return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1794 }
1795
1796 _LIBCPP_INLINE_VISIBILITY
1797 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
1798 _LIBCPP_INLINE_VISIBILITY
1799 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
1800 _LIBCPP_INLINE_VISIBILITY
1801 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
1802 _LIBCPP_INLINE_VISIBILITY
1803 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
1804 _LIBCPP_INLINE_VISIBILITY
1805 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
1806 _LIBCPP_INLINE_VISIBILITY
1807 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
1808 _LIBCPP_INLINE_VISIBILITY
1809 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
1810 _LIBCPP_INLINE_VISIBILITY
1811 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
1812 _LIBCPP_INLINE_VISIBILITY
1813 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
1814 _LIBCPP_INLINE_VISIBILITY
1815 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
1816 _LIBCPP_INLINE_VISIBILITY
1817 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
1818 _LIBCPP_INLINE_VISIBILITY
1819 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
1820
1821 atomic& operator=(const atomic&) = delete;
1822 atomic& operator=(const atomic&) volatile = delete;
1823};
1824
1825// atomic_is_lock_free
1826
1827template <class _Tp>
1828_LIBCPP_INLINE_VISIBILITY
1829bool
1830atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
1831{
1832 return __o->is_lock_free();
1833}
1834
1835template <class _Tp>
1836_LIBCPP_INLINE_VISIBILITY
1837bool
1838atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
1839{
1840 return __o->is_lock_free();
1841}
1842
1843// atomic_init
1844
1845template <class _Tp>
1846_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
1847void
1848atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
1849{
1850 std::__cxx_atomic_init(&__o->__a_, __d);
1851}
1852
1853template <class _Tp>
1854_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
1855void
1856atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
1857{
1858 std::__cxx_atomic_init(&__o->__a_, __d);
1859}
1860
1861// atomic_store
1862
1863template <class _Tp>
1864_LIBCPP_INLINE_VISIBILITY
1865void
1866atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
1867{
1868 __o->store(__d);
1869}
1870
1871template <class _Tp>
1872_LIBCPP_INLINE_VISIBILITY
1873void
1874atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
1875{
1876 __o->store(__d);
1877}
1878
1879// atomic_store_explicit
1880
1881template <class _Tp>
1882_LIBCPP_INLINE_VISIBILITY
1883void
1884atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
1885 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
1886{
1887 __o->store(__d, __m);
1888}
1889
1890template <class _Tp>
1891_LIBCPP_INLINE_VISIBILITY
1892void
1893atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
1894 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
1895{
1896 __o->store(__d, __m);
1897}
1898
1899// atomic_load
1900
1901template <class _Tp>
1902_LIBCPP_INLINE_VISIBILITY
1903_Tp
1904atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
1905{
1906 return __o->load();
1907}
1908
1909template <class _Tp>
1910_LIBCPP_INLINE_VISIBILITY
1911_Tp
1912atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
1913{
1914 return __o->load();
1915}
1916
1917// atomic_load_explicit
1918
1919template <class _Tp>
1920_LIBCPP_INLINE_VISIBILITY
1921_Tp
1922atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1923 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
1924{
1925 return __o->load(__m);
1926}
1927
1928template <class _Tp>
1929_LIBCPP_INLINE_VISIBILITY
1930_Tp
1931atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1932 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
1933{
1934 return __o->load(__m);
1935}
1936
1937// atomic_exchange
1938
1939template <class _Tp>
1940_LIBCPP_INLINE_VISIBILITY
1941_Tp
1942atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
1943{
1944 return __o->exchange(__d);
1945}
1946
1947template <class _Tp>
1948_LIBCPP_INLINE_VISIBILITY
1949_Tp
1950atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
1951{
1952 return __o->exchange(__d);
1953}
1954
1955// atomic_exchange_explicit
1956
1957template <class _Tp>
1958_LIBCPP_INLINE_VISIBILITY
1959_Tp
1960atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
1961{
1962 return __o->exchange(__d, __m);
1963}
1964
1965template <class _Tp>
1966_LIBCPP_INLINE_VISIBILITY
1967_Tp
1968atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
1969{
1970 return __o->exchange(__d, __m);
1971}
1972
1973// atomic_compare_exchange_weak
1974
1975template <class _Tp>
1976_LIBCPP_INLINE_VISIBILITY
1977bool
1978atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
1979{
1980 return __o->compare_exchange_weak(*__e, __d);
1981}
1982
1983template <class _Tp>
1984_LIBCPP_INLINE_VISIBILITY
1985bool
1986atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
1987{
1988 return __o->compare_exchange_weak(*__e, __d);
1989}
1990
1991// atomic_compare_exchange_strong
1992
1993template <class _Tp>
1994_LIBCPP_INLINE_VISIBILITY
1995bool
1996atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
1997{
1998 return __o->compare_exchange_strong(*__e, __d);
1999}
2000
2001template <class _Tp>
2002_LIBCPP_INLINE_VISIBILITY
2003bool
2004atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
2005{
2006 return __o->compare_exchange_strong(*__e, __d);
2007}
2008
2009// atomic_compare_exchange_weak_explicit
2010
2011template <class _Tp>
2012_LIBCPP_INLINE_VISIBILITY
2013bool
2014atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2015 typename atomic<_Tp>::value_type __d,
2016 memory_order __s, memory_order __f) _NOEXCEPT
2017 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
2018{
2019 return __o->compare_exchange_weak(*__e, __d, __s, __f);
2020}
2021
2022template <class _Tp>
2023_LIBCPP_INLINE_VISIBILITY
2024bool
2025atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
2026 memory_order __s, memory_order __f) _NOEXCEPT
2027 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
2028{
2029 return __o->compare_exchange_weak(*__e, __d, __s, __f);
2030}
2031
2032// atomic_compare_exchange_strong_explicit
2033
2034template <class _Tp>
2035_LIBCPP_INLINE_VISIBILITY
2036bool
2037atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
2038 typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
2039 memory_order __s, memory_order __f) _NOEXCEPT
2040 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
2041{
2042 return __o->compare_exchange_strong(*__e, __d, __s, __f);
2043}
2044
2045template <class _Tp>
2046_LIBCPP_INLINE_VISIBILITY
2047bool
2048atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2049 typename atomic<_Tp>::value_type __d,
2050 memory_order __s, memory_order __f) _NOEXCEPT
2051 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
2052{
2053 return __o->compare_exchange_strong(*__e, __d, __s, __f);
2054}
2055
2056// atomic_wait
2057
2058template <class _Tp>
2059_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2060void atomic_wait(const volatile atomic<_Tp>* __o,
2061 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2062{
2063 return __o->wait(__v);
2064}
2065
2066template <class _Tp>
2067_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2068void atomic_wait(const atomic<_Tp>* __o,
2069 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2070{
2071 return __o->wait(__v);
2072}
2073
2074// atomic_wait_explicit
2075
2076template <class _Tp>
2077_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2078void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
2079 typename atomic<_Tp>::value_type __v,
2080 memory_order __m) _NOEXCEPT
2081 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2082{
2083 return __o->wait(__v, __m);
2084}
2085
2086template <class _Tp>
2087_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2088void atomic_wait_explicit(const atomic<_Tp>* __o,
2089 typename atomic<_Tp>::value_type __v,
2090 memory_order __m) _NOEXCEPT
2091 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2092{
2093 return __o->wait(__v, __m);
2094}
2095
2096// atomic_notify_one
2097
2098template <class _Tp>
2099_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2100void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
2101{
2102 __o->notify_one();
2103}
2104template <class _Tp>
2105_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2106void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
2107{
2108 __o->notify_one();
2109}
2110
2111// atomic_notify_all
2112
2113template <class _Tp>
2114_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2115void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
2116{
2117 __o->notify_all();
2118}
2119template <class _Tp>
2120_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2121void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
2122{
2123 __o->notify_all();
2124}
2125
2126// atomic_fetch_add
2127
2128template <class _Tp>
2129_LIBCPP_INLINE_VISIBILITY
2130_Tp
2131atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
2132{
2133 return __o->fetch_add(__op);
2134}
2135
2136template <class _Tp>
2137_LIBCPP_INLINE_VISIBILITY
2138_Tp
2139atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
2140{
2141 return __o->fetch_add(__op);
2142}
2143
2144// atomic_fetch_add_explicit
2145
2146template <class _Tp>
2147_LIBCPP_INLINE_VISIBILITY
2148_Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
2149{
2150 return __o->fetch_add(__op, __m);
2151}
2152
2153template <class _Tp>
2154_LIBCPP_INLINE_VISIBILITY
2155_Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
2156{
2157 return __o->fetch_add(__op, __m);
2158}
2159
2160// atomic_fetch_sub
2161
2162template <class _Tp>
2163_LIBCPP_INLINE_VISIBILITY
2164_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
2165{
2166 return __o->fetch_sub(__op);
2167}
2168
2169template <class _Tp>
2170_LIBCPP_INLINE_VISIBILITY
2171_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
2172{
2173 return __o->fetch_sub(__op);
2174}
2175
2176// atomic_fetch_sub_explicit
2177
2178template <class _Tp>
2179_LIBCPP_INLINE_VISIBILITY
2180_Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
2181{
2182 return __o->fetch_sub(__op, __m);
2183}
2184
2185template <class _Tp>
2186_LIBCPP_INLINE_VISIBILITY
2187_Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
2188{
2189 return __o->fetch_sub(__op, __m);
2190}
2191
2192// atomic_fetch_and
2193
2194template <class _Tp>
2195_LIBCPP_INLINE_VISIBILITY
2196typename enable_if
2197<
2198 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2199 _Tp
2200>::type
2201atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2202{
2203 return __o->fetch_and(__op);
2204}
2205
2206template <class _Tp>
2207_LIBCPP_INLINE_VISIBILITY
2208typename enable_if
2209<
2210 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2211 _Tp
2212>::type
2213atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2214{
2215 return __o->fetch_and(__op);
2216}
2217
2218// atomic_fetch_and_explicit
2219
2220template <class _Tp>
2221_LIBCPP_INLINE_VISIBILITY
2222typename enable_if
2223<
2224 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2225 _Tp
2226>::type
2227atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2228{
2229 return __o->fetch_and(__op, __m);
2230}
2231
2232template <class _Tp>
2233_LIBCPP_INLINE_VISIBILITY
2234typename enable_if
2235<
2236 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2237 _Tp
2238>::type
2239atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2240{
2241 return __o->fetch_and(__op, __m);
2242}
2243
2244// atomic_fetch_or
2245
2246template <class _Tp>
2247_LIBCPP_INLINE_VISIBILITY
2248typename enable_if
2249<
2250 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2251 _Tp
2252>::type
2253atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2254{
2255 return __o->fetch_or(__op);
2256}
2257
2258template <class _Tp>
2259_LIBCPP_INLINE_VISIBILITY
2260typename enable_if
2261<
2262 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2263 _Tp
2264>::type
2265atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2266{
2267 return __o->fetch_or(__op);
2268}
2269
2270// atomic_fetch_or_explicit
2271
2272template <class _Tp>
2273_LIBCPP_INLINE_VISIBILITY
2274typename enable_if
2275<
2276 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2277 _Tp
2278>::type
2279atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2280{
2281 return __o->fetch_or(__op, __m);
2282}
2283
2284template <class _Tp>
2285_LIBCPP_INLINE_VISIBILITY
2286typename enable_if
2287<
2288 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2289 _Tp
2290>::type
2291atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2292{
2293 return __o->fetch_or(__op, __m);
2294}
2295
2296// atomic_fetch_xor
2297
2298template <class _Tp>
2299_LIBCPP_INLINE_VISIBILITY
2300typename enable_if
2301<
2302 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2303 _Tp
2304>::type
2305atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2306{
2307 return __o->fetch_xor(__op);
2308}
2309
2310template <class _Tp>
2311_LIBCPP_INLINE_VISIBILITY
2312typename enable_if
2313<
2314 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2315 _Tp
2316>::type
2317atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2318{
2319 return __o->fetch_xor(__op);
2320}
2321
2322// atomic_fetch_xor_explicit
2323
2324template <class _Tp>
2325_LIBCPP_INLINE_VISIBILITY
2326typename enable_if
2327<
2328 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2329 _Tp
2330>::type
2331atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2332{
2333 return __o->fetch_xor(__op, __m);
2334}
2335
2336template <class _Tp>
2337_LIBCPP_INLINE_VISIBILITY
2338typename enable_if
2339<
2340 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2341 _Tp
2342>::type
2343atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2344{
2345 return __o->fetch_xor(__op, __m);
2346}
2347
2348// flag type and operations
2349
2350typedef struct atomic_flag
2351{
2352 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
2353
2354 _LIBCPP_INLINE_VISIBILITY
2355 bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2356 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2357 _LIBCPP_INLINE_VISIBILITY
2358 bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2359 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2360
2361 _LIBCPP_INLINE_VISIBILITY
2362 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
2363 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
2364 _LIBCPP_INLINE_VISIBILITY
2365 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
2366 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
2367 _LIBCPP_INLINE_VISIBILITY
2368 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
2369 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
2370 _LIBCPP_INLINE_VISIBILITY
2371 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
2372 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
2373
2374 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2375 void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2376 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
2377 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2378 void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2379 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
2380 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2381 void notify_one() volatile _NOEXCEPT
2382 {__cxx_atomic_notify_one(&__a_);}
2383 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2384 void notify_one() _NOEXCEPT
2385 {__cxx_atomic_notify_one(&__a_);}
2386 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2387 void notify_all() volatile _NOEXCEPT
2388 {__cxx_atomic_notify_all(&__a_);}
2389 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
2390 void notify_all() _NOEXCEPT
2391 {__cxx_atomic_notify_all(&__a_);}
2392
2393#if _LIBCPP_STD_VER > 17
2394 _LIBCPP_INLINE_VISIBILITY constexpr
2395 atomic_flag() _NOEXCEPT : __a_(false) {}
2396#else
2397 _LIBCPP_INLINE_VISIBILITY
2398 atomic_flag() _NOEXCEPT = default;
2399#endif
2400
2401 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
2402 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
2403
2404 atomic_flag(const atomic_flag&) = delete;
2405 atomic_flag& operator=(const atomic_flag&) = delete;
2406 atomic_flag& operator=(const atomic_flag&) volatile = delete;
2407
2408} atomic_flag;
2409
2410
2411inline _LIBCPP_INLINE_VISIBILITY
2412bool
2413atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
2414{
2415 return __o->test();
2416}
2417
2418inline _LIBCPP_INLINE_VISIBILITY
2419bool
2420atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
2421{
2422 return __o->test();
2423}
2424
2425inline _LIBCPP_INLINE_VISIBILITY
2426bool
2427atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2428{
2429 return __o->test(__m);
2430}
2431
2432inline _LIBCPP_INLINE_VISIBILITY
2433bool
2434atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
2435{
2436 return __o->test(__m);
2437}
2438
2439inline _LIBCPP_INLINE_VISIBILITY
2440bool
2441atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
2442{
2443 return __o->test_and_set();
2444}
2445
2446inline _LIBCPP_INLINE_VISIBILITY
2447bool
2448atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
2449{
2450 return __o->test_and_set();
2451}
2452
2453inline _LIBCPP_INLINE_VISIBILITY
2454bool
2455atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2456{
2457 return __o->test_and_set(__m);
2458}
2459
2460inline _LIBCPP_INLINE_VISIBILITY
2461bool
2462atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
2463{
2464 return __o->test_and_set(__m);
2465}
2466
2467inline _LIBCPP_INLINE_VISIBILITY
2468void
2469atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
2470{
2471 __o->clear();
2472}
2473
2474inline _LIBCPP_INLINE_VISIBILITY
2475void
2476atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
2477{
2478 __o->clear();
2479}
2480
2481inline _LIBCPP_INLINE_VISIBILITY
2482void
2483atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2484{
2485 __o->clear(__m);
2486}
2487
2488inline _LIBCPP_INLINE_VISIBILITY
2489void
2490atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
2491{
2492 __o->clear(__m);
2493}
2494
2495inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
2496void
2497atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
2498{
2499 __o->wait(__v);
2500}
2501
2502inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
2503void
2504atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
2505{
2506 __o->wait(__v);
2507}
2508
2509inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
2510void
2511atomic_flag_wait_explicit(const volatile atomic_flag* __o,
2512 bool __v, memory_order __m) _NOEXCEPT
2513{
2514 __o->wait(__v, __m);
2515}
2516
2517inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
2518void
2519atomic_flag_wait_explicit(const atomic_flag* __o,
2520 bool __v, memory_order __m) _NOEXCEPT
2521{
2522 __o->wait(__v, __m);
2523}
2524
2525inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
2526void
2527atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
2528{
2529 __o->notify_one();
2530}
2531
2532inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
2533void
2534atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
2535{
2536 __o->notify_one();
2537}
2538
2539inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
2540void
2541atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
2542{
2543 __o->notify_all();
2544}
2545
2546inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
2547void
2548atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
2549{
2550 __o->notify_all();
2551}
2552
2553// fences
2554
2555inline _LIBCPP_INLINE_VISIBILITY
2556void
2557atomic_thread_fence(memory_order __m) _NOEXCEPT
2558{
2559 __cxx_atomic_thread_fence(__m);
2560}
2561
2562inline _LIBCPP_INLINE_VISIBILITY
2563void
2564atomic_signal_fence(memory_order __m) _NOEXCEPT
2565{
2566 __cxx_atomic_signal_fence(__m);
2567}
2568
2569// Atomics for standard typedef types
2570
2571typedef atomic<bool> atomic_bool;
2572typedef atomic<char> atomic_char;
2573typedef atomic<signed char> atomic_schar;
2574typedef atomic<unsigned char> atomic_uchar;
2575typedef atomic<short> atomic_short;
2576typedef atomic<unsigned short> atomic_ushort;
2577typedef atomic<int> atomic_int;
2578typedef atomic<unsigned int> atomic_uint;
2579typedef atomic<long> atomic_long;
2580typedef atomic<unsigned long> atomic_ulong;
2581typedef atomic<long long> atomic_llong;
2582typedef atomic<unsigned long long> atomic_ullong;
2583#ifndef _LIBCPP_HAS_NO_CHAR8_T
2584typedef atomic<char8_t> atomic_char8_t;
2585#endif
2586typedef atomic<char16_t> atomic_char16_t;
2587typedef atomic<char32_t> atomic_char32_t;
2588#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
2589typedef atomic<wchar_t> atomic_wchar_t;
2590#endif
2591
2592typedef atomic<int_least8_t> atomic_int_least8_t;
2593typedef atomic<uint_least8_t> atomic_uint_least8_t;
2594typedef atomic<int_least16_t> atomic_int_least16_t;
2595typedef atomic<uint_least16_t> atomic_uint_least16_t;
2596typedef atomic<int_least32_t> atomic_int_least32_t;
2597typedef atomic<uint_least32_t> atomic_uint_least32_t;
2598typedef atomic<int_least64_t> atomic_int_least64_t;
2599typedef atomic<uint_least64_t> atomic_uint_least64_t;
2600
2601typedef atomic<int_fast8_t> atomic_int_fast8_t;
2602typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
2603typedef atomic<int_fast16_t> atomic_int_fast16_t;
2604typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2605typedef atomic<int_fast32_t> atomic_int_fast32_t;
2606typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2607typedef atomic<int_fast64_t> atomic_int_fast64_t;
2608typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2609
2610typedef atomic< int8_t> atomic_int8_t;
2611typedef atomic<uint8_t> atomic_uint8_t;
2612typedef atomic< int16_t> atomic_int16_t;
2613typedef atomic<uint16_t> atomic_uint16_t;
2614typedef atomic< int32_t> atomic_int32_t;
2615typedef atomic<uint32_t> atomic_uint32_t;
2616typedef atomic< int64_t> atomic_int64_t;
2617typedef atomic<uint64_t> atomic_uint64_t;
2618
2619typedef atomic<intptr_t> atomic_intptr_t;
2620typedef atomic<uintptr_t> atomic_uintptr_t;
2621typedef atomic<size_t> atomic_size_t;
2622typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2623typedef atomic<intmax_t> atomic_intmax_t;
2624typedef atomic<uintmax_t> atomic_uintmax_t;
2625
2626// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
2627
2628#ifdef __cpp_lib_atomic_is_always_lock_free
2629# define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value
2630#else
2631# define _LIBCPP_CONTENTION_LOCK_FREE false
2632#endif
2633
2634#if ATOMIC_LLONG_LOCK_FREE == 2
2635typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long> __libcpp_signed_lock_free;
2636typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long> __libcpp_unsigned_lock_free;
2637#elif ATOMIC_INT_LOCK_FREE == 2
2638typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int> __libcpp_signed_lock_free;
2639typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int> __libcpp_unsigned_lock_free;
2640#elif ATOMIC_SHORT_LOCK_FREE == 2
2641typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short> __libcpp_signed_lock_free;
2642typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short> __libcpp_unsigned_lock_free;
2643#elif ATOMIC_CHAR_LOCK_FREE == 2
2644typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char> __libcpp_signed_lock_free;
2645typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char> __libcpp_unsigned_lock_free;
2646#else
2647 // No signed/unsigned lock-free types
2648#define _LIBCPP_NO_LOCK_FREE_TYPES
2649#endif
2650
2651#if !defined(_LIBCPP_NO_LOCK_FREE_TYPES)
2652typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
2653typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
547#ifdef kill_dependency
548# error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23.
2654549#endif
2655550
2656#define ATOMIC_FLAG_INIT {false}
2657#define ATOMIC_VAR_INIT(__v) {__v}
2658
2659#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
2660# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400
2661# pragma clang deprecated(ATOMIC_VAR_INIT)
2662# endif
2663#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
2664
2665_LIBCPP_END_NAMESPACE_STD
2666
2667551#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
2668552# include <cmath>
2669553# include <compare>
554# include <cstring>
2670555# include <type_traits>
2671556#endif
2672557
lib/libcxx/include/barrier+33-8
......@@ -46,13 +46,18 @@ namespace std
4646*/
4747
4848#include <__assert> // all public C++ headers provide the assertion handler
49#include <__atomic/atomic_base.h>
50#include <__atomic/memory_order.h>
4951#include <__availability>
5052#include <__config>
5153#include <__memory/unique_ptr.h>
54#include <__thread/poll_with_backoff.h>
5255#include <__thread/timed_backoff_policy.h>
5356#include <__utility/move.h>
54#include <atomic>
57#include <cstddef>
58#include <cstdint>
5559#include <limits>
60#include <version>
5661
5762#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5863# pragma GCC system_header
......@@ -119,7 +124,7 @@ class __barrier_base {
119124public:
120125 using arrival_token = __barrier_phase_t;
121126
122 static constexpr ptrdiff_t max() noexcept {
127 static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {
123128 return numeric_limits<ptrdiff_t>::max();
124129 }
125130
......@@ -130,9 +135,12 @@ public:
130135 __expected_adjustment_(0), __completion_(std::move(__completion)), __phase_(0)
131136 {
132137 }
133 [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
138 [[__nodiscard__]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
134139 arrival_token arrive(ptrdiff_t __update)
135140 {
141 _LIBCPP_ASSERT_UNCATEGORIZED(
142 __update <= __expected_, "update is greater than the expected count for the current barrier phase");
143
136144 auto const __old_phase = __phase_.load(memory_order_relaxed);
137145 for(; __update; --__update)
138146 if(__arrive_barrier_algorithm_base(__base_.get(), __old_phase)) {
......@@ -200,7 +208,11 @@ public:
200208 auto const __old_phase = __phase.load(memory_order_relaxed);
201209 auto const __result = __arrived.fetch_sub(update, memory_order_acq_rel) - update;
202210 auto const new_expected = __expected.load(memory_order_relaxed);
203 if(0 == __result) {
211
212 _LIBCPP_ASSERT_UNCATEGORIZED(
213 update <= new_expected, "update is greater than the expected count for the current barrier phase");
214
215 if (0 == __result) {
204216 __completion();
205217 __arrived.store(new_expected, memory_order_relaxed);
206218 __phase.store(!__old_phase, memory_order_release);
......@@ -256,7 +268,11 @@ public:
256268 {
257269 auto const __inc = __arrived_unit * update;
258270 auto const __old = __phase_arrived_expected.fetch_add(__inc, memory_order_acq_rel);
259 if((__old ^ (__old + __inc)) & __phase_bit) {
271
272 _LIBCPP_ASSERT_UNCATEGORIZED(
273 update <= __old, "update is greater than the expected count for the current barrier phase");
274
275 if ((__old ^ (__old + __inc)) & __phase_bit) {
260276 __phase_arrived_expected.fetch_add((__old & __expected_mask) << 32, memory_order_relaxed);
261277 __phase_arrived_expected.notify_all();
262278 }
......@@ -288,21 +304,29 @@ class barrier {
288304public:
289305 using arrival_token = typename __barrier_base<_CompletionF>::arrival_token;
290306
291 static constexpr ptrdiff_t max() noexcept {
307 static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {
292308 return __barrier_base<_CompletionF>::max();
293309 }
294310
295311 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
296 barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF())
312 explicit barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF())
297313 : __b_(__count, _VSTD::move(__completion)) {
314 _LIBCPP_ASSERT_UNCATEGORIZED(
315 __count >= 0,
316 "barrier::barrier(ptrdiff_t, CompletionFunction): barrier cannot be initialized with a negative value");
317 _LIBCPP_ASSERT_UNCATEGORIZED(
318 __count <= max(),
319 "barrier::barrier(ptrdiff_t, CompletionFunction): barrier cannot be initialized with "
320 "a value greater than max()");
298321 }
299322
300323 barrier(barrier const&) = delete;
301324 barrier& operator=(barrier const&) = delete;
302325
303 [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
326 [[__nodiscard__]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
304327 arrival_token arrive(ptrdiff_t __update = 1)
305328 {
329 _LIBCPP_ASSERT_UNCATEGORIZED(__update > 0, "barrier:arrive must be called with a value greater than 0");
306330 return __b_.arrive(__update);
307331 }
308332 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
......@@ -329,6 +353,7 @@ _LIBCPP_END_NAMESPACE_STD
329353_LIBCPP_POP_MACROS
330354
331355#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
356# include <atomic>
332357# include <concepts>
333358# include <iterator>
334359# include <memory>
lib/libcxx/include/bit+1
......@@ -83,6 +83,7 @@ namespace std {
8383#endif
8484
8585#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
86# include <cstdlib>
8687# include <iosfwd>
8788# include <limits>
8889# include <type_traits>
lib/libcxx/include/bitset+54-65
......@@ -79,7 +79,7 @@ public:
7979 size_t count() const noexcept; // constexpr since C++23
8080 constexpr size_t size() const noexcept; // constexpr since C++23
8181 bool operator==(const bitset& rhs) const noexcept; // constexpr since C++23
82 bool operator!=(const bitset& rhs) const noexcept; // constexpr since C++23
82 bool operator!=(const bitset& rhs) const noexcept; // removed in C++20
8383 bool test(size_t pos) const; // constexpr since C++23
8484 bool all() const noexcept; // constexpr since C++23
8585 bool any() const noexcept; // constexpr since C++23
......@@ -122,6 +122,7 @@ template <size_t N> struct hash<std::bitset<N>>;
122122#include <climits>
123123#include <cstddef>
124124#include <stdexcept>
125#include <string_view>
125126#include <version>
126127
127128// standard-mandated includes
......@@ -691,18 +692,30 @@ public:
691692 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}
692693 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
693694 bitset(unsigned long long __v) _NOEXCEPT : base(__v) {}
694 template<class _CharT, class = __enable_if_t<_IsCharLikeType<_CharT>::value> >
695 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
696 explicit bitset(const _CharT* __str,
697 typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos,
698 _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));
699 template<class _CharT, class _Traits, class _Allocator>
700 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
701 explicit bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
702 typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos = 0,
703 typename basic_string<_CharT,_Traits,_Allocator>::size_type __n =
704 (basic_string<_CharT,_Traits,_Allocator>::npos),
705 _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));
695 template <class _CharT, class = __enable_if_t<_IsCharLikeType<_CharT>::value> >
696 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
697 const _CharT* __str,
698 typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos,
699 _CharT __zero = _CharT('0'),
700 _CharT __one = _CharT('1')) {
701
702 size_t __rlen = std::min(__n, char_traits<_CharT>::length(__str));
703 __init_from_string_view(basic_string_view<_CharT>(__str, __rlen), __zero, __one);
704 }
705 template <class _CharT, class _Traits, class _Allocator>
706 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
707 const basic_string<_CharT, _Traits, _Allocator>& __str,
708 typename basic_string<_CharT, _Traits, _Allocator>::size_type __pos = 0,
709 typename basic_string<_CharT, _Traits, _Allocator>::size_type __n =
710 basic_string<_CharT, _Traits, _Allocator>::npos,
711 _CharT __zero = _CharT('0'),
712 _CharT __one = _CharT('1')) {
713 if (__pos > __str.size())
714 std::__throw_out_of_range("bitset string pos out of range");
715
716 size_t __rlen = std::min(__n, __str.size() - __pos);
717 __init_from_string_view(basic_string_view<_CharT, _Traits>(__str.data() + __pos, __rlen), __zero, __one);
718 }
706719
707720 // 23.3.5.2 bitset operations:
708721 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
......@@ -761,8 +774,10 @@ public:
761774 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT {return _Size;}
762775 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
763776 bool operator==(const bitset& __rhs) const _NOEXCEPT;
764 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
777#if _LIBCPP_STD_VER <= 17
778 _LIBCPP_INLINE_VISIBILITY
765779 bool operator!=(const bitset& __rhs) const _NOEXCEPT;
780#endif
766781 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
767782 bool test(size_t __pos) const;
768783 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
......@@ -776,6 +791,22 @@ public:
776791 bitset operator>>(size_t __pos) const _NOEXCEPT;
777792
778793private:
794 template <class _CharT, class _Traits>
795 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
796 __init_from_string_view(basic_string_view<_CharT, _Traits> __str, _CharT __zero, _CharT __one) {
797
798 for (size_t __i = 0; __i < __str.size(); ++__i)
799 if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one))
800 std::__throw_invalid_argument("bitset string ctor has invalid argument");
801
802 size_t __mp = std::min(__str.size(), _Size);
803 size_t __i = 0;
804 for (; __i < __mp; ++__i) {
805 _CharT __c = __str[__mp - 1 - __i];
806 (*this)[__i] = _Traits::eq(__c, __one);
807 }
808 std::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
809 }
779810
780811 _LIBCPP_INLINE_VISIBILITY
781812 size_t __hash_code() const _NOEXCEPT {return base::__hash_code();}
......@@ -783,54 +814,6 @@ private:
783814 friend struct hash<bitset>;
784815};
785816
786template <size_t _Size>
787template<class _CharT, class>
788_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
789bitset<_Size>::bitset(const _CharT* __str,
790 typename basic_string<_CharT>::size_type __n,
791 _CharT __zero, _CharT __one)
792{
793 size_t __rlen = _VSTD::min(__n, char_traits<_CharT>::length(__str));
794 for (size_t __i = 0; __i < __rlen; ++__i)
795 if (__str[__i] != __zero && __str[__i] != __one)
796 __throw_invalid_argument("bitset string ctor has invalid argument");
797
798 size_t _Mp = _VSTD::min(__rlen, _Size);
799 size_t __i = 0;
800 for (; __i < _Mp; ++__i)
801 {
802 _CharT __c = __str[_Mp - 1 - __i];
803 (*this)[__i] = (__c == __one);
804 }
805 _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
806}
807
808template <size_t _Size>
809template<class _CharT, class _Traits, class _Allocator>
810_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
811bitset<_Size>::bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
812 typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos,
813 typename basic_string<_CharT,_Traits,_Allocator>::size_type __n,
814 _CharT __zero, _CharT __one)
815{
816 if (__pos > __str.size())
817 __throw_out_of_range("bitset string pos out of range");
818
819 size_t __rlen = _VSTD::min(__n, __str.size() - __pos);
820 for (size_t __i = __pos; __i < __pos + __rlen; ++__i)
821 if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one))
822 __throw_invalid_argument("bitset string ctor has invalid argument");
823
824 size_t _Mp = _VSTD::min(__rlen, _Size);
825 size_t __i = 0;
826 for (; __i < _Mp; ++__i)
827 {
828 _CharT __c = __str[__pos + _Mp - 1 - __i];
829 (*this)[__i] = _Traits::eq(__c, __one);
830 }
831 _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
832}
833
834817template <size_t _Size>
835818inline
836819_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
......@@ -956,8 +939,8 @@ bitset<_Size>::flip(size_t __pos)
956939 if (__pos >= _Size)
957940 __throw_out_of_range("bitset flip argument out of range");
958941
959 reference r = base::__make_ref(__pos);
960 r = ~r;
942 reference __r = base::__make_ref(__pos);
943 __r = ~__r;
961944 return *this;
962945}
963946
......@@ -1041,15 +1024,19 @@ bitset<_Size>::operator==(const bitset& __rhs) const _NOEXCEPT
10411024 return _VSTD::equal(base::__make_iter(0), base::__make_iter(_Size), __rhs.__make_iter(0));
10421025}
10431026
1027#if _LIBCPP_STD_VER <= 17
1028
10441029template <size_t _Size>
10451030inline
1046_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
1031_LIBCPP_HIDE_FROM_ABI
10471032bool
10481033bitset<_Size>::operator!=(const bitset& __rhs) const _NOEXCEPT
10491034{
10501035 return !(*this == __rhs);
10511036}
10521037
1038#endif
1039
10531040template <size_t _Size>
10541041_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
10551042bool
......@@ -1154,6 +1141,8 @@ _LIBCPP_POP_MACROS
11541141
11551142#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
11561143# include <concepts>
1144# include <cstdlib>
1145# include <type_traits>
11571146#endif
11581147
11591148#endif // _LIBCPP_BITSET
lib/libcxx/include/charconv+9-753
......@@ -63,785 +63,41 @@ namespace std {
6363 constexpr from_chars_result from_chars(const char* first, const char* last,
6464 see below& value, int base = 10); // constexpr since C++23
6565
66 from_chars_result from_chars(const char* first, const char* last,
67 float& value,
68 chars_format fmt = chars_format::general);
69 from_chars_result from_chars(const char* first, const char* last,
70 double& value,
71 chars_format fmt = chars_format::general);
72 from_chars_result from_chars(const char* first, const char* last,
73 long double& value,
74 chars_format fmt = chars_format::general);
75
7666} // namespace std
7767
7868*/
7969
80#include <__algorithm/copy_n.h>
8170#include <__assert> // all public C++ headers provide the assertion handler
82#include <__availability>
83#include <__bit/countl.h>
8471#include <__charconv/chars_format.h>
72#include <__charconv/from_chars_integral.h>
8573#include <__charconv/from_chars_result.h>
8674#include <__charconv/tables.h>
75#include <__charconv/to_chars.h>
8776#include <__charconv/to_chars_base_10.h>
77#include <__charconv/to_chars_floating_point.h>
78#include <__charconv/to_chars_integral.h>
8879#include <__charconv/to_chars_result.h>
80#include <__charconv/traits.h>
8981#include <__config>
90#include <__debug>
91#include <__errc>
92#include <__memory/addressof.h>
93#include <__type_traits/make_32_64_or_128_bit.h>
94#include <__utility/unreachable.h>
82#include <__system_error/errc.h>
9583#include <cmath> // for log2f
9684#include <cstdint>
97#include <cstdlib>
98#include <cstring>
9985#include <limits>
100#include <type_traits>
10186
10287#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
10388# pragma GCC system_header
10489#endif
10590
106_LIBCPP_PUSH_MACROS
107#include <__undef_macros>
108
10991_LIBCPP_BEGIN_NAMESPACE_STD
11092
111#if _LIBCPP_STD_VER > 14
112
113to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
114from_chars_result from_chars(const char*, const char*, bool, int = 10) = delete;
115
116namespace __itoa
117{
118
119template <typename _Tp, typename = void>
120struct _LIBCPP_HIDDEN __traits_base;
121
122template <typename _Tp>
123struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) <= sizeof(uint32_t)>>
124{
125 using type = uint32_t;
126
127 /// The width estimation using a log10 algorithm.
128 ///
129 /// The algorithm is based on
130 /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
131 /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
132 /// function requires its input to have at least one bit set the value of
133 /// zero is set to one. This means the first element of the lookup table is
134 /// zero.
135 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v)
136 {
137 auto __t = (32 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
138 return __t - (__v < __itoa::__pow10_32[__t]) + 1;
139 }
140
141 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v)
142 {
143 return __itoa::__base_10_u32(__p, __v);
144 }
145
146 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_32)& __pow() { return __itoa::__pow10_32; }
147};
148
149template <typename _Tp>
150struct _LIBCPP_HIDDEN
151 __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(uint64_t)>> {
152 using type = uint64_t;
153
154 /// The width estimation using a log10 algorithm.
155 ///
156 /// The algorithm is based on
157 /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
158 /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
159 /// function requires its input to have at least one bit set the value of
160 /// zero is set to one. This means the first element of the lookup table is
161 /// zero.
162 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
163 auto __t = (64 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
164 return __t - (__v < __itoa::__pow10_64[__t]) + 1;
165 }
166
167 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { return __itoa::__base_10_u64(__p, __v); }
168
169 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_64)& __pow() { return __itoa::__pow10_64; }
170};
171
172
173# ifndef _LIBCPP_HAS_NO_INT128
174template <typename _Tp>
175struct _LIBCPP_HIDDEN
176 __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__uint128_t)> > {
177 using type = __uint128_t;
178
179 /// The width estimation using a log10 algorithm.
180 ///
181 /// The algorithm is based on
182 /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
183 /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
184 /// function requires its input to have at least one bit set the value of
185 /// zero is set to one. This means the first element of the lookup table is
186 /// zero.
187 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
188 _LIBCPP_ASSERT(__v > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true.");
189 // There's always a bit set in the upper 64-bits.
190 auto __t = (128 - std::__libcpp_clz(static_cast<uint64_t>(__v >> 64))) * 1233 >> 12;
191 _LIBCPP_ASSERT(__t >= __itoa::__pow10_128_offset, "Index out of bounds");
192 // __t is adjusted since the lookup table misses the lower entries.
193 return __t - (__v < __itoa::__pow10_128[__t - __itoa::__pow10_128_offset]) + 1;
194 }
195
196 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { return __itoa::__base_10_u128(__p, __v); }
197
198 // TODO FMT This pow function should get an index.
199 // By moving this to its own header it can be reused by the pow function in to_chars_base_10.
200 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_128)& __pow() { return __itoa::__pow10_128; }
201};
202#endif
203
204template <typename _Tp>
205inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
206__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r)
207{
208 auto __c = __a * __b;
209 __r = __c;
210 return __c > numeric_limits<unsigned char>::max();
211}
212
213template <typename _Tp>
214inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
215__mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r)
216{
217 auto __c = __a * __b;
218 __r = __c;
219 return __c > numeric_limits<unsigned short>::max();
220}
221
222template <typename _Tp>
223inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
224__mul_overflowed(_Tp __a, _Tp __b, _Tp& __r)
225{
226 static_assert(is_unsigned<_Tp>::value, "");
227 return __builtin_mul_overflow(__a, __b, &__r);
228}
229
230template <typename _Tp, typename _Up>
231inline _LIBCPP_HIDE_FROM_ABI bool
232_LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r)
233{
234 return __itoa::__mul_overflowed(__a, static_cast<_Tp>(__b), __r);
235}
236
237template <typename _Tp>
238struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp>
239{
240 static constexpr int digits = numeric_limits<_Tp>::digits10 + 1;
241 using __traits_base<_Tp>::__pow;
242 using typename __traits_base<_Tp>::type;
243
244 // precondition: at least one non-zero character available
245 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char const*
246 __read(char const* __p, char const* __ep, type& __a, type& __b)
247 {
248 type __cprod[digits];
249 int __j = digits - 1;
250 int __i = digits;
251 do
252 {
253 if (*__p < '0' || *__p > '9')
254 break;
255 __cprod[--__i] = *__p++ - '0';
256 } while (__p != __ep && __i != 0);
257
258 __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1,
259 __cprod[__i]);
260 if (__itoa::__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b))
261 --__p;
262 return __p;
263 }
264
265 template <typename _It1, typename _It2, class _Up>
266 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Up
267 __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init)
268 {
269 for (; __first1 < __last1; ++__first1, ++__first2)
270 __init = __init + *__first1 * *__first2;
271 return __init;
272 }
273};
274
275} // namespace __itoa
276
277template <typename _Tp>
278inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Tp
279__complement(_Tp __x)
280{
281 static_assert(is_unsigned<_Tp>::value, "cast to unsigned first");
282 return _Tp(~__x + 1);
283}
284
285template <typename _Tp>
286inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
287__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type);
288
289template <typename _Tp>
290inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
291__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type)
292{
293 auto __x = std::__to_unsigned_like(__value);
294 if (__value < 0 && __first != __last)
295 {
296 *__first++ = '-';
297 __x = std::__complement(__x);
298 }
299
300 return std::__to_chars_itoa(__first, __last, __x, false_type());
301}
302
303template <typename _Tp>
304inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
305__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type)
306{
307 using __tx = __itoa::__traits<_Tp>;
308 auto __diff = __last - __first;
309
310 if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
311 return {__tx::__convert(__first, __value), errc(0)};
312 else
313 return {__last, errc::value_too_large};
314}
315
316# ifndef _LIBCPP_HAS_NO_INT128
317template <>
318inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
319__to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type)
320{
321 // When the value fits in 64-bits use the 64-bit code path. This reduces
322 // the number of expensive calculations on 128-bit values.
323 //
324 // NOTE the 128-bit code path requires this optimization.
325 if(__value <= numeric_limits<uint64_t>::max())
326 return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type());
327
328 using __tx = __itoa::__traits<__uint128_t>;
329 auto __diff = __last - __first;
330
331 if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
332 return {__tx::__convert(__first, __value), errc(0)};
333 else
334 return {__last, errc::value_too_large};
335}
336#endif
337
338template <class _Tp>
339inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
340__to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type);
341
342template <typename _Tp>
343inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
344__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
345 true_type)
346{
347 auto __x = std::__to_unsigned_like(__value);
348 if (__value < 0 && __first != __last)
349 {
350 *__first++ = '-';
351 __x = std::__complement(__x);
352 }
353
354 return std::__to_chars_integral(__first, __last, __x, __base, false_type());
355}
356
357namespace __itoa {
358
359template <unsigned _Base>
360struct _LIBCPP_HIDDEN __integral;
361
362template <>
363struct _LIBCPP_HIDDEN __integral<2> {
364 template <typename _Tp>
365 _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
366 // If value == 0 still need one digit. If the value != this has no
367 // effect since the code scans for the most significant bit set. (Note
368 // that __libcpp_clz doesn't work for 0.)
369 return numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1);
370 }
371
372 template <typename _Tp>
373 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) {
374 ptrdiff_t __cap = __last - __first;
375 int __n = __width(__value);
376 if (__n > __cap)
377 return {__last, errc::value_too_large};
378
379 __last = __first + __n;
380 char* __p = __last;
381 const unsigned __divisor = 16;
382 while (__value > __divisor) {
383 unsigned __c = __value % __divisor;
384 __value /= __divisor;
385 __p -= 4;
386 std::copy_n(&__base_2_lut[4 * __c], 4, __p);
387 }
388 do {
389 unsigned __c = __value % 2;
390 __value /= 2;
391 *--__p = "01"[__c];
392 } while (__value != 0);
393 return {__last, errc(0)};
394 }
395};
396
397template <>
398struct _LIBCPP_HIDDEN __integral<8> {
399 template <typename _Tp>
400 _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
401 // If value == 0 still need one digit. If the value != this has no
402 // effect since the code scans for the most significat bit set. (Note
403 // that __libcpp_clz doesn't work for 0.)
404 return ((numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1)) + 2) / 3;
405 }
406
407 template <typename _Tp>
408 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) {
409 ptrdiff_t __cap = __last - __first;
410 int __n = __width(__value);
411 if (__n > __cap)
412 return {__last, errc::value_too_large};
413
414 __last = __first + __n;
415 char* __p = __last;
416 unsigned __divisor = 64;
417 while (__value > __divisor) {
418 unsigned __c = __value % __divisor;
419 __value /= __divisor;
420 __p -= 2;
421 std::copy_n(&__base_8_lut[2 * __c], 2, __p);
422 }
423 do {
424 unsigned __c = __value % 8;
425 __value /= 8;
426 *--__p = "01234567"[__c];
427 } while (__value != 0);
428 return {__last, errc(0)};
429 }
430
431};
432
433template <>
434struct _LIBCPP_HIDDEN __integral<16> {
435 template <typename _Tp>
436 _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
437 // If value == 0 still need one digit. If the value != this has no
438 // effect since the code scans for the most significat bit set. (Note
439 // that __libcpp_clz doesn't work for 0.)
440 return (numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1) + 3) / 4;
441 }
442
443 template <typename _Tp>
444 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) {
445 ptrdiff_t __cap = __last - __first;
446 int __n = __width(__value);
447 if (__n > __cap)
448 return {__last, errc::value_too_large};
449
450 __last = __first + __n;
451 char* __p = __last;
452 unsigned __divisor = 256;
453 while (__value > __divisor) {
454 unsigned __c = __value % __divisor;
455 __value /= __divisor;
456 __p -= 2;
457 std::copy_n(&__base_16_lut[2 * __c], 2, __p);
458 }
459 if (__first != __last)
460 do {
461 unsigned __c = __value % 16;
462 __value /= 16;
463 *--__p = "0123456789abcdef"[__c];
464 } while (__value != 0);
465 return {__last, errc(0)};
466 }
467};
468
469} // namespace __itoa
470
471template <unsigned _Base, typename _Tp,
472 typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0>
473_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int
474__to_chars_integral_width(_Tp __value) {
475 return __itoa::__integral<_Base>::__width(__value);
476}
477
478template <unsigned _Base, typename _Tp,
479 typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0>
480_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int
481__to_chars_integral_width(_Tp __value) {
482 return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value));
483}
484
485template <unsigned _Base, typename _Tp,
486 typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0>
487_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
488__to_chars_integral(char* __first, char* __last, _Tp __value) {
489 return __itoa::__integral<_Base>::__to_chars(__first, __last, __value);
490}
491
492template <unsigned _Base, typename _Tp,
493 typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0>
494_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
495__to_chars_integral(char* __first, char* __last, _Tp __value) {
496 return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value));
497}
498
499template <typename _Tp>
500_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int
501__to_chars_integral_width(_Tp __value, unsigned __base) {
502 _LIBCPP_ASSERT(__value >= 0, "The function requires a non-negative value.");
503
504 unsigned __base_2 = __base * __base;
505 unsigned __base_3 = __base_2 * __base;
506 unsigned __base_4 = __base_2 * __base_2;
507
508 int __r = 0;
509 while (true) {
510 if (__value < __base)
511 return __r + 1;
512 if (__value < __base_2)
513 return __r + 2;
514 if (__value < __base_3)
515 return __r + 3;
516 if (__value < __base_4)
517 return __r + 4;
518
519 __value /= __base_4;
520 __r += 4;
521 }
522
523 __libcpp_unreachable();
524}
525
526template <typename _Tp>
527inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
528__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
529 false_type)
530{
531 if (__base == 10) [[likely]]
532 return std::__to_chars_itoa(__first, __last, __value, false_type());
533
534 switch (__base) {
535 case 2:
536 return std::__to_chars_integral<2>(__first, __last, __value);
537 case 8:
538 return std::__to_chars_integral<8>(__first, __last, __value);
539 case 16:
540 return std::__to_chars_integral<16>(__first, __last, __value);
541 }
542
543 ptrdiff_t __cap = __last - __first;
544 int __n = std::__to_chars_integral_width(__value, __base);
545 if (__n > __cap)
546 return {__last, errc::value_too_large};
547
548 __last = __first + __n;
549 char* __p = __last;
550 do {
551 unsigned __c = __value % __base;
552 __value /= __base;
553 *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
554 } while (__value != 0);
555 return {__last, errc(0)};
556}
557
558template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
559inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
560to_chars(char* __first, char* __last, _Tp __value)
561{
562 using _Type = __make_32_64_or_128_bit_t<_Tp>;
563 static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars");
564 return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>());
565}
566
567template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
568inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
569to_chars(char* __first, char* __last, _Tp __value, int __base)
570{
571 _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
572
573 using _Type = __make_32_64_or_128_bit_t<_Tp>;
574 return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>());
575}
576
577template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
578inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
579__sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
580{
581 using __tl = numeric_limits<_Tp>;
582 decltype(std::__to_unsigned_like(__value)) __x;
583
584 bool __neg = (__first != __last && *__first == '-');
585 auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...);
586 switch (__r.ec)
587 {
588 case errc::invalid_argument:
589 return {__first, __r.ec};
590 case errc::result_out_of_range:
591 return __r;
592 default:
593 break;
594 }
595
596 if (__neg)
597 {
598 if (__x <= std::__complement(std::__to_unsigned_like(__tl::min())))
599 {
600 __x = std::__complement(__x);
601 std::copy_n(std::addressof(__x), 1, std::addressof(__value));
602 return __r;
603 }
604 }
605 else
606 {
607 if (__x <= std::__to_unsigned_like(__tl::max()))
608 {
609 __value = __x;
610 return __r;
611 }
612 }
613
614 return {__r.ptr, errc::result_out_of_range};
615}
616
617template <typename _Tp>
618inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
619__in_pattern(_Tp __c)
620{
621 return '0' <= __c && __c <= '9';
622}
623
624struct _LIBCPP_HIDDEN __in_pattern_result
625{
626 bool __ok;
627 int __val;
628
629 explicit _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI operator bool() const { return __ok; }
630};
631
632template <typename _Tp>
633inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __in_pattern_result
634__in_pattern(_Tp __c, int __base)
635{
636 if (__base <= 10)
637 return {'0' <= __c && __c < '0' + __base, __c - '0'};
638 else if (std::__in_pattern(__c))
639 return {true, __c - '0'};
640 else if ('a' <= __c && __c < 'a' + __base - 10)
641 return {true, __c - 'a' + 10};
642 else
643 return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10};
644}
645
646template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
647inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
648__subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f,
649 _Ts... __args)
650{
651 auto __find_non_zero = [](_It __firstit, _It __lastit) {
652 for (; __firstit != __lastit; ++__firstit)
653 if (*__firstit != '0')
654 break;
655 return __firstit;
656 };
657
658 auto __p = __find_non_zero(__first, __last);
659 if (__p == __last || !std::__in_pattern(*__p, __args...))
660 {
661 if (__p == __first)
662 return {__first, errc::invalid_argument};
663 else
664 {
665 __value = 0;
666 return {__p, {}};
667 }
668 }
669
670 auto __r = __f(__p, __last, __value, __args...);
671 if (__r.ec == errc::result_out_of_range)
672 {
673 for (; __r.ptr != __last; ++__r.ptr)
674 {
675 if (!std::__in_pattern(*__r.ptr, __args...))
676 break;
677 }
678 }
679
680 return __r;
681}
682
683template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
684inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
685__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
686{
687 using __tx = __itoa::__traits<_Tp>;
688 using __output_type = typename __tx::type;
689
690 return std::__subject_seq_combinator(
691 __first, __last, __value,
692 [](const char* __f, const char* __l,
693 _Tp& __val) -> from_chars_result {
694 __output_type __a, __b;
695 auto __p = __tx::__read(__f, __l, __a, __b);
696 if (__p == __l || !std::__in_pattern(*__p))
697 {
698 __output_type __m = numeric_limits<_Tp>::max();
699 if (__m >= __a && __m - __a >= __b)
700 {
701 __val = __a + __b;
702 return {__p, {}};
703 }
704 }
705 return {__p, errc::result_out_of_range};
706 });
707}
708
709template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
710inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
711__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
712{
713 using __t = decltype(std::__to_unsigned_like(__value));
714 return std::__sign_combinator(__first, __last, __value, __from_chars_atoi<__t>);
715}
716
717
718/*
719// Code used to generate __from_chars_log2f_lut.
720#include <cmath>
721#include <iostream>
722#include <format>
723
724int main() {
725 for (int i = 2; i <= 36; ++i)
726 std::cout << std::format("{},\n", log2f(i));
727}
728*/
729/// log2f table for bases [2, 36].
730inline constexpr float __from_chars_log2f_lut[35] = {
731 1, 1.5849625, 2, 2.321928, 2.5849626, 2.807355, 3, 3.169925, 3.321928,
732 3.4594316, 3.5849626, 3.7004397, 3.807355, 3.9068906, 4, 4.087463, 4.169925, 4.2479277,
733 4.321928, 4.3923173, 4.4594316, 4.523562, 4.5849624, 4.643856, 4.70044, 4.7548876, 4.807355,
734 4.857981, 4.9068904, 4.9541965, 5, 5.044394, 5.087463, 5.129283, 5.169925};
735
736template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
737inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
738__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
739 int __base)
740{
741 if (__base == 10)
742 return std::__from_chars_atoi(__first, __last, __value);
743
744 return std::__subject_seq_combinator(
745 __first, __last, __value,
746 [](const char* __p, const char* __lastp, _Tp& __val,
747 int __b) -> from_chars_result {
748 using __tl = numeric_limits<_Tp>;
749 // __base is always between 2 and 36 inclusive.
750 auto __digits = __tl::digits / __from_chars_log2f_lut[__b - 2];
751 _Tp __x = __in_pattern(*__p++, __b).__val, __y = 0;
752
753 for (int __i = 1; __p != __lastp; ++__i, ++__p)
754 {
755 if (auto __c = __in_pattern(*__p, __b))
756 {
757 if (__i < __digits - 1)
758 __x = __x * __b + __c.__val;
759 else
760 {
761 if (!__itoa::__mul_overflowed(__x, __b, __x))
762 ++__p;
763 __y = __c.__val;
764 break;
765 }
766 }
767 else
768 break;
769 }
770
771 if (__p == __lastp || !__in_pattern(*__p, __b))
772 {
773 if (__tl::max() - __x >= __y)
774 {
775 __val = __x + __y;
776 return {__p, {}};
777 }
778 }
779 return {__p, errc::result_out_of_range};
780 },
781 __base);
782}
783
784template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
785inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
786__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
787 int __base)
788{
789 using __t = decltype(std::__to_unsigned_like(__value));
790 return std::__sign_combinator(__first, __last, __value,
791 __from_chars_integral<__t>, __base);
792}
793
794template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
795inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
796from_chars(const char* __first, const char* __last, _Tp& __value)
797{
798 return std::__from_chars_atoi(__first, __last, __value);
799}
800
801template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
802inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
803from_chars(const char* __first, const char* __last, _Tp& __value, int __base)
804{
805 _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
806 return std::__from_chars_integral(__first, __last, __value, __base);
807}
808
809_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
810to_chars_result to_chars(char* __first, char* __last, float __value);
811
812_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
813to_chars_result to_chars(char* __first, char* __last, double __value);
814
815_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
816to_chars_result to_chars(char* __first, char* __last, long double __value);
817
818_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
819to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt);
820
821_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
822to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt);
823
824_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
825to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt);
826
827_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
828to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision);
829
830_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
831to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision);
832
833_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
834to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision);
835
836#endif // _LIBCPP_STD_VER > 14
837
83893_LIBCPP_END_NAMESPACE_STD
83994
840_LIBCPP_POP_MACROS
841
84295#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
84396# include <concepts>
97# include <cstdlib>
98# include <cstring>
84499# include <iosfwd>
100# include <type_traits>
845101#endif
846102
847103#endif // _LIBCPP_CHARCONV
lib/libcxx/include/chrono+41-12
......@@ -182,7 +182,7 @@ template <class Rep1, class Period1, class Rep2, class Period2>
182182 bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
183183template <class Rep1, class Period1, class Rep2, class Period2>
184184 constexpr
185 bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
185 bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); // removed in C++20
186186template <class Rep1, class Period1, class Rep2, class Period2>
187187 constexpr
188188 bool operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
......@@ -195,6 +195,10 @@ template <class Rep1, class Period1, class Rep2, class Period2>
195195template <class Rep1, class Period1, class Rep2, class Period2>
196196 constexpr
197197 bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
198template<class Rep1, class Period1, class Rep2, class Period2>
199 requires three_way_comparable<typename CT::rep>
200 constexpr auto operator<=>(const duration<Rep1, Period1>& lhs,
201 const duration<Rep2, Period2>& rhs); // since C++20
198202
199203// duration_cast
200204template <class ToDuration, class Rep, class Period>
......@@ -231,7 +235,7 @@ template <class Clock, class Duration1, class Duration2>
231235template <class Clock, class Duration1, class Duration2>
232236 bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
233237template <class Clock, class Duration1, class Duration2>
234 bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
238 bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); // removed in C++20
235239template <class Clock, class Duration1, class Duration2>
236240 bool operator< (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
237241template <class Clock, class Duration1, class Duration2>
......@@ -240,6 +244,10 @@ template <class Clock, class Duration1, class Duration2>
240244 bool operator> (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
241245template <class Clock, class Duration1, class Duration2>
242246 bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
247template<class Clock, class Duration1,
248 three_way_comparable_with<Duration1> Duration2>
249 constexpr auto operator<=>(const time_point<Clock, Duration1>& lhs,
250 const time_point<Clock, Duration2>& rhs); // since C++20
243251
244252// time_point_cast (constexpr in C++14)
245253
......@@ -282,6 +290,10 @@ template <class Duration>
282290using sys_seconds = sys_time<seconds>; // C++20
283291using sys_days = sys_time<days>; // C++20
284292
293template<class charT, class traits, class Duration> // C++20
294 basic_ostream<charT, traits>&
295 operator<<(basic_ostream<charT, traits>& os, const sys_time<Duration>& tp);
296
285297class file_clock // C++20
286298{
287299public:
......@@ -303,6 +315,10 @@ public:
303315template<class Duration>
304316 using file_time = time_point<file_clock, Duration>; // C++20
305317
318template<class charT, class traits, class Duration> // C++20
319 basic_ostream<charT, traits>&
320 operator<<(basic_ostream<charT, traits>& os, const file_time<Duration>& tp);
321
306322class steady_clock
307323{
308324public:
......@@ -324,6 +340,10 @@ template<class Duration>
324340using local_seconds = local_time<seconds>;
325341using local_days = local_time<days>;
326342
343template<class charT, class traits, class Duration> // C++20
344 basic_ostream<charT, traits>&
345 operator<<(basic_ostream<charT, traits>& os, const local_time<Duration>& tp);
346
327347// 25.8.2, class last_spec // C++20
328348struct last_spec;
329349
......@@ -370,7 +390,6 @@ template<class charT, class traits>
370390class weekday;
371391
372392constexpr bool operator==(const weekday& x, const weekday& y) noexcept;
373constexpr bool operator!=(const weekday& x, const weekday& y) noexcept;
374393constexpr weekday operator+(const weekday& x, const days& y) noexcept;
375394constexpr weekday operator+(const days& x, const weekday& y) noexcept;
376395constexpr weekday operator-(const weekday& x, const days& y) noexcept;
......@@ -383,7 +402,6 @@ template<class charT, class traits>
383402
384403class weekday_indexed;
385404constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept;
386constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept;
387405
388406template<class charT, class traits>
389407 basic_ostream<charT, traits>&
......@@ -393,7 +411,6 @@ template<class charT, class traits>
393411class weekday_last;
394412
395413constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept;
396constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept;
397414
398415template<class charT, class traits>
399416 basic_ostream<charT, traits>&
......@@ -423,7 +440,6 @@ template<class charT, class traits>
423440class month_weekday;
424441
425442constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept;
426constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept;
427443
428444template<class charT, class traits>
429445 basic_ostream<charT, traits>&
......@@ -433,7 +449,6 @@ template<class charT, class traits>
433449class month_weekday_last;
434450
435451constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept;
436constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept;
437452
438453template<class charT, class traits>
439454 basic_ostream<charT, traits>&
......@@ -503,8 +518,6 @@ class year_month_weekday;
503518
504519constexpr bool operator==(const year_month_weekday& x,
505520 const year_month_weekday& y) noexcept;
506constexpr bool operator!=(const year_month_weekday& x,
507 const year_month_weekday& y) noexcept;
508521
509522constexpr year_month_weekday
510523 operator+(const year_month_weekday& ymwd, const months& dm) noexcept;
......@@ -528,8 +541,6 @@ class year_month_weekday_last;
528541
529542constexpr bool operator==(const year_month_weekday_last& x,
530543 const year_month_weekday_last& y) noexcept;
531constexpr bool operator!=(const year_month_weekday_last& x,
532 const year_month_weekday_last& y) noexcept;
533544constexpr year_month_weekday_last
534545 operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
535546constexpr year_month_weekday_last
......@@ -656,6 +667,10 @@ public:
656667 constexpr precision to_duration() const noexcept;
657668};
658669
670template<class charT, class traits, class Duration>
671 basic_ostream<charT, traits>&
672 operator<<(basic_ostream<charT, traits>& os, const hh_mm_ss<Duration>& hms); // C++20
673
659674// 26.10, 12/24 hour functions
660675constexpr bool is_am(hours const& h) noexcept;
661676constexpr bool is_pm(hours const& h) noexcept;
......@@ -674,6 +689,12 @@ bool operator>=(const time_zone& x, const time_zone& y) noexcept;
674689} // chrono
675690
676691namespace std {
692 template<class Duration, class charT>
693 struct formatter<chrono::sys_time<Duration>, charT>; // C++20
694 template<class Duration, class charT>
695 struct formatter<chrono::filetime<Duration>, charT>; // C++20
696 template<class Duration, class charT>
697 struct formatter<chrono::local_time<Duration>, charT>; // C++20
677698 template<class Rep, class Period, class charT>
678699 struct formatter<chrono::duration<Rep, Period>, charT>; // C++20
679700 template<class charT> struct formatter<chrono::day, charT>; // C++20
......@@ -691,6 +712,8 @@ namespace std {
691712 template<class charT> struct formatter<chrono::year_month_day_last, charT>; // C++20
692713 template<class charT> struct formatter<chrono::year_month_weekday, charT>; // C++20
693714 template<class charT> struct formatter<chrono::year_month_weekday_last, charT>; // C++20
715 template<class Rep, class Period, class charT>
716 struct formatter<chrono::hh_mm_ss<duration<Rep, Period>>, charT>; // C++20
694717} // namespace std
695718
696719namespace chrono {
......@@ -769,7 +792,7 @@ constexpr chrono::year operator ""y(unsigned lo
769792// [time.syn]
770793#include <compare>
771794
772#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) && _LIBCPP_STD_VER > 17
795#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && _LIBCPP_STD_VER >= 20
773796# include <__chrono/formatter.h>
774797# include <__chrono/ostream.h>
775798# include <__chrono/parser_std_format_spec.h>
......@@ -782,7 +805,13 @@ constexpr chrono::year operator ""y(unsigned lo
782805#endif
783806
784807#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
808# include <bit>
785809# include <concepts>
810# include <cstring>
811#endif
812
813#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER == 20
814# include <charconv>
786815#endif
787816
788817#endif // _LIBCPP_CHRONO
lib/libcxx/include/cmath+4-3
......@@ -311,6 +311,7 @@ constexpr long double lerp(long double a, long double b, long double t) noexcept
311311#include <__type_traits/is_constant_evaluated.h>
312312#include <__type_traits/is_floating_point.h>
313313#include <__type_traits/is_same.h>
314#include <__type_traits/promote.h>
314315#include <__type_traits/remove_cv.h>
315316#include <version>
316317
......@@ -543,7 +544,7 @@ using ::scalbnl _LIBCPP_USING_IF_EXISTS;
543544using ::tgammal _LIBCPP_USING_IF_EXISTS;
544545using ::truncl _LIBCPP_USING_IF_EXISTS;
545546
546#if _LIBCPP_STD_VER > 14
547#if _LIBCPP_STD_VER >= 17
547548inline _LIBCPP_INLINE_VISIBILITY float hypot( float __x, float __y, float __z ) { return sqrt(__x*__x + __y*__y + __z*__z); }
548549inline _LIBCPP_INLINE_VISIBILITY double hypot( double __x, double __y, double __z ) { return sqrt(__x*__x + __y*__y + __z*__z); }
549550inline _LIBCPP_INLINE_VISIBILITY long double hypot( long double __x, long double __y, long double __z ) { return sqrt(__x*__x + __y*__y + __z*__z); }
......@@ -782,7 +783,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp __constexpr_scalbn(_Tp _
782783 return __builtin_scalbn(__x, __exp);
783784}
784785
785#if _LIBCPP_STD_VER > 17
786#if _LIBCPP_STD_VER >= 20
786787template <typename _Fp>
787788_LIBCPP_HIDE_FROM_ABI constexpr
788789_Fp __lerp(_Fp __a, _Fp __b, _Fp __t) noexcept {
......@@ -823,7 +824,7 @@ lerp(_A1 __a, _A2 __b, _A3 __t) noexcept
823824 _IsSame<_A3, __result_type>::value));
824825 return std::__lerp((__result_type)__a, (__result_type)__b, (__result_type)__t);
825826}
826#endif // _LIBCPP_STD_VER > 17
827#endif // _LIBCPP_STD_VER >= 20
827828
828829_LIBCPP_END_NAMESPACE_STD
829830
lib/libcxx/include/codecvt+12-12
......@@ -78,7 +78,7 @@ template <class _Elem> class __codecvt_utf8;
7878
7979#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
8080template <>
81class _LIBCPP_TYPE_VIS __codecvt_utf8<wchar_t>
81class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8<wchar_t>
8282 : public codecvt<wchar_t, char, mbstate_t>
8383{
8484 unsigned long __maxcode_;
......@@ -115,7 +115,7 @@ protected:
115115
116116_LIBCPP_SUPPRESS_DEPRECATED_PUSH
117117template <>
118class _LIBCPP_TYPE_VIS __codecvt_utf8<char16_t>
118class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8<char16_t>
119119 : public codecvt<char16_t, char, mbstate_t>
120120{
121121 unsigned long __maxcode_;
......@@ -149,7 +149,7 @@ protected:
149149
150150_LIBCPP_SUPPRESS_DEPRECATED_PUSH
151151template <>
152class _LIBCPP_TYPE_VIS __codecvt_utf8<char32_t>
152class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8<char32_t>
153153 : public codecvt<char32_t, char, mbstate_t>
154154{
155155 unsigned long __maxcode_;
......@@ -203,7 +203,7 @@ template <class _Elem, bool _LittleEndian> class __codecvt_utf16;
203203
204204#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
205205template <>
206class _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, false>
206class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<wchar_t, false>
207207 : public codecvt<wchar_t, char, mbstate_t>
208208{
209209 unsigned long __maxcode_;
......@@ -239,7 +239,7 @@ protected:
239239};
240240
241241template <>
242class _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, true>
242class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<wchar_t, true>
243243 : public codecvt<wchar_t, char, mbstate_t>
244244{
245245 unsigned long __maxcode_;
......@@ -276,7 +276,7 @@ protected:
276276
277277_LIBCPP_SUPPRESS_DEPRECATED_PUSH
278278template <>
279class _LIBCPP_TYPE_VIS __codecvt_utf16<char16_t, false>
279class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<char16_t, false>
280280 : public codecvt<char16_t, char, mbstate_t>
281281{
282282 unsigned long __maxcode_;
......@@ -310,7 +310,7 @@ protected:
310310
311311_LIBCPP_SUPPRESS_DEPRECATED_PUSH
312312template <>
313class _LIBCPP_TYPE_VIS __codecvt_utf16<char16_t, true>
313class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<char16_t, true>
314314 : public codecvt<char16_t, char, mbstate_t>
315315{
316316 unsigned long __maxcode_;
......@@ -344,7 +344,7 @@ protected:
344344
345345_LIBCPP_SUPPRESS_DEPRECATED_PUSH
346346template <>
347class _LIBCPP_TYPE_VIS __codecvt_utf16<char32_t, false>
347class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<char32_t, false>
348348 : public codecvt<char32_t, char, mbstate_t>
349349{
350350 unsigned long __maxcode_;
......@@ -378,7 +378,7 @@ protected:
378378
379379_LIBCPP_SUPPRESS_DEPRECATED_PUSH
380380template <>
381class _LIBCPP_TYPE_VIS __codecvt_utf16<char32_t, true>
381class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<char32_t, true>
382382 : public codecvt<char32_t, char, mbstate_t>
383383{
384384 unsigned long __maxcode_;
......@@ -432,7 +432,7 @@ template <class _Elem> class __codecvt_utf8_utf16;
432432
433433#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
434434template <>
435class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<wchar_t>
435class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8_utf16<wchar_t>
436436 : public codecvt<wchar_t, char, mbstate_t>
437437{
438438 unsigned long __maxcode_;
......@@ -469,7 +469,7 @@ protected:
469469
470470_LIBCPP_SUPPRESS_DEPRECATED_PUSH
471471template <>
472class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<char32_t>
472class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8_utf16<char32_t>
473473 : public codecvt<char32_t, char, mbstate_t>
474474{
475475 unsigned long __maxcode_;
......@@ -503,7 +503,7 @@ protected:
503503
504504_LIBCPP_SUPPRESS_DEPRECATED_PUSH
505505template <>
506class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<char16_t>
506class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8_utf16<char16_t>
507507 : public codecvt<char16_t, char, mbstate_t>
508508{
509509 unsigned long __maxcode_;
lib/libcxx/include/compare+1
......@@ -151,6 +151,7 @@ namespace std {
151151#include <__compare/ordering.h>
152152#include <__compare/partial_order.h>
153153#include <__compare/strong_order.h>
154#include <__compare/synth_three_way.h>
154155#include <__compare/three_way_comparable.h>
155156#include <__compare/weak_order.h>
156157#include <__config>
lib/libcxx/include/complex+15-8
......@@ -148,12 +148,12 @@ template<class T> complex<T> operator/(const complex<T>&, const T&); //
148148template<class T> complex<T> operator/(const T&, const complex<T>&); // constexpr in C++20
149149template<class T> complex<T> operator+(const complex<T>&); // constexpr in C++20
150150template<class T> complex<T> operator-(const complex<T>&); // constexpr in C++20
151template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14
152template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14
153template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14
154template<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14
155template<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14
156template<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14
151template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14
152template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14
153template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14, removed in C++20
154template<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14, removed in C++20
155template<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14, removed in C++20
156template<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14, removed in C++20
157157
158158template<class T, class charT, class traits>
159159 basic_istream<charT, traits>&
......@@ -236,7 +236,6 @@ template<class T> complex<T> tanh (const complex<T>&);
236236#include <cmath>
237237#include <iosfwd>
238238#include <stdexcept>
239#include <type_traits>
240239#include <version>
241240
242241#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
......@@ -828,6 +827,8 @@ operator==(const complex<_Tp>& __x, const _Tp& __y)
828827 return __x.real() == __y && __x.imag() == 0;
829828}
830829
830#if _LIBCPP_STD_VER <= 17
831
831832template<class _Tp>
832833inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
833834bool
......@@ -860,6 +861,8 @@ operator!=(const _Tp& __x, const complex<_Tp>& __y)
860861 return !(__x == __y);
861862}
862863
864#endif
865
863866// 26.3.7 values:
864867
865868template <class _Tp, bool = is_integral<_Tp>::value,
......@@ -1522,7 +1525,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
15221525}
15231526#endif // !_LIBCPP_HAS_NO_LOCALIZATION
15241527
1525#if _LIBCPP_STD_VER > 11
1528#if _LIBCPP_STD_VER >= 14
15261529// Literal suffix for complex number literals [complex.literals]
15271530inline namespace literals
15281531{
......@@ -1565,4 +1568,8 @@ inline namespace literals
15651568
15661569_LIBCPP_END_NAMESPACE_STD
15671570
1571#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1572# include <type_traits>
1573#endif
1574
15681575#endif // _LIBCPP_COMPLEX
lib/libcxx/include/condition_variable+23-7
......@@ -107,10 +107,18 @@ public:
107107*/
108108
109109#include <__assert> // all public C++ headers provide the assertion handler
110#include <__chrono/duration.h>
111#include <__chrono/steady_clock.h>
112#include <__chrono/time_point.h>
113#include <__condition_variable/condition_variable.h>
110114#include <__config>
111115#include <__memory/shared_ptr.h>
112116#include <__memory/unique_ptr.h>
113#include <__mutex_base>
117#include <__mutex/lock_guard.h>
118#include <__mutex/mutex.h>
119#include <__mutex/tag_types.h>
120#include <__mutex/unique_lock.h>
121#include <__utility/move.h>
114122#include <version>
115123
116124#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -121,7 +129,7 @@ public:
121129
122130_LIBCPP_BEGIN_NAMESPACE_STD
123131
124class _LIBCPP_TYPE_VIS condition_variable_any
132class _LIBCPP_EXPORTED_FROM_ABI condition_variable_any
125133{
126134 condition_variable __cv_;
127135 shared_ptr<mutex> __mut_;
......@@ -191,7 +199,7 @@ condition_variable_any::notify_all() _NOEXCEPT
191199struct __lock_external
192200{
193201 template <class _Lock>
194 void operator()(_Lock* __m) {__m->lock();}
202 _LIBCPP_HIDE_FROM_ABI void operator()(_Lock* __m) {__m->lock();}
195203};
196204
197205template <class _Lock>
......@@ -202,7 +210,7 @@ condition_variable_any::wait(_Lock& __lock)
202210 unique_lock<mutex> __lk(*__mut);
203211 __lock.unlock();
204212 unique_ptr<_Lock, __lock_external> __lxx(&__lock);
205 lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);
213 lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock_t());
206214 __cv_.wait(__lk);
207215} // __mut_.unlock(), __lock.lock()
208216
......@@ -224,7 +232,7 @@ condition_variable_any::wait_until(_Lock& __lock,
224232 unique_lock<mutex> __lk(*__mut);
225233 __lock.unlock();
226234 unique_ptr<_Lock, __lock_external> __lxx(&__lock);
227 lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);
235 lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock_t());
228236 return __cv_.wait_until(__lk, __t);
229237} // __mut_.unlock(), __lock.lock()
230238
......@@ -261,16 +269,24 @@ condition_variable_any::wait_for(_Lock& __lock,
261269 _VSTD::move(__pred));
262270}
263271
264_LIBCPP_FUNC_VIS
265void notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>);
272_LIBCPP_EXPORTED_FROM_ABI void notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>);
266273
267274_LIBCPP_END_NAMESPACE_STD
268275
269276#endif // !_LIBCPP_HAS_NO_THREADS
270277
271278#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
279# include <atomic>
272280# include <concepts>
281# include <cstdint>
282# include <cstdlib>
283# include <cstring>
284# include <initializer_list>
285# include <new>
286# include <stdexcept>
287# include <system_error>
273288# include <type_traits>
289# include <typeinfo>
274290#endif
275291
276292#endif // _LIBCPP_CONDITION_VARIABLE
lib/libcxx/include/cstddef+1-1
......@@ -66,7 +66,7 @@ using ::max_align_t _LIBCPP_USING_IF_EXISTS;
6666
6767_LIBCPP_END_NAMESPACE_STD
6868
69#if _LIBCPP_STD_VER > 14
69#if _LIBCPP_STD_VER >= 17
7070namespace std // purposefully not versioned
7171{
7272enum class byte : unsigned char {};
lib/libcxx/include/cstdlib+1-1
......@@ -144,7 +144,7 @@ using ::wcstombs _LIBCPP_USING_IF_EXISTS;
144144using ::at_quick_exit _LIBCPP_USING_IF_EXISTS;
145145using ::quick_exit _LIBCPP_USING_IF_EXISTS;
146146#endif
147#if _LIBCPP_STD_VER > 14
147#if _LIBCPP_STD_VER >= 17
148148using ::aligned_alloc _LIBCPP_USING_IF_EXISTS;
149149#endif
150150
lib/libcxx/include/cstring-47
......@@ -100,53 +100,6 @@ using ::memset _LIBCPP_USING_IF_EXISTS;
100100using ::strerror _LIBCPP_USING_IF_EXISTS;
101101using ::strlen _LIBCPP_USING_IF_EXISTS;
102102
103inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t __constexpr_strlen(const char* __str) {
104 // GCC currently doesn't support __builtin_strlen for heap-allocated memory during constant evaluation.
105 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70816
106#ifdef _LIBCPP_COMPILER_GCC
107 if (__libcpp_is_constant_evaluated()) {
108 size_t __i = 0;
109 for (; __str[__i] != '\0'; ++__i)
110 ;
111 return __i;
112 }
113#endif
114 return __builtin_strlen(__str);
115}
116
117template <class _Tp>
118_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int
119__constexpr_memcmp(const _Tp* __lhs, const _Tp* __rhs, size_t __count) {
120#ifdef _LIBCPP_COMPILER_GCC
121 if (__libcpp_is_constant_evaluated()) {
122 for (; __count; --__count, ++__lhs, ++__rhs) {
123 if (*__lhs < *__rhs)
124 return -1;
125 if (*__rhs < *__lhs)
126 return 1;
127 }
128 return 0;
129 }
130#endif
131 return __builtin_memcmp(__lhs, __rhs, __count);
132}
133
134inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const char*
135__constexpr_char_memchr(const char* __str, int __char, size_t __count) {
136#if __has_builtin(__builtin_char_memchr)
137 return __builtin_char_memchr(__str, __char, __count);
138#else
139 if (!__libcpp_is_constant_evaluated())
140 return static_cast<const char*>(std::memchr(__str, __char, __count));
141 for (; __count; --__count) {
142 if (*__str == __char)
143 return __str;
144 ++__str;
145 }
146 return nullptr;
147#endif
148}
149
150103_LIBCPP_END_NAMESPACE_STD
151104
152105#endif // _LIBCPP_CSTRING
lib/libcxx/include/ctime+2-2
......@@ -66,7 +66,7 @@ using ::clock_t _LIBCPP_USING_IF_EXISTS;
6666using ::size_t _LIBCPP_USING_IF_EXISTS;
6767using ::time_t _LIBCPP_USING_IF_EXISTS;
6868using ::tm _LIBCPP_USING_IF_EXISTS;
69#if _LIBCPP_STD_VER > 14
69#if _LIBCPP_STD_VER >= 17
7070using ::timespec _LIBCPP_USING_IF_EXISTS;
7171#endif
7272using ::clock _LIBCPP_USING_IF_EXISTS;
......@@ -78,7 +78,7 @@ using ::ctime _LIBCPP_USING_IF_EXISTS;
7878using ::gmtime _LIBCPP_USING_IF_EXISTS;
7979using ::localtime _LIBCPP_USING_IF_EXISTS;
8080using ::strftime _LIBCPP_USING_IF_EXISTS;
81#if _LIBCPP_STD_VER > 14
81#if _LIBCPP_STD_VER >= 17
8282using ::timespec_get _LIBCPP_USING_IF_EXISTS;
8383#endif
8484
lib/libcxx/include/cwchar+23-9
......@@ -104,7 +104,11 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
104104
105105#include <__assert> // all public C++ headers provide the assertion handler
106106#include <__config>
107#include <__type_traits/apply_cv.h>
107108#include <__type_traits/is_constant_evaluated.h>
109#include <__type_traits/is_equality_comparable.h>
110#include <__type_traits/is_same.h>
111#include <__type_traits/remove_cv.h>
108112#include <cwctype>
109113
110114#include <wchar.h>
......@@ -222,21 +226,31 @@ __constexpr_wmemcmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __count)
222226#endif
223227}
224228
225inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const wchar_t*
226__constexpr_wmemchr(const wchar_t* __str, wchar_t __char, size_t __count) {
227#if __has_feature(cxx_constexpr_string_builtins)
228 return __builtin_wmemchr(__str, __char, __count);
229#else
230 if (!__libcpp_is_constant_evaluated())
231 return std::wmemchr(__str, __char, __count);
229template <class _Tp, class _Up>
230_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __constexpr_wmemchr(_Tp* __str, _Up __value, size_t __count) {
231 static_assert(sizeof(_Tp) == sizeof(wchar_t)&& _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t) &&
232 __libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value,
233 "Calling wmemchr on non-trivially equality comparable types is unsafe.");
234
235#if __has_builtin(__builtin_wmemchr)
236 if (!__libcpp_is_constant_evaluated()) {
237 wchar_t __value_buffer = 0;
238 __builtin_memcpy(&__value_buffer, &__value, sizeof(wchar_t));
239 return reinterpret_cast<_Tp*>(
240 __builtin_wmemchr(reinterpret_cast<__apply_cv_t<_Tp, wchar_t>*>(__str), __value_buffer, __count));
241 }
242# if _LIBCPP_STD_VER >= 17
243 else if constexpr (is_same_v<remove_cv_t<_Tp>, wchar_t>)
244 return __builtin_wmemchr(__str, __value, __count);
245# endif
246#endif // __has_builtin(__builtin_wmemchr)
232247
233248 for (; __count; --__count) {
234 if (*__str == __char)
249 if (*__str == __value)
235250 return __str;
236251 ++__str;
237252 }
238253 return nullptr;
239#endif
240254}
241255
242256_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/deque+629-66
......@@ -47,6 +47,8 @@ public:
4747 deque(InputIterator f, InputIterator l);
4848 template <class InputIterator>
4949 deque(InputIterator f, InputIterator l, const allocator_type& a);
50 template<container-compatible-range<T> R>
51 deque(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
5052 deque(const deque& c);
5153 deque(deque&& c)
5254 noexcept(is_nothrow_move_constructible<allocator_type>::value);
......@@ -64,6 +66,8 @@ public:
6466
6567 template <class InputIterator>
6668 void assign(InputIterator f, InputIterator l);
69 template<container-compatible-range<T> R>
70 void assign_range(R&& rg); // C++23
6771 void assign(size_type n, const value_type& v);
6872 void assign(initializer_list<value_type> il);
6973
......@@ -107,8 +111,12 @@ public:
107111 // modifiers:
108112 void push_front(const value_type& v);
109113 void push_front(value_type&& v);
114 template<container-compatible-range<T> R>
115 void prepend_range(R&& rg); // C++23
110116 void push_back(const value_type& v);
111117 void push_back(value_type&& v);
118 template<container-compatible-range<T> R>
119 void append_range(R&& rg); // C++23
112120 template <class... Args> reference emplace_front(Args&&... args); // reference in C++17
113121 template <class... Args> reference emplace_back(Args&&... args); // reference in C++17
114122 template <class... Args> iterator emplace(const_iterator p, Args&&... args);
......@@ -117,6 +125,8 @@ public:
117125 iterator insert(const_iterator p, size_type n, const value_type& v);
118126 template <class InputIterator>
119127 iterator insert(const_iterator p, InputIterator f, InputIterator l);
128 template<container-compatible-range<T> R>
129 iterator insert_range(const_iterator position, R&& rg); // C++23
120130 iterator insert(const_iterator p, initializer_list<value_type> il);
121131 void pop_front();
122132 void pop_back();
......@@ -131,18 +141,25 @@ template <class InputIterator, class Allocator = allocator<typename iterator_tra
131141 deque(InputIterator, InputIterator, Allocator = Allocator())
132142 -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
133143
144template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
145 deque(from_range_t, R&&, Allocator = Allocator())
146 -> deque<ranges::range_value_t<R>, Allocator>; // C++23
147
134148template <class T, class Allocator>
135149 bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
136150template <class T, class Allocator>
137 bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
151 bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
138152template <class T, class Allocator>
139 bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
153 bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
140154template <class T, class Allocator>
141 bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
155 bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
142156template <class T, class Allocator>
143 bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
157 bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
144158template <class T, class Allocator>
145 bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
159 bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20
160template<class T, class Allocator>
161 synth-three-way-result<T> operator<=>(const deque<T, Allocator>& x,
162 const deque<T, Allocator>& y); // since C++20
146163
147164// specialized algorithms:
148165template <class T, class Allocator>
......@@ -162,34 +179,47 @@ template <class T, class Allocator, class Predicate>
162179
163180#include <__algorithm/copy.h>
164181#include <__algorithm/copy_backward.h>
182#include <__algorithm/copy_n.h>
165183#include <__algorithm/equal.h>
166184#include <__algorithm/fill_n.h>
167185#include <__algorithm/lexicographical_compare.h>
186#include <__algorithm/lexicographical_compare_three_way.h>
168187#include <__algorithm/min.h>
169188#include <__algorithm/remove.h>
170189#include <__algorithm/remove_if.h>
171190#include <__algorithm/unwrap_iter.h>
172191#include <__assert> // all public C++ headers provide the assertion handler
192#include <__availability>
173193#include <__config>
174194#include <__format/enable_insertable.h>
195#include <__iterator/distance.h>
175196#include <__iterator/iterator_traits.h>
176197#include <__iterator/next.h>
177198#include <__iterator/prev.h>
178199#include <__iterator/reverse_iterator.h>
179200#include <__iterator/segmented_iterator.h>
201#include <__memory/addressof.h>
180202#include <__memory/allocator_destructor.h>
181203#include <__memory/pointer_traits.h>
182204#include <__memory/temp_value.h>
183205#include <__memory/unique_ptr.h>
184206#include <__memory_resource/polymorphic_allocator.h>
207#include <__ranges/access.h>
208#include <__ranges/concepts.h>
209#include <__ranges/container_compatible_range.h>
210#include <__ranges/from_range.h>
211#include <__ranges/size.h>
185212#include <__split_buffer>
186213#include <__type_traits/is_allocator.h>
214#include <__type_traits/is_convertible.h>
215#include <__type_traits/is_same.h>
216#include <__type_traits/type_identity.h>
187217#include <__utility/forward.h>
188218#include <__utility/move.h>
219#include <__utility/pair.h>
189220#include <__utility/swap.h>
190221#include <limits>
191222#include <stdexcept>
192#include <type_traits>
193223#include <version>
194224
195225// standard-mandated includes
......@@ -249,7 +279,7 @@ public:
249279 typedef _Reference reference;
250280
251281 _LIBCPP_HIDE_FROM_ABI __deque_iterator() _NOEXCEPT
252#if _LIBCPP_STD_VER > 11
282#if _LIBCPP_STD_VER >= 14
253283 : __m_iter_(nullptr), __ptr_(nullptr)
254284#endif
255285 {}
......@@ -451,6 +481,7 @@ public:
451481 using __map_alloc_traits = allocator_traits<__pointer_allocator>;
452482 using __map_pointer = typename __map_alloc_traits::pointer;
453483 using __map_const_pointer = typename allocator_traits<__const_pointer_allocator>::const_pointer;
484 using __map_const_iterator = typename __map::const_iterator;
454485
455486 using reference = value_type&;
456487 using const_reference = const value_type&;
......@@ -550,10 +581,13 @@ public:
550581 // construct/copy/destroy:
551582 _LIBCPP_HIDE_FROM_ABI
552583 deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
553 : __start_(0), __size_(0, __default_init_tag()) {}
584 : __start_(0), __size_(0, __default_init_tag()) {
585 __annotate_new(0);
586 }
554587
555588 _LIBCPP_HIDE_FROM_ABI ~deque() {
556589 clear();
590 __annotate_delete();
557591 typename __map::iterator __i = __map_.begin();
558592 typename __map::iterator __e = __map_.end();
559593 for (; __i != __e; ++__i)
......@@ -561,10 +595,12 @@ public:
561595 }
562596
563597 _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a)
564 : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {}
598 : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {
599 __annotate_new(0);
600 }
565601
566602 explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n);
567#if _LIBCPP_STD_VER > 11
603#if _LIBCPP_STD_VER >= 14
568604 explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a);
569605#endif
570606 _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v);
......@@ -573,16 +609,34 @@ public:
573609 _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a)
574610 : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
575611 {
612 __annotate_new(0);
576613 if (__n > 0)
577614 __append(__n, __v);
578615 }
579616
580617 template <class _InputIter>
581618 _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l,
582 typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
619 typename enable_if<__has_input_iterator_category<_InputIter>::value>::type* = 0);
583620 template <class _InputIter>
584621 _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
585 typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
622 typename enable_if<__has_input_iterator_category<_InputIter>::value>::type* = 0);
623
624#if _LIBCPP_STD_VER >= 23
625 template <_ContainerCompatibleRange<_Tp> _Range>
626 _LIBCPP_HIDE_FROM_ABI deque(from_range_t, _Range&& __range,
627 const allocator_type& __a = allocator_type())
628 : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {
629 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
630 __append_with_size(ranges::begin(__range), ranges::distance(__range));
631
632 } else {
633 for (auto&& __e : __range) {
634 emplace_back(std::forward<decltype(__e)>(__e));
635 }
636 }
637 }
638#endif
639
586640 _LIBCPP_HIDE_FROM_ABI deque(const deque& __c);
587641 _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a);
588642
......@@ -610,11 +664,30 @@ public:
610664
611665 template <class _InputIter>
612666 _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l,
613 typename enable_if<__is_cpp17_input_iterator<_InputIter>::value &&
614 !__is_cpp17_random_access_iterator<_InputIter>::value>::type* = 0);
667 typename enable_if<__has_input_iterator_category<_InputIter>::value &&
668 !__has_random_access_iterator_category<_InputIter>::value>::type* = 0);
615669 template <class _RAIter>
616670 _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l,
617 typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
671 typename enable_if<__has_random_access_iterator_category<_RAIter>::value>::type* = 0);
672
673#if _LIBCPP_STD_VER >= 23
674 template <_ContainerCompatibleRange<_Tp> _Range>
675 _LIBCPP_HIDE_FROM_ABI
676 void assign_range(_Range&& __range) {
677 if constexpr (ranges::random_access_range<_Range>) {
678 auto __n = static_cast<size_type>(ranges::distance(__range));
679 __assign_with_size_random_access(ranges::begin(__range), __n);
680
681 } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
682 auto __n = static_cast<size_type>(ranges::distance(__range));
683 __assign_with_size(ranges::begin(__range), __n);
684
685 } else {
686 __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
687 }
688 }
689#endif
690
618691 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);
619692
620693 _LIBCPP_HIDE_FROM_ABI
......@@ -713,7 +786,7 @@ public:
713786 _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v);
714787 _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v);
715788#ifndef _LIBCPP_CXX03_LANG
716#if _LIBCPP_STD_VER > 14
789#if _LIBCPP_STD_VER >= 17
717790 template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args);
718791 template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_back (_Args&&... __args);
719792#else
......@@ -724,6 +797,21 @@ public:
724797
725798 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v);
726799 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v);
800
801#if _LIBCPP_STD_VER >= 23
802 template <_ContainerCompatibleRange<_Tp> _Range>
803 _LIBCPP_HIDE_FROM_ABI
804 void prepend_range(_Range&& __range) {
805 insert_range(begin(), std::forward<_Range>(__range));
806 }
807
808 template <_ContainerCompatibleRange<_Tp> _Range>
809 _LIBCPP_HIDE_FROM_ABI
810 void append_range(_Range&& __range) {
811 insert_range(end(), std::forward<_Range>(__range));
812 }
813#endif
814
727815 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v);
728816
729817 _LIBCPP_HIDE_FROM_ABI
......@@ -734,13 +822,31 @@ public:
734822 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v);
735823 template <class _InputIter>
736824 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l,
737 typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type* = 0);
825 typename enable_if<__has_exactly_input_iterator_category<_InputIter>::value>::type* = 0);
738826 template <class _ForwardIterator>
739827 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
740 typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0);
828 typename enable_if<__has_exactly_forward_iterator_category<_ForwardIterator>::value>::type* = 0);
741829 template <class _BiIter>
742830 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l,
743 typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type* = 0);
831 typename enable_if<__has_bidirectional_iterator_category<_BiIter>::value>::type* = 0);
832
833#if _LIBCPP_STD_VER >= 23
834 template <_ContainerCompatibleRange<_Tp> _Range>
835 _LIBCPP_HIDE_FROM_ABI
836 iterator insert_range(const_iterator __position, _Range&& __range) {
837 if constexpr (ranges::bidirectional_range<_Range>) {
838 auto __n = static_cast<size_type>(ranges::distance(__range));
839 return __insert_bidirectional(__position, ranges::begin(__range), ranges::end(__range), __n);
840
841 } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
842 auto __n = static_cast<size_type>(ranges::distance(__range));
843 return __insert_with_size(__position, ranges::begin(__range), __n);
844
845 } else {
846 return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
847 }
848 }
849#endif
744850
745851 _LIBCPP_HIDE_FROM_ABI void pop_front();
746852 _LIBCPP_HIDE_FROM_ABI void pop_back();
......@@ -764,7 +870,7 @@ public:
764870 return false;
765871 if (__map_.size() >= size_type(-1) / __block_size)
766872 return false;
767 for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end();
873 for (__map_const_iterator __i = __map_.begin(), __e = __map_.end();
768874 __i != __e; ++__i)
769875 if (*__i == nullptr)
770876 return false;
......@@ -851,9 +957,264 @@ public:
851957 }
852958
853959 private:
960 enum __asan_annotation_type {
961 __asan_unposion,
962 __asan_poison
963 };
964
965 enum __asan_annotation_place {
966 __asan_front_moved,
967 __asan_back_moved,
968 };
969
970// The following functions are no-ops outside of AddressSanitizer mode.
971// We call annotations for every allocator, unless explicitly disabled.
972//
973// To disable annotations for a particular allocator, change value of
974// __asan_annotate_container_with_allocator to false.
975// For more details, see the "Using libc++" documentation page or
976// the documentation for __sanitizer_annotate_contiguous_container.
977#if !defined(_LIBCPP_HAS_NO_ASAN) && _LIBCPP_CLANG_VER >= 1600
978 // TODO LLVM18: Remove the special-casing
979 _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container(
980 const void* __beg,
981 const void* __end,
982 const void* __old_con_beg,
983 const void* __old_con_end,
984 const void* __new_con_beg,
985 const void* __new_con_end) const {
986 if (__beg != nullptr && __asan_annotate_container_with_allocator<_Allocator>::value)
987 __sanitizer_annotate_double_ended_contiguous_container(
988 __beg, __end, __old_con_beg, __old_con_end, __new_con_beg, __new_con_end);
989 }
990#else
991 _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container(
992 const void*, const void*, const void*, const void*, const void*, const void*) const _NOEXCEPT {}
993#endif // !defined(_LIBCPP_HAS_NO_ASAN) && _LIBCPP_CLANG_VER >= 1600
994
995 _LIBCPP_HIDE_FROM_ABI
996 void __annotate_from_to(size_type __beg, size_type __end, __asan_annotation_type __annotation_type, __asan_annotation_place __place) const _NOEXCEPT {
997 // __beg - index of the first item to annotate
998 // __end - index behind the last item to annotate (so last item + 1)
999 // __annotation_type - __asan_unposion or __asan_poison
1000 // __place - __asan_front_moved or __asan_back_moved
1001 // Note: All indexes in __map_
1002 if (__beg == __end)
1003 return;
1004 // __annotations_beg_map - first chunk which annotations we want to modify
1005 // __annotations_end_map - last chunk which annotations we want to modify
1006 // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist
1007 __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size;
1008 __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size;
1009
1010 bool const __poisoning = __annotation_type == __asan_poison;
1011 // __old_c_beg_index - index of the first element in old container
1012 // __old_c_end_index - index of the end of old container (last + 1)
1013 // Note: may be outside the area we are annotating
1014 size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_;
1015 size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved) ? __end : __start_ + size();
1016 bool const __front = __place == __asan_front_moved;
1017
1018 if (__poisoning && empty()) {
1019 // Special case: we shouldn't trust __start_
1020 __old_c_beg_index = __beg;
1021 __old_c_end_index = __end;
1022 }
1023 // __old_c_beg_map - memory block (chunk) with first element
1024 // __old_c_end_map - memory block (chunk) with end of old container
1025 // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block,
1026 // which may not exist
1027 __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size;
1028 __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size;
1029
1030 // One edge (front/end) of the container was moved and one was not modified.
1031 // __new_edge_index - index of new edge
1032 // __new_edge_map - memory block (chunk) with new edge, it always equals to
1033 // __annotations_beg_map or __annotations_end_map
1034 // __old_edge_map - memory block (chunk) with old edge, it always equals to
1035 // __old_c_beg_map or __old_c_end_map
1036 size_t __new_edge_index = (__poisoning ^ __front) ? __beg : __end;
1037 __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size;
1038 __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map;
1039
1040 // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last.
1041 // First and last chunk may be partially poisoned.
1042 // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it.
1043 for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) {
1044 if (__map_it == __annotations_end_map && __end % __block_size == 0)
1045 // Chunk may not exist, but nothing to do here anyway
1046 break;
1047
1048 // The beginning and the end of the current memory block
1049 const void* __mem_beg = std::__to_address(*__map_it);
1050 const void* __mem_end = std::__to_address(*__map_it + __block_size);
1051
1052 // The beginning of memory-in-use in the memory block before container modification
1053 const void* __old_beg =
1054 (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg;
1055
1056 // The end of memory-in-use in the memory block before container modification
1057 const void* __old_end;
1058 if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty()))
1059 __old_end = __old_beg;
1060 else
1061 __old_end = (__map_it == __old_c_end_map) ? std::__to_address(*__map_it + (__old_c_end_index % __block_size))
1062 : __mem_end;
1063
1064 // New edge of the container in current memory block
1065 // If the edge is in a different chunk it points on corresponding end of the memory block
1066 const void* __new_edge;
1067 if (__map_it == __new_edge_map)
1068 __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size));
1069 else
1070 __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end;
1071
1072 // Not modified edge of the container
1073 // If the edge is in a different chunk it points on corresponding end of the memory block
1074 const void* __old_edge;
1075 if (__map_it == __old_edge_map)
1076 __old_edge = __front ? __old_end : __old_beg;
1077 else
1078 __old_edge = __front ? __mem_end : __mem_beg;
1079
1080 // __new_beg - the beginning of memory-in-use in the memory block after container modification
1081 // __new_end - the end of memory-in-use in the memory block after container modification
1082 const void* __new_beg = __front ? __new_edge : __old_edge;
1083 const void* __new_end = __front ? __old_edge : __new_edge;
1084
1085 __annotate_double_ended_contiguous_container(__mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end);
1086 }
1087 }
1088
1089 _LIBCPP_HIDE_FROM_ABI
1090 void __annotate_new(size_type __current_size) const _NOEXCEPT {
1091 if (__current_size == 0)
1092 __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved);
1093 else {
1094 __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved);
1095 __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved);
1096 }
1097 }
1098
1099 _LIBCPP_HIDE_FROM_ABI
1100 void __annotate_delete() const _NOEXCEPT {
1101 if (empty()) {
1102 for(size_t __i = 0; __i < __map_.size(); ++__i) {
1103 __annotate_whole_block(__i, __asan_unposion);
1104 }
1105 }
1106 else {
1107 __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved);
1108 __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved);
1109 }
1110 }
1111
1112 _LIBCPP_HIDE_FROM_ABI
1113 void __annotate_increase_front(size_type __n) const _NOEXCEPT {
1114 __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved);
1115 }
1116
1117 _LIBCPP_HIDE_FROM_ABI
1118 void __annotate_increase_back(size_type __n) const _NOEXCEPT {
1119 __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved);
1120 }
1121
1122 _LIBCPP_HIDE_FROM_ABI
1123 void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT {
1124 __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved);
1125 }
1126
1127 _LIBCPP_HIDE_FROM_ABI
1128 void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT {
1129 __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved);
1130 }
1131
1132 _LIBCPP_HIDE_FROM_ABI
1133 void __annotate_poison_block(const void *__beginning, const void *__end) const _NOEXCEPT {
1134 __annotate_double_ended_contiguous_container(__beginning, __end, __beginning, __end, __end, __end);
1135 }
1136
1137 _LIBCPP_HIDE_FROM_ABI
1138 void __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT {
1139 __map_const_iterator __block_it = __map_.begin() + __block_index;
1140 const void* __block_start = std::__to_address(*__block_it);
1141 const void* __block_end = std::__to_address(*__block_it + __block_size);
1142
1143 if(__annotation_type == __asan_poison)
1144 __annotate_poison_block(__block_start, __block_end);
1145 else {
1146 __annotate_double_ended_contiguous_container(
1147 __block_start, __block_end, __block_start, __block_start, __block_start, __block_end);
1148 }
1149 }
1150#if !defined(_LIBCPP_HAS_NO_ASAN)
1151
1152 public:
1153 _LIBCPP_HIDE_FROM_ABI
1154 bool __verify_asan_annotations() const _NOEXCEPT {
1155 // This function tests deque object annotations.
1156 if (empty()) {
1157 for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) {
1158 if (!__sanitizer_verify_double_ended_contiguous_container(
1159 std::__to_address(*__it),
1160 std::__to_address(*__it),
1161 std::__to_address(*__it),
1162 std::__to_address(*__it + __block_size)))
1163 return false;
1164 }
1165
1166 return true;
1167 }
1168
1169 size_type __end = __start_ + size();
1170 __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size;
1171 __map_const_iterator __last_mp = __map_.begin() + (__end - 1) / __block_size;
1172
1173 // Pointers to first and after last elements
1174 // Those can be in different deque blocks
1175 const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size));
1176 const void* __p_end =
1177 std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size));
1178
1179 for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) {
1180 // Go over all blocks, find the place we are in and verify its annotations
1181 // Note that __p_end points *behind* the last item.
1182
1183 // - blocks before the first block with container elements
1184 // - first block with items
1185 // - last block with items
1186 // - blocks after last block with ciontainer elements
1187
1188 // Is the block before or after deque blocks that contain elements?
1189 if (__it < __first_mp || __it > __last_mp) {
1190 if (!__sanitizer_verify_double_ended_contiguous_container(
1191 std::__to_address(*__it),
1192 std::__to_address(*__it),
1193 std::__to_address(*__it),
1194 std::__to_address(*__it + __block_size)))
1195 return false;
1196 } else {
1197 const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it);
1198 const void* __containers_buffer_end =
1199 (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size);
1200 if (!__sanitizer_verify_double_ended_contiguous_container(
1201 std::__to_address(*__it),
1202 __containers_buffer_beg,
1203 __containers_buffer_end,
1204 std::__to_address(*__it + __block_size))) {
1205 return false;
1206 }
1207 }
1208 }
1209 return true;
1210 }
1211
1212 private:
1213#endif // _LIBCPP_VERIFY_ASAN_DEQUE_ANNOTATIONS
8541214 _LIBCPP_HIDE_FROM_ABI
8551215 bool __maybe_remove_front_spare(bool __keep_one = true) {
8561216 if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) {
1217 __annotate_whole_block(0, __asan_unposion);
8571218 __alloc_traits::deallocate(__alloc(), __map_.front(),
8581219 __block_size);
8591220 __map_.pop_front();
......@@ -866,6 +1227,7 @@ public:
8661227 _LIBCPP_HIDE_FROM_ABI
8671228 bool __maybe_remove_back_spare(bool __keep_one = true) {
8681229 if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) {
1230 __annotate_whole_block(__map_.size() - 1, __asan_unposion);
8691231 __alloc_traits::deallocate(__alloc(), __map_.back(),
8701232 __block_size);
8711233 __map_.pop_back();
......@@ -874,12 +1236,44 @@ public:
8741236 return false;
8751237 }
8761238
1239 template <class _Iterator, class _Sentinel>
1240 _LIBCPP_HIDE_FROM_ABI
1241 void __assign_with_sentinel(_Iterator __f, _Sentinel __l);
1242
1243 template <class _RandomAccessIterator>
1244 _LIBCPP_HIDE_FROM_ABI
1245 void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n);
1246 template <class _Iterator>
1247 _LIBCPP_HIDE_FROM_ABI
1248 void __assign_with_size(_Iterator __f, difference_type __n);
1249
1250 template <class _Iterator, class _Sentinel>
1251 _LIBCPP_HIDE_FROM_ABI
1252 iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l);
1253
1254 template <class _Iterator>
1255 _LIBCPP_HIDE_FROM_ABI
1256 iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n);
1257
1258 template <class _BiIter, class _Sentinel>
1259 _LIBCPP_HIDE_FROM_ABI
1260 iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n);
1261 template <class _BiIter>
1262 _LIBCPP_HIDE_FROM_ABI
1263 iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n);
1264
8771265 template <class _InpIter>
8781266 _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l,
879 typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type* = 0);
1267 typename enable_if<__has_exactly_input_iterator_category<_InpIter>::value>::type* = 0);
8801268 template <class _ForIter>
8811269 _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l,
882 typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type* = 0);
1270 typename enable_if<__has_forward_iterator_category<_ForIter>::value>::type* = 0);
1271
1272 template <class _InputIterator>
1273 _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n);
1274 template <class _InputIterator, class _Sentinel>
1275 _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l);
1276
8831277 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);
8841278 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v);
8851279 _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f);
......@@ -929,7 +1323,7 @@ _LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque
9291323#if _LIBCPP_STD_VER >= 17
9301324template<class _InputIterator,
9311325 class _Alloc = allocator<__iter_value_type<_InputIterator>>,
932 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1326 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
9331327 class = enable_if_t<__is_allocator<_Alloc>::value>
9341328 >
9351329deque(_InputIterator, _InputIterator)
......@@ -937,26 +1331,37 @@ deque(_InputIterator, _InputIterator)
9371331
9381332template<class _InputIterator,
9391333 class _Alloc,
940 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1334 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
9411335 class = enable_if_t<__is_allocator<_Alloc>::value>
9421336 >
9431337deque(_InputIterator, _InputIterator, _Alloc)
9441338 -> deque<__iter_value_type<_InputIterator>, _Alloc>;
9451339#endif
9461340
1341#if _LIBCPP_STD_VER >= 23
1342template <ranges::input_range _Range,
1343 class _Alloc = allocator<ranges::range_value_t<_Range>>,
1344 class = enable_if_t<__is_allocator<_Alloc>::value>
1345 >
1346deque(from_range_t, _Range&&, _Alloc = _Alloc())
1347 -> deque<ranges::range_value_t<_Range>, _Alloc>;
1348#endif
1349
9471350template <class _Tp, class _Allocator>
9481351deque<_Tp, _Allocator>::deque(size_type __n)
9491352 : __start_(0), __size_(0, __default_init_tag())
9501353{
1354 __annotate_new(0);
9511355 if (__n > 0)
9521356 __append(__n);
9531357}
9541358
955#if _LIBCPP_STD_VER > 11
1359#if _LIBCPP_STD_VER >= 14
9561360template <class _Tp, class _Allocator>
9571361deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
9581362 : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
9591363{
1364 __annotate_new(0);
9601365 if (__n > 0)
9611366 __append(__n);
9621367}
......@@ -966,6 +1371,7 @@ template <class _Tp, class _Allocator>
9661371deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
9671372 : __start_(0), __size_(0, __default_init_tag())
9681373{
1374 __annotate_new(0);
9691375 if (__n > 0)
9701376 __append(__n, __v);
9711377}
......@@ -973,18 +1379,20 @@ deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
9731379template <class _Tp, class _Allocator>
9741380template <class _InputIter>
9751381deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,
976 typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*)
1382 typename enable_if<__has_input_iterator_category<_InputIter>::value>::type*)
9771383 : __start_(0), __size_(0, __default_init_tag())
9781384{
1385 __annotate_new(0);
9791386 __append(__f, __l);
9801387}
9811388
9821389template <class _Tp, class _Allocator>
9831390template <class _InputIter>
9841391deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
985 typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*)
1392 typename enable_if<__has_input_iterator_category<_InputIter>::value>::type*)
9861393 : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
9871394{
1395 __annotate_new(0);
9881396 __append(__f, __l);
9891397}
9901398
......@@ -994,6 +1402,7 @@ deque<_Tp, _Allocator>::deque(const deque& __c)
9941402 __start_(0),
9951403 __size_(0, __map_.__alloc())
9961404{
1405 __annotate_new(0);
9971406 __append(__c.begin(), __c.end());
9981407}
9991408
......@@ -1001,6 +1410,7 @@ template <class _Tp, class _Allocator>
10011410deque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a)
10021411 : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
10031412{
1413 __annotate_new(0);
10041414 __append(__c.begin(), __c.end());
10051415}
10061416
......@@ -1022,6 +1432,7 @@ template <class _Tp, class _Allocator>
10221432deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)
10231433 : __start_(0), __size_(0, __default_init_tag())
10241434{
1435 __annotate_new(0);
10251436 __append(__il.begin(), __il.end());
10261437}
10271438
......@@ -1029,6 +1440,7 @@ template <class _Tp, class _Allocator>
10291440deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
10301441 : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a)
10311442{
1443 __annotate_new(0);
10321444 __append(__il.begin(), __il.end());
10331445}
10341446
......@@ -1105,15 +1517,22 @@ template <class _Tp, class _Allocator>
11051517template <class _InputIter>
11061518void
11071519deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l,
1108 typename enable_if<__is_cpp17_input_iterator<_InputIter>::value &&
1109 !__is_cpp17_random_access_iterator<_InputIter>::value>::type*)
1520 typename enable_if<__has_input_iterator_category<_InputIter>::value &&
1521 !__has_random_access_iterator_category<_InputIter>::value>::type*)
11101522{
1523 __assign_with_sentinel(__f, __l);
1524}
1525
1526template <class _Tp, class _Allocator>
1527template <class _Iterator, class _Sentinel>
1528_LIBCPP_HIDE_FROM_ABI
1529void deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) {
11111530 iterator __i = begin();
11121531 iterator __e = end();
11131532 for (; __f != __l && __i != __e; ++__f, (void) ++__i)
11141533 *__i = *__f;
11151534 if (__f != __l)
1116 __append(__f, __l);
1535 __append_with_sentinel(std::move(__f), std::move(__l));
11171536 else
11181537 __erase_to_end(__i);
11191538}
......@@ -1122,16 +1541,42 @@ template <class _Tp, class _Allocator>
11221541template <class _RAIter>
11231542void
11241543deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l,
1125 typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
1544 typename enable_if<__has_random_access_iterator_category<_RAIter>::value>::type*)
11261545{
1127 if (static_cast<size_type>(__l - __f) > size())
1546 __assign_with_size_random_access(__f, __l - __f);
1547}
1548
1549template <class _Tp, class _Allocator>
1550template <class _RandomAccessIterator>
1551_LIBCPP_HIDE_FROM_ABI
1552void deque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) {
1553 if (static_cast<size_type>(__n) > size())
11281554 {
1129 _RAIter __m = __f + size();
1130 _VSTD::copy(__f, __m, begin());
1131 __append(__m, __l);
1555 auto __l = __f + size();
1556 std::copy(__f, __l, begin());
1557 __append_with_size(__l, __n - size());
11321558 }
11331559 else
1134 __erase_to_end(_VSTD::copy(__f, __l, begin()));
1560 __erase_to_end(std::copy_n(__f, __n, begin()));
1561}
1562
1563template <class _Tp, class _Allocator>
1564template <class _Iterator>
1565_LIBCPP_HIDE_FROM_ABI
1566void deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) {
1567 if (static_cast<size_type>(__n) > size()) {
1568 auto __added_size = __n - size();
1569
1570 auto __i = begin();
1571 for (auto __count = size(); __count != 0; --__count) {
1572 *__i++ = *__f++;
1573 }
1574
1575 __append_with_size(__f, __added_size);
1576
1577 } else {
1578 __erase_to_end(std::copy_n(__f, __n, begin()));
1579 }
11351580}
11361581
11371582template <class _Tp, class _Allocator>
......@@ -1183,6 +1628,7 @@ deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
11831628 allocator_type& __a = __alloc();
11841629 if (empty())
11851630 {
1631 __annotate_delete();
11861632 while (__map_.size() > 0)
11871633 {
11881634 __alloc_traits::deallocate(__a, __map_.back(), __block_size);
......@@ -1282,6 +1728,7 @@ deque<_Tp, _Allocator>::push_back(const value_type& __v)
12821728 if (__back_spare() == 0)
12831729 __add_back_capacity();
12841730 // __back_spare() >= 1
1731 __annotate_increase_back(1);
12851732 __alloc_traits::construct(__a, _VSTD::addressof(*end()), __v);
12861733 ++__size();
12871734}
......@@ -1294,6 +1741,7 @@ deque<_Tp, _Allocator>::push_front(const value_type& __v)
12941741 if (__front_spare() == 0)
12951742 __add_front_capacity();
12961743 // __front_spare() >= 1
1744 __annotate_increase_front(1);
12971745 __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v);
12981746 --__start_;
12991747 ++__size();
......@@ -1308,13 +1756,14 @@ deque<_Tp, _Allocator>::push_back(value_type&& __v)
13081756 if (__back_spare() == 0)
13091757 __add_back_capacity();
13101758 // __back_spare() >= 1
1759 __annotate_increase_back(1);
13111760 __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::move(__v));
13121761 ++__size();
13131762}
13141763
13151764template <class _Tp, class _Allocator>
13161765template <class... _Args>
1317#if _LIBCPP_STD_VER > 14
1766#if _LIBCPP_STD_VER >= 17
13181767typename deque<_Tp, _Allocator>::reference
13191768#else
13201769void
......@@ -1325,10 +1774,11 @@ deque<_Tp, _Allocator>::emplace_back(_Args&&... __args)
13251774 if (__back_spare() == 0)
13261775 __add_back_capacity();
13271776 // __back_spare() >= 1
1777 __annotate_increase_back(1);
13281778 __alloc_traits::construct(__a, _VSTD::addressof(*end()),
13291779 _VSTD::forward<_Args>(__args)...);
13301780 ++__size();
1331#if _LIBCPP_STD_VER > 14
1781#if _LIBCPP_STD_VER >= 17
13321782 return *--end();
13331783#endif
13341784}
......@@ -1341,6 +1791,7 @@ deque<_Tp, _Allocator>::push_front(value_type&& __v)
13411791 if (__front_spare() == 0)
13421792 __add_front_capacity();
13431793 // __front_spare() >= 1
1794 __annotate_increase_front(1);
13441795 __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v));
13451796 --__start_;
13461797 ++__size();
......@@ -1349,7 +1800,7 @@ deque<_Tp, _Allocator>::push_front(value_type&& __v)
13491800
13501801template <class _Tp, class _Allocator>
13511802template <class... _Args>
1352#if _LIBCPP_STD_VER > 14
1803#if _LIBCPP_STD_VER >= 17
13531804typename deque<_Tp, _Allocator>::reference
13541805#else
13551806void
......@@ -1360,10 +1811,11 @@ deque<_Tp, _Allocator>::emplace_front(_Args&&... __args)
13601811 if (__front_spare() == 0)
13611812 __add_front_capacity();
13621813 // __front_spare() >= 1
1814 __annotate_increase_front(1);
13631815 __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...);
13641816 --__start_;
13651817 ++__size();
1366#if _LIBCPP_STD_VER > 14
1818#if _LIBCPP_STD_VER >= 17
13671819 return *begin();
13681820#endif
13691821}
......@@ -1380,6 +1832,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
13801832 if (__front_spare() == 0)
13811833 __add_front_capacity();
13821834 // __front_spare() >= 1
1835 __annotate_increase_front(1);
13831836 if (__pos == 0)
13841837 {
13851838 __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v));
......@@ -1403,6 +1856,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
14031856 if (__back_spare() == 0)
14041857 __add_back_capacity();
14051858 // __back_capacity >= 1
1859 __annotate_increase_back(1);
14061860 size_type __de = size() - __pos;
14071861 if (__de == 0)
14081862 {
......@@ -1436,6 +1890,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
14361890 if (__front_spare() == 0)
14371891 __add_front_capacity();
14381892 // __front_spare() >= 1
1893 __annotate_increase_front(1);
14391894 if (__pos == 0)
14401895 {
14411896 __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...);
......@@ -1460,6 +1915,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
14601915 if (__back_spare() == 0)
14611916 __add_back_capacity();
14621917 // __back_capacity >= 1
1918 __annotate_increase_back(1);
14631919 size_type __de = size() - __pos;
14641920 if (__de == 0)
14651921 {
......@@ -1496,6 +1952,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
14961952 if (__front_spare() == 0)
14971953 __add_front_capacity();
14981954 // __front_spare() >= 1
1955 __annotate_increase_front(1);
14991956 if (__pos == 0)
15001957 {
15011958 __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v);
......@@ -1522,6 +1979,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
15221979 if (__back_spare() == 0)
15231980 __add_back_capacity();
15241981 // __back_capacity >= 1
1982 __annotate_increase_back(1);
15251983 size_type __de = size() - __pos;
15261984 if (__de == 0)
15271985 {
......@@ -1557,6 +2015,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_ty
15572015 if (__n > __front_spare())
15582016 __add_front_capacity(__n - __front_spare());
15592017 // __n <= __front_spare()
2018 __annotate_increase_front(__n);
15602019 iterator __old_begin = begin();
15612020 iterator __i = __old_begin;
15622021 if (__n > __pos)
......@@ -1581,6 +2040,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_ty
15812040 if (__n > __back_capacity)
15822041 __add_back_capacity(__n - __back_capacity);
15832042 // __n <= __back_capacity
2043 __annotate_increase_back(__n);
15842044 iterator __old_end = end();
15852045 iterator __i = __old_end;
15862046 size_type __de = size() - __pos;
......@@ -1607,10 +2067,18 @@ template <class _Tp, class _Allocator>
16072067template <class _InputIter>
16082068typename deque<_Tp, _Allocator>::iterator
16092069deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
1610 typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type*)
2070 typename enable_if<__has_exactly_input_iterator_category<_InputIter>::value>::type*)
16112071{
2072 return __insert_with_sentinel(__p, __f, __l);
2073}
2074
2075template <class _Tp, class _Allocator>
2076template <class _Iterator, class _Sentinel>
2077_LIBCPP_HIDE_FROM_ABI
2078typename deque<_Tp, _Allocator>::iterator
2079deque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) {
16122080 __split_buffer<value_type, allocator_type&> __buf(__alloc());
1613 __buf.__construct_at_end(__f, __l);
2081 __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l));
16142082 typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
16152083 return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
16162084}
......@@ -1619,11 +2087,18 @@ template <class _Tp, class _Allocator>
16192087template <class _ForwardIterator>
16202088typename deque<_Tp, _Allocator>::iterator
16212089deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
1622 typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type*)
2090 typename enable_if<__has_exactly_forward_iterator_category<_ForwardIterator>::value>::type*)
16232091{
1624 size_type __n = _VSTD::distance(__f, __l);
2092 return __insert_with_size(__p, __f, std::distance(__f, __l));
2093}
2094
2095template <class _Tp, class _Allocator>
2096template <class _Iterator>
2097_LIBCPP_HIDE_FROM_ABI
2098typename deque<_Tp, _Allocator>::iterator
2099deque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) {
16252100 __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc());
1626 __buf.__construct_at_end(__f, __l);
2101 __buf.__construct_at_end_with_size(__f, __n);
16272102 typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd;
16282103 return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end()));
16292104}
......@@ -1632,9 +2107,24 @@ template <class _Tp, class _Allocator>
16322107template <class _BiIter>
16332108typename deque<_Tp, _Allocator>::iterator
16342109deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
1635 typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type*)
2110 typename enable_if<__has_bidirectional_iterator_category<_BiIter>::value>::type*)
16362111{
1637 size_type __n = _VSTD::distance(__f, __l);
2112 return __insert_bidirectional(__p, __f, __l, std::distance(__f, __l));
2113}
2114
2115template <class _Tp, class _Allocator>
2116template <class _BiIter, class _Sentinel>
2117_LIBCPP_HIDE_FROM_ABI
2118typename deque<_Tp, _Allocator>::iterator
2119deque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel, size_type __n) {
2120 return __insert_bidirectional(__p, __f, std::next(__f, __n), __n);
2121}
2122
2123template <class _Tp, class _Allocator>
2124template <class _BiIter>
2125_LIBCPP_HIDE_FROM_ABI
2126typename deque<_Tp, _Allocator>::iterator
2127deque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n) {
16382128 size_type __pos = __p - begin();
16392129 size_type __to_end = size() - __pos;
16402130 allocator_type& __a = __alloc();
......@@ -1643,6 +2133,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
16432133 if (__n > __front_spare())
16442134 __add_front_capacity(__n - __front_spare());
16452135 // __n <= __front_spare()
2136 __annotate_increase_front(__n);
16462137 iterator __old_begin = begin();
16472138 iterator __i = __old_begin;
16482139 _BiIter __m = __f;
......@@ -1673,6 +2164,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
16732164 if (__n > __back_capacity)
16742165 __add_back_capacity(__n - __back_capacity);
16752166 // __n <= __back_capacity
2167 __annotate_increase_back(__n);
16762168 iterator __old_end = end();
16772169 iterator __i = __old_end;
16782170 _BiIter __m = __l;
......@@ -1701,8 +2193,15 @@ template <class _Tp, class _Allocator>
17012193template <class _InpIter>
17022194void
17032195deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
1704 typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type*)
2196 typename enable_if<__has_exactly_input_iterator_category<_InpIter>::value>::type*)
17052197{
2198 __append_with_sentinel(__f, __l);
2199}
2200
2201template <class _Tp, class _Allocator>
2202template <class _InputIterator, class _Sentinel>
2203_LIBCPP_HIDE_FROM_ABI
2204void deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) {
17062205 for (; __f != __l; ++__f)
17072206#ifdef _LIBCPP_CXX03_LANG
17082207 push_back(*__f);
......@@ -1715,14 +2214,22 @@ template <class _Tp, class _Allocator>
17152214template <class _ForIter>
17162215void
17172216deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l,
1718 typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type*)
2217 typename enable_if<__has_forward_iterator_category<_ForIter>::value>::type*)
17192218{
1720 size_type __n = _VSTD::distance(__f, __l);
2219 __append_with_size(__f, std::distance(__f, __l));
2220}
2221
2222template <class _Tp, class _Allocator>
2223template <class _InputIterator>
2224_LIBCPP_HIDE_FROM_ABI
2225void deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) {
17212226 allocator_type& __a = __alloc();
17222227 size_type __back_capacity = __back_spare();
17232228 if (__n > __back_capacity)
17242229 __add_back_capacity(__n - __back_capacity);
2230
17252231 // __n <= __back_capacity
2232 __annotate_increase_back(__n);
17262233 for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
17272234 _ConstructTransaction __tx(this, __br);
17282235 for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) {
......@@ -1740,6 +2247,7 @@ deque<_Tp, _Allocator>::__append(size_type __n)
17402247 if (__n > __back_capacity)
17412248 __add_back_capacity(__n - __back_capacity);
17422249 // __n <= __back_capacity
2250 __annotate_increase_back(__n);
17432251 for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
17442252 _ConstructTransaction __tx(this, __br);
17452253 for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
......@@ -1757,6 +2265,7 @@ deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)
17572265 if (__n > __back_capacity)
17582266 __add_back_capacity(__n - __back_capacity);
17592267 // __n <= __back_capacity
2268 __annotate_increase_back(__n);
17602269 for (__deque_block_range __br : __deque_range(end(), end() + __n)) {
17612270 _ConstructTransaction __tx(this, __br);
17622271 for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
......@@ -1824,6 +2333,7 @@ deque<_Tp, _Allocator>::__add_front_capacity()
18242333 __block_size / 2 :
18252334 __start_ + __block_size;
18262335 }
2336 __annotate_whole_block(0, __asan_poison);
18272337}
18282338
18292339// Create front capacity for __n elements.
......@@ -1859,6 +2369,7 @@ deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
18592369 if (__map_.__front_spare() == 0)
18602370 break;
18612371 __map_.push_front(__alloc_traits::allocate(__a, __block_size));
2372 __annotate_whole_block(0, __asan_poison);
18622373 }
18632374 for (; __nb > 0; --__nb, ++__back_capacity)
18642375 __map_.push_back(__alloc_traits::allocate(__a, __block_size));
......@@ -1869,6 +2380,7 @@ deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
18692380 pointer __pt = __map_.back();
18702381 __map_.pop_back();
18712382 __map_.push_front(__pt);
2383 __annotate_whole_block(0, __asan_poison);
18722384 }
18732385 }
18742386 // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
......@@ -1879,22 +2391,28 @@ deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
18792391 __buf(std::max<size_type>(2* __map_.capacity(),
18802392 __nb + __map_.size()),
18812393 0, __map_.__alloc());
1882#ifndef _LIBCPP_NO_EXCEPTIONS
2394#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
18832395 try
18842396 {
1885#endif // _LIBCPP_NO_EXCEPTIONS
1886 for (; __nb > 0; --__nb)
2397#endif // _LIBCPP_HAS_NO_EXCEPTIONS
2398 for (; __nb > 0; --__nb) {
18872399 __buf.push_back(__alloc_traits::allocate(__a, __block_size));
1888#ifndef _LIBCPP_NO_EXCEPTIONS
2400 // ASan: this is empty container, we have to poison whole block
2401 __annotate_poison_block(
2402 std::__to_address(__buf.back()),
2403 std::__to_address(__buf.back() + __block_size));
2404 }
2405#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
18892406 }
18902407 catch (...)
18912408 {
2409 __annotate_delete();
18922410 for (__map_pointer __i = __buf.begin();
18932411 __i != __buf.end(); ++__i)
18942412 __alloc_traits::deallocate(__a, *__i, __block_size);
18952413 throw;
18962414 }
1897#endif // _LIBCPP_NO_EXCEPTIONS
2415#endif // _LIBCPP_HAS_NO_EXCEPTIONS
18982416 for (; __back_capacity > 0; --__back_capacity)
18992417 {
19002418 __buf.push_back(__map_.back());
......@@ -1940,6 +2458,7 @@ deque<_Tp, _Allocator>::__add_back_capacity()
19402458 __map_.pop_front();
19412459 __map_.push_back(__pt);
19422460 }
2461 __annotate_whole_block(__map_.size() - 1, __asan_poison);
19432462 }
19442463 // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
19452464 else
......@@ -1963,6 +2482,7 @@ deque<_Tp, _Allocator>::__add_back_capacity()
19632482 _VSTD::swap(__map_.__begin_, __buf.__begin_);
19642483 _VSTD::swap(__map_.__end_, __buf.__end_);
19652484 _VSTD::swap(__map_.__end_cap(), __buf.__end_cap());
2485 __annotate_whole_block(__map_.size() - 1, __asan_poison);
19662486 }
19672487}
19682488
......@@ -1999,10 +2519,13 @@ deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
19992519 if (__map_.__back_spare() == 0)
20002520 break;
20012521 __map_.push_back(__alloc_traits::allocate(__a, __block_size));
2522 __annotate_whole_block(__map_.size() - 1, __asan_poison);
20022523 }
20032524 for (; __nb > 0; --__nb, ++__front_capacity, __start_ +=
2004 __block_size - (__map_.size() == 1))
2525 __block_size - (__map_.size() == 1)) {
20052526 __map_.push_front(__alloc_traits::allocate(__a, __block_size));
2527 __annotate_whole_block(0, __asan_poison);
2528 }
20062529 // Done allocating, reorder capacity
20072530 __start_ -= __block_size * __front_capacity;
20082531 for (; __front_capacity > 0; --__front_capacity)
......@@ -2021,22 +2544,28 @@ deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
20212544 __nb + __map_.size()),
20222545 __map_.size() - __front_capacity,
20232546 __map_.__alloc());
2024#ifndef _LIBCPP_NO_EXCEPTIONS
2547#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
20252548 try
20262549 {
2027#endif // _LIBCPP_NO_EXCEPTIONS
2028 for (; __nb > 0; --__nb)
2550#endif // _LIBCPP_HAS_NO_EXCEPTIONS
2551 for (; __nb > 0; --__nb) {
20292552 __buf.push_back(__alloc_traits::allocate(__a, __block_size));
2030#ifndef _LIBCPP_NO_EXCEPTIONS
2553 // ASan: this is an empty container, we have to poison the whole block
2554 __annotate_poison_block(
2555 std::__to_address(__buf.back()),
2556 std::__to_address(__buf.back() + __block_size));
2557 }
2558#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
20312559 }
20322560 catch (...)
20332561 {
2562 __annotate_delete();
20342563 for (__map_pointer __i = __buf.begin();
20352564 __i != __buf.end(); ++__i)
20362565 __alloc_traits::deallocate(__a, *__i, __block_size);
20372566 throw;
20382567 }
2039#endif // _LIBCPP_NO_EXCEPTIONS
2568#endif // _LIBCPP_HAS_NO_EXCEPTIONS
20402569 for (; __front_capacity > 0; --__front_capacity)
20412570 {
20422571 __buf.push_back(__map_.front());
......@@ -2057,12 +2586,15 @@ template <class _Tp, class _Allocator>
20572586void
20582587deque<_Tp, _Allocator>::pop_front()
20592588{
2589 size_type __old_sz = size();
2590 size_type __old_start = __start_;
20602591 allocator_type& __a = __alloc();
20612592 __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() +
20622593 __start_ / __block_size) +
20632594 __start_ % __block_size));
20642595 --__size();
20652596 ++__start_;
2597 __annotate_shrink_front(__old_sz, __old_start);
20662598 __maybe_remove_front_spare();
20672599}
20682600
......@@ -2070,13 +2602,16 @@ template <class _Tp, class _Allocator>
20702602void
20712603deque<_Tp, _Allocator>::pop_back()
20722604{
2073 _LIBCPP_ASSERT(!empty(), "deque::pop_back called on an empty deque");
2605 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque");
2606 size_type __old_sz = size();
2607 size_type __old_start = __start_;
20742608 allocator_type& __a = __alloc();
20752609 size_type __p = size() + __start_ - 1;
20762610 __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() +
20772611 __p / __block_size) +
20782612 __p % __block_size));
20792613 --__size();
2614 __annotate_shrink_back(__old_sz, __old_start);
20802615 __maybe_remove_back_spare();
20812616}
20822617
......@@ -2216,6 +2751,8 @@ template <class _Tp, class _Allocator>
22162751typename deque<_Tp, _Allocator>::iterator
22172752deque<_Tp, _Allocator>::erase(const_iterator __f)
22182753{
2754 size_type __old_sz = size();
2755 size_type __old_start = __start_;
22192756 iterator __b = begin();
22202757 difference_type __pos = __f - __b;
22212758 iterator __p = __b + __pos;
......@@ -2226,6 +2763,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f)
22262763 __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
22272764 --__size();
22282765 ++__start_;
2766 __annotate_shrink_front(__old_sz, __old_start);
22292767 __maybe_remove_front_spare();
22302768 }
22312769 else
......@@ -2233,6 +2771,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f)
22332771 iterator __i = _VSTD::move(_VSTD::next(__p), end(), __p);
22342772 __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
22352773 --__size();
2774 __annotate_shrink_back(__old_sz, __old_start);
22362775 __maybe_remove_back_spare();
22372776 }
22382777 return begin() + __pos;
......@@ -2242,6 +2781,8 @@ template <class _Tp, class _Allocator>
22422781typename deque<_Tp, _Allocator>::iterator
22432782deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
22442783{
2784 size_type __old_sz = size();
2785 size_type __old_start = __start_;
22452786 difference_type __n = __l - __f;
22462787 iterator __b = begin();
22472788 difference_type __pos = __f - __b;
......@@ -2256,6 +2797,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
22562797 __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
22572798 __size() -= __n;
22582799 __start_ += __n;
2800 __annotate_shrink_front(__old_sz, __old_start);
22592801 while (__maybe_remove_front_spare()) {
22602802 }
22612803 }
......@@ -2265,6 +2807,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
22652807 for (iterator __e = end(); __i != __e; ++__i)
22662808 __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
22672809 __size() -= __n;
2810 __annotate_shrink_back(__old_sz, __old_start);
22682811 while (__maybe_remove_back_spare()) {
22692812 }
22702813 }
......@@ -2276,6 +2819,8 @@ template <class _Tp, class _Allocator>
22762819void
22772820deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
22782821{
2822 size_type __old_sz = size();
2823 size_type __old_start = __start_;
22792824 iterator __e = end();
22802825 difference_type __n = __e - __f;
22812826 if (__n > 0)
......@@ -2286,6 +2831,7 @@ deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
22862831 for (iterator __p = __b + __pos; __p != __e; ++__p)
22872832 __alloc_traits::destroy(__a, _VSTD::addressof(*__p));
22882833 __size() -= __n;
2834 __annotate_shrink_back(__old_sz, __old_start);
22892835 while (__maybe_remove_back_spare()) {
22902836 }
22912837 }
......@@ -2313,6 +2859,7 @@ inline
23132859void
23142860deque<_Tp, _Allocator>::clear() _NOEXCEPT
23152861{
2862 __annotate_delete();
23162863 allocator_type& __a = __alloc();
23172864 for (iterator __i = begin(), __e = end(); __i != __e; ++__i)
23182865 __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
......@@ -2331,6 +2878,7 @@ deque<_Tp, _Allocator>::clear() _NOEXCEPT
23312878 __start_ = __block_size;
23322879 break;
23332880 }
2881 __annotate_new(0);
23342882}
23352883
23362884template <class _Tp, class _Allocator>
......@@ -2342,6 +2890,8 @@ operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
23422890 return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
23432891}
23442892
2893#if _LIBCPP_STD_VER <= 17
2894
23452895template <class _Tp, class _Allocator>
23462896inline _LIBCPP_HIDE_FROM_ABI
23472897bool
......@@ -2382,6 +2932,17 @@ operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
23822932 return !(__y < __x);
23832933}
23842934
2935#else // _LIBCPP_STD_VER <= 17
2936
2937template <class _Tp, class _Allocator>
2938_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp>
2939operator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {
2940 return std::lexicographical_compare_three_way(
2941 __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>);
2942}
2943
2944#endif // _LIBCPP_STD_VER <= 17
2945
23852946template <class _Tp, class _Allocator>
23862947inline _LIBCPP_HIDE_FROM_ABI
23872948void
......@@ -2391,7 +2952,7 @@ swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
23912952 __x.swap(__y);
23922953}
23932954
2394#if _LIBCPP_STD_VER > 17
2955#if _LIBCPP_STD_VER >= 20
23952956template <class _Tp, class _Allocator, class _Up>
23962957inline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type
23972958erase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
......@@ -2415,15 +2976,15 @@ template <>
24152976inline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true;
24162977#endif
24172978
2418#endif // _LIBCPP_STD_VER > 17
2979#endif // _LIBCPP_STD_VER >= 20
24192980
24202981_LIBCPP_END_NAMESPACE_STD
24212982
2422#if _LIBCPP_STD_VER > 14
2983#if _LIBCPP_STD_VER >= 17
24232984_LIBCPP_BEGIN_NAMESPACE_STD
24242985namespace pmr {
24252986template <class _ValueT>
2426using deque = std::deque<_ValueT, polymorphic_allocator<_ValueT>>;
2987using deque _LIBCPP_AVAILABILITY_PMR = std::deque<_ValueT, polymorphic_allocator<_ValueT>>;
24272988} // namespace pmr
24282989_LIBCPP_END_NAMESPACE_STD
24292990#endif
......@@ -2434,9 +2995,11 @@ _LIBCPP_POP_MACROS
24342995# include <algorithm>
24352996# include <atomic>
24362997# include <concepts>
2998# include <cstdlib>
24372999# include <functional>
24383000# include <iosfwd>
24393001# include <iterator>
3002# include <type_traits>
24403003# include <typeinfo>
24413004#endif
24423005
lib/libcxx/include/exception+6-293
......@@ -77,307 +77,20 @@ template <class E> void rethrow_if_nested(const E& e);
7777*/
7878
7979#include <__assert> // all public C++ headers provide the assertion handler
80#include <__availability>
8180#include <__config>
82#include <__memory/addressof.h>
83#include <__type_traits/decay.h>
84#include <__type_traits/is_base_of.h>
85#include <__type_traits/is_class.h>
86#include <__type_traits/is_convertible.h>
87#include <__type_traits/is_copy_constructible.h>
88#include <__type_traits/is_final.h>
89#include <__type_traits/is_polymorphic.h>
90#include <cstddef>
91#include <cstdlib>
81#include <__exception/exception.h>
82#include <__exception/exception_ptr.h>
83#include <__exception/nested_exception.h>
84#include <__exception/operations.h>
85#include <__exception/terminate.h>
9286#include <version>
9387
94// <vcruntime_exception.h> defines its own std::exception and std::bad_exception types,
95// which we use in order to be ABI-compatible with other STLs on Windows.
96#if defined(_LIBCPP_ABI_VCRUNTIME)
97# include <vcruntime_exception.h>
98#endif
99
10088#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
10189# pragma GCC system_header
10290#endif
10391
104namespace std // purposefully not using versioning namespace
105{
106
107#if defined(_LIBCPP_ABI_VCRUNTIME) && (!defined(_HAS_EXCEPTIONS) || _HAS_EXCEPTIONS != 0)
108// The std::exception class was already included above, but we're explicit about this condition here for clarity.
109
110#elif defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0
111// However, <vcruntime_exception.h> does not define std::exception and std::bad_exception
112// when _HAS_EXCEPTIONS == 0.
113//
114// Since libc++ still wants to provide the std::exception hierarchy even when _HAS_EXCEPTIONS == 0
115// (after all those are simply types like any other), we define an ABI-compatible version
116// of the VCRuntime std::exception and std::bad_exception types in that mode.
117
118struct __std_exception_data {
119 char const* _What;
120 bool _DoFree;
121};
122
123class exception { // base of all library exceptions
124public:
125 exception() _NOEXCEPT : __data_() {}
126
127 explicit exception(char const* __message) _NOEXCEPT : __data_() {
128 __data_._What = __message;
129 __data_._DoFree = true;
130 }
131
132 exception(exception const&) _NOEXCEPT {}
133
134 exception& operator=(exception const&) _NOEXCEPT { return *this; }
135
136 virtual ~exception() _NOEXCEPT {}
137
138 virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; }
139
140private:
141 __std_exception_data __data_;
142};
143
144class bad_exception : public exception {
145public:
146 bad_exception() _NOEXCEPT : exception("bad exception") {}
147};
148
149#else // !defined(_LIBCPP_ABI_VCRUNTIME)
150// On all other platforms, we define our own std::exception and std::bad_exception types
151// regardless of whether exceptions are turned on as a language feature.
152
153class _LIBCPP_EXCEPTION_ABI exception {
154public:
155 _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {}
156 _LIBCPP_INLINE_VISIBILITY exception(const exception&) _NOEXCEPT = default;
157
158 virtual ~exception() _NOEXCEPT;
159 virtual const char* what() const _NOEXCEPT;
160};
161
162class _LIBCPP_EXCEPTION_ABI bad_exception : public exception {
163public:
164 _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {}
165 ~bad_exception() _NOEXCEPT override;
166 const char* what() const _NOEXCEPT override;
167};
168#endif // !_LIBCPP_ABI_VCRUNTIME
169
170#if _LIBCPP_STD_VER <= 14 \
171 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) \
172 || defined(_LIBCPP_BUILDING_LIBRARY)
173typedef void (*unexpected_handler)();
174_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
175_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT;
176_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected();
177#endif
178
179typedef void (*terminate_handler)();
180_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
181_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT;
182_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT;
183
184_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT;
185_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_exceptions() _NOEXCEPT;
186
187class _LIBCPP_TYPE_VIS exception_ptr;
188
189_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
190_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
191
192#ifndef _LIBCPP_ABI_MICROSOFT
193
194class _LIBCPP_TYPE_VIS exception_ptr
195{
196 void* __ptr_;
197public:
198 _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {}
199 _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
200
201 exception_ptr(const exception_ptr&) _NOEXCEPT;
202 exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
203 ~exception_ptr() _NOEXCEPT;
204
205 _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT
206 {return __ptr_ != nullptr;}
207
208 friend _LIBCPP_INLINE_VISIBILITY
209 bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
210 {return __x.__ptr_ == __y.__ptr_;}
211
212 friend _LIBCPP_INLINE_VISIBILITY
213 bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
214 {return !(__x == __y);}
215
216 friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
217 friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
218};
219
220template<class _Ep>
221_LIBCPP_INLINE_VISIBILITY exception_ptr
222make_exception_ptr(_Ep __e) _NOEXCEPT
223{
224#ifndef _LIBCPP_NO_EXCEPTIONS
225 try
226 {
227 throw __e;
228 }
229 catch (...)
230 {
231 return current_exception();
232 }
233#else
234 ((void)__e);
235 _VSTD::abort();
236#endif
237}
238
239#else // _LIBCPP_ABI_MICROSOFT
240
241class _LIBCPP_TYPE_VIS exception_ptr
242{
243_LIBCPP_DIAGNOSTIC_PUSH
244_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field")
245 void* __ptr1_;
246 void* __ptr2_;
247_LIBCPP_DIAGNOSTIC_POP
248public:
249 exception_ptr() _NOEXCEPT;
250 exception_ptr(nullptr_t) _NOEXCEPT;
251 exception_ptr(const exception_ptr& __other) _NOEXCEPT;
252 exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT;
253 exception_ptr& operator=(nullptr_t) _NOEXCEPT;
254 ~exception_ptr() _NOEXCEPT;
255 explicit operator bool() const _NOEXCEPT;
256};
257
258_LIBCPP_FUNC_VIS
259bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT;
260
261inline _LIBCPP_INLINE_VISIBILITY
262bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
263 {return !(__x == __y);}
264
265_LIBCPP_FUNC_VIS void swap(exception_ptr&, exception_ptr&) _NOEXCEPT;
266
267_LIBCPP_FUNC_VIS exception_ptr __copy_exception_ptr(void *__except, const void* __ptr);
268_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
269_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
270
271// This is a built-in template function which automagically extracts the required
272// information.
273template <class _E> void *__GetExceptionInfo(_E);
274
275template<class _Ep>
276_LIBCPP_INLINE_VISIBILITY exception_ptr
277make_exception_ptr(_Ep __e) _NOEXCEPT
278{
279 return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e));
280}
281
282#endif // _LIBCPP_ABI_MICROSOFT
283// nested_exception
284
285class _LIBCPP_EXCEPTION_ABI nested_exception
286{
287 exception_ptr __ptr_;
288public:
289 nested_exception() _NOEXCEPT;
290// nested_exception(const nested_exception&) noexcept = default;
291// nested_exception& operator=(const nested_exception&) noexcept = default;
292 virtual ~nested_exception() _NOEXCEPT;
293
294 // access functions
295 _LIBCPP_NORETURN void rethrow_nested() const;
296 _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;}
297};
298
299template <class _Tp>
300struct __nested
301 : public _Tp,
302 public nested_exception
303{
304 _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {}
305};
306
307#ifndef _LIBCPP_NO_EXCEPTIONS
308template <class _Tp, class _Up, bool>
309struct __throw_with_nested;
310
311template <class _Tp, class _Up>
312struct __throw_with_nested<_Tp, _Up, true> {
313 _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void
314 __do_throw(_Tp&& __t)
315 {
316 throw __nested<_Up>(static_cast<_Tp&&>(__t));
317 }
318};
319
320template <class _Tp, class _Up>
321struct __throw_with_nested<_Tp, _Up, false> {
322 _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void
323#ifndef _LIBCPP_CXX03_LANG
324 __do_throw(_Tp&& __t)
325#else
326 __do_throw (_Tp& __t)
327#endif // _LIBCPP_CXX03_LANG
328 {
329 throw static_cast<_Tp&&>(__t);
330 }
331};
332#endif
333
334template <class _Tp>
335_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
336void
337throw_with_nested(_Tp&& __t)
338{
339#ifndef _LIBCPP_NO_EXCEPTIONS
340 typedef typename decay<_Tp>::type _Up;
341 static_assert( is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible");
342 __throw_with_nested<_Tp, _Up,
343 is_class<_Up>::value &&
344 !is_base_of<nested_exception, _Up>::value &&
345 !__libcpp_is_final<_Up>::value>::
346 __do_throw(static_cast<_Tp&&>(__t));
347#else
348 ((void)__t);
349 // FIXME: Make this abort
350#endif
351}
352
353template <class _From, class _To>
354struct __can_dynamic_cast : _BoolConstant<
355 is_polymorphic<_From>::value &&
356 (!is_base_of<_To, _From>::value ||
357 is_convertible<const _From*, const _To*>::value)> {};
358
359template <class _Ep>
360inline _LIBCPP_INLINE_VISIBILITY
361void
362rethrow_if_nested(const _Ep& __e,
363 __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value>* = 0)
364{
365 const nested_exception* __nep = dynamic_cast<const nested_exception*>(_VSTD::addressof(__e));
366 if (__nep)
367 __nep->rethrow_nested();
368}
369
370template <class _Ep>
371inline _LIBCPP_INLINE_VISIBILITY
372void
373rethrow_if_nested(const _Ep&,
374 __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value>* = 0)
375{
376}
377
378} // namespace std
379
38092#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
93# include <cstdlib>
38194# include <type_traits>
38295#endif
38396
lib/libcxx/include/execution+125-4
......@@ -10,16 +10,137 @@
1010#ifndef _LIBCPP_EXECUTION
1111#define _LIBCPP_EXECUTION
1212
13/*
14namespace std::execution {
15 struct sequenced_policy;
16 struct parallel_policy;
17 struct parallel_unsequenced_policy;
18 struct unsequenced_policy; // since C++20
19
20 inline constexpr sequenced_policy seq = implementation-defined;
21 inline constexpr parallel_policy par = implementation-defined;
22 inline constexpr parallel_unsequenced_policy par_unseq = implementation-defined;
23 inline constexpr unsequenced_policy unseq = implementation-defined; // since C++20
24}
25
26namespace std {
27 template <class T>
28 struct is_execution_policy;
29
30 template <class T>
31 inline constexpr bool is_execution_policy_v;
32}
33*/
34
1335#include <__assert> // all public C++ headers provide the assertion handler
1436#include <__config>
37#include <__type_traits/is_execution_policy.h>
38#include <__type_traits/is_same.h>
39#include <__type_traits/remove_cvref.h>
1540#include <version>
1641
17#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
18# include <__pstl_execution>
19#endif
20
2142#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2243# pragma GCC system_header
2344#endif
2445
46#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
47
48_LIBCPP_BEGIN_NAMESPACE_STD
49
50namespace execution {
51struct sequenced_policy {
52 _LIBCPP_HIDE_FROM_ABI constexpr explicit sequenced_policy(__disable_user_instantiations_tag) {}
53 sequenced_policy(const sequenced_policy&) = delete;
54 sequenced_policy& operator=(const sequenced_policy&) = delete;
55};
56
57inline constexpr sequenced_policy seq{__disable_user_instantiations_tag{}};
58
59struct parallel_policy {
60 _LIBCPP_HIDE_FROM_ABI constexpr explicit parallel_policy(__disable_user_instantiations_tag) {}
61 parallel_policy(const parallel_policy&) = delete;
62 parallel_policy& operator=(const parallel_policy&) = delete;
63};
64
65inline constexpr parallel_policy par{__disable_user_instantiations_tag{}};
66
67struct parallel_unsequenced_policy {
68 _LIBCPP_HIDE_FROM_ABI constexpr explicit parallel_unsequenced_policy(__disable_user_instantiations_tag) {}
69 parallel_unsequenced_policy(const parallel_unsequenced_policy&) = delete;
70 parallel_unsequenced_policy& operator=(const parallel_unsequenced_policy&) = delete;
71};
72
73inline constexpr parallel_unsequenced_policy par_unseq{__disable_user_instantiations_tag{}};
74
75struct __unsequenced_policy {
76 _LIBCPP_HIDE_FROM_ABI constexpr explicit __unsequenced_policy(__disable_user_instantiations_tag) {}
77 __unsequenced_policy(const __unsequenced_policy&) = delete;
78 __unsequenced_policy& operator=(const __unsequenced_policy&) = delete;
79};
80
81constexpr __unsequenced_policy __unseq{__disable_user_instantiations_tag{}};
82
83# if _LIBCPP_STD_VER >= 20
84
85struct unsequenced_policy {
86 _LIBCPP_HIDE_FROM_ABI constexpr explicit unsequenced_policy(__disable_user_instantiations_tag) {}
87 unsequenced_policy(const unsequenced_policy&) = delete;
88 unsequenced_policy& operator=(const unsequenced_policy&) = delete;
89};
90
91inline constexpr unsequenced_policy unseq{__disable_user_instantiations_tag{}};
92
93# endif // _LIBCPP_STD_VER >= 20
94
95} // namespace execution
96
97template <>
98inline constexpr bool is_execution_policy_v<execution::sequenced_policy> = true;
99
100template <>
101inline constexpr bool is_execution_policy_v<execution::parallel_policy> = true;
102
103template <>
104inline constexpr bool is_execution_policy_v<execution::parallel_unsequenced_policy> = true;
105
106template <>
107inline constexpr bool is_execution_policy_v<execution::__unsequenced_policy> = true;
108
109template <>
110inline constexpr bool __is_parallel_execution_policy_impl<execution::parallel_policy> = true;
111
112template <>
113inline constexpr bool __is_parallel_execution_policy_impl<execution::parallel_unsequenced_policy> = true;
114
115template <>
116inline constexpr bool __is_unsequenced_execution_policy_impl<execution::__unsequenced_policy> = true;
117
118template <>
119inline constexpr bool __is_unsequenced_execution_policy_impl<execution::parallel_unsequenced_policy> = true;
120
121# if _LIBCPP_STD_VER >= 20
122template <>
123inline constexpr bool is_execution_policy_v<execution::unsequenced_policy> = true;
124
125template <>
126inline constexpr bool __is_unsequenced_execution_policy_impl<execution::unsequenced_policy> = true;
127
128# endif
129
130template <class _Tp>
131struct is_execution_policy : bool_constant<is_execution_policy_v<_Tp>> {};
132
133template <class _ExecutionPolicy>
134_LIBCPP_HIDE_FROM_ABI auto __remove_parallel_policy(const _ExecutionPolicy&) {
135 if constexpr (is_same_v<_ExecutionPolicy, execution::parallel_policy>) {
136 return execution::sequenced_policy(execution::__disable_user_instantiations_tag{});
137 } else if constexpr (is_same_v<_ExecutionPolicy, execution::parallel_unsequenced_policy>) {
138 return execution::__unsequenced_policy{execution::__disable_user_instantiations_tag{}};
139 }
140}
141
142_LIBCPP_END_NAMESPACE_STD
143
144#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
145
25146#endif // _LIBCPP_EXECUTION
lib/libcxx/include/experimental/__config-12
......@@ -32,18 +32,6 @@
3232#define _LIBCPP_END_NAMESPACE_LFTS_PMR _LIBCPP_END_NAMESPACE_LFTS }
3333#define _VSTD_LFTS_PMR _VSTD_LFTS::pmr
3434
35#if !defined(__cpp_coroutines) || __cpp_coroutines < 201703L
36#define _LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES
37#endif
38
39#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_COROUTINES \
40 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace coroutines_v1 {
41
42#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_COROUTINES \
43 } _LIBCPP_END_NAMESPACE_EXPERIMENTAL
44
45#define _VSTD_CORO _VSTD_EXPERIMENTAL::coroutines_v1
46
4735#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD \
4836 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace parallelism_v2 {
4937
lib/libcxx/include/experimental/__memory+5-2
......@@ -12,9 +12,12 @@
1212
1313#include <__memory/allocator_arg_t.h>
1414#include <__memory/uses_allocator.h>
15#include <__type_traits/conditional.h>
16#include <__type_traits/is_constructible.h>
17#include <__type_traits/is_convertible.h>
18#include <__type_traits/is_same.h>
1519#include <experimental/__config>
1620#include <experimental/utility> // for erased_type
17#include <type_traits>
1821
1922#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2023# pragma GCC system_header
......@@ -90,7 +93,7 @@ template <class _Tp, class _Allocator, class... _Args>
9093inline _LIBCPP_INLINE_VISIBILITY
9194void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
9295{
93 new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
96 new (__storage) _Tp (allocator_arg_t(), __a, _VSTD::forward<_Args>(__args)...);
9497}
9598
9699// FIXME: This should have a version which takes a non-const alloc.
lib/libcxx/include/experimental/algorithm deleted-53
......@@ -1,53 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_EXPERIMENTAL_ALGORITHM
11#define _LIBCPP_EXPERIMENTAL_ALGORITHM
12
13/*
14 experimental/algorithm synopsis
15
16#include <algorithm>
17
18namespace std {
19namespace experimental {
20inline namespace fundamentals_v1 {
21
22template <class ForwardIterator, class Searcher>
23ForwardIterator search(ForwardIterator first, ForwardIterator last,
24 const Searcher &searcher);
25
26// sample removed because it's now part of C++17
27
28} // namespace fundamentals_v1
29} // namespace experimental
30} // namespace std
31
32*/
33
34#include <__assert> // all public C++ headers provide the assertion handler
35#include <__debug>
36#include <algorithm>
37#include <experimental/__config>
38#include <type_traits>
39
40#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
41# pragma GCC system_header
42#endif
43
44_LIBCPP_BEGIN_NAMESPACE_LFTS
45
46template <class _ForwardIterator, class _Searcher>
47_LIBCPP_INLINE_VISIBILITY
48_ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s)
49{ return __s(__f, __l).first; }
50
51_LIBCPP_END_NAMESPACE_LFTS
52
53#endif /* _LIBCPP_EXPERIMENTAL_ALGORITHM */
lib/libcxx/include/experimental/coroutine deleted-344
......@@ -1,344 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_EXPERIMENTAL_COROUTINE
11#define _LIBCPP_EXPERIMENTAL_COROUTINE
12
13/**
14 experimental/coroutine synopsis
15
16// C++next
17
18namespace std {
19namespace experimental {
20inline namespace coroutines_v1 {
21
22 // 18.11.1 coroutine traits
23template <typename R, typename... ArgTypes>
24class coroutine_traits;
25// 18.11.2 coroutine handle
26template <typename Promise = void>
27class coroutine_handle;
28// 18.11.2.7 comparison operators:
29bool operator==(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
30bool operator!=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
31bool operator<(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
32bool operator<=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
33bool operator>=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
34bool operator>(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
35// 18.11.3 trivial awaitables
36struct suspend_never;
37struct suspend_always;
38// 18.11.2.8 hash support:
39template <class T> struct hash;
40template <class P> struct hash<coroutine_handle<P>>;
41
42} // namespace coroutines_v1
43} // namespace experimental
44} // namespace std
45
46 */
47
48#include <__assert> // all public C++ headers provide the assertion handler
49#include <__functional/hash.h>
50#include <__functional/operations.h>
51#include <cstddef>
52#include <experimental/__config>
53#include <new>
54#include <type_traits>
55
56#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
57# include <atomic>
58# include <climits>
59# include <cmath>
60# include <compare>
61# include <concepts>
62# include <ctime>
63# include <initializer_list>
64# include <iosfwd>
65# include <iterator>
66# include <memory>
67# include <ratio>
68# include <stdexcept>
69# include <tuple>
70# include <typeinfo>
71# include <utility>
72# include <variant>
73#endif
74
75#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
76# pragma GCC system_header
77#endif
78
79#ifndef _LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES
80
81_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_COROUTINES
82
83template <class _Tp, class = void>
84struct __coroutine_traits_sfinae {};
85
86template <class _Tp>
87struct __coroutine_traits_sfinae<_Tp, __void_t<typename _Tp::promise_type> >
88{
89 using promise_type = typename _Tp::promise_type;
90};
91
92template <typename _Ret, typename... _Args>
93struct coroutine_traits
94 : public __coroutine_traits_sfinae<_Ret>
95{
96};
97
98template <typename _Promise = void>
99class _LIBCPP_TEMPLATE_VIS coroutine_handle;
100
101template <>
102class _LIBCPP_TEMPLATE_VIS coroutine_handle<void> {
103public:
104 _LIBCPP_INLINE_VISIBILITY
105 _LIBCPP_CONSTEXPR coroutine_handle() _NOEXCEPT : __handle_(nullptr) {}
106
107 _LIBCPP_INLINE_VISIBILITY
108 _LIBCPP_CONSTEXPR coroutine_handle(nullptr_t) _NOEXCEPT : __handle_(nullptr) {}
109
110 _LIBCPP_INLINE_VISIBILITY
111 coroutine_handle& operator=(nullptr_t) _NOEXCEPT {
112 __handle_ = nullptr;
113 return *this;
114 }
115
116 _LIBCPP_INLINE_VISIBILITY
117 _LIBCPP_CONSTEXPR void* address() const _NOEXCEPT { return __handle_; }
118
119 _LIBCPP_INLINE_VISIBILITY
120 _LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return __handle_; }
121
122 _LIBCPP_INLINE_VISIBILITY
123 void operator()() { resume(); }
124
125 _LIBCPP_INLINE_VISIBILITY
126 void resume() {
127 _LIBCPP_ASSERT(__is_suspended(),
128 "resume() can only be called on suspended coroutines");
129 _LIBCPP_ASSERT(!done(),
130 "resume() has undefined behavior when the coroutine is done");
131 __builtin_coro_resume(__handle_);
132 }
133
134 _LIBCPP_INLINE_VISIBILITY
135 void destroy() {
136 _LIBCPP_ASSERT(__is_suspended(),
137 "destroy() can only be called on suspended coroutines");
138 __builtin_coro_destroy(__handle_);
139 }
140
141 _LIBCPP_INLINE_VISIBILITY
142 bool done() const {
143 _LIBCPP_ASSERT(__is_suspended(),
144 "done() can only be called on suspended coroutines");
145 return __builtin_coro_done(__handle_);
146 }
147
148public:
149 _LIBCPP_INLINE_VISIBILITY
150 static coroutine_handle from_address(void* __addr) _NOEXCEPT {
151 coroutine_handle __tmp;
152 __tmp.__handle_ = __addr;
153 return __tmp;
154 }
155
156 // FIXME: Should from_address(nullptr) be allowed?
157 _LIBCPP_INLINE_VISIBILITY
158 static coroutine_handle from_address(nullptr_t) _NOEXCEPT {
159 return coroutine_handle(nullptr);
160 }
161
162 template <class _Tp, bool _CallIsValid = false>
163 static coroutine_handle from_address(_Tp*) {
164 static_assert(_CallIsValid,
165 "coroutine_handle<void>::from_address cannot be called with "
166 "non-void pointers");
167 }
168
169private:
170 bool __is_suspended() const _NOEXCEPT {
171 // FIXME actually implement a check for if the coro is suspended.
172 return __handle_;
173 }
174
175 template <class _PromiseT> friend class coroutine_handle;
176 void* __handle_;
177};
178
179// 18.11.2.7 comparison operators:
180inline _LIBCPP_INLINE_VISIBILITY
181bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
182 return __x.address() == __y.address();
183}
184inline _LIBCPP_INLINE_VISIBILITY
185bool operator!=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
186 return !(__x == __y);
187}
188inline _LIBCPP_INLINE_VISIBILITY
189bool operator<(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
190 return less<void*>()(__x.address(), __y.address());
191}
192inline _LIBCPP_INLINE_VISIBILITY
193bool operator>(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
194 return __y < __x;
195}
196inline _LIBCPP_INLINE_VISIBILITY
197bool operator<=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
198 return !(__x > __y);
199}
200inline _LIBCPP_INLINE_VISIBILITY
201bool operator>=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
202 return !(__x < __y);
203}
204
205template <typename _Promise>
206class _LIBCPP_TEMPLATE_VIS coroutine_handle : public coroutine_handle<> {
207 using _Base = coroutine_handle<>;
208public:
209#ifndef _LIBCPP_CXX03_LANG
210 // 18.11.2.1 construct/reset
211 using coroutine_handle<>::coroutine_handle;
212#else
213 _LIBCPP_INLINE_VISIBILITY coroutine_handle() _NOEXCEPT : _Base() {}
214 _LIBCPP_INLINE_VISIBILITY coroutine_handle(nullptr_t) _NOEXCEPT : _Base(nullptr) {}
215#endif
216 _LIBCPP_INLINE_VISIBILITY
217 coroutine_handle& operator=(nullptr_t) _NOEXCEPT {
218 _Base::operator=(nullptr);
219 return *this;
220 }
221
222 _LIBCPP_INLINE_VISIBILITY
223 _Promise& promise() const {
224 return *static_cast<_Promise*>(
225 __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false));
226 }
227
228public:
229 _LIBCPP_INLINE_VISIBILITY
230 static coroutine_handle from_address(void* __addr) _NOEXCEPT {
231 coroutine_handle __tmp;
232 __tmp.__handle_ = __addr;
233 return __tmp;
234 }
235
236 // NOTE: this overload isn't required by the standard but is needed so
237 // the deleted _Promise* overload doesn't make from_address(nullptr)
238 // ambiguous.
239 // FIXME: should from_address work with nullptr?
240 _LIBCPP_INLINE_VISIBILITY
241 static coroutine_handle from_address(nullptr_t) _NOEXCEPT {
242 return coroutine_handle(nullptr);
243 }
244
245 template <class _Tp, bool _CallIsValid = false>
246 static coroutine_handle from_address(_Tp*) {
247 static_assert(_CallIsValid,
248 "coroutine_handle<promise_type>::from_address cannot be called with "
249 "non-void pointers");
250 }
251
252 template <bool _CallIsValid = false>
253 static coroutine_handle from_address(_Promise*) {
254 static_assert(_CallIsValid,
255 "coroutine_handle<promise_type>::from_address cannot be used with "
256 "pointers to the coroutine's promise type; use 'from_promise' instead");
257 }
258
259 _LIBCPP_INLINE_VISIBILITY
260 static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT {
261 typedef __remove_cv_t<_Promise> _RawPromise;
262 coroutine_handle __tmp;
263 __tmp.__handle_ = __builtin_coro_promise(
264 _VSTD::addressof(const_cast<_RawPromise&>(__promise)),
265 _LIBCPP_ALIGNOF(_Promise), true);
266 return __tmp;
267 }
268};
269
270#if __has_builtin(__builtin_coro_noop)
271struct noop_coroutine_promise {};
272
273template <>
274class _LIBCPP_TEMPLATE_VIS coroutine_handle<noop_coroutine_promise>
275 : public coroutine_handle<> {
276 using _Base = coroutine_handle<>;
277 using _Promise = noop_coroutine_promise;
278public:
279
280 _LIBCPP_INLINE_VISIBILITY
281 _Promise& promise() const {
282 return *static_cast<_Promise*>(
283 __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false));
284 }
285
286 _LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return true; }
287 _LIBCPP_CONSTEXPR bool done() const _NOEXCEPT { return false; }
288
289 _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()() const _NOEXCEPT {}
290 _LIBCPP_CONSTEXPR_SINCE_CXX20 void resume() const _NOEXCEPT {}
291 _LIBCPP_CONSTEXPR_SINCE_CXX20 void destroy() const _NOEXCEPT {}
292
293private:
294 _LIBCPP_INLINE_VISIBILITY
295 friend coroutine_handle<noop_coroutine_promise> noop_coroutine() _NOEXCEPT;
296
297 _LIBCPP_INLINE_VISIBILITY coroutine_handle() _NOEXCEPT {
298 this->__handle_ = __builtin_coro_noop();
299 }
300};
301
302using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
303
304inline _LIBCPP_INLINE_VISIBILITY
305noop_coroutine_handle noop_coroutine() _NOEXCEPT {
306 return noop_coroutine_handle();
307}
308#endif // __has_builtin(__builtin_coro_noop)
309
310struct suspend_never {
311 _LIBCPP_INLINE_VISIBILITY
312 bool await_ready() const _NOEXCEPT { return true; }
313 _LIBCPP_INLINE_VISIBILITY
314 void await_suspend(coroutine_handle<>) const _NOEXCEPT {}
315 _LIBCPP_INLINE_VISIBILITY
316 void await_resume() const _NOEXCEPT {}
317};
318
319struct suspend_always {
320 _LIBCPP_INLINE_VISIBILITY
321 bool await_ready() const _NOEXCEPT { return false; }
322 _LIBCPP_INLINE_VISIBILITY
323 void await_suspend(coroutine_handle<>) const _NOEXCEPT {}
324 _LIBCPP_INLINE_VISIBILITY
325 void await_resume() const _NOEXCEPT {}
326};
327
328_LIBCPP_END_NAMESPACE_EXPERIMENTAL_COROUTINES
329
330_LIBCPP_BEGIN_NAMESPACE_STD
331
332template <class _Tp>
333struct hash<_VSTD_CORO::coroutine_handle<_Tp> > {
334 using __arg_type = _VSTD_CORO::coroutine_handle<_Tp>;
335 _LIBCPP_INLINE_VISIBILITY
336 size_t operator()(__arg_type const& __v) const _NOEXCEPT
337 {return hash<void*>()(__v.address());}
338};
339
340_LIBCPP_END_NAMESPACE_STD
341
342#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)
343
344#endif /* _LIBCPP_EXPERIMENTAL_COROUTINE */
lib/libcxx/include/experimental/functional deleted-436
......@@ -1,436 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_EXPERIMENTAL_FUNCTIONAL
11#define _LIBCPP_EXPERIMENTAL_FUNCTIONAL
12
13/*
14 experimental/functional synopsis
15
16#include <algorithm>
17
18namespace std {
19namespace experimental {
20inline namespace fundamentals_v1 {
21 // 4.3, Searchers
22 template<class ForwardIterator, class BinaryPredicate = equal_to<>>
23 class default_searcher;
24
25 template<class RandomAccessIterator,
26 class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
27 class BinaryPredicate = equal_to<>>
28 class boyer_moore_searcher;
29
30 template<class RandomAccessIterator,
31 class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
32 class BinaryPredicate = equal_to<>>
33 class boyer_moore_horspool_searcher;
34
35 template<class ForwardIterator, class BinaryPredicate = equal_to<>>
36 default_searcher<ForwardIterator, BinaryPredicate>
37 make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last,
38 BinaryPredicate pred = BinaryPredicate());
39
40 template<class RandomAccessIterator,
41 class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
42 class BinaryPredicate = equal_to<>>
43 boyer_moore_searcher<RandomAccessIterator, Hash, BinaryPredicate>
44 make_boyer_moore_searcher(
45 RandomAccessIterator pat_first, RandomAccessIterator pat_last,
46 Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
47
48 template<class RandomAccessIterator,
49 class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
50 class BinaryPredicate = equal_to<>>
51 boyer_moore_horspool_searcher<RandomAccessIterator, Hash, BinaryPredicate>
52 make_boyer_moore_horspool_searcher(
53 RandomAccessIterator pat_first, RandomAccessIterator pat_last,
54 Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
55
56 } // namespace fundamentals_v1
57 } // namespace experimental
58
59} // namespace std
60
61*/
62
63#include <__assert> // all public C++ headers provide the assertion handler
64#include <__debug>
65#include <__functional/identity.h>
66#include <__memory/uses_allocator.h>
67#include <array>
68#include <experimental/__config>
69#include <functional>
70#include <type_traits>
71#include <unordered_map>
72#include <vector>
73
74#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
75# pragma GCC system_header
76#endif
77
78_LIBCPP_PUSH_MACROS
79#include <__undef_macros>
80
81_LIBCPP_BEGIN_NAMESPACE_LFTS
82
83#ifdef _LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
84# define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER
85# define _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER
86# define _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER
87#else
88# define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_DEPRECATED_("std::experimental::default_searcher will be removed in LLVM 17. Use std::default_searcher instead")
89# define _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_DEPRECATED_("std::experimental::boyer_moore_searcher will be removed in LLVM 17. Use std::boyer_moore_searcher instead")
90# define _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_DEPRECATED_("std::experimental::boyer_moore_horspool_searcher will be removed in LLVM 17. Use std::boyer_moore_horspool_searcher instead")
91#endif
92
93#if _LIBCPP_STD_VER > 11
94// default searcher
95template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
96class _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_TEMPLATE_VIS default_searcher {
97public:
98 _LIBCPP_INLINE_VISIBILITY
99 default_searcher(_ForwardIterator __f, _ForwardIterator __l,
100 _BinaryPredicate __p = _BinaryPredicate())
101 : __first_(__f), __last_(__l), __pred_(__p) {}
102
103 template <typename _ForwardIterator2>
104 _LIBCPP_INLINE_VISIBILITY
105 pair<_ForwardIterator2, _ForwardIterator2>
106 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const
107 {
108 auto __proj = __identity();
109 return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj);
110 }
111
112private:
113 _ForwardIterator __first_;
114 _ForwardIterator __last_;
115 _BinaryPredicate __pred_;
116 };
117
118template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
119_LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_INLINE_VISIBILITY
120default_searcher<_ForwardIterator, _BinaryPredicate>
121make_default_searcher( _ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate ())
122{
123 return default_searcher<_ForwardIterator, _BinaryPredicate>(__f, __l, __p);
124}
125
126template<class _Key, class _Value, class _Hash, class _BinaryPredicate, bool /*useArray*/> class _BMSkipTable;
127
128// General case for BM data searching; use a map
129template<class _Key, typename _Value, class _Hash, class _BinaryPredicate>
130class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> {
131 typedef _Value value_type;
132 typedef _Key key_type;
133
134 const _Value __default_value_;
135 std::unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table_;
136
137public:
138 _LIBCPP_INLINE_VISIBILITY
139 _BMSkipTable(size_t __sz, _Value __default, _Hash __hf, _BinaryPredicate __pred)
140 : __default_value_(__default), __table_(__sz, __hf, __pred) {}
141
142 _LIBCPP_INLINE_VISIBILITY
143 void insert(const key_type &__key, value_type __val)
144 {
145 __table_ [__key] = __val; // Would skip_.insert (val) be better here?
146 }
147
148 _LIBCPP_INLINE_VISIBILITY
149 value_type operator [](const key_type & __key) const
150 {
151 auto __it = __table_.find (__key);
152 return __it == __table_.end() ? __default_value_ : __it->second;
153 }
154};
155
156
157// Special case small numeric values; use an array
158template<class _Key, typename _Value, class _Hash, class _BinaryPredicate>
159class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> {
160private:
161 typedef _Value value_type;
162 typedef _Key key_type;
163
164 typedef __make_unsigned_t<key_type> unsigned_key_type;
165 typedef std::array<value_type, 256> skip_map;
166 skip_map __table_;
167
168public:
169 _LIBCPP_INLINE_VISIBILITY
170 _BMSkipTable(size_t /*__sz*/, _Value __default, _Hash /*__hf*/, _BinaryPredicate /*__pred*/)
171 {
172 std::fill_n(__table_.begin(), __table_.size(), __default);
173 }
174
175 _LIBCPP_INLINE_VISIBILITY
176 void insert(key_type __key, value_type __val)
177 {
178 __table_[static_cast<unsigned_key_type>(__key)] = __val;
179 }
180
181 _LIBCPP_INLINE_VISIBILITY
182 value_type operator [](key_type __key) const
183 {
184 return __table_[static_cast<unsigned_key_type>(__key)];
185 }
186};
187
188
189template <class _RandomAccessIterator1,
190 class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
191 class _BinaryPredicate = equal_to<>>
192class _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_searcher {
193private:
194 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
195 typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type;
196 typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate,
197 is_integral<value_type>::value && // what about enums?
198 sizeof(value_type) == 1 &&
199 is_same<_Hash, hash<value_type>>::value &&
200 is_same<_BinaryPredicate, equal_to<>>::value
201 > skip_table_type;
202
203public:
204 boyer_moore_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l,
205 _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate())
206 : __first_(__f), __last_(__l), __pred_(__pred),
207 __pattern_length_(_VSTD::distance(__first_, __last_)),
208 __skip_{std::make_shared<skip_table_type>(__pattern_length_, -1, __hf, __pred_)},
209 __suffix_{std::make_shared<vector<difference_type>>(__pattern_length_ + 1)}
210 {
211 // build the skip table
212 for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i )
213 __skip_->insert(*__f, __i);
214
215 this->__build_suffix_table ( __first_, __last_, __pred_ );
216 }
217
218 template <typename _RandomAccessIterator2>
219 pair<_RandomAccessIterator2, _RandomAccessIterator2>
220 operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
221 {
222 static_assert(__is_same_uncvref<typename iterator_traits<_RandomAccessIterator1>::value_type,
223 typename iterator_traits<_RandomAccessIterator2>::value_type>::value,
224 "Corpus and Pattern iterators must point to the same type");
225
226 if (__f == __l ) return std::make_pair(__l, __l); // empty corpus
227 if (__first_ == __last_) return std::make_pair(__f, __f); // empty pattern
228
229 // If the pattern is larger than the corpus, we can't find it!
230 if ( __pattern_length_ > _VSTD::distance(__f, __l))
231 return std::make_pair(__l, __l);
232
233 // Do the search
234 return this->__search(__f, __l);
235 }
236
237private:
238 _RandomAccessIterator1 __first_;
239 _RandomAccessIterator1 __last_;
240 _BinaryPredicate __pred_;
241 difference_type __pattern_length_;
242 shared_ptr<skip_table_type> __skip_;
243 shared_ptr<vector<difference_type>> __suffix_;
244
245 template <typename _RandomAccessIterator2>
246 pair<_RandomAccessIterator2, _RandomAccessIterator2>
247 __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
248 {
249 _RandomAccessIterator2 __cur = __f;
250 const _RandomAccessIterator2 __last = __l - __pattern_length_;
251 const skip_table_type & __skip = *__skip_.get();
252 const vector<difference_type> & __suffix = *__suffix_.get();
253
254 while (__cur <= __last)
255 {
256
257 // Do we match right where we are?
258 difference_type __j = __pattern_length_;
259 while (__pred_(__first_ [__j-1], __cur [__j-1])) {
260 __j--;
261 // We matched - we're done!
262 if ( __j == 0 )
263 return std::make_pair(__cur, __cur + __pattern_length_);
264 }
265
266 // Since we didn't match, figure out how far to skip forward
267 difference_type __k = __skip[__cur [ __j - 1 ]];
268 difference_type __m = __j - __k - 1;
269 if (__k < __j && __m > __suffix[ __j ])
270 __cur += __m;
271 else
272 __cur += __suffix[ __j ];
273 }
274
275 return std::make_pair(__l, __l); // We didn't find anything
276 }
277
278
279 template<typename _Iterator, typename _Container>
280 void __compute_bm_prefix ( _Iterator __f, _Iterator __l, _BinaryPredicate __pred, _Container &__prefix )
281 {
282 const size_t __count = _VSTD::distance(__f, __l);
283
284 __prefix[0] = 0;
285 size_t __k = 0;
286 for ( size_t __i = 1; __i < __count; ++__i )
287 {
288 while ( __k > 0 && !__pred ( __f[__k], __f[__i] ))
289 __k = __prefix [ __k - 1 ];
290
291 if ( __pred ( __f[__k], __f[__i] ))
292 __k++;
293 __prefix [ __i ] = __k;
294 }
295 }
296
297 void __build_suffix_table(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l,
298 _BinaryPredicate __pred)
299 {
300 const size_t __count = _VSTD::distance(__f, __l);
301 vector<difference_type> & __suffix = *__suffix_.get();
302 if (__count > 0)
303 {
304 vector<difference_type> __scratch(__count);
305
306 __compute_bm_prefix(__f, __l, __pred, __scratch);
307 for ( size_t __i = 0; __i <= __count; __i++ )
308 __suffix[__i] = __count - __scratch[__count-1];
309
310 typedef reverse_iterator<_RandomAccessIterator1> _RevIter;
311 __compute_bm_prefix(_RevIter(__l), _RevIter(__f), __pred, __scratch);
312
313 for ( size_t __i = 0; __i < __count; __i++ )
314 {
315 const size_t __j = __count - __scratch[__i];
316 const difference_type __k = __i - __scratch[__i] + 1;
317
318 if (__suffix[__j] > __k)
319 __suffix[__j] = __k;
320 }
321 }
322 }
323
324};
325
326template<class _RandomAccessIterator,
327 class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>,
328 class _BinaryPredicate = equal_to<>>
329_LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_INLINE_VISIBILITY
330boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
331make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
332 _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
333{
334 return boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p);
335}
336
337// boyer-moore-horspool
338template <class _RandomAccessIterator1,
339 class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
340 class _BinaryPredicate = equal_to<>>
341class _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher {
342private:
343 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
344 typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type;
345 typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate,
346 is_integral<value_type>::value && // what about enums?
347 sizeof(value_type) == 1 &&
348 is_same<_Hash, hash<value_type>>::value &&
349 is_same<_BinaryPredicate, equal_to<>>::value
350 > skip_table_type;
351
352public:
353 boyer_moore_horspool_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l,
354 _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate())
355 : __first_(__f), __last_(__l), __pred_(__pred),
356 __pattern_length_(_VSTD::distance(__first_, __last_)),
357 __skip_{_VSTD::make_shared<skip_table_type>(__pattern_length_, __pattern_length_, __hf, __pred_)}
358 {
359 // build the skip table
360 if ( __f != __l )
361 {
362 __l = __l - 1;
363 for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i )
364 __skip_->insert(*__f, __pattern_length_ - 1 - __i);
365 }
366 }
367
368 template <typename _RandomAccessIterator2>
369 pair<_RandomAccessIterator2, _RandomAccessIterator2>
370 operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
371 {
372 static_assert(__is_same_uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type,
373 typename std::iterator_traits<_RandomAccessIterator2>::value_type>::value,
374 "Corpus and Pattern iterators must point to the same type");
375
376 if (__f == __l ) return std::make_pair(__l, __l); // empty corpus
377 if (__first_ == __last_) return std::make_pair(__f, __f); // empty pattern
378
379 // If the pattern is larger than the corpus, we can't find it!
380 if ( __pattern_length_ > _VSTD::distance(__f, __l))
381 return std::make_pair(__l, __l);
382
383 // Do the search
384 return this->__search(__f, __l);
385 }
386
387private:
388 _RandomAccessIterator1 __first_;
389 _RandomAccessIterator1 __last_;
390 _BinaryPredicate __pred_;
391 difference_type __pattern_length_;
392 shared_ptr<skip_table_type> __skip_;
393
394 template <typename _RandomAccessIterator2>
395 pair<_RandomAccessIterator2, _RandomAccessIterator2>
396 __search ( _RandomAccessIterator2 __f, _RandomAccessIterator2 __l ) const {
397 _RandomAccessIterator2 __cur = __f;
398 const _RandomAccessIterator2 __last = __l - __pattern_length_;
399 const skip_table_type & __skip = *__skip_.get();
400
401 while (__cur <= __last)
402 {
403 // Do we match right where we are?
404 difference_type __j = __pattern_length_;
405 while (__pred_(__first_[__j-1], __cur[__j-1]))
406 {
407 __j--;
408 // We matched - we're done!
409 if ( __j == 0 )
410 return std::make_pair(__cur, __cur + __pattern_length_);
411 }
412 __cur += __skip[__cur[__pattern_length_-1]];
413 }
414
415 return std::make_pair(__l, __l);
416 }
417};
418
419template<class _RandomAccessIterator,
420 class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>,
421 class _BinaryPredicate = equal_to<>>
422_LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_INLINE_VISIBILITY
423boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
424make_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
425 _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
426{
427 return boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p);
428}
429
430#endif // _LIBCPP_STD_VER > 11
431
432_LIBCPP_END_NAMESPACE_LFTS
433
434_LIBCPP_POP_MACROS
435
436#endif /* _LIBCPP_EXPERIMENTAL_FUNCTIONAL */
lib/libcxx/include/experimental/iterator+10-10
......@@ -65,7 +65,7 @@ namespace std {
6565# pragma GCC system_header
6666#endif
6767
68#if _LIBCPP_STD_VER > 11
68#if _LIBCPP_STD_VER >= 14
6969
7070_LIBCPP_BEGIN_NAMESPACE_LFTS
7171
......@@ -82,15 +82,15 @@ public:
8282 typedef void pointer;
8383 typedef void reference;
8484
85 ostream_joiner(ostream_type& __os, _Delim&& __d)
85 _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, _Delim&& __d)
8686 : __output_iter_(_VSTD::addressof(__os)), __delim_(_VSTD::move(__d)), __first_(true) {}
8787
88 ostream_joiner(ostream_type& __os, const _Delim& __d)
88 _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, const _Delim& __d)
8989 : __output_iter_(_VSTD::addressof(__os)), __delim_(__d), __first_(true) {}
9090
9191
9292 template<typename _Tp>
93 ostream_joiner& operator=(const _Tp& __v)
93 _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator=(const _Tp& __v)
9494 {
9595 if (!__first_)
9696 *__output_iter_ << __delim_;
......@@ -99,9 +99,9 @@ public:
9999 return *this;
100100 }
101101
102 ostream_joiner& operator*() _NOEXCEPT { return *this; }
103 ostream_joiner& operator++() _NOEXCEPT { return *this; }
104 ostream_joiner& operator++(int) _NOEXCEPT { return *this; }
102 _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator*() _NOEXCEPT { return *this; }
103 _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++() _NOEXCEPT { return *this; }
104 _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++(int) _NOEXCEPT { return *this; }
105105
106106private:
107107 ostream_type* __output_iter_;
......@@ -111,13 +111,13 @@ private:
111111
112112
113113template <class _CharT, class _Traits, class _Delim>
114_LIBCPP_HIDE_FROM_ABI ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>
114_LIBCPP_HIDE_FROM_ABI ostream_joiner<__decay_t<_Delim>, _CharT, _Traits>
115115make_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d)
116{ return ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); }
116{ return ostream_joiner<__decay_t<_Delim>, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); }
117117
118118_LIBCPP_END_NAMESPACE_LFTS
119119
120#endif // _LIBCPP_STD_VER > 11
120#endif // _LIBCPP_STD_VER >= 14
121121
122122#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
123123# include <type_traits>
lib/libcxx/include/experimental/memory_resource+21-20
......@@ -66,16 +66,15 @@ namespace pmr {
6666
6767#include <__assert> // all public C++ headers provide the assertion handler
6868#include <__memory/allocator_traits.h>
69#include <__type_traits/aligned_storage.h>
6970#include <__utility/move.h>
7071#include <cstddef>
71#include <cstdlib>
7272#include <experimental/__config>
7373#include <experimental/__memory>
7474#include <limits>
7575#include <new>
7676#include <stdexcept>
7777#include <tuple>
78#include <type_traits>
7978
8079#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
8180# pragma GCC system_header
......@@ -96,18 +95,18 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
9695inline _LIBCPP_INLINE_VISIBILITY
9796size_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT
9897{
99 _LIBCPP_ASSERT(__s + __a > __s, "aligned allocation size overflows");
98 _LIBCPP_ASSERT_UNCATEGORIZED(__s + __a > __s, "aligned allocation size overflows");
10099 return (__s + __a - 1) & ~(__a - 1);
101100}
102101
103102// 8.5, memory.resource
104class _LIBCPP_DEPCREATED_MEMORY_RESOURCE("memory_resource") _LIBCPP_TYPE_VIS memory_resource
103class _LIBCPP_DEPCREATED_MEMORY_RESOURCE("memory_resource") _LIBCPP_EXPORTED_FROM_ABI memory_resource
105104{
106105 static const size_t __max_align = _LIBCPP_ALIGNOF(max_align_t);
107106
108107// 8.5.2, memory.resource.public
109108public:
110 virtual ~memory_resource() = default;
109 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~memory_resource() = default;
111110
112111 _LIBCPP_INLINE_VISIBILITY
113112 void* allocate(size_t __bytes, size_t __align = __max_align)
......@@ -143,16 +142,16 @@ bool operator!=(memory_resource const & __lhs,
143142 return !(__lhs == __rhs);
144143}
145144
146_LIBCPP_DEPCREATED_MEMORY_RESOURCE("new_delete_resource()") _LIBCPP_FUNC_VIS
145_LIBCPP_DEPCREATED_MEMORY_RESOURCE("new_delete_resource()") _LIBCPP_EXPORTED_FROM_ABI
147146memory_resource * new_delete_resource() _NOEXCEPT;
148147
149_LIBCPP_DEPCREATED_MEMORY_RESOURCE("null_memory_resource()") _LIBCPP_FUNC_VIS
148_LIBCPP_DEPCREATED_MEMORY_RESOURCE("null_memory_resource()") _LIBCPP_EXPORTED_FROM_ABI
150149memory_resource * null_memory_resource() _NOEXCEPT;
151150
152_LIBCPP_DEPCREATED_MEMORY_RESOURCE("get_default_resource()") _LIBCPP_FUNC_VIS
151_LIBCPP_DEPCREATED_MEMORY_RESOURCE("get_default_resource()") _LIBCPP_EXPORTED_FROM_ABI
153152memory_resource * get_default_resource() _NOEXCEPT;
154153
155_LIBCPP_DEPCREATED_MEMORY_RESOURCE("set_default_resource()") _LIBCPP_FUNC_VIS
154_LIBCPP_DEPCREATED_MEMORY_RESOURCE("set_default_resource()") _LIBCPP_EXPORTED_FROM_ABI
156155memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT;
157156
158157// 8.6, memory.polymorphic.allocator.class
......@@ -175,7 +174,7 @@ public:
175174 : __res_(__r)
176175 {}
177176
178 polymorphic_allocator(polymorphic_allocator const &) = default;
177 _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(polymorphic_allocator const &) = default;
179178
180179 template <class _Tp>
181180 _LIBCPP_INLINE_VISIBILITY
......@@ -198,8 +197,8 @@ public:
198197
199198 _LIBCPP_INLINE_VISIBILITY
200199 void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT {
201 _LIBCPP_ASSERT(__n <= __max_size(),
202 "deallocate called for size which exceeds max_size()");
200 _LIBCPP_ASSERT_UNCATEGORIZED(__n <= __max_size(),
201 "deallocate called for size which exceeds max_size()");
203202 __res_->deallocate(__p, __n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType));
204203 }
205204
......@@ -363,9 +362,9 @@ class _LIBCPP_TEMPLATE_VIS __resource_adaptor_imp
363362public:
364363 typedef _CharAlloc allocator_type;
365364
366 __resource_adaptor_imp() = default;
367 __resource_adaptor_imp(__resource_adaptor_imp const &) = default;
368 __resource_adaptor_imp(__resource_adaptor_imp &&) = default;
365 _LIBCPP_HIDE_FROM_ABI __resource_adaptor_imp() = default;
366 _LIBCPP_HIDE_FROM_ABI __resource_adaptor_imp(__resource_adaptor_imp const &) = default;
367 _LIBCPP_HIDE_FROM_ABI __resource_adaptor_imp(__resource_adaptor_imp &&) = default;
369368
370369 // 8.7.2, memory.resource.adaptor.ctor
371370
......@@ -379,7 +378,7 @@ public:
379378 : __alloc_(_VSTD::move(__a))
380379 {}
381380
382 __resource_adaptor_imp &
381 _LIBCPP_HIDE_FROM_ABI __resource_adaptor_imp &
383382 operator=(__resource_adaptor_imp const &) = default;
384383
385384 _LIBCPP_INLINE_VISIBILITY
......@@ -388,7 +387,7 @@ public:
388387
389388// 8.7.3, memory.resource.adaptor.mem
390389private:
391 void * do_allocate(size_t __bytes, size_t) override
390 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void * do_allocate(size_t __bytes, size_t) override
392391 {
393392 if (__bytes > __max_size())
394393 __throw_bad_array_new_length();
......@@ -396,15 +395,15 @@ private:
396395 return __alloc_.allocate(__s);
397396 }
398397
399 void do_deallocate(void * __p, size_t __bytes, size_t) override
398 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void do_deallocate(void * __p, size_t __bytes, size_t) override
400399 {
401 _LIBCPP_ASSERT(__bytes <= __max_size(),
400 _LIBCPP_ASSERT_UNCATEGORIZED(__bytes <= __max_size(),
402401 "do_deallocate called for size which exceeds the maximum allocation size");
403402 size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign;
404403 __alloc_.deallocate((_ValueType*)__p, __s);
405404 }
406405
407 bool do_is_equal(memory_resource const & __other) const _NOEXCEPT override {
406 _LIBCPP_HIDE_FROM_ABI_VIRTUAL bool do_is_equal(memory_resource const & __other) const _NOEXCEPT override {
408407 __resource_adaptor_imp const * __p
409408 = dynamic_cast<__resource_adaptor_imp const *>(&__other);
410409 return __p ? __alloc_ == __p->__alloc_ : false;
......@@ -432,11 +431,13 @@ _LIBCPP_POP_MACROS
432431# include <atomic>
433432# include <climits>
434433# include <concepts>
434# include <cstdlib>
435435# include <cstring>
436436# include <ctime>
437437# include <iterator>
438438# include <memory>
439439# include <ratio>
440# include <type_traits>
440441# include <variant>
441442#endif
442443
lib/libcxx/include/experimental/propagate_const+63-38
......@@ -110,17 +110,35 @@
110110#include <__assert> // all public C++ headers provide the assertion handler
111111#include <__functional/operations.h>
112112#include <__fwd/hash.h>
113#include <__type_traits/conditional.h>
114#include <__type_traits/decay.h>
115#include <__type_traits/enable_if.h>
116#include <__type_traits/is_array.h>
117#include <__type_traits/is_constructible.h>
118#include <__type_traits/is_convertible.h>
119#include <__type_traits/is_function.h>
120#include <__type_traits/is_pointer.h>
121#include <__type_traits/is_reference.h>
122#include <__type_traits/is_same.h>
123#include <__type_traits/is_swappable.h>
124#include <__type_traits/remove_cv.h>
125#include <__type_traits/remove_pointer.h>
126#include <__type_traits/remove_reference.h>
127#include <__utility/declval.h>
113128#include <__utility/forward.h>
114129#include <__utility/move.h>
115130#include <__utility/swap.h>
131#include <cstddef>
116132#include <experimental/__config>
117#include <type_traits>
118133
119134#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
120135# pragma GCC system_header
121136#endif
122137
123#if _LIBCPP_STD_VER > 11
138_LIBCPP_PUSH_MACROS
139#include <__undef_macros>
140
141#if _LIBCPP_STD_VER >= 14
124142
125143_LIBCPP_BEGIN_NAMESPACE_LFTS_V2
126144
......@@ -152,25 +170,25 @@ public:
152170
153171private:
154172 template <class _Up>
155 static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u)
173 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u)
156174 {
157175 return __u;
158176 }
159177
160178 template <class _Up>
161 static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u)
179 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u)
162180 {
163181 return __get_pointer(__u.get());
164182 }
165183
166184 template <class _Up>
167 static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u)
185 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u)
168186 {
169187 return __u;
170188 }
171189
172190 template <class _Up>
173 static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u)
191 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u)
174192 {
175193 return __get_pointer(__u.get());
176194 }
......@@ -192,22 +210,22 @@ public:
192210 template <class _Up> friend _LIBCPP_CONSTEXPR const _Up& ::_VSTD_LFTS_V2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT;
193211 template <class _Up> friend _LIBCPP_CONSTEXPR _Up& ::_VSTD_LFTS_V2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT;
194212
195 _LIBCPP_CONSTEXPR propagate_const() = default;
213 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const() = default;
196214
197215 propagate_const(const propagate_const&) = delete;
198216
199 _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default;
217 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default;
200218
201219 template <class _Up, enable_if_t<!is_convertible<_Up, _Tp>::value &&
202220 is_constructible<_Tp, _Up&&>::value,bool> = true>
203 explicit _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
221 explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
204222 : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu)))
205223 {
206224 }
207225
208226 template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value &&
209227 is_constructible<_Tp, _Up&&>::value,bool> = false>
210 _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
228 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
211229 : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu)))
212230 {
213231 }
......@@ -215,7 +233,7 @@ public:
215233 template <class _Up, enable_if_t<!is_convertible<_Up&&, _Tp>::value &&
216234 is_constructible<_Tp, _Up&&>::value &&
217235 !__is_propagate_const<decay_t<_Up>>::value,bool> = true>
218 explicit _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
236 explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
219237 : __t_(std::forward<_Up>(__u))
220238 {
221239 }
......@@ -223,78 +241,78 @@ public:
223241 template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value &&
224242 is_constructible<_Tp, _Up&&>::value &&
225243 !__is_propagate_const<decay_t<_Up>>::value,bool> = false>
226 _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
244 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
227245 : __t_(std::forward<_Up>(__u))
228246 {
229247 }
230248
231249 propagate_const& operator=(const propagate_const&) = delete;
232250
233 _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default;
251 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default;
234252
235253 template <class _Up>
236 _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu)
254 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu)
237255 {
238256 __t_ = std::move(_VSTD_LFTS_V2::get_underlying(__pu));
239257 return *this;
240258 }
241259
242260 template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>>
243 _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u)
261 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u)
244262 {
245263 __t_ = std::forward<_Up>(__u);
246264 return *this;
247265 }
248266
249 _LIBCPP_CONSTEXPR const element_type* get() const
267 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* get() const
250268 {
251269 return __get_pointer(__t_);
252270 }
253271
254 _LIBCPP_CONSTEXPR element_type* get()
272 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* get()
255273 {
256274 return __get_pointer(__t_);
257275 }
258276
259 explicit _LIBCPP_CONSTEXPR operator bool() const
277 _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR operator bool() const
260278 {
261279 return get() != nullptr;
262280 }
263281
264 _LIBCPP_CONSTEXPR const element_type* operator->() const
282 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* operator->() const
265283 {
266284 return get();
267285 }
268286
269 template <class _Tp_ = _Tp, class _Up = enable_if_t<is_convertible<
270 const _Tp_, const element_type *>::value>>
271 _LIBCPP_CONSTEXPR operator const element_type *() const {
287 template <class _Dummy = _Tp, class _Up = enable_if_t<is_convertible<
288 const _Dummy, const element_type *>::value>>
289 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator const element_type *() const {
272290 return get();
273291 }
274292
275 _LIBCPP_CONSTEXPR const element_type& operator*() const
293 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type& operator*() const
276294 {
277295 return *get();
278296 }
279297
280 _LIBCPP_CONSTEXPR element_type* operator->()
298 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* operator->()
281299 {
282300 return get();
283301 }
284302
285 template <class _Tp_ = _Tp, class _Up = enable_if_t<
286 is_convertible<_Tp_, element_type *>::value>>
287 _LIBCPP_CONSTEXPR operator element_type *() {
303 template <class _Dummy = _Tp, class _Up = enable_if_t<
304 is_convertible<_Dummy, element_type *>::value>>
305 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator element_type *() {
288306 return get();
289307 }
290308
291 _LIBCPP_CONSTEXPR element_type& operator*()
309 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type& operator*()
292310 {
293311 return *get();
294312 }
295313
296 _LIBCPP_CONSTEXPR void swap(propagate_const& __pt) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
297 {
314 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR void swap(propagate_const& __pt)
315 _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) {
298316 using _VSTD::swap;
299317 swap(__t_, __pt.__t_);
300318 }
......@@ -491,7 +509,7 @@ struct hash<experimental::fundamentals_v2::propagate_const<_Tp>>
491509 typedef size_t result_type;
492510 typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type;
493511
494 size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const
512 _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const
495513 {
496514 return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1));
497515 }
......@@ -503,7 +521,7 @@ struct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
503521 typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
504522 typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
505523
506 bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
524 _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
507525 const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
508526 {
509527 return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
......@@ -516,7 +534,7 @@ struct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
516534 typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
517535 typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
518536
519 bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
537 _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
520538 const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
521539 {
522540 return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
......@@ -529,7 +547,7 @@ struct less<experimental::fundamentals_v2::propagate_const<_Tp>>
529547 typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
530548 typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
531549
532 bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
550 _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
533551 const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
534552 {
535553 return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
......@@ -542,7 +560,7 @@ struct greater<experimental::fundamentals_v2::propagate_const<_Tp>>
542560 typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
543561 typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
544562
545 bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
563 _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
546564 const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
547565 {
548566 return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
......@@ -555,7 +573,7 @@ struct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
555573 typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
556574 typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
557575
558 bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
576 _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
559577 const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
560578 {
561579 return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
......@@ -568,7 +586,7 @@ struct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
568586 typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
569587 typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
570588
571 bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
589 _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
572590 const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
573591 {
574592 return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
......@@ -577,5 +595,12 @@ struct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
577595
578596_LIBCPP_END_NAMESPACE_STD
579597
580#endif // _LIBCPP_STD_VER > 11
598#endif // _LIBCPP_STD_VER >= 14
599
600_LIBCPP_POP_MACROS
601
602#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
603# include <type_traits>
604#endif
605
581606#endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
lib/libcxx/include/experimental/simd+41-41
......@@ -691,8 +691,8 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> {
691691 friend struct simd_mask;
692692
693693public:
694 _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }
695 void __set(size_t __index, _Tp __val) noexcept {
694 _LIBCPP_HIDE_FROM_ABI _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }
695 _LIBCPP_HIDE_FROM_ABI void __set(size_t __index, _Tp __val) noexcept {
696696 __storage_[__index] = __val;
697697 }
698698};
......@@ -708,8 +708,8 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> {
708708 friend struct simd_mask;
709709
710710public:
711 _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; }
712 void __set(size_t __index, _Tp __val) noexcept {
711 _LIBCPP_HIDE_FROM_ABI _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; }
712 _LIBCPP_HIDE_FROM_ABI void __set(size_t __index, _Tp __val) noexcept {
713713 (&__storage_)[__index] = __val;
714714 }
715715};
......@@ -810,8 +810,8 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_VecExt, __num_element>> {
810810 friend struct simd_mask;
811811
812812public:
813 _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }
814 void __set(size_t __index, _Tp __val) noexcept {
813 _LIBCPP_HIDE_FROM_ABI _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }
814 _LIBCPP_HIDE_FROM_ABI void __set(size_t __index, _Tp __val) noexcept {
815815 __storage_[__index] = __val;
816816 }
817817};
......@@ -831,79 +831,79 @@ class __simd_reference {
831831 __simd_storage<_Tp, _Abi>* __ptr_;
832832 size_t __index_;
833833
834 __simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index)
834 _LIBCPP_HIDE_FROM_ABI __simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index)
835835 : __ptr_(__ptr), __index_(__index) {}
836836
837 __simd_reference(const __simd_reference&) = default;
837 _LIBCPP_HIDE_FROM_ABI __simd_reference(const __simd_reference&) = default;
838838
839839public:
840840 __simd_reference() = delete;
841841 __simd_reference& operator=(const __simd_reference&) = delete;
842842
843 operator _Vp() const { return __ptr_->__get(__index_); }
843 _LIBCPP_HIDE_FROM_ABI operator _Vp() const { return __ptr_->__get(__index_); }
844844
845 __simd_reference operator=(_Vp __value) && {
845 _LIBCPP_HIDE_FROM_ABI __simd_reference operator=(_Vp __value) && {
846846 __ptr_->__set(__index_, __value);
847847 return *this;
848848 }
849849
850 __simd_reference operator++() && {
850 _LIBCPP_HIDE_FROM_ABI __simd_reference operator++() && {
851851 return std::move(*this) = __ptr_->__get(__index_) + 1;
852852 }
853853
854 _Vp operator++(int) && {
854 _LIBCPP_HIDE_FROM_ABI _Vp operator++(int) && {
855855 auto __val = __ptr_->__get(__index_);
856856 __ptr_->__set(__index_, __val + 1);
857857 return __val;
858858 }
859859
860 __simd_reference operator--() && {
860 _LIBCPP_HIDE_FROM_ABI __simd_reference operator--() && {
861861 return std::move(*this) = __ptr_->__get(__index_) - 1;
862862 }
863863
864 _Vp operator--(int) && {
864 _LIBCPP_HIDE_FROM_ABI _Vp operator--(int) && {
865865 auto __val = __ptr_->__get(__index_);
866866 __ptr_->__set(__index_, __val - 1);
867867 return __val;
868868 }
869869
870 __simd_reference operator+=(_Vp __value) && {
870 _LIBCPP_HIDE_FROM_ABI __simd_reference operator+=(_Vp __value) && {
871871 return std::move(*this) = __ptr_->__get(__index_) + __value;
872872 }
873873
874 __simd_reference operator-=(_Vp __value) && {
874 _LIBCPP_HIDE_FROM_ABI __simd_reference operator-=(_Vp __value) && {
875875 return std::move(*this) = __ptr_->__get(__index_) - __value;
876876 }
877877
878 __simd_reference operator*=(_Vp __value) && {
878 _LIBCPP_HIDE_FROM_ABI __simd_reference operator*=(_Vp __value) && {
879879 return std::move(*this) = __ptr_->__get(__index_) * __value;
880880 }
881881
882 __simd_reference operator/=(_Vp __value) && {
882 _LIBCPP_HIDE_FROM_ABI __simd_reference operator/=(_Vp __value) && {
883883 return std::move(*this) = __ptr_->__get(__index_) / __value;
884884 }
885885
886 __simd_reference operator%=(_Vp __value) && {
886 _LIBCPP_HIDE_FROM_ABI __simd_reference operator%=(_Vp __value) && {
887887 return std::move(*this) = __ptr_->__get(__index_) % __value;
888888 }
889889
890 __simd_reference operator>>=(_Vp __value) && {
890 _LIBCPP_HIDE_FROM_ABI __simd_reference operator>>=(_Vp __value) && {
891891 return std::move(*this) = __ptr_->__get(__index_) >> __value;
892892 }
893893
894 __simd_reference operator<<=(_Vp __value) && {
894 _LIBCPP_HIDE_FROM_ABI __simd_reference operator<<=(_Vp __value) && {
895895 return std::move(*this) = __ptr_->__get(__index_) << __value;
896896 }
897897
898 __simd_reference operator&=(_Vp __value) && {
898 _LIBCPP_HIDE_FROM_ABI __simd_reference operator&=(_Vp __value) && {
899899 return std::move(*this) = __ptr_->__get(__index_) & __value;
900900 }
901901
902 __simd_reference operator|=(_Vp __value) && {
902 _LIBCPP_HIDE_FROM_ABI __simd_reference operator|=(_Vp __value) && {
903903 return std::move(*this) = __ptr_->__get(__index_) | __value;
904904 }
905905
906 __simd_reference operator^=(_Vp __value) && {
906 _LIBCPP_HIDE_FROM_ABI __simd_reference operator^=(_Vp __value) && {
907907 return std::move(*this) = __ptr_->__get(__index_) ^ __value;
908908 }
909909};
......@@ -1350,11 +1350,11 @@ public:
13501350 using mask_type = simd_mask<_Tp, _Abi>;
13511351 using abi_type = _Abi;
13521352
1353 simd() = default;
1354 simd(const simd&) = default;
1355 simd& operator=(const simd&) = default;
1353 _LIBCPP_HIDE_FROM_ABI simd() = default;
1354 _LIBCPP_HIDE_FROM_ABI simd(const simd&) = default;
1355 _LIBCPP_HIDE_FROM_ABI simd& operator=(const simd&) = default;
13561356
1357 static constexpr size_t size() noexcept {
1357 static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept {
13581358 return simd_size<_Tp, _Abi>::value;
13591359 }
13601360
......@@ -1362,7 +1362,7 @@ private:
13621362 __simd_storage<_Tp, _Abi> __s_;
13631363
13641364 template <class _Up>
1365 static constexpr bool __can_broadcast() {
1365 static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_broadcast() {
13661366 return (std::is_arithmetic<_Up>::value &&
13671367 __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()) ||
13681368 (!std::is_arithmetic<_Up>::value &&
......@@ -1374,7 +1374,7 @@ private:
13741374 }
13751375
13761376 template <class _Generator, size_t... __indicies>
1377 static constexpr decltype(
1377 static _LIBCPP_HIDE_FROM_ABI constexpr decltype(
13781378 std::forward_as_tuple(std::declval<_Generator>()(
13791379 std::integral_constant<size_t, __indicies>())...),
13801380 bool())
......@@ -1385,12 +1385,12 @@ private:
13851385 }
13861386
13871387 template <class _Generator>
1388 static bool __can_generate(...) {
1388 static _LIBCPP_HIDE_FROM_ABI bool __can_generate(...) {
13891389 return false;
13901390 }
13911391
13921392 template <class _Generator, size_t... __indicies>
1393 void __generator_init(_Generator&& __g, std::index_sequence<__indicies...>) {
1393 _LIBCPP_HIDE_FROM_ABI void __generator_init(_Generator&& __g, std::index_sequence<__indicies...>) {
13941394 int __not_used[]{((*this)[__indicies] =
13951395 __g(std::integral_constant<size_t, __indicies>()),
13961396 0)...};
......@@ -1403,7 +1403,7 @@ public:
14031403 class = typename std::enable_if<
14041404 std::is_same<_Abi, simd_abi::fixed_size<size()>>::value &&
14051405 __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()>::type>
1406 simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v) {
1406 _LIBCPP_HIDE_FROM_ABI simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v) {
14071407 for (size_t __i = 0; __i < size(); __i++) {
14081408 (*this)[__i] = static_cast<_Tp>(__v[__i]);
14091409 }
......@@ -1412,7 +1412,7 @@ public:
14121412 // implicit broadcast constructor
14131413 template <class _Up,
14141414 class = typename std::enable_if<__can_broadcast<_Up>()>::type>
1415 simd(_Up&& __rv) {
1415 _LIBCPP_HIDE_FROM_ABI simd(_Up&& __rv) {
14161416 auto __v = static_cast<_Tp>(__rv);
14171417 for (size_t __i = 0; __i < size(); __i++) {
14181418 (*this)[__i] = __v;
......@@ -1424,7 +1424,7 @@ public:
14241424 int = typename std::enable_if<
14251425 __can_generate<_Generator>(std::make_index_sequence<size()>()),
14261426 int>::type()>
1427 explicit simd(_Generator&& __g) {
1427 explicit _LIBCPP_HIDE_FROM_ABI simd(_Generator&& __g) {
14281428 __generator_init(std::forward<_Generator>(__g),
14291429 std::make_index_sequence<size()>());
14301430 }
......@@ -1434,7 +1434,7 @@ public:
14341434 class _Up, class _Flags,
14351435 class = typename std::enable_if<__vectorizable<_Up>()>::type,
14361436 class = typename std::enable_if<is_simd_flag_type<_Flags>::value>::type>
1437 simd(const _Up* __buffer, _Flags) {
1437 _LIBCPP_HIDE_FROM_ABI simd(const _Up* __buffer, _Flags) {
14381438 // TODO: optimize for overaligned flags
14391439 for (size_t __i = 0; __i < size(); __i++) {
14401440 (*this)[__i] = static_cast<_Tp>(__buffer[__i]);
......@@ -1445,7 +1445,7 @@ public:
14451445 template <class _Up, class _Flags>
14461446 typename std::enable_if<__vectorizable<_Up>() &&
14471447 is_simd_flag_type<_Flags>::value>::type
1448 copy_from(const _Up* __buffer, _Flags) {
1448 _LIBCPP_HIDE_FROM_ABI copy_from(const _Up* __buffer, _Flags) {
14491449 *this = simd(__buffer, _Flags());
14501450 }
14511451
......@@ -1453,7 +1453,7 @@ public:
14531453 template <class _Up, class _Flags>
14541454 typename std::enable_if<__vectorizable<_Up>() &&
14551455 is_simd_flag_type<_Flags>::value>::type
1456 copy_to(_Up* __buffer, _Flags) const {
1456 _LIBCPP_HIDE_FROM_ABI copy_to(_Up* __buffer, _Flags) const {
14571457 // TODO: optimize for overaligned flags
14581458 for (size_t __i = 0; __i < size(); __i++) {
14591459 __buffer[__i] = static_cast<_Up>((*this)[__i]);
......@@ -1461,9 +1461,9 @@ public:
14611461 }
14621462
14631463 // scalar access [simd.subscr]
1464 reference operator[](size_t __i) { return reference(&__s_, __i); }
1464 _LIBCPP_HIDE_FROM_ABI reference operator[](size_t __i) { return reference(&__s_, __i); }
14651465
1466 value_type operator[](size_t __i) const { return __s_.__get(__i); }
1466 _LIBCPP_HIDE_FROM_ABI value_type operator[](size_t __i) const { return __s_.__get(__i); }
14671467
14681468 // unary operators [simd.unary]
14691469 simd& operator++();
......@@ -1526,7 +1526,7 @@ public:
15261526 using simd_type = simd<_Tp, _Abi>;
15271527 using abi_type = _Abi;
15281528 static constexpr size_t size() noexcept;
1529 simd_mask() = default;
1529 _LIBCPP_HIDE_FROM_ABI simd_mask() = default;
15301530
15311531 // broadcast constructor
15321532 explicit simd_mask(value_type) noexcept;
lib/libcxx/include/experimental/type_traits+14-14
......@@ -71,7 +71,7 @@ inline namespace fundamentals_v1 {
7171#include <__assert> // all public C++ headers provide the assertion handler
7272#include <experimental/__config>
7373
74#if _LIBCPP_STD_VER > 11
74#if _LIBCPP_STD_VER >= 14
7575
7676#include <initializer_list>
7777#include <type_traits>
......@@ -132,24 +132,24 @@ template <template<class...> class _Op, class... _Args>
132132template <template<class...> class _Op, class... _Args>
133133 _LIBCPP_CONSTEXPR bool is_detected_v = is_detected<_Op, _Args...>::value;
134134
135template <class Default, template<class...> class _Op, class... _Args>
136 using detected_or = _DETECTOR<Default, void, _Op, _Args...>;
137template <class Default, template<class...> class _Op, class... _Args>
138 using detected_or_t = typename detected_or<Default, _Op, _Args...>::type;
135template <class _Default, template<class...> class _Op, class... _Args>
136 using detected_or = _DETECTOR<_Default, void, _Op, _Args...>;
137template <class _Default, template<class...> class _Op, class... _Args>
138 using detected_or_t = typename detected_or<_Default, _Op, _Args...>::type;
139139
140template <class Expected, template<class...> class _Op, class... _Args>
141 using is_detected_exact = is_same<Expected, detected_t<_Op, _Args...>>;
142template <class Expected, template<class...> class _Op, class... _Args>
143 _LIBCPP_CONSTEXPR bool is_detected_exact_v = is_detected_exact<Expected, _Op, _Args...>::value;
140template <class _Expected, template<class...> class _Op, class... _Args>
141 using is_detected_exact = is_same<_Expected, detected_t<_Op, _Args...>>;
142template <class _Expected, template<class...> class _Op, class... _Args>
143 _LIBCPP_CONSTEXPR bool is_detected_exact_v = is_detected_exact<_Expected, _Op, _Args...>::value;
144144
145template <class To, template<class...> class _Op, class... _Args>
146 using is_detected_convertible = is_convertible<detected_t<_Op, _Args...>, To>;
147template <class To, template<class...> class _Op, class... _Args>
148 _LIBCPP_CONSTEXPR bool is_detected_convertible_v = is_detected_convertible<To, _Op, _Args...>::value;
145template <class _To, template<class...> class _Op, class... _Args>
146 using is_detected_convertible = is_convertible<detected_t<_Op, _Args...>, _To>;
147template <class _To, template<class...> class _Op, class... _Args>
148 _LIBCPP_CONSTEXPR bool is_detected_convertible_v = is_detected_convertible<_To, _Op, _Args...>::value;
149149
150150
151151_LIBCPP_END_NAMESPACE_LFTS
152152
153#endif /* _LIBCPP_STD_VER > 11 */
153#endif /* _LIBCPP_STD_VER >= 14 */
154154
155155#endif /* _LIBCPP_EXPERIMENTAL_TYPE_TRAITS */
lib/libcxx/include/ext/hash_map+16-16
......@@ -208,7 +208,6 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
208208#include <ext/__hash>
209209#include <functional>
210210#include <stdexcept>
211#include <type_traits>
212211
213212#if defined(__DEPRECATED) && __DEPRECATED
214213#if defined(_LIBCPP_WARNING)
......@@ -324,7 +323,7 @@ public:
324323 bool __first_constructed;
325324 bool __second_constructed;
326325
327 __hash_map_node_destructor(__hash_map_node_destructor const&) = default;
326 _LIBCPP_HIDE_FROM_ABI __hash_map_node_destructor(__hash_map_node_destructor const&) = default;
328327 __hash_map_node_destructor& operator=(const __hash_map_node_destructor&) = delete;
329328
330329 _LIBCPP_INLINE_VISIBILITY
......@@ -508,23 +507,23 @@ public:
508507 typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
509508
510509 _LIBCPP_INLINE_VISIBILITY hash_map() { }
511 explicit hash_map(size_type __n, const hasher& __hf = hasher(),
510 explicit _LIBCPP_HIDE_FROM_ABI hash_map(size_type __n, const hasher& __hf = hasher(),
512511 const key_equal& __eql = key_equal());
513 hash_map(size_type __n, const hasher& __hf,
512 _LIBCPP_HIDE_FROM_ABI hash_map(size_type __n, const hasher& __hf,
514513 const key_equal& __eql,
515514 const allocator_type& __a);
516515 template <class _InputIterator>
517 hash_map(_InputIterator __first, _InputIterator __last);
516 _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last);
518517 template <class _InputIterator>
519 hash_map(_InputIterator __first, _InputIterator __last,
518 _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last,
520519 size_type __n, const hasher& __hf = hasher(),
521520 const key_equal& __eql = key_equal());
522521 template <class _InputIterator>
523 hash_map(_InputIterator __first, _InputIterator __last,
522 _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last,
524523 size_type __n, const hasher& __hf,
525524 const key_equal& __eql,
526525 const allocator_type& __a);
527 hash_map(const hash_map& __u);
526 _LIBCPP_HIDE_FROM_ABI hash_map(const hash_map& __u);
528527
529528 _LIBCPP_INLINE_VISIBILITY
530529 allocator_type get_allocator() const
......@@ -588,7 +587,7 @@ public:
588587 std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
589588 {return __table_.__equal_range_unique(__k);}
590589
591 mapped_type& operator[](const key_type& __k);
590 _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
592591
593592 _LIBCPP_INLINE_VISIBILITY
594593 size_type bucket_count() const {return __table_.bucket_count();}
......@@ -603,7 +602,7 @@ public:
603602 void resize(size_type __n) {__table_.__rehash_unique(__n);}
604603
605604private:
606 __node_holder __construct_node(const key_type& __k);
605 _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(const key_type& __k);
607606};
608607
609608template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
......@@ -780,23 +779,23 @@ public:
780779
781780 _LIBCPP_INLINE_VISIBILITY
782781 hash_multimap() { }
783 explicit hash_multimap(size_type __n, const hasher& __hf = hasher(),
782 explicit _LIBCPP_HIDE_FROM_ABI hash_multimap(size_type __n, const hasher& __hf = hasher(),
784783 const key_equal& __eql = key_equal());
785 hash_multimap(size_type __n, const hasher& __hf,
784 _LIBCPP_HIDE_FROM_ABI hash_multimap(size_type __n, const hasher& __hf,
786785 const key_equal& __eql,
787786 const allocator_type& __a);
788787 template <class _InputIterator>
789 hash_multimap(_InputIterator __first, _InputIterator __last);
788 _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last);
790789 template <class _InputIterator>
791 hash_multimap(_InputIterator __first, _InputIterator __last,
790 _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last,
792791 size_type __n, const hasher& __hf = hasher(),
793792 const key_equal& __eql = key_equal());
794793 template <class _InputIterator>
795 hash_multimap(_InputIterator __first, _InputIterator __last,
794 _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last,
796795 size_type __n, const hasher& __hf,
797796 const key_equal& __eql,
798797 const allocator_type& __a);
799 hash_multimap(const hash_multimap& __u);
798 _LIBCPP_HIDE_FROM_ABI hash_multimap(const hash_multimap& __u);
800799
801800 _LIBCPP_INLINE_VISIBILITY
802801 allocator_type get_allocator() const
......@@ -985,6 +984,7 @@ operator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
985984#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
986985# include <concepts>
987986# include <iterator>
987# include <type_traits>
988988#endif
989989
990990#endif // _LIBCPP_HASH_MAP
lib/libcxx/include/ext/hash_set+13-12
......@@ -244,21 +244,21 @@ public:
244244
245245 _LIBCPP_INLINE_VISIBILITY
246246 hash_set() { }
247 explicit hash_set(size_type __n, const hasher& __hf = hasher(),
247 _LIBCPP_HIDE_FROM_ABI explicit hash_set(size_type __n, const hasher& __hf = hasher(),
248248 const key_equal& __eql = key_equal());
249 hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
249 _LIBCPP_HIDE_FROM_ABI hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
250250 const allocator_type& __a);
251251 template <class _InputIterator>
252 hash_set(_InputIterator __first, _InputIterator __last);
252 _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last);
253253 template <class _InputIterator>
254 hash_set(_InputIterator __first, _InputIterator __last,
254 _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last,
255255 size_type __n, const hasher& __hf = hasher(),
256256 const key_equal& __eql = key_equal());
257257 template <class _InputIterator>
258 hash_set(_InputIterator __first, _InputIterator __last,
258 _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last,
259259 size_type __n, const hasher& __hf, const key_equal& __eql,
260260 const allocator_type& __a);
261 hash_set(const hash_set& __u);
261 _LIBCPP_HIDE_FROM_ABI hash_set(const hash_set& __u);
262262
263263 _LIBCPP_INLINE_VISIBILITY
264264 allocator_type get_allocator() const
......@@ -465,21 +465,21 @@ public:
465465
466466 _LIBCPP_INLINE_VISIBILITY
467467 hash_multiset() { }
468 explicit hash_multiset(size_type __n, const hasher& __hf = hasher(),
468 explicit _LIBCPP_HIDE_FROM_ABI hash_multiset(size_type __n, const hasher& __hf = hasher(),
469469 const key_equal& __eql = key_equal());
470 hash_multiset(size_type __n, const hasher& __hf,
470 _LIBCPP_HIDE_FROM_ABI hash_multiset(size_type __n, const hasher& __hf,
471471 const key_equal& __eql, const allocator_type& __a);
472472 template <class _InputIterator>
473 hash_multiset(_InputIterator __first, _InputIterator __last);
473 _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last);
474474 template <class _InputIterator>
475 hash_multiset(_InputIterator __first, _InputIterator __last,
475 _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last,
476476 size_type __n, const hasher& __hf = hasher(),
477477 const key_equal& __eql = key_equal());
478478 template <class _InputIterator>
479 hash_multiset(_InputIterator __first, _InputIterator __last,
479 _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last,
480480 size_type __n , const hasher& __hf,
481481 const key_equal& __eql, const allocator_type& __a);
482 hash_multiset(const hash_multiset& __u);
482 _LIBCPP_HIDE_FROM_ABI hash_multiset(const hash_multiset& __u);
483483
484484 _LIBCPP_INLINE_VISIBILITY
485485 allocator_type get_allocator() const
......@@ -665,6 +665,7 @@ operator!=(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
665665#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
666666# include <concepts>
667667# include <iterator>
668# include <type_traits>
668669#endif
669670
670671#endif // _LIBCPP_HASH_SET
lib/libcxx/include/filesystem+109-7
......@@ -159,6 +159,9 @@
159159 void swap(path& lhs, path& rhs) noexcept;
160160 size_t hash_value(const path& p) noexcept;
161161
162 // [fs.path.hash], hash support
163 template<> struct hash<filesystem::path>;
164
162165 template <class Source>
163166 path u8path(const Source& source);
164167 template <class InputIterator>
......@@ -233,19 +236,120 @@
233236 friend class directory_iterator; // exposition only
234237 };
235238
236 class directory_iterator;
239 class directory_iterator {
240 public:
241 using iterator_category = input_iterator_tag;
242 using value_type = directory_entry;
243 using difference_type = ptrdiff_t;
244 using pointer = const directory_entry*;
245 using reference = const directory_entry&;
246
247 // [fs.dir.itr.members], member functions
248 directory_iterator() noexcept;
249 explicit directory_iterator(const path& p);
250 directory_iterator(const path& p, directory_options options);
251 directory_iterator(const path& p, error_code& ec);
252 directory_iterator(const path& p, directory_options options,
253 error_code& ec);
254 directory_iterator(const directory_iterator& rhs);
255 directory_iterator(directory_iterator&& rhs) noexcept;
256 ~directory_iterator();
257
258 directory_iterator& operator=(const directory_iterator& rhs);
259 directory_iterator& operator=(directory_iterator&& rhs) noexcept;
260
261 const directory_entry& operator*() const;
262 const directory_entry* operator->() const;
263 directory_iterator& operator++();
264 directory_iterator& increment(error_code& ec);
265
266 bool operator==(default_sentinel_t) const noexcept { // since C++20
267 return *this == directory_iterator();
268 }
269
270 // other members as required by [input.iterators], input iterators
271 };
237272
238273 // enable directory_iterator range-based for statements
239274 directory_iterator begin(directory_iterator iter) noexcept;
240275 directory_iterator end(directory_iterator) noexcept;
241276
242 class recursive_directory_iterator;
277class recursive_directory_iterator {
278 public:
279 using iterator_category = input_iterator_tag;
280 using value_type = directory_entry;
281 using difference_type = ptrdiff_t;
282 using pointer = const directory_entry*;
283 using reference = const directory_entry&;
284
285 // [fs.rec.dir.itr.members], constructors and destructor
286 recursive_directory_iterator() noexcept;
287 explicit recursive_directory_iterator(const path& p);
288 recursive_directory_iterator(const path& p, directory_options options);
289 recursive_directory_iterator(const path& p, directory_options options,
290 error_code& ec);
291 recursive_directory_iterator(const path& p, error_code& ec);
292 recursive_directory_iterator(const recursive_directory_iterator& rhs);
293 recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;
294 ~recursive_directory_iterator();
295
296 // [fs.rec.dir.itr.members], observers
297 directory_options options() const;
298 int depth() const;
299 bool recursion_pending() const;
300
301 const directory_entry& operator*() const;
302 const directory_entry* operator->() const;
303
304 // [fs.rec.dir.itr.members], modifiers
305 recursive_directory_iterator&
306 operator=(const recursive_directory_iterator& rhs);
307 recursive_directory_iterator&
308 operator=(recursive_directory_iterator&& rhs) noexcept;
309
310 recursive_directory_iterator& operator++();
311 recursive_directory_iterator& increment(error_code& ec);
312
313 void pop();
314 void pop(error_code& ec);
315 void disable_recursion_pending();
316
317 bool operator==(default_sentinel_t) const noexcept { // since C++20
318 return *this == recursive_directory_iterator();
319 }
320
321 // other members as required by [input.iterators], input iterators
322 };
243323
244324 // enable recursive_directory_iterator range-based for statements
245325 recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
246326 recursive_directory_iterator end(recursive_directory_iterator) noexcept;
247327
248 class file_status;
328 class file_status {
329 public:
330 // [fs.file.status.cons], constructors and destructor
331 file_status() noexcept : file_status(file_type::none) {}
332 explicit file_status(file_type ft,
333 perms prms = perms::unknown) noexcept;
334 file_status(const file_status&) noexcept = default;
335 file_status(file_status&&) noexcept = default;
336 ~file_status();
337
338 // assignments
339 file_status& operator=(const file_status&) noexcept = default;
340 file_status& operator=(file_status&&) noexcept = default;
341
342 // [fs.file.status.mods], modifiers
343 void type(file_type ft) noexcept;
344 void permissions(perms prms) noexcept;
345
346 // [fs.file.status.obs], observers
347 file_type type() const noexcept;
348 perms permissions() const noexcept;
349
350 friend bool operator==(const file_status& lhs, const file_status& rhs) noexcept
351 { return lhs.type() == rhs.type() && lhs.permissions() == rhs.permissions(); } // C++20
352 };
249353
250354 struct space_info
251355 {
......@@ -454,16 +558,14 @@ inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_direct
454558// [fs.filesystem.syn]
455559#include <compare>
456560
457#if defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
458# error "The <filesystem> library is not supported since libc++ has been configured without support for a filesystem."
459#endif
460
461561#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
462562# pragma GCC system_header
463563#endif
464564
465565#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
466566# include <concepts>
567# include <cstdlib>
568# include <system_error>
467569#endif
468570
469571#endif // _LIBCPP_FILESYSTEM
lib/libcxx/include/format+1-7
......@@ -170,11 +170,6 @@ namespace std {
170170*/
171171
172172#include <__assert> // all public C++ headers provide the assertion handler
173// Make sure all feature-test macros are available.
174#include <version>
175// Enable the contents of the header only when libc++ was built with experimental features enabled.
176#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
177
178173#include <__config>
179174#include <__format/buffer.h>
180175#include <__format/concepts.h>
......@@ -202,11 +197,10 @@ namespace std {
202197#include <__format/range_default_formatter.h>
203198#include <__format/range_formatter.h>
204199#include <__format/unicode.h>
200#include <version>
205201
206202#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
207203# pragma GCC system_header
208204#endif
209205
210#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
211
212206#endif // _LIBCPP_FORMAT
lib/libcxx/include/forward_list+243-104
......@@ -44,6 +44,8 @@ public:
4444 forward_list(InputIterator first, InputIterator last);
4545 template <class InputIterator>
4646 forward_list(InputIterator first, InputIterator last, const allocator_type& a);
47 template<container-compatible-range<T> R>
48 forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
4749 forward_list(const forward_list& x);
4850 forward_list(const forward_list& x, const allocator_type& a);
4951 forward_list(forward_list&& x)
......@@ -63,6 +65,8 @@ public:
6365
6466 template <class InputIterator>
6567 void assign(InputIterator first, InputIterator last);
68 template<container-compatible-range<T> R>
69 void assign_range(R&& rg); // C++23
6670 void assign(size_type n, const value_type& v);
6771 void assign(initializer_list<value_type> il);
6872
......@@ -89,6 +93,8 @@ public:
8993 template <class... Args> reference emplace_front(Args&&... args); // reference in C++17
9094 void push_front(const value_type& v);
9195 void push_front(value_type&& v);
96 template<container-compatible-range<T> R>
97 void prepend_range(R&& rg); // C++23
9298
9399 void pop_front();
94100
......@@ -100,6 +106,8 @@ public:
100106 template <class InputIterator>
101107 iterator insert_after(const_iterator p,
102108 InputIterator first, InputIterator last);
109 template<container-compatible-range<T> R>
110 iterator insert_range_after(const_iterator position, R&& rg); // C++23
103111 iterator insert_after(const_iterator p, initializer_list<value_type> il);
104112
105113 iterator erase_after(const_iterator p);
......@@ -140,29 +148,37 @@ template <class InputIterator, class Allocator = allocator<typename iterator_tra
140148 forward_list(InputIterator, InputIterator, Allocator = Allocator())
141149 -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
142150
151template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
152 forward_list(from_range_t, R&&, Allocator = Allocator())
153 -> forward_list<ranges::range_value_t<R>, Allocator>; // C++23
154
143155template <class T, class Allocator>
144156 bool operator==(const forward_list<T, Allocator>& x,
145157 const forward_list<T, Allocator>& y);
146158
147159template <class T, class Allocator>
148160 bool operator< (const forward_list<T, Allocator>& x,
149 const forward_list<T, Allocator>& y);
161 const forward_list<T, Allocator>& y); // removed in C++20
150162
151163template <class T, class Allocator>
152164 bool operator!=(const forward_list<T, Allocator>& x,
153 const forward_list<T, Allocator>& y);
165 const forward_list<T, Allocator>& y); // removed in C++20
154166
155167template <class T, class Allocator>
156168 bool operator> (const forward_list<T, Allocator>& x,
157 const forward_list<T, Allocator>& y);
169 const forward_list<T, Allocator>& y); // removed in C++20
158170
159171template <class T, class Allocator>
160172 bool operator>=(const forward_list<T, Allocator>& x,
161 const forward_list<T, Allocator>& y);
173 const forward_list<T, Allocator>& y); // removed in C++20
162174
163175template <class T, class Allocator>
164176 bool operator<=(const forward_list<T, Allocator>& x,
165 const forward_list<T, Allocator>& y);
177 const forward_list<T, Allocator>& y); // removed in C++20
178
179template<class T, class Allocator>
180 synth-three-way-result<T> operator<=>(const forward_list<T, Allocator>& x,
181 const forward_list<T, Allocator>& y); // since C++20
166182
167183template <class T, class Allocator>
168184 void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
......@@ -181,14 +197,17 @@ template <class T, class Allocator, class Predicate>
181197
182198#include <__algorithm/comp.h>
183199#include <__algorithm/lexicographical_compare.h>
200#include <__algorithm/lexicographical_compare_three_way.h>
184201#include <__algorithm/min.h>
185202#include <__assert> // all public C++ headers provide the assertion handler
203#include <__availability>
186204#include <__config>
187205#include <__iterator/distance.h>
188206#include <__iterator/iterator_traits.h>
189207#include <__iterator/move_iterator.h>
190208#include <__iterator/next.h>
191209#include <__memory/addressof.h>
210#include <__memory/allocation_guard.h>
192211#include <__memory/allocator.h>
193212#include <__memory/allocator_destructor.h>
194213#include <__memory/allocator_traits.h>
......@@ -197,11 +216,22 @@ template <class T, class Allocator, class Predicate>
197216#include <__memory/swap_allocator.h>
198217#include <__memory/unique_ptr.h>
199218#include <__memory_resource/polymorphic_allocator.h>
219#include <__ranges/access.h>
220#include <__ranges/concepts.h>
221#include <__ranges/container_compatible_range.h>
222#include <__ranges/from_range.h>
223#include <__type_traits/conditional.h>
200224#include <__type_traits/is_allocator.h>
225#include <__type_traits/is_const.h>
226#include <__type_traits/is_nothrow_default_constructible.h>
227#include <__type_traits/is_nothrow_move_assignable.h>
228#include <__type_traits/is_nothrow_move_constructible.h>
229#include <__type_traits/is_pointer.h>
230#include <__type_traits/is_same.h>
231#include <__type_traits/type_identity.h>
201232#include <__utility/forward.h>
202233#include <__utility/move.h>
203234#include <limits>
204#include <type_traits>
205235#include <version>
206236
207237// standard-mandated includes
......@@ -279,6 +309,7 @@ struct __forward_begin_node
279309 pointer __next_;
280310
281311 _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
312 _LIBCPP_INLINE_VISIBILITY explicit __forward_begin_node(pointer __n) : __next_(__n) {}
282313
283314 _LIBCPP_INLINE_VISIBILITY
284315 __begin_node_pointer __next_as_begin() const {
......@@ -294,8 +325,13 @@ struct _LIBCPP_STANDALONE_DEBUG __forward_list_node
294325 : public __begin_node_of<_Tp, _VoidPtr>
295326{
296327 typedef _Tp value_type;
328 typedef __begin_node_of<_Tp, _VoidPtr> _Base;
329 typedef typename _Base::pointer _NodePtr;
297330
298331 value_type __value_;
332
333 _LIBCPP_HIDE_FROM_ABI __forward_list_node() = default;
334 _LIBCPP_HIDE_FROM_ABI __forward_list_node(const value_type& __v, _NodePtr __next) : _Base(__next), __value_(__v) {}
299335};
300336
301337
......@@ -395,11 +431,11 @@ class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator
395431
396432 __iter_node_pointer __ptr_;
397433
398 __begin_node_pointer __get_begin() const {
434 _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __get_begin() const {
399435 return static_cast<__begin_node_pointer>(
400436 static_cast<__void_pointer>(__ptr_));
401437 }
402 __node_pointer __get_unsafe_node_pointer() const {
438 _LIBCPP_HIDE_FROM_ABI __node_pointer __get_unsafe_node_pointer() const {
403439 return static_cast<__node_pointer>(
404440 static_cast<__void_pointer>(__ptr_));
405441 }
......@@ -482,14 +518,6 @@ protected:
482518 typedef typename allocator_traits<__begin_node_allocator>::pointer
483519 __begin_node_pointer;
484520
485 static_assert((!is_same<allocator_type, __node_allocator>::value),
486 "internal allocator type must differ from user-specified "
487 "type; otherwise overload resolution breaks");
488
489 static_assert(is_same<allocator_type, __rebind_alloc<__node_traits, value_type> >::value,
490 "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
491 "original allocator");
492
493521 __compressed_pair<__begin_node, __node_allocator> __before_begin_;
494522
495523 _LIBCPP_INLINE_VISIBILITY
......@@ -533,7 +561,7 @@ private:
533561 __forward_list_base& operator=(const __forward_list_base&);
534562
535563public:
536 ~__forward_list_base();
564 _LIBCPP_HIDE_FROM_ABI ~__forward_list_base();
537565
538566protected:
539567 _LIBCPP_INLINE_VISIBILITY
......@@ -558,7 +586,7 @@ public:
558586 __is_nothrow_swappable<__node_allocator>::value);
559587#endif
560588protected:
561 void clear() _NOEXCEPT;
589 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
562590
563591private:
564592 _LIBCPP_INLINE_VISIBILITY
......@@ -659,9 +687,17 @@ public:
659687 typedef _Tp value_type;
660688 typedef _Alloc allocator_type;
661689
662 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
690 static_assert(is_same<value_type, typename allocator_type::value_type>::value,
663691 "Allocator::value_type must be same type as value_type");
664692
693 static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value,
694 "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
695 "original allocator");
696
697 static_assert((!is_same<allocator_type, __node_allocator>::value),
698 "internal allocator type must differ from user-specified "
699 "type; otherwise overload resolution breaks");
700
665701 typedef value_type& reference;
666702 typedef const value_type& const_reference;
667703 typedef typename allocator_traits<allocator_type>::pointer pointer;
......@@ -671,7 +707,7 @@ public:
671707
672708 typedef typename base::iterator iterator;
673709 typedef typename base::const_iterator const_iterator;
674#if _LIBCPP_STD_VER > 17
710#if _LIBCPP_STD_VER >= 20
675711 typedef size_type __remove_return_type;
676712#else
677713 typedef void __remove_return_type;
......@@ -683,39 +719,48 @@ public:
683719 {} // = default;
684720 _LIBCPP_INLINE_VISIBILITY
685721 explicit forward_list(const allocator_type& __a);
686 explicit forward_list(size_type __n);
687#if _LIBCPP_STD_VER > 11
688 explicit forward_list(size_type __n, const allocator_type& __a);
722 _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n);
723#if _LIBCPP_STD_VER >= 14
724 _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n, const allocator_type& __a);
689725#endif
690 forward_list(size_type __n, const value_type& __v);
726 _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v);
691727
692728 template <class = __enable_if_t<__is_allocator<_Alloc>::value> >
693 forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a)
729 _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a)
694730 {
695731 insert_after(cbefore_begin(), __n, __v);
696732 }
697733
698734 template <class _InputIterator>
699 forward_list(_InputIterator __f, _InputIterator __l,
700 __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>* = nullptr);
735 _LIBCPP_HIDE_FROM_ABI forward_list(_InputIterator __f, _InputIterator __l,
736 __enable_if_t<__has_input_iterator_category<_InputIterator>::value>* = nullptr);
701737 template <class _InputIterator>
702 forward_list(_InputIterator __f, _InputIterator __l,
738 _LIBCPP_HIDE_FROM_ABI forward_list(_InputIterator __f, _InputIterator __l,
703739 const allocator_type& __a,
704 __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>* = nullptr);
705 forward_list(const forward_list& __x);
706 forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a);
740 __enable_if_t<__has_input_iterator_category<_InputIterator>::value>* = nullptr);
707741
708 forward_list& operator=(const forward_list& __x);
742#if _LIBCPP_STD_VER >= 23
743 template <_ContainerCompatibleRange<_Tp> _Range>
744 _LIBCPP_HIDE_FROM_ABI forward_list(from_range_t, _Range&& __range,
745 const allocator_type& __a = allocator_type()) : base(__a) {
746 prepend_range(std::forward<_Range>(__range));
747 }
748#endif
749
750 _LIBCPP_HIDE_FROM_ABI forward_list(const forward_list& __x);
751 _LIBCPP_HIDE_FROM_ABI forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a);
752
753 _LIBCPP_HIDE_FROM_ABI forward_list& operator=(const forward_list& __x);
709754
710755#ifndef _LIBCPP_CXX03_LANG
711756 _LIBCPP_INLINE_VISIBILITY
712757 forward_list(forward_list&& __x)
713758 _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
714759 : base(_VSTD::move(__x)) {}
715 forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a);
760 _LIBCPP_HIDE_FROM_ABI forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a);
716761
717 forward_list(initializer_list<value_type> __il);
718 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
762 _LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il);
763 _LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il, const allocator_type& __a);
719764
720765 _LIBCPP_INLINE_VISIBILITY
721766 forward_list& operator=(forward_list&& __x)
......@@ -733,9 +778,18 @@ public:
733778 // ~forward_list() = default;
734779
735780 template <class _InputIterator>
736 __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>
737 assign(_InputIterator __f, _InputIterator __l);
738 void assign(size_type __n, const value_type& __v);
781 __enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>
782 _LIBCPP_HIDE_FROM_ABI assign(_InputIterator __f, _InputIterator __l);
783
784#if _LIBCPP_STD_VER >= 23
785 template <_ContainerCompatibleRange<_Tp> _Range>
786 _LIBCPP_HIDE_FROM_ABI
787 void assign_range(_Range&& __range) {
788 __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
789 }
790#endif
791
792 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);
739793
740794 _LIBCPP_INLINE_VISIBILITY
741795 allocator_type get_allocator() const _NOEXCEPT
......@@ -787,34 +841,56 @@ public:
787841 const_reference front() const {return base::__before_begin()->__next_->__value_;}
788842
789843#ifndef _LIBCPP_CXX03_LANG
790#if _LIBCPP_STD_VER > 14
791 template <class... _Args> reference emplace_front(_Args&&... __args);
844#if _LIBCPP_STD_VER >= 17
845 template <class... _Args>
846 _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args);
792847#else
793 template <class... _Args> void emplace_front(_Args&&... __args);
848 template <class... _Args>
849 _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args);
794850#endif
795 void push_front(value_type&& __v);
851 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v);
796852#endif // _LIBCPP_CXX03_LANG
797 void push_front(const value_type& __v);
853 _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v);
798854
799 void pop_front();
855#if _LIBCPP_STD_VER >= 23
856 template <_ContainerCompatibleRange<_Tp> _Range>
857 _LIBCPP_HIDE_FROM_ABI
858 void prepend_range(_Range&& __range) {
859 insert_range_after(cbefore_begin(), std::forward<_Range>(__range));
860 }
861#endif
862
863 _LIBCPP_HIDE_FROM_ABI void pop_front();
800864
801865#ifndef _LIBCPP_CXX03_LANG
802866 template <class... _Args>
803 iterator emplace_after(const_iterator __p, _Args&&... __args);
867 _LIBCPP_HIDE_FROM_ABI iterator emplace_after(const_iterator __p, _Args&&... __args);
804868
805 iterator insert_after(const_iterator __p, value_type&& __v);
806 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
869 _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, value_type&& __v);
870 _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
807871 {return insert_after(__p, __il.begin(), __il.end());}
808872#endif // _LIBCPP_CXX03_LANG
809 iterator insert_after(const_iterator __p, const value_type& __v);
810 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
873 _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, const value_type& __v);
874 _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
811875 template <class _InputIterator>
812876 _LIBCPP_INLINE_VISIBILITY
813 __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, iterator>
877 __enable_if_t<__has_input_iterator_category<_InputIterator>::value, iterator>
814878 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
815879
816 iterator erase_after(const_iterator __p);
817 iterator erase_after(const_iterator __f, const_iterator __l);
880#if _LIBCPP_STD_VER >= 23
881 template <_ContainerCompatibleRange<_Tp> _Range>
882 _LIBCPP_HIDE_FROM_ABI
883 iterator insert_range_after(const_iterator __position, _Range&& __range) {
884 return __insert_after_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
885 }
886#endif
887
888 template <class _InputIterator, class _Sentinel>
889 _LIBCPP_HIDE_FROM_ABI
890 iterator __insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l);
891
892 _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __p);
893 _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __f, const_iterator __l);
818894
819895 _LIBCPP_INLINE_VISIBILITY
820896 void swap(forward_list& __x)
......@@ -826,8 +902,8 @@ public:
826902#endif
827903 {base::swap(__x);}
828904
829 void resize(size_type __n);
830 void resize(size_type __n, const value_type& __v);
905 _LIBCPP_HIDE_FROM_ABI void resize(size_type __n);
906 _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v);
831907 _LIBCPP_INLINE_VISIBILITY
832908 void clear() _NOEXCEPT {base::clear();}
833909
......@@ -838,46 +914,54 @@ public:
838914 _LIBCPP_INLINE_VISIBILITY
839915 void splice_after(const_iterator __p, forward_list&& __x,
840916 const_iterator __f, const_iterator __l);
841 void splice_after(const_iterator __p, forward_list& __x);
842 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
843 void splice_after(const_iterator __p, forward_list& __x,
917 _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x);
918 _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
919 _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x,
844920 const_iterator __f, const_iterator __l);
845 __remove_return_type remove(const value_type& __v);
846 template <class _Predicate> __remove_return_type remove_if(_Predicate __pred);
921 _LIBCPP_HIDE_FROM_ABI __remove_return_type remove(const value_type& __v);
922 template <class _Predicate>
923 _LIBCPP_HIDE_FROM_ABI __remove_return_type remove_if(_Predicate __pred);
847924 _LIBCPP_INLINE_VISIBILITY
848925 __remove_return_type unique() { return unique(__equal_to()); }
849 template <class _BinaryPredicate> __remove_return_type unique(_BinaryPredicate __binary_pred);
926 template <class _BinaryPredicate>
927 _LIBCPP_HIDE_FROM_ABI __remove_return_type unique(_BinaryPredicate __binary_pred);
850928#ifndef _LIBCPP_CXX03_LANG
851929 _LIBCPP_INLINE_VISIBILITY
852 void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
930 void merge(forward_list&& __x) {merge(__x, __less<>());}
853931 template <class _Compare>
854932 _LIBCPP_INLINE_VISIBILITY
855933 void merge(forward_list&& __x, _Compare __comp)
856934 {merge(__x, _VSTD::move(__comp));}
857935#endif // _LIBCPP_CXX03_LANG
858936 _LIBCPP_INLINE_VISIBILITY
859 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
860 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
937 void merge(forward_list& __x) {merge(__x, __less<>());}
938 template <class _Compare>
939 _LIBCPP_HIDE_FROM_ABI void merge(forward_list& __x, _Compare __comp);
861940 _LIBCPP_INLINE_VISIBILITY
862 void sort() {sort(__less<value_type>());}
941 void sort() {sort(__less<>());}
863942 template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp);
864 void reverse() _NOEXCEPT;
943 _LIBCPP_HIDE_FROM_ABI void reverse() _NOEXCEPT;
865944
866945private:
867946
868947#ifndef _LIBCPP_CXX03_LANG
869 void __move_assign(forward_list& __x, true_type)
948 _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, true_type)
870949 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
871 void __move_assign(forward_list& __x, false_type);
950 _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, false_type);
872951#endif // _LIBCPP_CXX03_LANG
873952
953 template <class _Iter, class _Sent>
954 _LIBCPP_HIDE_FROM_ABI
955 void __assign_with_sentinel(_Iter __f, _Sent __l);
956
874957 template <class _Compare>
875 static
958 static _LIBCPP_HIDE_FROM_ABI
876959 __node_pointer
877960 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
878961
962 // TODO: Make this _LIBCPP_HIDE_FROM_ABI
879963 template <class _Compare>
880 static
964 static _LIBCPP_HIDDEN
881965 __node_pointer
882966 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
883967};
......@@ -886,7 +970,7 @@ private:
886970#if _LIBCPP_STD_VER >= 17
887971template<class _InputIterator,
888972 class _Alloc = allocator<__iter_value_type<_InputIterator>>,
889 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
973 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
890974 class = enable_if_t<__is_allocator<_Alloc>::value>
891975 >
892976forward_list(_InputIterator, _InputIterator)
......@@ -894,13 +978,22 @@ forward_list(_InputIterator, _InputIterator)
894978
895979template<class _InputIterator,
896980 class _Alloc,
897 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
981 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
898982 class = enable_if_t<__is_allocator<_Alloc>::value>
899983 >
900984forward_list(_InputIterator, _InputIterator, _Alloc)
901985 -> forward_list<__iter_value_type<_InputIterator>, _Alloc>;
902986#endif
903987
988#if _LIBCPP_STD_VER >= 23
989template <ranges::input_range _Range,
990 class _Alloc = allocator<ranges::range_value_t<_Range>>,
991 class = enable_if_t<__is_allocator<_Alloc>::value>
992 >
993forward_list(from_range_t, _Range&&, _Alloc = _Alloc())
994 -> forward_list<ranges::range_value_t<_Range>, _Alloc>;
995#endif
996
904997template <class _Tp, class _Alloc>
905998inline
906999forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
......@@ -927,7 +1020,7 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n)
9271020 }
9281021}
9291022
930#if _LIBCPP_STD_VER > 11
1023#if _LIBCPP_STD_VER >= 14
9311024template <class _Tp, class _Alloc>
9321025forward_list<_Tp, _Alloc>::forward_list(size_type __n,
9331026 const allocator_type& __base_alloc)
......@@ -959,7 +1052,7 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
9591052template <class _Tp, class _Alloc>
9601053template <class _InputIterator>
9611054forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
962 __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>*)
1055 __enable_if_t<__has_input_iterator_category<_InputIterator>::value>*)
9631056{
9641057 insert_after(cbefore_begin(), __f, __l);
9651058}
......@@ -968,7 +1061,7 @@ template <class _Tp, class _Alloc>
9681061template <class _InputIterator>
9691062forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
9701063 const allocator_type& __a,
971 __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>*)
1064 __enable_if_t<__has_input_iterator_category<_InputIterator>::value>*)
9721065 : base(__a)
9731066{
9741067 insert_after(cbefore_begin(), __f, __l);
......@@ -1078,16 +1171,23 @@ forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
10781171
10791172template <class _Tp, class _Alloc>
10801173template <class _InputIterator>
1081__enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>
1174__enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>
10821175forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
10831176{
1177 __assign_with_sentinel(__f, __l);
1178}
1179
1180template <class _Tp, class _Alloc>
1181template <class _Iter, class _Sent>
1182_LIBCPP_HIDE_FROM_ABI
1183void forward_list<_Tp, _Alloc>::__assign_with_sentinel(_Iter __f, _Sent __l) {
10841184 iterator __i = before_begin();
10851185 iterator __j = _VSTD::next(__i);
10861186 iterator __e = end();
10871187 for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f)
10881188 *__j = *__f;
10891189 if (__j == __e)
1090 insert_after(__i, __f, __l);
1190 __insert_after_with_sentinel(__i, std::move(__f), std::move(__l));
10911191 else
10921192 erase_after(__i, __e);
10931193}
......@@ -1119,7 +1219,7 @@ forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
11191219
11201220template <class _Tp, class _Alloc>
11211221template <class... _Args>
1122#if _LIBCPP_STD_VER > 14
1222#if _LIBCPP_STD_VER >= 17
11231223typename forward_list<_Tp, _Alloc>::reference
11241224#else
11251225void
......@@ -1133,7 +1233,7 @@ forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
11331233 _VSTD::forward<_Args>(__args)...);
11341234 __h->__next_ = base::__before_begin()->__next_;
11351235 base::__before_begin()->__next_ = __h.release();
1136#if _LIBCPP_STD_VER > 14
1236#if _LIBCPP_STD_VER >= 17
11371237 return base::__before_begin()->__next_->__value_;
11381238#endif
11391239}
......@@ -1228,26 +1328,33 @@ typename forward_list<_Tp, _Alloc>::iterator
12281328forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
12291329 const value_type& __v)
12301330{
1331 using _Guard = __allocation_guard<__node_allocator>;
1332
12311333 __begin_node_pointer __r = __p.__get_begin();
12321334 if (__n > 0)
12331335 {
12341336 __node_allocator& __a = base::__alloc();
1235 typedef __allocator_destructor<__node_allocator> _Dp;
1236 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1237 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1238 __node_pointer __first = __h.release();
1337
1338 __node_pointer __first = nullptr;
1339 {
1340 _Guard __h(__a, 1);
1341 __node_traits::construct(__a, std::addressof(__h.__get()->__value_), __v);
1342 __h.__get()->__next_ = nullptr;
1343 __first = __h.__release_ptr();
1344 }
12391345 __node_pointer __last = __first;
1240#ifndef _LIBCPP_NO_EXCEPTIONS
1346#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
12411347 try
12421348 {
1243#endif // _LIBCPP_NO_EXCEPTIONS
1349#endif // _LIBCPP_HAS_NO_EXCEPTIONS
12441350 for (--__n; __n != 0; --__n, __last = __last->__next_)
12451351 {
1246 __h.reset(__node_traits::allocate(__a, 1));
1247 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1248 __last->__next_ = __h.release();
1352 _Guard __h(__a, 1);
1353 __node_traits::construct(__a, std::addressof(__h.__get()->__value_), __v);
1354 __h.__get()->__next_ = nullptr;
1355 __last->__next_ = __h.__release_ptr();
12491356 }
1250#ifndef _LIBCPP_NO_EXCEPTIONS
1357#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
12511358 }
12521359 catch (...)
12531360 {
......@@ -1260,7 +1367,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
12601367 }
12611368 throw;
12621369 }
1263#endif // _LIBCPP_NO_EXCEPTIONS
1370#endif // _LIBCPP_HAS_NO_EXCEPTIONS
12641371 __last->__next_ = __r->__next_;
12651372 __r->__next_ = __first;
12661373 __r = static_cast<__begin_node_pointer>(__last);
......@@ -1270,30 +1377,45 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
12701377
12711378template <class _Tp, class _Alloc>
12721379template <class _InputIterator>
1273__enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, typename forward_list<_Tp, _Alloc>::iterator>
1380__enable_if_t<__has_input_iterator_category<_InputIterator>::value, typename forward_list<_Tp, _Alloc>::iterator>
12741381forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
12751382 _InputIterator __f, _InputIterator __l)
12761383{
1384 return __insert_after_with_sentinel(__p, std::move(__f), std::move(__l));
1385}
1386
1387template <class _Tp, class _Alloc>
1388template <class _InputIterator, class _Sentinel>
1389_LIBCPP_HIDE_FROM_ABI
1390typename forward_list<_Tp, _Alloc>::iterator
1391forward_list<_Tp, _Alloc>::__insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l) {
1392 using _Guard = __allocation_guard<__node_allocator>;
12771393 __begin_node_pointer __r = __p.__get_begin();
1394
12781395 if (__f != __l)
12791396 {
12801397 __node_allocator& __a = base::__alloc();
1281 typedef __allocator_destructor<__node_allocator> _Dp;
1282 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1283 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
1284 __node_pointer __first = __h.release();
1398 __node_pointer __first = nullptr;
1399 {
1400 _Guard __h(__a, 1);
1401 __node_traits::construct(__a, std::addressof(__h.__get()->__value_), *__f);
1402 __h.__get()->__next_ = nullptr;
1403 __first = __h.__release_ptr();
1404 }
12851405 __node_pointer __last = __first;
1286#ifndef _LIBCPP_NO_EXCEPTIONS
1406
1407#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
12871408 try
12881409 {
1289#endif // _LIBCPP_NO_EXCEPTIONS
1410#endif // _LIBCPP_HAS_NO_EXCEPTIONS
12901411 for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_)))
12911412 {
1292 __h.reset(__node_traits::allocate(__a, 1));
1293 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
1294 __last->__next_ = __h.release();
1413 _Guard __h(__a, 1);
1414 __node_traits::construct(__a, std::addressof(__h.__get()->__value_), *__f);
1415 __h.__get()->__next_ = nullptr;
1416 __last->__next_ = __h.__release_ptr();
12951417 }
1296#ifndef _LIBCPP_NO_EXCEPTIONS
1418#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
12971419 }
12981420 catch (...)
12991421 {
......@@ -1306,11 +1428,13 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
13061428 }
13071429 throw;
13081430 }
1309#endif // _LIBCPP_NO_EXCEPTIONS
1431#endif // _LIBCPP_HAS_NO_EXCEPTIONS
1432
13101433 __last->__next_ = __r->__next_;
13111434 __r->__next_ = __first;
13121435 __r = static_cast<__begin_node_pointer>(__last);
13131436 }
1437
13141438 return iterator(__r);
13151439}
13161440
......@@ -1711,6 +1835,8 @@ bool operator==(const forward_list<_Tp, _Alloc>& __x,
17111835 return (__ix == __ex) == (__iy == __ey);
17121836}
17131837
1838#if _LIBCPP_STD_VER <= 17
1839
17141840template <class _Tp, class _Alloc>
17151841inline _LIBCPP_INLINE_VISIBILITY
17161842bool operator!=(const forward_list<_Tp, _Alloc>& __x,
......@@ -1752,6 +1878,17 @@ bool operator<=(const forward_list<_Tp, _Alloc>& __x,
17521878 return !(__y < __x);
17531879}
17541880
1881#else // #if _LIBCPP_STD_VER <= 17
1882
1883template <class _Tp, class _Allocator>
1884_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp>
1885operator<=>(const forward_list<_Tp, _Allocator>& __x, const forward_list<_Tp, _Allocator>& __y) {
1886 return std::lexicographical_compare_three_way(
1887 __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>);
1888}
1889
1890#endif // #if _LIBCPP_STD_VER <= 17
1891
17551892template <class _Tp, class _Alloc>
17561893inline _LIBCPP_INLINE_VISIBILITY
17571894void
......@@ -1761,7 +1898,7 @@ swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
17611898 __x.swap(__y);
17621899}
17631900
1764#if _LIBCPP_STD_VER > 17
1901#if _LIBCPP_STD_VER >= 20
17651902template <class _Tp, class _Allocator, class _Predicate>
17661903inline _LIBCPP_INLINE_VISIBILITY
17671904 typename forward_list<_Tp, _Allocator>::size_type
......@@ -1779,11 +1916,11 @@ inline _LIBCPP_INLINE_VISIBILITY
17791916
17801917_LIBCPP_END_NAMESPACE_STD
17811918
1782#if _LIBCPP_STD_VER > 14
1919#if _LIBCPP_STD_VER >= 17
17831920_LIBCPP_BEGIN_NAMESPACE_STD
17841921namespace pmr {
17851922template <class _ValueT>
1786using forward_list = std::forward_list<_ValueT, polymorphic_allocator<_ValueT>>;
1923using forward_list _LIBCPP_AVAILABILITY_PMR = std::forward_list<_ValueT, polymorphic_allocator<_ValueT>>;
17871924} // namespace pmr
17881925_LIBCPP_END_NAMESPACE_STD
17891926#endif
......@@ -1794,9 +1931,11 @@ _LIBCPP_POP_MACROS
17941931# include <algorithm>
17951932# include <atomic>
17961933# include <concepts>
1934# include <cstdlib>
17971935# include <functional>
17981936# include <iosfwd>
17991937# include <iterator>
1938# include <type_traits>
18001939# include <typeinfo>
18011940#endif
18021941
lib/libcxx/include/fstream+27-30
......@@ -183,22 +183,18 @@ typedef basic_fstream<wchar_t> wfstream;
183183#include <__assert> // all public C++ headers provide the assertion handler
184184#include <__availability>
185185#include <__config>
186#include <__fwd/fstream.h>
186187#include <__locale>
187188#include <__utility/move.h>
188189#include <__utility/swap.h>
189190#include <__utility/unreachable.h>
190191#include <cstdio>
191#include <cstdlib>
192#include <cstring>
192#include <filesystem>
193193#include <istream>
194194#include <ostream>
195195#include <typeinfo>
196196#include <version>
197197
198#if !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
199# include <filesystem>
200#endif
201
202198#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
203199# pragma GCC system_header
204200#endif
......@@ -210,7 +206,7 @@ _LIBCPP_PUSH_MACROS
210206# define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
211207#endif
212208
213#if !defined(_LIBCPP_HAS_NO_FSTREAM)
209#if !defined(_LIBCPP_HAS_NO_FILESYSTEM)
214210
215211_LIBCPP_BEGIN_NAMESPACE_STD
216212
......@@ -246,8 +242,8 @@ public:
246242 _LIBCPP_INLINE_VISIBILITY
247243 basic_filebuf* open(const string& __s, ios_base::openmode __mode);
248244
249#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
250 _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
245#if _LIBCPP_STD_VER >= 17
246 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
251247 basic_filebuf* open(const _VSTD_FS::path& __p, ios_base::openmode __mode) {
252248 return open(__p.c_str(), __mode);
253249 }
......@@ -398,17 +394,17 @@ basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs)
398394template <class _CharT, class _Traits>
399395basic_filebuf<_CharT, _Traits>::~basic_filebuf()
400396{
401#ifndef _LIBCPP_NO_EXCEPTIONS
397#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
402398 try
403399 {
404#endif // _LIBCPP_NO_EXCEPTIONS
400#endif // _LIBCPP_HAS_NO_EXCEPTIONS
405401 close();
406#ifndef _LIBCPP_NO_EXCEPTIONS
402#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
407403 }
408404 catch (...)
409405 {
410406 }
411#endif // _LIBCPP_NO_EXCEPTIONS
407#endif // _LIBCPP_HAS_NO_EXCEPTIONS
412408 if (__owns_eb_)
413409 delete [] __extbuf_;
414410 if (__owns_ib_)
......@@ -754,8 +750,8 @@ basic_filebuf<_CharT, _Traits>::underflow()
754750 else
755751 {
756752 if (__extbufend_ != __extbufnext_) {
757 _LIBCPP_ASSERT(__extbufnext_ != nullptr, "underflow moving from nullptr");
758 _LIBCPP_ASSERT(__extbuf_ != nullptr, "underflow moving into nullptr");
753 _LIBCPP_ASSERT_UNCATEGORIZED(__extbufnext_ != nullptr, "underflow moving from nullptr");
754 _LIBCPP_ASSERT_UNCATEGORIZED(__extbuf_ != nullptr, "underflow moving into nullptr");
759755 _VSTD::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
760756 }
761757 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
......@@ -1169,8 +1165,8 @@ public:
11691165#endif
11701166 _LIBCPP_INLINE_VISIBILITY
11711167 explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
1172#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
1173 _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
1168#if _LIBCPP_STD_VER >= 17
1169 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
11741170 explicit basic_ifstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in)
11751171 : basic_ifstream(__p.c_str(), __mode) {}
11761172#endif // _LIBCPP_STD_VER >= 17
......@@ -1190,8 +1186,8 @@ public:
11901186 void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
11911187#endif
11921188 void open(const string& __s, ios_base::openmode __mode = ios_base::in);
1193#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
1194 _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
1189#if _LIBCPP_STD_VER >= 17
1190 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
11951191 void open(const filesystem::path& __p,
11961192 ios_base::openmode __mode = ios_base::in) {
11971193 return open(__p.c_str(), __mode);
......@@ -1370,8 +1366,8 @@ public:
13701366 _LIBCPP_INLINE_VISIBILITY
13711367 explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
13721368
1373#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
1374 _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
1369#if _LIBCPP_STD_VER >= 17
1370 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
13751371 explicit basic_ofstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
13761372 : basic_ofstream(__p.c_str(), __mode) {}
13771373#endif // _LIBCPP_STD_VER >= 17
......@@ -1393,8 +1389,8 @@ public:
13931389#endif
13941390 void open(const string& __s, ios_base::openmode __mode = ios_base::out);
13951391
1396#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
1397 _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
1392#if _LIBCPP_STD_VER >= 17
1393 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
13981394 void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
13991395 { return open(__p.c_str(), __mode); }
14001396#endif // _LIBCPP_STD_VER >= 17
......@@ -1571,8 +1567,8 @@ public:
15711567 _LIBCPP_INLINE_VISIBILITY
15721568 explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
15731569
1574#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
1575 _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
1570#if _LIBCPP_STD_VER >= 17
1571 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
15761572 explicit basic_fstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
15771573 : basic_fstream(__p.c_str(), __mode) {}
15781574#endif // _LIBCPP_STD_VER >= 17
......@@ -1590,14 +1586,14 @@ public:
15901586 basic_filebuf<char_type, traits_type>* rdbuf() const;
15911587 _LIBCPP_INLINE_VISIBILITY
15921588 bool is_open() const;
1593 void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1589 _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
15941590#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
15951591 void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
15961592#endif
1597 void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1593 _LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
15981594
1599#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
1600 _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
1595#if _LIBCPP_STD_VER >= 17
1596 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY
16011597 void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in|ios_base::out)
16021598 { return open(__p.c_str(), __mode); }
16031599#endif // _LIBCPP_STD_VER >= 17
......@@ -1746,13 +1742,14 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>;
17461742
17471743_LIBCPP_END_NAMESPACE_STD
17481744
1749#endif // _LIBCPP_HAS_NO_FSTREAM
1745#endif // _LIBCPP_HAS_NO_FILESYSTEM
17501746
17511747_LIBCPP_POP_MACROS
17521748
17531749#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
17541750# include <atomic>
17551751# include <concepts>
1752# include <cstdlib>
17561753# include <iosfwd>
17571754# include <limits>
17581755# include <new>
lib/libcxx/include/functional+54-41
......@@ -43,20 +43,22 @@ public:
4343
4444 // construct/copy/destroy
4545 template<class U>
46 reference_wrapper(U&&);
47 reference_wrapper(const reference_wrapper<T>& x) noexcept;
46 constexpr reference_wrapper(U&&); // constexpr since C++20
47 constexpr reference_wrapper(const reference_wrapper<T>& x) noexcept; // constexpr since C++20
4848
4949 // assignment
50 reference_wrapper& operator=(const reference_wrapper<T>& x) noexcept;
50 constexpr reference_wrapper&
51 operator=(const reference_wrapper<T>& x) noexcept; // constexpr since C++20
5152
5253 // access
53 operator T& () const noexcept;
54 T& get() const noexcept;
54 constexpr operator T& () const noexcept; // constexpr since C++20
55 constexpr T& get() const noexcept; // constexpr since C++20
5556
5657 // invoke
5758 template <class... ArgTypes>
58 typename result_of<T&(ArgTypes&&...)>::type
59 operator() (ArgTypes&&...) const;
59 constexpr typename result_of<T&(ArgTypes&&...)>::type // constexpr since C++20
60 operator() (ArgTypes&&...) const
61 noexcept(is_nothrow_invocable_v<T&, ArgTypes...>); // noexcept since C++17
6062};
6163
6264template <class T>
......@@ -220,11 +222,16 @@ template<class Fn, class... BoundArgs>
220222template<class R, class Fn, class... BoundArgs>
221223 constexpr unspecified bind(Fn&&, BoundArgs&&...); // constexpr in C++20
222224
225// [func.invoke]
223226template<class F, class... Args>
224227 constexpr // constexpr in C++20
225228 invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) // C++17
226229 noexcept(is_nothrow_invocable_v<F, Args...>);
227230
231template<class R, class F, class... Args>
232 constexpr R invoke_r(F&& f, Args&&... args) // C++23
233 noexcept(is_nothrow_invocable_r_v<R, F, Args...>);
234
228235namespace placeholders {
229236 // M is the implementation-defined number of placeholders
230237 extern unspecified _1;
......@@ -250,10 +257,10 @@ public:
250257};
251258
252259template <class Operation, class T>
253binder1st<Operation> bind1st(const Operation& op, const T& x); // deprecated in C++11, removed in C++17
260binder1st<Operation> bind1st(const Operation& op, const T& x); // deprecated in C++11, removed in C++17
254261
255262template <class Operation>
256class binder2nd // deprecated in C++11, removed in C++17
263class binder2nd // deprecated in C++11, removed in C++17
257264 : public unary_function<typename Operation::first_argument_type,
258265 typename Operation::result_type>
259266{
......@@ -267,9 +274,9 @@ public:
267274};
268275
269276template <class Operation, class T>
270binder2nd<Operation> bind2nd(const Operation& op, const T& x); // deprecated in C++11, removed in C++17
277binder2nd<Operation> bind2nd(const Operation& op, const T& x); // deprecated in C++11, removed in C++17
271278
272template <class Arg, class Result> // deprecated in C++11, removed in C++17
279template <class Arg, class Result> // deprecated in C++11, removed in C++17
273280class pointer_to_unary_function : public unary_function<Arg, Result>
274281{
275282public:
......@@ -278,9 +285,9 @@ public:
278285};
279286
280287template <class Arg, class Result>
281pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg)); // deprecated in C++11, removed in C++17
288pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg)); // deprecated in C++11, removed in C++17
282289
283template <class Arg1, class Arg2, class Result> // deprecated in C++11, removed in C++17
290template <class Arg1, class Arg2, class Result> // deprecated in C++11, removed in C++17
284291class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result>
285292{
286293public:
......@@ -289,9 +296,9 @@ public:
289296};
290297
291298template <class Arg1, class Arg2, class Result>
292pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1,Arg2)); // deprecated in C++11, removed in C++17
299pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1,Arg2)); // deprecated in C++11, removed in C++17
293300
294template<class S, class T> // deprecated in C++11, removed in C++17
301template<class S, class T> // deprecated in C++11, removed in C++17
295302class mem_fun_t : public unary_function<T*, S>
296303{
297304public:
......@@ -300,18 +307,18 @@ public:
300307};
301308
302309template<class S, class T, class A>
303class mem_fun1_t : public binary_function<T*, A, S> // deprecated in C++11, removed in C++17
310class mem_fun1_t : public binary_function<T*, A, S> // deprecated in C++11, removed in C++17
304311{
305312public:
306313 explicit mem_fun1_t(S (T::*p)(A));
307314 S operator()(T* p, A x) const;
308315};
309316
310template<class S, class T> mem_fun_t<S,T> mem_fun(S (T::*f)()); // deprecated in C++11, removed in C++17
311template<class S, class T, class A> mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A)); // deprecated in C++11, removed in C++17
317template<class S, class T> mem_fun_t<S,T> mem_fun(S (T::*f)()); // deprecated in C++11, removed in C++17
318template<class S, class T, class A> mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A)); // deprecated in C++11, removed in C++17
312319
313320template<class S, class T>
314class mem_fun_ref_t : public unary_function<T, S> // deprecated in C++11, removed in C++17
321class mem_fun_ref_t : public unary_function<T, S> // deprecated in C++11, removed in C++17
315322{
316323public:
317324 explicit mem_fun_ref_t(S (T::*p)());
......@@ -319,18 +326,20 @@ public:
319326};
320327
321328template<class S, class T, class A>
322class mem_fun1_ref_t : public binary_function<T, A, S> // deprecated in C++11, removed in C++17
329class mem_fun1_ref_t : public binary_function<T, A, S> // deprecated in C++11, removed in C++17
323330{
324331public:
325332 explicit mem_fun1_ref_t(S (T::*p)(A));
326333 S operator()(T& p, A x) const;
327334};
328335
329template<class S, class T> mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()); // deprecated in C++11, removed in C++17
330template<class S, class T, class A> mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A)); // deprecated in C++11, removed in C++17
336template<class S, class T>
337mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()); // deprecated in C++11, removed in C++17
338template<class S, class T, class A>
339mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A)); // deprecated in C++11, removed in C++17
331340
332341template <class S, class T>
333class const_mem_fun_t : public unary_function<const T*, S> // deprecated in C++11, removed in C++17
342class const_mem_fun_t : public unary_function<const T*, S> // deprecated in C++11, removed in C++17
334343{
335344public:
336345 explicit const_mem_fun_t(S (T::*p)() const);
......@@ -338,18 +347,20 @@ public:
338347};
339348
340349template <class S, class T, class A>
341class const_mem_fun1_t : public binary_function<const T*, A, S> // deprecated in C++11, removed in C++17
350class const_mem_fun1_t : public binary_function<const T*, A, S> // deprecated in C++11, removed in C++17
342351{
343352public:
344353 explicit const_mem_fun1_t(S (T::*p)(A) const);
345354 S operator()(const T* p, A x) const;
346355};
347356
348template <class S, class T> const_mem_fun_t<S,T> mem_fun(S (T::*f)() const); // deprecated in C++11, removed in C++17
349template <class S, class T, class A> const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const); // deprecated in C++11, removed in C++17
357template <class S, class T>
358const_mem_fun_t<S,T> mem_fun(S (T::*f)() const); // deprecated in C++11, removed in C++17
359template <class S, class T, class A>
360const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const); // deprecated in C++11, removed in C++17
350361
351362template <class S, class T>
352class const_mem_fun_ref_t : public unary_function<T, S> // deprecated in C++11, removed in C++17
363class const_mem_fun_ref_t : public unary_function<T, S> // deprecated in C++11, removed in C++17
353364{
354365public:
355366 explicit const_mem_fun_ref_t(S (T::*p)() const);
......@@ -357,18 +368,19 @@ public:
357368};
358369
359370template <class S, class T, class A>
360class const_mem_fun1_ref_t : public binary_function<T, A, S> // deprecated in C++11, removed in C++17
371class const_mem_fun1_ref_t : public binary_function<T, A, S> // deprecated in C++11, removed in C++17
361372{
362373public:
363374 explicit const_mem_fun1_ref_t(S (T::*p)(A) const);
364375 S operator()(const T& p, A x) const;
365376};
366377
367template <class S, class T> const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const); // deprecated in C++11, removed in C++17
368template <class S, class T, class A> const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const); // deprecated in C++11, removed in C++17
378template <class S, class T>
379const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const); // deprecated in C++11, removed in C++17
380template <class S, class T, class A>
381const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const); // deprecated in C++11, removed in C++17
369382
370template<class R, class T>
371constexpr unspecified mem_fn(R T::*); // constexpr in C++20
383template<class R, class T> constexpr unspecified mem_fn(R T::*); // constexpr in C++20
372384
373385class bad_function_call
374386 : public exception
......@@ -444,13 +456,13 @@ template <class R, class ... ArgTypes>
444456 bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
445457
446458template <class R, class ... ArgTypes>
447 bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
459 bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept; // removed in C++20
448460
449461template <class R, class ... ArgTypes>
450 bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
462 bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept; // removed in C++20
451463
452464template <class R, class ... ArgTypes>
453 bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
465 bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept; // removed in C++20
454466
455467// specialized algorithms:
456468template <class R, class ... ArgTypes>
......@@ -504,8 +516,7 @@ POLICY: For non-variadic implementations, the number of arguments is limited
504516#include <__assert> // all public C++ headers provide the assertion handler
505517#include <__compare/compare_three_way.h>
506518#include <__config>
507#include <__debug>
508#include <__functional/binary_function.h> // TODO: deprecate
519#include <__functional/binary_function.h>
509520#include <__functional/binary_negate.h>
510521#include <__functional/bind.h>
511522#include <__functional/bind_back.h>
......@@ -527,13 +538,11 @@ POLICY: For non-variadic implementations, the number of arguments is limited
527538#include <__functional/pointer_to_unary_function.h>
528539#include <__functional/ranges_operations.h>
529540#include <__functional/reference_wrapper.h>
530#include <__functional/unary_function.h> // TODO: deprecate
541#include <__functional/unary_function.h>
531542#include <__functional/unary_negate.h>
532#include <__functional/unwrap_ref.h>
543#include <__type_traits/unwrap_ref.h>
533544#include <__utility/forward.h>
534#include <exception>
535545#include <memory> // TODO: find out why removing this breaks the modules build
536#include <type_traits>
537546#include <typeinfo>
538547#include <version>
539548
......@@ -542,8 +551,12 @@ POLICY: For non-variadic implementations, the number of arguments is limited
542551#endif
543552
544553#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
554# include <atomic>
545555# include <concepts>
556# include <cstdlib>
557# include <exception>
546558# include <tuple>
559# include <type_traits>
547560# include <utility>
548561#endif
549562
lib/libcxx/include/future+147-129
......@@ -366,17 +366,29 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
366366#include <__chrono/duration.h>
367367#include <__chrono/time_point.h>
368368#include <__config>
369#include <__exception/exception_ptr.h>
370#include <__memory/addressof.h>
371#include <__memory/allocator.h>
369372#include <__memory/allocator_arg_t.h>
370373#include <__memory/allocator_destructor.h>
374#include <__memory/allocator_traits.h>
375#include <__memory/compressed_pair.h>
376#include <__memory/pointer_traits.h>
377#include <__memory/shared_ptr.h>
378#include <__memory/unique_ptr.h>
371379#include <__memory/uses_allocator.h>
380#include <__system_error/error_category.h>
381#include <__system_error/error_code.h>
382#include <__system_error/error_condition.h>
383#include <__type_traits/aligned_storage.h>
384#include <__type_traits/alignment_of.h>
372385#include <__type_traits/strip_signature.h>
373386#include <__utility/auto_cast.h>
374387#include <__utility/forward.h>
375388#include <__utility/move.h>
376#include <exception>
377389#include <mutex>
378390#include <new>
379#include <system_error>
391#include <stdexcept>
380392#include <thread>
381393#include <version>
382394
......@@ -488,8 +500,7 @@ _LIBCPP_DECLARE_STRONG_ENUM(future_status)
488500};
489501_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
490502
491_LIBCPP_FUNC_VIS
492const error_category& future_category() _NOEXCEPT;
503_LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT;
493504
494505inline _LIBCPP_INLINE_VISIBILITY
495506error_code
......@@ -505,7 +516,7 @@ make_error_condition(future_errc __e) _NOEXCEPT
505516 return error_condition(static_cast<int>(__e), future_category());
506517}
507518
508class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
519class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
509520 : public logic_error
510521{
511522 error_code __ec_;
......@@ -515,25 +526,25 @@ public:
515526 _LIBCPP_INLINE_VISIBILITY
516527 const error_code& code() const _NOEXCEPT {return __ec_;}
517528
518 future_error(const future_error&) _NOEXCEPT = default;
529 _LIBCPP_HIDE_FROM_ABI future_error(const future_error&) _NOEXCEPT = default;
519530 ~future_error() _NOEXCEPT override;
520531};
521532
522533_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
523#ifndef _LIBCPP_NO_EXCEPTIONS
534#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
524535_LIBCPP_AVAILABILITY_FUTURE_ERROR
525536#endif
526537void __throw_future_error(future_errc __ev)
527538{
528#ifndef _LIBCPP_NO_EXCEPTIONS
539#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
529540 throw future_error(make_error_code(__ev));
530541#else
531 ((void)__ev);
532 _VSTD::abort();
542 (void)__ev;
543 _LIBCPP_VERBOSE_ABORT("future_error was thrown in -fno-exceptions mode");
533544#endif
534545}
535546
536class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
547class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
537548 : public __shared_count
538549{
539550protected:
......@@ -631,17 +642,17 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
631642protected:
632643 _Up __value_;
633644
634 void __on_zero_shared() _NOEXCEPT override;
645 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
635646public:
636647
637648 template <class _Arg>
638 void set_value(_Arg&& __arg);
649 _LIBCPP_HIDE_FROM_ABI void set_value(_Arg&& __arg);
639650
640651 template <class _Arg>
641 void set_value_at_thread_exit(_Arg&& __arg);
652 _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Arg&& __arg);
642653
643 _Rp move();
644 __add_lvalue_reference_t<_Rp> copy();
654 _LIBCPP_HIDE_FROM_ABI _Rp move();
655 _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<_Rp> copy();
645656};
646657
647658template <class _Rp>
......@@ -711,13 +722,13 @@ class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
711722protected:
712723 _Up __value_;
713724
714 void __on_zero_shared() _NOEXCEPT override;
725 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
715726public:
716727
717 void set_value(_Rp& __arg);
718 void set_value_at_thread_exit(_Rp& __arg);
728 _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __arg);
729 _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp& __arg);
719730
720 _Rp& copy();
731 _LIBCPP_HIDE_FROM_ABI _Rp& copy();
721732};
722733
723734template <class _Rp>
......@@ -769,7 +780,7 @@ class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
769780 typedef __assoc_state<_Rp> base;
770781 _Alloc __alloc_;
771782
772 virtual void __on_zero_shared() _NOEXCEPT;
783 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
773784public:
774785 _LIBCPP_INLINE_VISIBILITY
775786 explicit __assoc_state_alloc(const _Alloc& __a)
......@@ -797,7 +808,7 @@ class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
797808 typedef __assoc_state<_Rp&> base;
798809 _Alloc __alloc_;
799810
800 virtual void __on_zero_shared() _NOEXCEPT;
811 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
801812public:
802813 _LIBCPP_INLINE_VISIBILITY
803814 explicit __assoc_state_alloc(const _Alloc& __a)
......@@ -823,7 +834,7 @@ class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
823834 typedef __assoc_sub_state base;
824835 _Alloc __alloc_;
825836
826 void __on_zero_shared() _NOEXCEPT override;
837 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
827838public:
828839 _LIBCPP_INLINE_VISIBILITY
829840 explicit __assoc_sub_state_alloc(const _Alloc& __a)
......@@ -854,7 +865,7 @@ public:
854865 _LIBCPP_INLINE_VISIBILITY
855866 explicit __deferred_assoc_state(_Fp&& __f);
856867
857 virtual void __execute();
868 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
858869};
859870
860871template <class _Rp, class _Fp>
......@@ -869,18 +880,18 @@ template <class _Rp, class _Fp>
869880void
870881__deferred_assoc_state<_Rp, _Fp>::__execute()
871882{
872#ifndef _LIBCPP_NO_EXCEPTIONS
883#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
873884 try
874885 {
875#endif // _LIBCPP_NO_EXCEPTIONS
886#endif // _LIBCPP_HAS_NO_EXCEPTIONS
876887 this->set_value(__func_());
877#ifndef _LIBCPP_NO_EXCEPTIONS
888#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
878889 }
879890 catch (...)
880891 {
881892 this->set_exception(current_exception());
882893 }
883#endif // _LIBCPP_NO_EXCEPTIONS
894#endif // _LIBCPP_HAS_NO_EXCEPTIONS
884895}
885896
886897template <class _Fp>
......@@ -895,7 +906,7 @@ public:
895906 _LIBCPP_INLINE_VISIBILITY
896907 explicit __deferred_assoc_state(_Fp&& __f);
897908
898 void __execute() override;
909 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
899910};
900911
901912template <class _Fp>
......@@ -910,19 +921,19 @@ template <class _Fp>
910921void
911922__deferred_assoc_state<void, _Fp>::__execute()
912923{
913#ifndef _LIBCPP_NO_EXCEPTIONS
924#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
914925 try
915926 {
916#endif // _LIBCPP_NO_EXCEPTIONS
927#endif // _LIBCPP_HAS_NO_EXCEPTIONS
917928 __func_();
918929 this->set_value();
919#ifndef _LIBCPP_NO_EXCEPTIONS
930#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
920931 }
921932 catch (...)
922933 {
923934 this->set_exception(current_exception());
924935 }
925#endif // _LIBCPP_NO_EXCEPTIONS
936#endif // _LIBCPP_HAS_NO_EXCEPTIONS
926937}
927938
928939template <class _Rp, class _Fp>
......@@ -933,12 +944,12 @@ class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
933944
934945 _Fp __func_;
935946
936 virtual void __on_zero_shared() _NOEXCEPT;
947 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
937948public:
938949 _LIBCPP_INLINE_VISIBILITY
939950 explicit __async_assoc_state(_Fp&& __f);
940951
941 virtual void __execute();
952 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
942953};
943954
944955template <class _Rp, class _Fp>
......@@ -952,18 +963,18 @@ template <class _Rp, class _Fp>
952963void
953964__async_assoc_state<_Rp, _Fp>::__execute()
954965{
955#ifndef _LIBCPP_NO_EXCEPTIONS
966#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
956967 try
957968 {
958#endif // _LIBCPP_NO_EXCEPTIONS
969#endif // _LIBCPP_HAS_NO_EXCEPTIONS
959970 this->set_value(__func_());
960#ifndef _LIBCPP_NO_EXCEPTIONS
971#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
961972 }
962973 catch (...)
963974 {
964975 this->set_exception(current_exception());
965976 }
966#endif // _LIBCPP_NO_EXCEPTIONS
977#endif // _LIBCPP_HAS_NO_EXCEPTIONS
967978}
968979
969980template <class _Rp, class _Fp>
......@@ -982,12 +993,12 @@ class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
982993
983994 _Fp __func_;
984995
985 void __on_zero_shared() _NOEXCEPT override;
996 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
986997public:
987998 _LIBCPP_INLINE_VISIBILITY
988999 explicit __async_assoc_state(_Fp&& __f);
9891000
990 void __execute() override;
1001 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
9911002};
9921003
9931004template <class _Fp>
......@@ -1001,19 +1012,19 @@ template <class _Fp>
10011012void
10021013__async_assoc_state<void, _Fp>::__execute()
10031014{
1004#ifndef _LIBCPP_NO_EXCEPTIONS
1015#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
10051016 try
10061017 {
1007#endif // _LIBCPP_NO_EXCEPTIONS
1018#endif // _LIBCPP_HAS_NO_EXCEPTIONS
10081019 __func_();
10091020 this->set_value();
1010#ifndef _LIBCPP_NO_EXCEPTIONS
1021#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
10111022 }
10121023 catch (...)
10131024 {
10141025 this->set_exception(current_exception());
10151026 }
1016#endif // _LIBCPP_NO_EXCEPTIONS
1027#endif // _LIBCPP_HAS_NO_EXCEPTIONS
10171028}
10181029
10191030template <class _Fp>
......@@ -1044,7 +1055,7 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
10441055{
10451056 __assoc_state<_Rp>* __state_;
10461057
1047 explicit future(__assoc_state<_Rp>* __state);
1058 explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp>* __state);
10481059
10491060 template <class> friend class promise;
10501061 template <class> friend class shared_future;
......@@ -1069,12 +1080,12 @@ public:
10691080 return *this;
10701081 }
10711082
1072 ~future();
1083 _LIBCPP_HIDE_FROM_ABI ~future();
10731084 _LIBCPP_INLINE_VISIBILITY
10741085 shared_future<_Rp> share() _NOEXCEPT;
10751086
10761087 // retrieving the value
1077 _Rp get();
1088 _LIBCPP_HIDE_FROM_ABI _Rp get();
10781089
10791090 _LIBCPP_INLINE_VISIBILITY
10801091 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
......@@ -1106,7 +1117,7 @@ future<_Rp>::future(__assoc_state<_Rp>* __state)
11061117
11071118struct __release_shared_count
11081119{
1109 void operator()(__shared_count* __p) {__p->__release_shared();}
1120 _LIBCPP_HIDE_FROM_ABI void operator()(__shared_count* __p) {__p->__release_shared();}
11101121};
11111122
11121123template <class _Rp>
......@@ -1120,7 +1131,7 @@ template <class _Rp>
11201131_Rp
11211132future<_Rp>::get()
11221133{
1123 unique_ptr<__shared_count, __release_shared_count> __(__state_);
1134 unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
11241135 __assoc_state<_Rp>* __s = __state_;
11251136 __state_ = nullptr;
11261137 return __s->move();
......@@ -1131,7 +1142,7 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
11311142{
11321143 __assoc_state<_Rp&>* __state_;
11331144
1134 explicit future(__assoc_state<_Rp&>* __state);
1145 explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp&>* __state);
11351146
11361147 template <class> friend class promise;
11371148 template <class> friend class shared_future;
......@@ -1156,12 +1167,12 @@ public:
11561167 return *this;
11571168 }
11581169
1159 ~future();
1170 _LIBCPP_HIDE_FROM_ABI ~future();
11601171 _LIBCPP_INLINE_VISIBILITY
11611172 shared_future<_Rp&> share() _NOEXCEPT;
11621173
11631174 // retrieving the value
1164 _Rp& get();
1175 _LIBCPP_HIDE_FROM_ABI _Rp& get();
11651176
11661177 _LIBCPP_INLINE_VISIBILITY
11671178 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
......@@ -1202,14 +1213,14 @@ template <class _Rp>
12021213_Rp&
12031214future<_Rp&>::get()
12041215{
1205 unique_ptr<__shared_count, __release_shared_count> __(__state_);
1216 unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
12061217 __assoc_state<_Rp&>* __s = __state_;
12071218 __state_ = nullptr;
12081219 return __s->copy();
12091220}
12101221
12111222template <>
1212class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
1223class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE future<void>
12131224{
12141225 __assoc_sub_state* __state_;
12151226
......@@ -1288,14 +1299,14 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
12881299
12891300 template <class> friend class packaged_task;
12901301public:
1291 promise();
1302 _LIBCPP_HIDE_FROM_ABI promise();
12921303 template <class _Alloc>
1293 promise(allocator_arg_t, const _Alloc& __a);
1304 _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Alloc& __a);
12941305 _LIBCPP_INLINE_VISIBILITY
12951306 promise(promise&& __rhs) _NOEXCEPT
12961307 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
12971308 promise(const promise& __rhs) = delete;
1298 ~promise();
1309 _LIBCPP_HIDE_FROM_ABI ~promise();
12991310
13001311 // assignment
13011312 _LIBCPP_INLINE_VISIBILITY
......@@ -1310,17 +1321,17 @@ public:
13101321 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
13111322
13121323 // retrieving the result
1313 future<_Rp> get_future();
1324 _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future();
13141325
13151326 // setting the result
1316 void set_value(const _Rp& __r);
1317 void set_value(_Rp&& __r);
1318 void set_exception(exception_ptr __p);
1327 _LIBCPP_HIDE_FROM_ABI void set_value(const _Rp& __r);
1328 _LIBCPP_HIDE_FROM_ABI void set_value(_Rp&& __r);
1329 _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
13191330
13201331 // setting the result with deferred notification
1321 void set_value_at_thread_exit(const _Rp& __r);
1322 void set_value_at_thread_exit(_Rp&& __r);
1323 void set_exception_at_thread_exit(exception_ptr __p);
1332 _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(const _Rp& __r);
1333 _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&& __r);
1334 _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
13241335};
13251336
13261337template <class _Rp>
......@@ -1386,7 +1397,7 @@ template <class _Rp>
13861397void
13871398promise<_Rp>::set_exception(exception_ptr __p)
13881399{
1389 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
1400 _LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception: received nullptr" );
13901401 if (__state_ == nullptr)
13911402 __throw_future_error(future_errc::no_state);
13921403 __state_->set_exception(__p);
......@@ -1414,7 +1425,7 @@ template <class _Rp>
14141425void
14151426promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
14161427{
1417 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
1428 _LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
14181429 if (__state_ == nullptr)
14191430 __throw_future_error(future_errc::no_state);
14201431 __state_->set_exception_at_thread_exit(__p);
......@@ -1433,14 +1444,14 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
14331444 template <class> friend class packaged_task;
14341445
14351446public:
1436 promise();
1447 _LIBCPP_HIDE_FROM_ABI promise();
14371448 template <class _Allocator>
1438 promise(allocator_arg_t, const _Allocator& __a);
1449 _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Allocator& __a);
14391450 _LIBCPP_INLINE_VISIBILITY
14401451 promise(promise&& __rhs) _NOEXCEPT
14411452 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
14421453 promise(const promise& __rhs) = delete;
1443 ~promise();
1454 _LIBCPP_HIDE_FROM_ABI ~promise();
14441455
14451456 // assignment
14461457 _LIBCPP_INLINE_VISIBILITY
......@@ -1455,15 +1466,15 @@ public:
14551466 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
14561467
14571468 // retrieving the result
1458 future<_Rp&> get_future();
1469 _LIBCPP_HIDE_FROM_ABI future<_Rp&> get_future();
14591470
14601471 // setting the result
1461 void set_value(_Rp& __r);
1462 void set_exception(exception_ptr __p);
1472 _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __r);
1473 _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
14631474
14641475 // setting the result with deferred notification
1465 void set_value_at_thread_exit(_Rp&);
1466 void set_exception_at_thread_exit(exception_ptr __p);
1476 _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&);
1477 _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
14671478};
14681479
14691480template <class _Rp>
......@@ -1520,7 +1531,7 @@ template <class _Rp>
15201531void
15211532promise<_Rp&>::set_exception(exception_ptr __p)
15221533{
1523 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
1534 _LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception: received nullptr" );
15241535 if (__state_ == nullptr)
15251536 __throw_future_error(future_errc::no_state);
15261537 __state_->set_exception(__p);
......@@ -1539,7 +1550,7 @@ template <class _Rp>
15391550void
15401551promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
15411552{
1542 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
1553 _LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
15431554 if (__state_ == nullptr)
15441555 __throw_future_error(future_errc::no_state);
15451556 __state_->set_exception_at_thread_exit(__p);
......@@ -1548,7 +1559,7 @@ promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
15481559// promise<void>
15491560
15501561template <>
1551class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
1562class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE promise<void>
15521563{
15531564 __assoc_sub_state* __state_;
15541565
......@@ -1654,10 +1665,10 @@ public:
16541665 _LIBCPP_INLINE_VISIBILITY
16551666 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
16561667 : __f_(_VSTD::move(__f), __a) {}
1657 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
1658 virtual void destroy();
1659 virtual void destroy_deallocate();
1660 virtual _Rp operator()(_ArgTypes&& ... __args);
1668 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
1669 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy();
1670 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate();
1671 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&& ... __args);
16611672};
16621673
16631674template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
......@@ -1716,22 +1727,22 @@ public:
17161727 _LIBCPP_INLINE_VISIBILITY
17171728 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
17181729 template<class _Fp>
1719 __packaged_task_function(_Fp&& __f);
1730 _LIBCPP_HIDE_FROM_ABI __packaged_task_function(_Fp&& __f);
17201731 template<class _Fp, class _Alloc>
1721 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
1732 _LIBCPP_HIDE_FROM_ABI __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
17221733
1723 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1724 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
1734 _LIBCPP_HIDE_FROM_ABI __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1735 _LIBCPP_HIDE_FROM_ABI __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
17251736
17261737 __packaged_task_function(const __packaged_task_function&) = delete;
17271738 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
17281739
1729 ~__packaged_task_function();
1740 _LIBCPP_HIDE_FROM_ABI ~__packaged_task_function();
17301741
1731 void swap(__packaged_task_function&) _NOEXCEPT;
1742 _LIBCPP_HIDE_FROM_ABI void swap(__packaged_task_function&) _NOEXCEPT;
17321743
17331744 _LIBCPP_INLINE_VISIBILITY
1734 _Rp operator()(_ArgTypes...) const;
1745 _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
17351746};
17361747
17371748template<class _Rp, class ..._ArgTypes>
......@@ -1756,7 +1767,7 @@ template <class _Fp>
17561767__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
17571768 : __f_(nullptr)
17581769{
1759 typedef __libcpp_remove_reference_t<typename decay<_Fp>::type> _FR;
1770 typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
17601771 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
17611772 if (sizeof(_FF) <= sizeof(__buf_))
17621773 {
......@@ -1780,7 +1791,7 @@ __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
17801791 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
17811792 : __f_(nullptr)
17821793{
1783 typedef __libcpp_remove_reference_t<typename decay<_Fp>::type> _FR;
1794 typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
17841795 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
17851796 if (sizeof(_FF) <= sizeof(__buf_))
17861797 {
......@@ -1902,8 +1913,8 @@ public:
19021913 class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
19031914 _LIBCPP_INLINE_VISIBILITY
19041915 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1905 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
1906 __p_(allocator_arg, __a) {}
1916 : __f_(allocator_arg_t(), __a, _VSTD::forward<_Fp>(__f)),
1917 __p_(allocator_arg_t(), __a) {}
19071918 // ~packaged_task() = default;
19081919
19091920 // no copy
......@@ -1936,10 +1947,10 @@ public:
19361947 future<result_type> get_future() {return __p_.get_future();}
19371948
19381949 // execution
1939 void operator()(_ArgTypes... __args);
1940 void make_ready_at_thread_exit(_ArgTypes... __args);
1950 _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
1951 _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
19411952
1942 void reset();
1953 _LIBCPP_HIDE_FROM_ABI void reset();
19431954};
19441955
19451956template<class _Rp, class ..._ArgTypes>
......@@ -1950,18 +1961,18 @@ packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
19501961 __throw_future_error(future_errc::no_state);
19511962 if (__p_.__state_->__has_value())
19521963 __throw_future_error(future_errc::promise_already_satisfied);
1953#ifndef _LIBCPP_NO_EXCEPTIONS
1964#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
19541965 try
19551966 {
1956#endif // _LIBCPP_NO_EXCEPTIONS
1967#endif // _LIBCPP_HAS_NO_EXCEPTIONS
19571968 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
1958#ifndef _LIBCPP_NO_EXCEPTIONS
1969#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
19591970 }
19601971 catch (...)
19611972 {
19621973 __p_.set_exception(current_exception());
19631974 }
1964#endif // _LIBCPP_NO_EXCEPTIONS
1975#endif // _LIBCPP_HAS_NO_EXCEPTIONS
19651976}
19661977
19671978template<class _Rp, class ..._ArgTypes>
......@@ -1972,18 +1983,18 @@ packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
19721983 __throw_future_error(future_errc::no_state);
19731984 if (__p_.__state_->__has_value())
19741985 __throw_future_error(future_errc::promise_already_satisfied);
1975#ifndef _LIBCPP_NO_EXCEPTIONS
1986#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
19761987 try
19771988 {
1978#endif // _LIBCPP_NO_EXCEPTIONS
1989#endif // _LIBCPP_HAS_NO_EXCEPTIONS
19791990 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
1980#ifndef _LIBCPP_NO_EXCEPTIONS
1991#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
19811992 }
19821993 catch (...)
19831994 {
19841995 __p_.set_exception_at_thread_exit(current_exception());
19851996 }
1986#endif // _LIBCPP_NO_EXCEPTIONS
1997#endif // _LIBCPP_HAS_NO_EXCEPTIONS
19871998}
19881999
19892000template<class _Rp, class ..._ArgTypes>
......@@ -2017,8 +2028,8 @@ public:
20172028 class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
20182029 _LIBCPP_INLINE_VISIBILITY
20192030 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2020 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2021 __p_(allocator_arg, __a) {}
2031 : __f_(allocator_arg_t(), __a, _VSTD::forward<_Fp>(__f)),
2032 __p_(allocator_arg_t(), __a) {}
20222033 // ~packaged_task() = default;
20232034
20242035 // no copy
......@@ -2051,10 +2062,10 @@ public:
20512062 future<result_type> get_future() {return __p_.get_future();}
20522063
20532064 // execution
2054 void operator()(_ArgTypes... __args);
2055 void make_ready_at_thread_exit(_ArgTypes... __args);
2065 _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
2066 _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
20562067
2057 void reset();
2068 _LIBCPP_HIDE_FROM_ABI void reset();
20582069};
20592070
20602071#if _LIBCPP_STD_VER >= 17
......@@ -2075,19 +2086,19 @@ packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
20752086 __throw_future_error(future_errc::no_state);
20762087 if (__p_.__state_->__has_value())
20772088 __throw_future_error(future_errc::promise_already_satisfied);
2078#ifndef _LIBCPP_NO_EXCEPTIONS
2089#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
20792090 try
20802091 {
2081#endif // _LIBCPP_NO_EXCEPTIONS
2092#endif // _LIBCPP_HAS_NO_EXCEPTIONS
20822093 __f_(_VSTD::forward<_ArgTypes>(__args)...);
20832094 __p_.set_value();
2084#ifndef _LIBCPP_NO_EXCEPTIONS
2095#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
20852096 }
20862097 catch (...)
20872098 {
20882099 __p_.set_exception(current_exception());
20892100 }
2090#endif // _LIBCPP_NO_EXCEPTIONS
2101#endif // _LIBCPP_HAS_NO_EXCEPTIONS
20912102}
20922103
20932104template<class ..._ArgTypes>
......@@ -2098,19 +2109,19 @@ packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args
20982109 __throw_future_error(future_errc::no_state);
20992110 if (__p_.__state_->__has_value())
21002111 __throw_future_error(future_errc::promise_already_satisfied);
2101#ifndef _LIBCPP_NO_EXCEPTIONS
2112#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
21022113 try
21032114 {
2104#endif // _LIBCPP_NO_EXCEPTIONS
2115#endif // _LIBCPP_HAS_NO_EXCEPTIONS
21052116 __f_(_VSTD::forward<_ArgTypes>(__args)...);
21062117 __p_.set_value_at_thread_exit();
2107#ifndef _LIBCPP_NO_EXCEPTIONS
2118#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
21082119 }
21092120 catch (...)
21102121 {
21112122 __p_.set_exception_at_thread_exit(current_exception());
21122123 }
2113#endif // _LIBCPP_NO_EXCEPTIONS
2124#endif // _LIBCPP_HAS_NO_EXCEPTIONS
21142125}
21152126
21162127template<class ..._ArgTypes>
......@@ -2170,14 +2181,14 @@ public:
21702181 _LIBCPP_INLINE_VISIBILITY
21712182 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
21722183
2173 _Rp operator()()
2184 _LIBCPP_HIDE_FROM_ABI _Rp operator()()
21742185 {
21752186 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
21762187 return __execute(_Index());
21772188 }
21782189private:
21792190 template <size_t ..._Indices>
2180 _Rp
2191 _LIBCPP_HIDE_FROM_ABI _Rp
21812192 __execute(__tuple_indices<_Indices...>)
21822193 {
21832194 return _VSTD::__invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
......@@ -2189,20 +2200,20 @@ inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, lau
21892200
21902201template <class _Fp, class... _Args>
21912202_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
2192future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2203future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
21932204async(launch __policy, _Fp&& __f, _Args&&... __args)
21942205{
2195 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2206 typedef __async_func<__decay_t<_Fp>, __decay_t<_Args>...> _BF;
21962207 typedef typename _BF::_Rp _Rp;
21972208
2198#ifndef _LIBCPP_NO_EXCEPTIONS
2209#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
21992210 try
22002211 {
22012212#endif
22022213 if (__does_policy_contain(__policy, launch::async))
22032214 return _VSTD::__make_async_assoc_state<_Rp>(_BF(_LIBCPP_AUTO_CAST(_VSTD::forward<_Fp>(__f)),
22042215 _LIBCPP_AUTO_CAST(_VSTD::forward<_Args>(__args))...));
2205#ifndef _LIBCPP_NO_EXCEPTIONS
2216#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
22062217 }
22072218 catch ( ... ) { if (__policy == launch::async) throw ; }
22082219#endif
......@@ -2215,7 +2226,7 @@ async(launch __policy, _Fp&& __f, _Args&&... __args)
22152226
22162227template <class _Fp, class... _Args>
22172228_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
2218future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2229future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
22192230async(_Fp&& __f, _Args&&... __args)
22202231{
22212232 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
......@@ -2243,8 +2254,8 @@ public:
22432254 _LIBCPP_INLINE_VISIBILITY
22442255 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
22452256 {__rhs.__state_ = nullptr;}
2246 ~shared_future();
2247 shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
2257 _LIBCPP_HIDE_FROM_ABI ~shared_future();
2258 _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
22482259 _LIBCPP_INLINE_VISIBILITY
22492260 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
22502261 {
......@@ -2313,8 +2324,8 @@ public:
23132324 _LIBCPP_INLINE_VISIBILITY
23142325 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
23152326 {__rhs.__state_ = nullptr;}
2316 ~shared_future();
2317 shared_future& operator=(const shared_future& __rhs);
2327 _LIBCPP_HIDE_FROM_ABI ~shared_future();
2328 _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs);
23182329 _LIBCPP_INLINE_VISIBILITY
23192330 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
23202331 {
......@@ -2367,7 +2378,7 @@ shared_future<_Rp&>::operator=(const shared_future& __rhs)
23672378}
23682379
23692380template <>
2370class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
2381class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
23712382{
23722383 __assoc_sub_state* __state_;
23732384
......@@ -2454,4 +2465,11 @@ _LIBCPP_END_NAMESPACE_STD
24542465# include <chrono>
24552466#endif
24562467
2468#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
2469# include <atomic>
2470# include <cstdlib>
2471# include <exception>
2472# include <system_error>
2473#endif
2474
24572475#endif // _LIBCPP_FUTURE
lib/libcxx/include/iomanip+18-22
......@@ -301,10 +301,10 @@ template <class _CharT, class _Traits, class _MoneyT>
301301_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
302302operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x)
303303{
304#ifndef _LIBCPP_NO_EXCEPTIONS
304#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
305305 try
306306 {
307#endif // _LIBCPP_NO_EXCEPTIONS
307#endif // _LIBCPP_HAS_NO_EXCEPTIONS
308308 typename basic_istream<_CharT, _Traits>::sentry __s(__is);
309309 if (__s)
310310 {
......@@ -315,13 +315,13 @@ operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x)
315315 __mf.get(_Ip(__is), _Ip(), __x.__intl_, __is, __err, __x.__mon_);
316316 __is.setstate(__err);
317317 }
318#ifndef _LIBCPP_NO_EXCEPTIONS
318#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
319319 }
320320 catch (...)
321321 {
322322 __is.__set_badbit_and_consider_rethrow();
323323 }
324#endif // _LIBCPP_NO_EXCEPTIONS
324#endif // _LIBCPP_HAS_NO_EXCEPTIONS
325325 return __is;
326326}
327327
......@@ -361,10 +361,10 @@ template <class _CharT, class _Traits, class _MoneyT>
361361_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
362362operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x)
363363{
364#ifndef _LIBCPP_NO_EXCEPTIONS
364#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
365365 try
366366 {
367#endif // _LIBCPP_NO_EXCEPTIONS
367#endif // _LIBCPP_HAS_NO_EXCEPTIONS
368368 typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
369369 if (__s)
370370 {
......@@ -374,13 +374,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x)
374374 if (__mf.put(_Op(__os), __x.__intl_, __os, __os.fill(), __x.__mon_).failed())
375375 __os.setstate(ios_base::badbit);
376376 }
377#ifndef _LIBCPP_NO_EXCEPTIONS
377#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
378378 }
379379 catch (...)
380380 {
381381 __os.__set_badbit_and_consider_rethrow();
382382 }
383#endif // _LIBCPP_NO_EXCEPTIONS
383#endif // _LIBCPP_HAS_NO_EXCEPTIONS
384384 return __os;
385385}
386386
......@@ -420,10 +420,10 @@ template <class _CharT, class _Traits>
420420_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
421421operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x)
422422{
423#ifndef _LIBCPP_NO_EXCEPTIONS
423#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
424424 try
425425 {
426#endif // _LIBCPP_NO_EXCEPTIONS
426#endif // _LIBCPP_HAS_NO_EXCEPTIONS
427427 typename basic_istream<_CharT, _Traits>::sentry __s(__is);
428428 if (__s)
429429 {
......@@ -435,13 +435,13 @@ operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x)
435435 __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_));
436436 __is.setstate(__err);
437437 }
438#ifndef _LIBCPP_NO_EXCEPTIONS
438#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
439439 }
440440 catch (...)
441441 {
442442 __is.__set_badbit_and_consider_rethrow();
443443 }
444#endif // _LIBCPP_NO_EXCEPTIONS
444#endif // _LIBCPP_HAS_NO_EXCEPTIONS
445445 return __is;
446446}
447447
......@@ -481,10 +481,10 @@ template <class _CharT, class _Traits>
481481_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
482482operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x)
483483{
484#ifndef _LIBCPP_NO_EXCEPTIONS
484#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
485485 try
486486 {
487#endif // _LIBCPP_NO_EXCEPTIONS
487#endif // _LIBCPP_HAS_NO_EXCEPTIONS
488488 typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
489489 if (__s)
490490 {
......@@ -495,13 +495,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x)
495495 __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_)).failed())
496496 __os.setstate(ios_base::badbit);
497497 }
498#ifndef _LIBCPP_NO_EXCEPTIONS
498#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
499499 }
500500 catch (...)
501501 {
502502 __os.__set_badbit_and_consider_rethrow();
503503 }
504#endif // _LIBCPP_NO_EXCEPTIONS
504#endif // _LIBCPP_HAS_NO_EXCEPTIONS
505505 return __os;
506506}
507507
......@@ -513,8 +513,6 @@ put_time(const tm* __tm, const _CharT* __fmt)
513513 return __iom_t10<_CharT>(__tm, __fmt);
514514}
515515
516#if _LIBCPP_STD_VER >= 11
517
518516template <class _CharT, class _Traits>
519517_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
520518__quoted_output(basic_ostream<_CharT, _Traits>& __os,
......@@ -622,9 +620,7 @@ __quoted(basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __delim = _CharT
622620 return __quoted_proxy<_CharT, _Traits, _Allocator>(__s, __delim, __escape);
623621}
624622
625#endif // _LIBCPP_STD_VER >= 11
626
627#if _LIBCPP_STD_VER > 11
623#if _LIBCPP_STD_VER >= 14
628624
629625template <class _CharT>
630626_LIBCPP_HIDE_FROM_ABI
......@@ -656,7 +652,7 @@ auto quoted(basic_string_view<_CharT, _Traits> __sv, _CharT __delim = _CharT('"'
656652 return __quoted_output_proxy<_CharT, _Traits>(__sv.data(), __sv.data() + __sv.size(), __delim, __escape);
657653}
658654
659#endif // _LIBCPP_STD_VER > 11
655#endif // _LIBCPP_STD_VER >= 14
660656
661657_LIBCPP_END_NAMESPACE_STD
662658
lib/libcxx/include/ios+24-13
......@@ -217,10 +217,15 @@ storage-class-specifier const error_category& iostream_category() noexcept;
217217#endif
218218
219219#include <__assert> // all public C++ headers provide the assertion handler
220#include <__fwd/ios.h>
220221#include <__ios/fpos.h>
221222#include <__locale>
223#include <__system_error/error_category.h>
224#include <__system_error/error_code.h>
225#include <__system_error/error_condition.h>
226#include <__system_error/system_error.h>
222227#include <__utility/swap.h>
223#include <system_error>
228#include <__verbose_abort>
224229#include <version>
225230
226231// standard-mandated includes
......@@ -229,7 +234,7 @@ storage-class-specifier const error_category& iostream_category() noexcept;
229234#include <iosfwd>
230235
231236#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
232#include <atomic> // for __xindex_
237# include <__atomic/atomic.h> // for __xindex_
233238#endif
234239
235240#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -240,10 +245,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
240245
241246typedef ptrdiff_t streamsize;
242247
243class _LIBCPP_TYPE_VIS ios_base
248class _LIBCPP_EXPORTED_FROM_ABI ios_base
244249{
245250public:
246 class _LIBCPP_EXCEPTION_ABI failure;
251 class _LIBCPP_EXPORTED_FROM_ABI failure;
247252
248253 typedef unsigned int fmtflags;
249254 static const fmtflags boolalpha = 0x0001;
......@@ -290,7 +295,7 @@ public:
290295 typedef _VSTD::streampos streampos;
291296#endif
292297
293 class _LIBCPP_TYPE_VIS Init;
298 class _LIBCPP_EXPORTED_FROM_ABI Init;
294299
295300 // 27.5.2.2 fmtflags state:
296301 _LIBCPP_INLINE_VISIBILITY fmtflags flags() const;
......@@ -419,8 +424,7 @@ template <>
419424struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<io_errc::__lx> : public true_type { };
420425#endif
421426
422_LIBCPP_FUNC_VIS
423const error_category& iostream_category() _NOEXCEPT;
427_LIBCPP_EXPORTED_FROM_ABI const error_category& iostream_category() _NOEXCEPT;
424428
425429inline _LIBCPP_INLINE_VISIBILITY
426430error_code
......@@ -436,27 +440,26 @@ make_error_condition(io_errc __e) _NOEXCEPT
436440 return error_condition(static_cast<int>(__e), iostream_category());
437441}
438442
439class _LIBCPP_EXCEPTION_ABI ios_base::failure
443class _LIBCPP_EXPORTED_FROM_ABI ios_base::failure
440444 : public system_error
441445{
442446public:
443447 explicit failure(const string& __msg, const error_code& __ec = io_errc::stream);
444448 explicit failure(const char* __msg, const error_code& __ec = io_errc::stream);
445 failure(const failure&) _NOEXCEPT = default;
449 _LIBCPP_HIDE_FROM_ABI failure(const failure&) _NOEXCEPT = default;
446450 ~failure() _NOEXCEPT override;
447451};
448452
449453_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
450454void __throw_failure(char const* __msg) {
451#ifndef _LIBCPP_NO_EXCEPTIONS
455#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
452456 throw ios_base::failure(__msg);
453457#else
454 ((void)__msg);
455 _VSTD::abort();
458 _LIBCPP_VERBOSE_ABORT("ios_base::failure was thrown in -fno-exceptions mode with message \"%s\"", __msg);
456459#endif
457460}
458461
459class _LIBCPP_TYPE_VIS ios_base::Init
462class _LIBCPP_EXPORTED_FROM_ABI ios_base::Init
460463{
461464public:
462465 Init();
......@@ -844,6 +847,12 @@ basic_ios<_CharT, _Traits>::set_rdbuf(basic_streambuf<char_type, traits_type>* _
844847 ios_base::set_rdbuf(__sb);
845848}
846849
850extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<char>;
851
852#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
853extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<wchar_t>;
854#endif
855
847856_LIBCPP_HIDE_FROM_ABI inline
848857ios_base&
849858boolalpha(ios_base& __str)
......@@ -1039,6 +1048,7 @@ defaultfloat(ios_base& __str)
10391048_LIBCPP_END_NAMESPACE_STD
10401049
10411050#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1051# include <atomic>
10421052# include <concepts>
10431053# include <cstddef>
10441054# include <cstdlib>
......@@ -1047,6 +1057,7 @@ _LIBCPP_END_NAMESPACE_STD
10471057# include <limits>
10481058# include <new>
10491059# include <stdexcept>
1060# include <system_error>
10501061# include <type_traits>
10511062# include <typeinfo>
10521063#endif
lib/libcxx/include/iosfwd+8-110
......@@ -96,8 +96,14 @@ using u32streampos = fpos<char_traits<char32_t>::state_type>;
9696
9797#include <__assert> // all public C++ headers provide the assertion handler
9898#include <__config>
99#include <__fwd/fstream.h>
100#include <__fwd/ios.h>
101#include <__fwd/istream.h>
102#include <__fwd/ostream.h>
103#include <__fwd/sstream.h>
104#include <__fwd/streambuf.h>
99105#include <__fwd/string.h>
100#include <__mbstate_t.h>
106#include <__std_mbstate_t.h>
101107#include <version>
102108
103109#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -106,114 +112,13 @@ using u32streampos = fpos<char_traits<char32_t>::state_type>;
106112
107113_LIBCPP_BEGIN_NAMESPACE_STD
108114
109class _LIBCPP_TYPE_VIS ios_base;
110
111template <class _CharT, class _Traits = char_traits<_CharT> >
112 class _LIBCPP_TEMPLATE_VIS basic_ios;
113
114template <class _CharT, class _Traits = char_traits<_CharT> >
115 class _LIBCPP_TEMPLATE_VIS basic_streambuf;
116template <class _CharT, class _Traits = char_traits<_CharT> >
117 class _LIBCPP_TEMPLATE_VIS basic_istream;
118template <class _CharT, class _Traits = char_traits<_CharT> >
119 class _LIBCPP_TEMPLATE_VIS basic_ostream;
120template <class _CharT, class _Traits = char_traits<_CharT> >
121 class _LIBCPP_TEMPLATE_VIS basic_iostream;
122
123template <class _CharT, class _Traits = char_traits<_CharT>,
124 class _Allocator = allocator<_CharT> >
125 class _LIBCPP_TEMPLATE_VIS basic_stringbuf;
126template <class _CharT, class _Traits = char_traits<_CharT>,
127 class _Allocator = allocator<_CharT> >
128 class _LIBCPP_TEMPLATE_VIS basic_istringstream;
129template <class _CharT, class _Traits = char_traits<_CharT>,
130 class _Allocator = allocator<_CharT> >
131 class _LIBCPP_TEMPLATE_VIS basic_ostringstream;
132template <class _CharT, class _Traits = char_traits<_CharT>,
133 class _Allocator = allocator<_CharT> >
134 class _LIBCPP_TEMPLATE_VIS basic_stringstream;
135
136template <class _CharT, class _Traits = char_traits<_CharT> >
137 class _LIBCPP_TEMPLATE_VIS basic_filebuf;
138template <class _CharT, class _Traits = char_traits<_CharT> >
139 class _LIBCPP_TEMPLATE_VIS basic_ifstream;
140template <class _CharT, class _Traits = char_traits<_CharT> >
141 class _LIBCPP_TEMPLATE_VIS basic_ofstream;
142template <class _CharT, class _Traits = char_traits<_CharT> >
143 class _LIBCPP_TEMPLATE_VIS basic_fstream;
115class _LIBCPP_EXPORTED_FROM_ABI ios_base;
144116
145117template <class _CharT, class _Traits = char_traits<_CharT> >
146118 class _LIBCPP_TEMPLATE_VIS istreambuf_iterator;
147119template <class _CharT, class _Traits = char_traits<_CharT> >
148120 class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator;
149121
150typedef basic_ios<char> ios;
151#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
152typedef basic_ios<wchar_t> wios;
153#endif
154
155typedef basic_streambuf<char> streambuf;
156typedef basic_istream<char> istream;
157typedef basic_ostream<char> ostream;
158typedef basic_iostream<char> iostream;
159
160typedef basic_stringbuf<char> stringbuf;
161typedef basic_istringstream<char> istringstream;
162typedef basic_ostringstream<char> ostringstream;
163typedef basic_stringstream<char> stringstream;
164
165typedef basic_filebuf<char> filebuf;
166typedef basic_ifstream<char> ifstream;
167typedef basic_ofstream<char> ofstream;
168typedef basic_fstream<char> fstream;
169
170#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
171typedef basic_streambuf<wchar_t> wstreambuf;
172typedef basic_istream<wchar_t> wistream;
173typedef basic_ostream<wchar_t> wostream;
174typedef basic_iostream<wchar_t> wiostream;
175
176typedef basic_stringbuf<wchar_t> wstringbuf;
177typedef basic_istringstream<wchar_t> wistringstream;
178typedef basic_ostringstream<wchar_t> wostringstream;
179typedef basic_stringstream<wchar_t> wstringstream;
180
181typedef basic_filebuf<wchar_t> wfilebuf;
182typedef basic_ifstream<wchar_t> wifstream;
183typedef basic_ofstream<wchar_t> wofstream;
184typedef basic_fstream<wchar_t> wfstream;
185#endif
186
187template <class _CharT, class _Traits>
188 class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios;
189
190template <class _CharT, class _Traits>
191 class _LIBCPP_PREFERRED_NAME(streambuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstreambuf)) basic_streambuf;
192template <class _CharT, class _Traits>
193 class _LIBCPP_PREFERRED_NAME(istream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wistream)) basic_istream;
194template <class _CharT, class _Traits>
195 class _LIBCPP_PREFERRED_NAME(ostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wostream)) basic_ostream;
196template <class _CharT, class _Traits>
197 class _LIBCPP_PREFERRED_NAME(iostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wiostream)) basic_iostream;
198
199template <class _CharT, class _Traits, class _Allocator>
200 class _LIBCPP_PREFERRED_NAME(stringbuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstringbuf)) basic_stringbuf;
201template <class _CharT, class _Traits, class _Allocator>
202 class _LIBCPP_PREFERRED_NAME(istringstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wistringstream)) basic_istringstream;
203template <class _CharT, class _Traits, class _Allocator>
204 class _LIBCPP_PREFERRED_NAME(ostringstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wostringstream)) basic_ostringstream;
205template <class _CharT, class _Traits, class _Allocator>
206 class _LIBCPP_PREFERRED_NAME(stringstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstringstream)) basic_stringstream;
207
208template <class _CharT, class _Traits>
209 class _LIBCPP_PREFERRED_NAME(filebuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wfilebuf)) basic_filebuf;
210template <class _CharT, class _Traits>
211 class _LIBCPP_PREFERRED_NAME(ifstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wifstream)) basic_ifstream;
212template <class _CharT, class _Traits>
213 class _LIBCPP_PREFERRED_NAME(ofstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wofstream)) basic_ofstream;
214template <class _CharT, class _Traits>
215 class _LIBCPP_PREFERRED_NAME(fstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wfstream)) basic_fstream;
216
217122template <class _State> class _LIBCPP_TEMPLATE_VIS fpos;
218123typedef fpos<mbstate_t> streampos;
219124typedef fpos<mbstate_t> wstreampos;
......@@ -223,13 +128,6 @@ typedef fpos<mbstate_t> u8streampos;
223128typedef fpos<mbstate_t> u16streampos;
224129typedef fpos<mbstate_t> u32streampos;
225130
226#if defined(_NEWLIB_VERSION)
227// On newlib, off_t is 'long int'
228typedef long int streamoff; // for char_traits in <string>
229#else
230typedef long long streamoff; // for char_traits in <string>
231#endif
232
233131// Include other forward declarations here
234132template <class _Tp, class _Alloc = allocator<_Tp> >
235133class _LIBCPP_TEMPLATE_VIS vector;
lib/libcxx/include/iostream+8-8
......@@ -51,16 +51,16 @@ extern wostream wclog;
5151
5252_LIBCPP_BEGIN_NAMESPACE_STD
5353
54extern _LIBCPP_FUNC_VIS istream cin;
55extern _LIBCPP_FUNC_VIS ostream cout;
56extern _LIBCPP_FUNC_VIS ostream cerr;
57extern _LIBCPP_FUNC_VIS ostream clog;
54extern _LIBCPP_EXPORTED_FROM_ABI istream cin;
55extern _LIBCPP_EXPORTED_FROM_ABI ostream cout;
56extern _LIBCPP_EXPORTED_FROM_ABI ostream cerr;
57extern _LIBCPP_EXPORTED_FROM_ABI ostream clog;
5858
5959#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
60extern _LIBCPP_FUNC_VIS wistream wcin;
61extern _LIBCPP_FUNC_VIS wostream wcout;
62extern _LIBCPP_FUNC_VIS wostream wcerr;
63extern _LIBCPP_FUNC_VIS wostream wclog;
60extern _LIBCPP_EXPORTED_FROM_ABI wistream wcin;
61extern _LIBCPP_EXPORTED_FROM_ABI wostream wcout;
62extern _LIBCPP_EXPORTED_FROM_ABI wostream wcerr;
63extern _LIBCPP_EXPORTED_FROM_ABI wostream wclog;
6464#endif
6565
6666_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/istream+84-79
......@@ -160,7 +160,12 @@ template <class Stream, class T>
160160
161161#include <__assert> // all public C++ headers provide the assertion handler
162162#include <__config>
163#include <__fwd/istream.h>
163164#include <__iterator/istreambuf_iterator.h>
165#include <__type_traits/conjunction.h>
166#include <__type_traits/enable_if.h>
167#include <__type_traits/is_base_of.h>
168#include <__utility/declval.h>
164169#include <__utility/forward.h>
165170#include <ostream>
166171#include <version>
......@@ -360,14 +365,14 @@ __input_arithmetic(basic_istream<_CharT, _Traits>& __is, _Tp& __n) {
360365 typename basic_istream<_CharT, _Traits>::sentry __s(__is);
361366 if (__s)
362367 {
363#ifndef _LIBCPP_NO_EXCEPTIONS
368#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
364369 try
365370 {
366#endif // _LIBCPP_NO_EXCEPTIONS
371#endif // _LIBCPP_HAS_NO_EXCEPTIONS
367372 typedef istreambuf_iterator<_CharT, _Traits> _Ip;
368373 typedef num_get<_CharT, _Ip> _Fp;
369374 std::use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __state, __n);
370#ifndef _LIBCPP_NO_EXCEPTIONS
375#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
371376 }
372377 catch (...)
373378 {
......@@ -469,10 +474,10 @@ __input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp
469474 typename basic_istream<_CharT, _Traits>::sentry __s(__is);
470475 if (__s)
471476 {
472#ifndef _LIBCPP_NO_EXCEPTIONS
477#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
473478 try
474479 {
475#endif // _LIBCPP_NO_EXCEPTIONS
480#endif // _LIBCPP_HAS_NO_EXCEPTIONS
476481 typedef istreambuf_iterator<_CharT, _Traits> _Ip;
477482 typedef num_get<_CharT, _Ip> _Fp;
478483 long __temp;
......@@ -491,7 +496,7 @@ __input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp
491496 {
492497 __n = static_cast<_Tp>(__temp);
493498 }
494#ifndef _LIBCPP_NO_EXCEPTIONS
499#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
495500 }
496501 catch (...)
497502 {
......@@ -502,7 +507,7 @@ __input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp
502507 throw;
503508 }
504509 }
505#endif // _LIBCPP_NO_EXCEPTIONS
510#endif // _LIBCPP_HAS_NO_EXCEPTIONS
506511 __is.setstate(__state);
507512 }
508513 return __is;
......@@ -531,7 +536,7 @@ __input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n)
531536 typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
532537 if (__sen)
533538 {
534#ifndef _LIBCPP_NO_EXCEPTIONS
539#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
535540 try
536541 {
537542#endif
......@@ -555,7 +560,7 @@ __input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n)
555560 __is.width(0);
556561 if (__s == __p)
557562 __state |= ios_base::failbit;
558#ifndef _LIBCPP_NO_EXCEPTIONS
563#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
559564 }
560565 catch (...)
561566 {
......@@ -572,7 +577,7 @@ __input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n)
572577 return __is;
573578}
574579
575#if _LIBCPP_STD_VER > 17
580#if _LIBCPP_STD_VER >= 20
576581
577582template<class _CharT, class _Traits, size_t _Np>
578583inline _LIBCPP_INLINE_VISIBILITY
......@@ -630,7 +635,7 @@ operator>>(basic_istream<char, _Traits>& __is, signed char* __s)
630635 return __is >> (char*)__s;
631636}
632637
633#endif // _LIBCPP_STD_VER > 17
638#endif // _LIBCPP_STD_VER >= 20
634639
635640template<class _CharT, class _Traits>
636641_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
......@@ -640,7 +645,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c)
640645 typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
641646 if (__sen)
642647 {
643#ifndef _LIBCPP_NO_EXCEPTIONS
648#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
644649 try
645650 {
646651#endif
......@@ -649,7 +654,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c)
649654 __state |= ios_base::eofbit | ios_base::failbit;
650655 else
651656 __c = _Traits::to_char_type(__i);
652#ifndef _LIBCPP_NO_EXCEPTIONS
657#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
653658 }
654659 catch (...)
655660 {
......@@ -693,10 +698,10 @@ basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_typ
693698 {
694699 if (__sb)
695700 {
696#ifndef _LIBCPP_NO_EXCEPTIONS
701#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
697702 try
698703 {
699#endif // _LIBCPP_NO_EXCEPTIONS
704#endif // _LIBCPP_HAS_NO_EXCEPTIONS
700705 while (true)
701706 {
702707 typename traits_type::int_type __i = this->rdbuf()->sgetc();
......@@ -714,7 +719,7 @@ basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_typ
714719 }
715720 if (__gc_ == 0)
716721 __state |= ios_base::failbit;
717#ifndef _LIBCPP_NO_EXCEPTIONS
722#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
718723 }
719724 catch (...)
720725 {
......@@ -728,7 +733,7 @@ basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_typ
728733 throw;
729734 }
730735 }
731#endif // _LIBCPP_NO_EXCEPTIONS
736#endif // _LIBCPP_HAS_NO_EXCEPTIONS
732737 }
733738 else
734739 {
......@@ -749,7 +754,7 @@ basic_istream<_CharT, _Traits>::get()
749754 sentry __s(*this, true);
750755 if (__s)
751756 {
752#ifndef _LIBCPP_NO_EXCEPTIONS
757#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
753758 try
754759 {
755760#endif
......@@ -758,7 +763,7 @@ basic_istream<_CharT, _Traits>::get()
758763 __state |= ios_base::failbit | ios_base::eofbit;
759764 else
760765 __gc_ = 1;
761#ifndef _LIBCPP_NO_EXCEPTIONS
766#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
762767 }
763768 catch (...)
764769 {
......@@ -785,7 +790,7 @@ basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __
785790 {
786791 if (__n > 0)
787792 {
788#ifndef _LIBCPP_NO_EXCEPTIONS
793#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
789794 try
790795 {
791796#endif
......@@ -806,7 +811,7 @@ basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __
806811 }
807812 if (__gc_ == 0)
808813 __state |= ios_base::failbit;
809#ifndef _LIBCPP_NO_EXCEPTIONS
814#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
810815 }
811816 catch (...)
812817 {
......@@ -845,10 +850,10 @@ basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __s
845850 sentry __sen(*this, true);
846851 if (__sen)
847852 {
848#ifndef _LIBCPP_NO_EXCEPTIONS
853#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
849854 try
850855 {
851#endif // _LIBCPP_NO_EXCEPTIONS
856#endif // _LIBCPP_HAS_NO_EXCEPTIONS
852857 while (true)
853858 {
854859 typename traits_type::int_type __i = this->rdbuf()->sgetc();
......@@ -865,14 +870,14 @@ basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __s
865870 ++__gc_;
866871 this->rdbuf()->sbumpc();
867872 }
868#ifndef _LIBCPP_NO_EXCEPTIONS
873#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
869874 }
870875 catch (...)
871876 {
872877 __state |= ios_base::badbit;
873878 // according to the spec, exceptions here are caught but not rethrown
874879 }
875#endif // _LIBCPP_NO_EXCEPTIONS
880#endif // _LIBCPP_HAS_NO_EXCEPTIONS
876881 if (__gc_ == 0)
877882 __state |= ios_base::failbit;
878883 this->setstate(__state);
......@@ -889,10 +894,10 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ
889894 sentry __sen(*this, true);
890895 if (__sen)
891896 {
892#ifndef _LIBCPP_NO_EXCEPTIONS
897#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
893898 try
894899 {
895#endif // _LIBCPP_NO_EXCEPTIONS
900#endif // _LIBCPP_HAS_NO_EXCEPTIONS
896901 while (true)
897902 {
898903 typename traits_type::int_type __i = this->rdbuf()->sgetc();
......@@ -917,7 +922,7 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ
917922 this->rdbuf()->sbumpc();
918923 ++__gc_;
919924 }
920#ifndef _LIBCPP_NO_EXCEPTIONS
925#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
921926 }
922927 catch (...)
923928 {
......@@ -932,7 +937,7 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ
932937 throw;
933938 }
934939 }
935#endif // _LIBCPP_NO_EXCEPTIONS
940#endif // _LIBCPP_HAS_NO_EXCEPTIONS
936941 }
937942 if (__n > 0)
938943 *__s = char_type();
......@@ -951,10 +956,10 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
951956 sentry __sen(*this, true);
952957 if (__sen)
953958 {
954#ifndef _LIBCPP_NO_EXCEPTIONS
959#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
955960 try
956961 {
957#endif // _LIBCPP_NO_EXCEPTIONS
962#endif // _LIBCPP_HAS_NO_EXCEPTIONS
958963 if (__n == numeric_limits<streamsize>::max())
959964 {
960965 while (true)
......@@ -985,7 +990,7 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
985990 break;
986991 }
987992 }
988#ifndef _LIBCPP_NO_EXCEPTIONS
993#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
989994 }
990995 catch (...)
991996 {
......@@ -996,7 +1001,7 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
9961001 throw;
9971002 }
9981003 }
999#endif // _LIBCPP_NO_EXCEPTIONS
1004#endif // _LIBCPP_HAS_NO_EXCEPTIONS
10001005 this->setstate(__state);
10011006 }
10021007 return *this;
......@@ -1012,14 +1017,14 @@ basic_istream<_CharT, _Traits>::peek()
10121017 sentry __sen(*this, true);
10131018 if (__sen)
10141019 {
1015#ifndef _LIBCPP_NO_EXCEPTIONS
1020#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
10161021 try
10171022 {
1018#endif // _LIBCPP_NO_EXCEPTIONS
1023#endif // _LIBCPP_HAS_NO_EXCEPTIONS
10191024 __r = this->rdbuf()->sgetc();
10201025 if (traits_type::eq_int_type(__r, traits_type::eof()))
10211026 __state |= ios_base::eofbit;
1022#ifndef _LIBCPP_NO_EXCEPTIONS
1027#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
10231028 }
10241029 catch (...)
10251030 {
......@@ -1030,7 +1035,7 @@ basic_istream<_CharT, _Traits>::peek()
10301035 throw;
10311036 }
10321037 }
1033#endif // _LIBCPP_NO_EXCEPTIONS
1038#endif // _LIBCPP_HAS_NO_EXCEPTIONS
10341039 this->setstate(__state);
10351040 }
10361041 return __r;
......@@ -1045,14 +1050,14 @@ basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n)
10451050 sentry __sen(*this, true);
10461051 if (__sen)
10471052 {
1048#ifndef _LIBCPP_NO_EXCEPTIONS
1053#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
10491054 try
10501055 {
1051#endif // _LIBCPP_NO_EXCEPTIONS
1056#endif // _LIBCPP_HAS_NO_EXCEPTIONS
10521057 __gc_ = this->rdbuf()->sgetn(__s, __n);
10531058 if (__gc_ != __n)
10541059 __state |= ios_base::failbit | ios_base::eofbit;
1055#ifndef _LIBCPP_NO_EXCEPTIONS
1060#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
10561061 }
10571062 catch (...)
10581063 {
......@@ -1063,7 +1068,7 @@ basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n)
10631068 throw;
10641069 }
10651070 }
1066#endif // _LIBCPP_NO_EXCEPTIONS
1071#endif // _LIBCPP_HAS_NO_EXCEPTIONS
10671072 }
10681073 else
10691074 {
......@@ -1082,10 +1087,10 @@ basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n)
10821087 sentry __sen(*this, true);
10831088 if (__sen)
10841089 {
1085#ifndef _LIBCPP_NO_EXCEPTIONS
1090#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
10861091 try
10871092 {
1088#endif // _LIBCPP_NO_EXCEPTIONS
1093#endif // _LIBCPP_HAS_NO_EXCEPTIONS
10891094 streamsize __c = this->rdbuf()->in_avail();
10901095 switch (__c)
10911096 {
......@@ -1101,7 +1106,7 @@ basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n)
11011106 __state |= ios_base::failbit | ios_base::eofbit;
11021107 break;
11031108 }
1104#ifndef _LIBCPP_NO_EXCEPTIONS
1109#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
11051110 }
11061111 catch (...)
11071112 {
......@@ -1112,7 +1117,7 @@ basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n)
11121117 throw;
11131118 }
11141119 }
1115#endif // _LIBCPP_NO_EXCEPTIONS
1120#endif // _LIBCPP_HAS_NO_EXCEPTIONS
11161121 }
11171122 else
11181123 {
......@@ -1132,13 +1137,13 @@ basic_istream<_CharT, _Traits>::putback(char_type __c)
11321137 sentry __sen(*this, true);
11331138 if (__sen)
11341139 {
1135#ifndef _LIBCPP_NO_EXCEPTIONS
1140#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
11361141 try
11371142 {
1138#endif // _LIBCPP_NO_EXCEPTIONS
1143#endif // _LIBCPP_HAS_NO_EXCEPTIONS
11391144 if (this->rdbuf() == nullptr || this->rdbuf()->sputbackc(__c) == traits_type::eof())
11401145 __state |= ios_base::badbit;
1141#ifndef _LIBCPP_NO_EXCEPTIONS
1146#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
11421147 }
11431148 catch (...)
11441149 {
......@@ -1149,7 +1154,7 @@ basic_istream<_CharT, _Traits>::putback(char_type __c)
11491154 throw;
11501155 }
11511156 }
1152#endif // _LIBCPP_NO_EXCEPTIONS
1157#endif // _LIBCPP_HAS_NO_EXCEPTIONS
11531158 }
11541159 else
11551160 {
......@@ -1169,13 +1174,13 @@ basic_istream<_CharT, _Traits>::unget()
11691174 sentry __sen(*this, true);
11701175 if (__sen)
11711176 {
1172#ifndef _LIBCPP_NO_EXCEPTIONS
1177#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
11731178 try
11741179 {
1175#endif // _LIBCPP_NO_EXCEPTIONS
1180#endif // _LIBCPP_HAS_NO_EXCEPTIONS
11761181 if (this->rdbuf() == nullptr || this->rdbuf()->sungetc() == traits_type::eof())
11771182 __state |= ios_base::badbit;
1178#ifndef _LIBCPP_NO_EXCEPTIONS
1183#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
11791184 }
11801185 catch (...)
11811186 {
......@@ -1186,7 +1191,7 @@ basic_istream<_CharT, _Traits>::unget()
11861191 throw;
11871192 }
11881193 }
1189#endif // _LIBCPP_NO_EXCEPTIONS
1194#endif // _LIBCPP_HAS_NO_EXCEPTIONS
11901195 }
11911196 else
11921197 {
......@@ -1205,10 +1210,10 @@ basic_istream<_CharT, _Traits>::sync()
12051210 sentry __sen(*this, true);
12061211 if (__sen)
12071212 {
1208#ifndef _LIBCPP_NO_EXCEPTIONS
1213#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
12091214 try
12101215 {
1211#endif // _LIBCPP_NO_EXCEPTIONS
1216#endif // _LIBCPP_HAS_NO_EXCEPTIONS
12121217 if (this->rdbuf() == nullptr)
12131218 return -1;
12141219 if (this->rdbuf()->pubsync() == -1)
......@@ -1216,7 +1221,7 @@ basic_istream<_CharT, _Traits>::sync()
12161221 __state |= ios_base::badbit;
12171222 return -1;
12181223 }
1219#ifndef _LIBCPP_NO_EXCEPTIONS
1224#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
12201225 }
12211226 catch (...)
12221227 {
......@@ -1227,7 +1232,7 @@ basic_istream<_CharT, _Traits>::sync()
12271232 throw;
12281233 }
12291234 }
1230#endif // _LIBCPP_NO_EXCEPTIONS
1235#endif // _LIBCPP_HAS_NO_EXCEPTIONS
12311236 this->setstate(__state);
12321237 }
12331238 return __r;
......@@ -1242,12 +1247,12 @@ basic_istream<_CharT, _Traits>::tellg()
12421247 sentry __sen(*this, true);
12431248 if (__sen)
12441249 {
1245#ifndef _LIBCPP_NO_EXCEPTIONS
1250#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
12461251 try
12471252 {
1248#endif // _LIBCPP_NO_EXCEPTIONS
1253#endif // _LIBCPP_HAS_NO_EXCEPTIONS
12491254 __r = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
1250#ifndef _LIBCPP_NO_EXCEPTIONS
1255#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
12511256 }
12521257 catch (...)
12531258 {
......@@ -1258,7 +1263,7 @@ basic_istream<_CharT, _Traits>::tellg()
12581263 throw;
12591264 }
12601265 }
1261#endif // _LIBCPP_NO_EXCEPTIONS
1266#endif // _LIBCPP_HAS_NO_EXCEPTIONS
12621267 this->setstate(__state);
12631268 }
12641269 return __r;
......@@ -1273,13 +1278,13 @@ basic_istream<_CharT, _Traits>::seekg(pos_type __pos)
12731278 sentry __sen(*this, true);
12741279 if (__sen)
12751280 {
1276#ifndef _LIBCPP_NO_EXCEPTIONS
1281#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
12771282 try
12781283 {
1279#endif // _LIBCPP_NO_EXCEPTIONS
1284#endif // _LIBCPP_HAS_NO_EXCEPTIONS
12801285 if (this->rdbuf()->pubseekpos(__pos, ios_base::in) == pos_type(-1))
12811286 __state |= ios_base::failbit;
1282#ifndef _LIBCPP_NO_EXCEPTIONS
1287#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
12831288 }
12841289 catch (...)
12851290 {
......@@ -1290,7 +1295,7 @@ basic_istream<_CharT, _Traits>::seekg(pos_type __pos)
12901295 throw;
12911296 }
12921297 }
1293#endif // _LIBCPP_NO_EXCEPTIONS
1298#endif // _LIBCPP_HAS_NO_EXCEPTIONS
12941299 this->setstate(__state);
12951300 }
12961301 return *this;
......@@ -1305,13 +1310,13 @@ basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir)
13051310 sentry __sen(*this, true);
13061311 if (__sen)
13071312 {
1308#ifndef _LIBCPP_NO_EXCEPTIONS
1313#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
13091314 try
13101315 {
1311#endif // _LIBCPP_NO_EXCEPTIONS
1316#endif // _LIBCPP_HAS_NO_EXCEPTIONS
13121317 if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::in) == pos_type(-1))
13131318 __state |= ios_base::failbit;
1314#ifndef _LIBCPP_NO_EXCEPTIONS
1319#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
13151320 }
13161321 catch (...)
13171322 {
......@@ -1322,7 +1327,7 @@ basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir)
13221327 throw;
13231328 }
13241329 }
1325#endif // _LIBCPP_NO_EXCEPTIONS
1330#endif // _LIBCPP_HAS_NO_EXCEPTIONS
13261331 this->setstate(__state);
13271332 }
13281333 return *this;
......@@ -1336,10 +1341,10 @@ ws(basic_istream<_CharT, _Traits>& __is)
13361341 typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);
13371342 if (__sen)
13381343 {
1339#ifndef _LIBCPP_NO_EXCEPTIONS
1344#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
13401345 try
13411346 {
1342#endif // _LIBCPP_NO_EXCEPTIONS
1347#endif // _LIBCPP_HAS_NO_EXCEPTIONS
13431348 const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc());
13441349 while (true)
13451350 {
......@@ -1353,7 +1358,7 @@ ws(basic_istream<_CharT, _Traits>& __is)
13531358 break;
13541359 __is.rdbuf()->sbumpc();
13551360 }
1356#ifndef _LIBCPP_NO_EXCEPTIONS
1361#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
13571362 }
13581363 catch (...)
13591364 {
......@@ -1364,7 +1369,7 @@ ws(basic_istream<_CharT, _Traits>& __is)
13641369 throw;
13651370 }
13661371 }
1367#endif // _LIBCPP_NO_EXCEPTIONS
1372#endif // _LIBCPP_HAS_NO_EXCEPTIONS
13681373 __is.setstate(__state);
13691374 }
13701375 return __is;
......@@ -1450,7 +1455,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
14501455 typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
14511456 if (__sen)
14521457 {
1453#ifndef _LIBCPP_NO_EXCEPTIONS
1458#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
14541459 try
14551460 {
14561461#endif
......@@ -1480,7 +1485,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
14801485 __is.width(0);
14811486 if (__c == 0)
14821487 __state |= ios_base::failbit;
1483#ifndef _LIBCPP_NO_EXCEPTIONS
1488#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
14841489 }
14851490 catch (...)
14861491 {
......@@ -1506,7 +1511,7 @@ getline(basic_istream<_CharT, _Traits>& __is,
15061511 typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);
15071512 if (__sen)
15081513 {
1509#ifndef _LIBCPP_NO_EXCEPTIONS
1514#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
15101515 try
15111516 {
15121517#endif
......@@ -1533,7 +1538,7 @@ getline(basic_istream<_CharT, _Traits>& __is,
15331538 }
15341539 if (__extr == 0)
15351540 __state |= ios_base::failbit;
1536#ifndef _LIBCPP_NO_EXCEPTIONS
1541#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
15371542 }
15381543 catch (...)
15391544 {
......@@ -1585,7 +1590,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
15851590 typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
15861591 if (__sen)
15871592 {
1588#ifndef _LIBCPP_NO_EXCEPTIONS
1593#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
15891594 try
15901595 {
15911596#endif
......@@ -1612,7 +1617,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
16121617 __x = bitset<_Size>(__str);
16131618 if (_Size > 0 && __c == 0)
16141619 __state |= ios_base::failbit;
1615#ifndef _LIBCPP_NO_EXCEPTIONS
1620#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
16161621 }
16171622 catch (...)
16181623 {
lib/libcxx/include/iterator+2-2
......@@ -387,7 +387,7 @@ template <class Iterator>
387387class move_iterator {
388388public:
389389 using iterator_type = Iterator;
390 using iterator_concept = input_iterator_tag; // From C++20
390 using iterator_concept = see below; // From C++20
391391 using iterator_category = see below; // not always present starting from C++20
392392 using value_type = iter_value_t<Iterator>; // Until C++20, iterator_traits<Iterator>::value_type
393393 using difference_type = iter_difference_t<Iterator>; // Until C++20, iterator_traits<Iterator>::difference_type;
......@@ -676,7 +676,6 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
676676
677677#include <__assert> // all public C++ headers provide the assertion handler
678678#include <__config>
679#include <__debug>
680679#include <__iterator/access.h>
681680#include <__iterator/advance.h>
682681#include <__iterator/back_insert_iterator.h>
......@@ -732,6 +731,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
732731#endif
733732
734733#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
734# include <cstdlib>
735735# include <exception>
736736# include <new>
737737# include <type_traits>
lib/libcxx/include/latch+30-6
......@@ -41,9 +41,12 @@ namespace std
4141*/
4242
4343#include <__assert> // all public C++ headers provide the assertion handler
44#include <__atomic/atomic_base.h>
45#include <__atomic/atomic_sync.h>
46#include <__atomic/memory_order.h>
4447#include <__availability>
4548#include <__config>
46#include <atomic>
49#include <cstddef>
4750#include <limits>
4851#include <version>
4952
......@@ -67,22 +70,35 @@ class latch
6770 __atomic_base<ptrdiff_t> __a_;
6871
6972public:
70 static constexpr ptrdiff_t max() noexcept {
73 static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {
7174 return numeric_limits<ptrdiff_t>::max();
7275 }
7376
7477 inline _LIBCPP_INLINE_VISIBILITY
75 constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected) { }
78 constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected)
79 {
80 _LIBCPP_ASSERT_UNCATEGORIZED(__expected >= 0,
81 "latch::latch(ptrdiff_t): latch cannot be "
82 "initialized with a negative value");
83 _LIBCPP_ASSERT_UNCATEGORIZED(__expected <= max(),
84 "latch::latch(ptrdiff_t): latch cannot be "
85 "initialized with a value greater than max()");
86 }
7687
77 ~latch() = default;
88 _LIBCPP_HIDE_FROM_ABI ~latch() = default;
7889 latch(const latch&) = delete;
7990 latch& operator=(const latch&) = delete;
8091
8192 inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
8293 void count_down(ptrdiff_t __update = 1)
8394 {
95 _LIBCPP_ASSERT_UNCATEGORIZED(
96 __update >= 0, "latch::count_down called with a negative value");
8497 auto const __old = __a_.fetch_sub(__update, memory_order_release);
85 if(__old == __update)
98 _LIBCPP_ASSERT_UNCATEGORIZED(
99 __update <= __old, "latch::count_down called with a value greater "
100 "than the internal counter");
101 if (__old == __update)
86102 __a_.notify_all();
87103 }
88104 inline _LIBCPP_INLINE_VISIBILITY
......@@ -93,13 +109,17 @@ public:
93109 inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
94110 void wait() const
95111 {
96 __cxx_atomic_wait(&__a_.__a_, [&]() -> bool {
112 __cxx_atomic_wait(&__a_.__a_, [this]() -> bool {
97113 return try_wait();
98114 });
99115 }
100116 inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
101117 void arrive_and_wait(ptrdiff_t __update = 1)
102118 {
119 _LIBCPP_ASSERT_UNCATEGORIZED(
120 __update >= 0, "latch::arrive_and_wait called with a negative value");
121 // other preconditions on __update are checked in count_down()
122
103123 count_down(__update);
104124 wait();
105125 }
......@@ -111,4 +131,8 @@ _LIBCPP_END_NAMESPACE_STD
111131
112132_LIBCPP_POP_MACROS
113133
134#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
135# include <atomic>
136#endif
137
114138#endif //_LIBCPP_LATCH
lib/libcxx/include/list+249-489
......@@ -46,6 +46,8 @@ public:
4646 list(Iter first, Iter last);
4747 template <class Iter>
4848 list(Iter first, Iter last, const allocator_type& a);
49 template<container-compatible-range<T> R>
50 list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
4951 list(const list& x);
5052 list(const list&, const allocator_type& a);
5153 list(list&& x)
......@@ -64,6 +66,8 @@ public:
6466 list& operator=(initializer_list<value_type>);
6567 template <class Iter>
6668 void assign(Iter first, Iter last);
69 template<container-compatible-range<T> R>
70 void assign_range(R&& rg); // C++23
6771 void assign(size_type n, const value_type& t);
6872 void assign(initializer_list<value_type>);
6973
......@@ -99,8 +103,12 @@ public:
99103 void pop_back();
100104 void push_front(const value_type& x);
101105 void push_front(value_type&& x);
106 template<container-compatible-range<T> R>
107 void prepend_range(R&& rg); // C++23
102108 void push_back(const value_type& x);
103109 void push_back(value_type&& x);
110 template<container-compatible-range<T> R>
111 void append_range(R&& rg); // C++23
104112 template <class... Args>
105113 iterator emplace(const_iterator position, Args&&... args);
106114 iterator insert(const_iterator position, const value_type& x);
......@@ -108,6 +116,8 @@ public:
108116 iterator insert(const_iterator position, size_type n, const value_type& x);
109117 template <class Iter>
110118 iterator insert(const_iterator position, Iter first, Iter last);
119 template<container-compatible-range<T> R>
120 iterator insert_range(const_iterator position, R&& rg); // C++23
111121 iterator insert(const_iterator position, initializer_list<value_type> il);
112122
113123 iterator erase(const_iterator position);
......@@ -152,18 +162,25 @@ template <class InputIterator, class Allocator = allocator<typename iterator_tra
152162 list(InputIterator, InputIterator, Allocator = Allocator())
153163 -> list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
154164
165template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
166 list(from_range_t, R&&, Allocator = Allocator())
167 -> list<ranges::range_value_t<R>, Allocator>; // C++23
168
155169template <class T, class Alloc>
156170 bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y);
157171template <class T, class Alloc>
158 bool operator< (const list<T,Alloc>& x, const list<T,Alloc>& y);
172 bool operator< (const list<T,Alloc>& x, const list<T,Alloc>& y); // removed in C++20
159173template <class T, class Alloc>
160 bool operator!=(const list<T,Alloc>& x, const list<T,Alloc>& y);
174 bool operator!=(const list<T,Alloc>& x, const list<T,Alloc>& y); // removed in C++20
161175template <class T, class Alloc>
162 bool operator> (const list<T,Alloc>& x, const list<T,Alloc>& y);
176 bool operator> (const list<T,Alloc>& x, const list<T,Alloc>& y); // removed in C++20
163177template <class T, class Alloc>
164 bool operator>=(const list<T,Alloc>& x, const list<T,Alloc>& y);
178 bool operator>=(const list<T,Alloc>& x, const list<T,Alloc>& y); // removed in C++20
165179template <class T, class Alloc>
166 bool operator<=(const list<T,Alloc>& x, const list<T,Alloc>& y);
180 bool operator<=(const list<T,Alloc>& x, const list<T,Alloc>& y); // removed in C++20
181template<class T, class Allocator>
182 synth-three-way-result<T> operator<=>(const list<T, Allocator>& x,
183 const list<T, Allocator>& y); // since C++20
167184
168185template <class T, class Alloc>
169186 void swap(list<T,Alloc>& x, list<T,Alloc>& y)
......@@ -171,10 +188,10 @@ template <class T, class Alloc>
171188
172189template <class T, class Allocator, class U>
173190 typename list<T, Allocator>::size_type
174 erase(list<T, Allocator>& c, const U& value); // C++20
191 erase(list<T, Allocator>& c, const U& value); // since C++20
175192template <class T, class Allocator, class Predicate>
176193 typename list<T, Allocator>::size_type
177 erase_if(list<T, Allocator>& c, Predicate pred); // C++20
194 erase_if(list<T, Allocator>& c, Predicate pred); // since C++20
178195
179196} // std
180197
......@@ -183,10 +200,11 @@ template <class T, class Allocator, class Predicate>
183200#include <__algorithm/comp.h>
184201#include <__algorithm/equal.h>
185202#include <__algorithm/lexicographical_compare.h>
203#include <__algorithm/lexicographical_compare_three_way.h>
186204#include <__algorithm/min.h>
187205#include <__assert> // all public C++ headers provide the assertion handler
206#include <__availability>
188207#include <__config>
189#include <__debug>
190208#include <__format/enable_insertable.h>
191209#include <__iterator/distance.h>
192210#include <__iterator/iterator_traits.h>
......@@ -203,13 +221,23 @@ template <class T, class Allocator, class Predicate>
203221#include <__memory/swap_allocator.h>
204222#include <__memory/unique_ptr.h>
205223#include <__memory_resource/polymorphic_allocator.h>
224#include <__ranges/access.h>
225#include <__ranges/concepts.h>
226#include <__ranges/container_compatible_range.h>
227#include <__ranges/from_range.h>
228#include <__type_traits/conditional.h>
206229#include <__type_traits/is_allocator.h>
230#include <__type_traits/is_nothrow_default_constructible.h>
231#include <__type_traits/is_nothrow_move_assignable.h>
232#include <__type_traits/is_nothrow_move_constructible.h>
233#include <__type_traits/is_pointer.h>
234#include <__type_traits/is_same.h>
235#include <__type_traits/type_identity.h>
207236#include <__utility/forward.h>
208237#include <__utility/move.h>
209238#include <__utility/swap.h>
210239#include <cstring>
211240#include <limits>
212#include <type_traits>
213241#include <version>
214242
215243// standard-mandated includes
......@@ -320,13 +348,9 @@ class _LIBCPP_TEMPLATE_VIS __list_iterator
320348 __link_pointer __ptr_;
321349
322350 _LIBCPP_INLINE_VISIBILITY
323 explicit __list_iterator(__link_pointer __p, const void* __c) _NOEXCEPT
351 explicit __list_iterator(__link_pointer __p) _NOEXCEPT
324352 : __ptr_(__p)
325353 {
326 (void)__c;
327#ifdef _LIBCPP_ENABLE_DEBUG_MODE
328 __get_db()->__insert_ic(this, __c);
329#endif
330354 }
331355
332356 template<class, class> friend class list;
......@@ -342,57 +366,22 @@ public:
342366 _LIBCPP_INLINE_VISIBILITY
343367 __list_iterator() _NOEXCEPT : __ptr_(nullptr)
344368 {
345 _VSTD::__debug_db_insert_i(this);
346 }
347
348#ifdef _LIBCPP_ENABLE_DEBUG_MODE
349
350 _LIBCPP_INLINE_VISIBILITY
351 __list_iterator(const __list_iterator& __p)
352 : __ptr_(__p.__ptr_)
353 {
354 __get_db()->__iterator_copy(this, _VSTD::addressof(__p));
355 }
356
357 _LIBCPP_INLINE_VISIBILITY
358 ~__list_iterator()
359 {
360 __get_db()->__erase_i(this);
361 }
362
363 _LIBCPP_INLINE_VISIBILITY
364 __list_iterator& operator=(const __list_iterator& __p)
365 {
366 if (this != _VSTD::addressof(__p))
367 {
368 __get_db()->__iterator_copy(this, _VSTD::addressof(__p));
369 __ptr_ = __p.__ptr_;
370 }
371 return *this;
372369 }
373370
374#endif // _LIBCPP_ENABLE_DEBUG_MODE
375
376371 _LIBCPP_INLINE_VISIBILITY
377372 reference operator*() const
378373 {
379 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
380 "Attempted to dereference a non-dereferenceable list::iterator");
381374 return __ptr_->__as_node()->__value_;
382375 }
383376 _LIBCPP_INLINE_VISIBILITY
384377 pointer operator->() const
385378 {
386 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
387 "Attempted to dereference a non-dereferenceable list::iterator");
388379 return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_);
389380 }
390381
391382 _LIBCPP_INLINE_VISIBILITY
392383 __list_iterator& operator++()
393384 {
394 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
395 "Attempted to increment a non-incrementable list::iterator");
396385 __ptr_ = __ptr_->__next_;
397386 return *this;
398387 }
......@@ -402,8 +391,6 @@ public:
402391 _LIBCPP_INLINE_VISIBILITY
403392 __list_iterator& operator--()
404393 {
405 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this),
406 "Attempted to decrement a non-decrementable list::iterator");
407394 __ptr_ = __ptr_->__prev_;
408395 return *this;
409396 }
......@@ -429,13 +416,9 @@ class _LIBCPP_TEMPLATE_VIS __list_const_iterator
429416 __link_pointer __ptr_;
430417
431418 _LIBCPP_INLINE_VISIBILITY
432 explicit __list_const_iterator(__link_pointer __p, const void* __c) _NOEXCEPT
419 explicit __list_const_iterator(__link_pointer __p) _NOEXCEPT
433420 : __ptr_(__p)
434421 {
435 (void)__c;
436#ifdef _LIBCPP_ENABLE_DEBUG_MODE
437 __get_db()->__insert_ic(this, __c);
438#endif
439422 }
440423
441424 template<class, class> friend class list;
......@@ -450,64 +433,27 @@ public:
450433 _LIBCPP_INLINE_VISIBILITY
451434 __list_const_iterator() _NOEXCEPT : __ptr_(nullptr)
452435 {
453 _VSTD::__debug_db_insert_i(this);
454436 }
455437 _LIBCPP_INLINE_VISIBILITY
456438 __list_const_iterator(const __list_iterator<_Tp, _VoidPtr>& __p) _NOEXCEPT
457439 : __ptr_(__p.__ptr_)
458440 {
459#ifdef _LIBCPP_ENABLE_DEBUG_MODE
460 __get_db()->__iterator_copy(this, _VSTD::addressof(__p));
461#endif
462 }
463
464#ifdef _LIBCPP_ENABLE_DEBUG_MODE
465
466 _LIBCPP_INLINE_VISIBILITY
467 __list_const_iterator(const __list_const_iterator& __p)
468 : __ptr_(__p.__ptr_)
469 {
470 __get_db()->__iterator_copy(this, _VSTD::addressof(__p));
471 }
472
473 _LIBCPP_INLINE_VISIBILITY
474 ~__list_const_iterator()
475 {
476 __get_db()->__erase_i(this);
477 }
478
479 _LIBCPP_INLINE_VISIBILITY
480 __list_const_iterator& operator=(const __list_const_iterator& __p)
481 {
482 if (this != _VSTD::addressof(__p))
483 {
484 __get_db()->__iterator_copy(this, _VSTD::addressof(__p));
485 __ptr_ = __p.__ptr_;
486 }
487 return *this;
488441 }
489442
490#endif // _LIBCPP_ENABLE_DEBUG_MODE
491443 _LIBCPP_INLINE_VISIBILITY
492444 reference operator*() const
493445 {
494 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
495 "Attempted to dereference a non-dereferenceable list::const_iterator");
496446 return __ptr_->__as_node()->__value_;
497447 }
498448 _LIBCPP_INLINE_VISIBILITY
499449 pointer operator->() const
500450 {
501 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
502 "Attempted to dereference a non-dereferenceable list::const_iterator");
503451 return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_);
504452 }
505453
506454 _LIBCPP_INLINE_VISIBILITY
507455 __list_const_iterator& operator++()
508456 {
509 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
510 "Attempted to increment a non-incrementable list::const_iterator");
511457 __ptr_ = __ptr_->__next_;
512458 return *this;
513459 }
......@@ -517,8 +463,6 @@ public:
517463 _LIBCPP_INLINE_VISIBILITY
518464 __list_const_iterator& operator--()
519465 {
520 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this),
521 "Attempted to decrement a non-decrementable list::const_iterator");
522466 __ptr_ = __ptr_->__prev_;
523467 return *this;
524468 }
......@@ -604,35 +548,35 @@ protected:
604548 _LIBCPP_INLINE_VISIBILITY
605549 __list_imp(const __node_allocator& __a);
606550#ifndef _LIBCPP_CXX03_LANG
607 __list_imp(__node_allocator&& __a) _NOEXCEPT;
551 _LIBCPP_HIDE_FROM_ABI __list_imp(__node_allocator&& __a) _NOEXCEPT;
608552#endif
609 ~__list_imp();
610 void clear() _NOEXCEPT;
553 _LIBCPP_HIDE_FROM_ABI ~__list_imp();
554 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
611555 _LIBCPP_INLINE_VISIBILITY
612556 bool empty() const _NOEXCEPT {return __sz() == 0;}
613557
614558 _LIBCPP_INLINE_VISIBILITY
615559 iterator begin() _NOEXCEPT
616560 {
617 return iterator(__end_.__next_, this);
561 return iterator(__end_.__next_);
618562 }
619563 _LIBCPP_INLINE_VISIBILITY
620564 const_iterator begin() const _NOEXCEPT
621565 {
622 return const_iterator(__end_.__next_, this);
566 return const_iterator(__end_.__next_);
623567 }
624568 _LIBCPP_INLINE_VISIBILITY
625569 iterator end() _NOEXCEPT
626570 {
627 return iterator(__end_as_link(), this);
571 return iterator(__end_as_link());
628572 }
629573 _LIBCPP_INLINE_VISIBILITY
630574 const_iterator end() const _NOEXCEPT
631575 {
632 return const_iterator(__end_as_link(), this);
576 return const_iterator(__end_as_link());
633577 }
634578
635 void swap(__list_imp& __c)
579 _LIBCPP_HIDE_FROM_ABI void swap(__list_imp& __c)
636580#if _LIBCPP_STD_VER >= 14
637581 _NOEXCEPT;
638582#else
......@@ -718,7 +662,6 @@ inline __list_imp<_Tp, _Alloc>::__list_imp(__node_allocator&& __a) _NOEXCEPT
718662template <class _Tp, class _Alloc>
719663__list_imp<_Tp, _Alloc>::~__list_imp() {
720664 clear();
721 std::__debug_db_erase_c(this);
722665}
723666
724667template <class _Tp, class _Alloc>
......@@ -739,7 +682,6 @@ __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT
739682 __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
740683 __node_alloc_traits::deallocate(__na, __np, 1);
741684 }
742 std::__debug_db_invalidate_all(this);
743685 }
744686}
745687
......@@ -753,10 +695,10 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
753695 __is_nothrow_swappable<allocator_type>::value)
754696#endif
755697{
756 _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
757 this->__node_alloc() == __c.__node_alloc(),
758 "list::swap: Either propagate_on_container_swap must be true"
759 " or the allocators must compare equal");
698 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__alloc_traits::propagate_on_container_swap::value ||
699 this->__node_alloc() == __c.__node_alloc(),
700 "list::swap: Either propagate_on_container_swap must be true"
701 " or the allocators must compare equal");
760702 using _VSTD::swap;
761703 _VSTD::__swap_allocator(__node_alloc(), __c.__node_alloc());
762704 swap(__sz(), __c.__sz());
......@@ -769,42 +711,6 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
769711 __c.__end_.__next_ = __c.__end_.__prev_ = __c.__end_as_link();
770712 else
771713 __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_as_link();
772
773#ifdef _LIBCPP_ENABLE_DEBUG_MODE
774 __libcpp_db* __db = __get_db();
775 __c_node* __cn1 = __db->__find_c_and_lock(this);
776 __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c));
777 _VSTD::swap(__cn1->beg_, __cn2->beg_);
778 _VSTD::swap(__cn1->end_, __cn2->end_);
779 _VSTD::swap(__cn1->cap_, __cn2->cap_);
780 for (__i_node** __p = __cn1->end_; __p != __cn1->beg_;)
781 {
782 --__p;
783 const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
784 if (__i->__ptr_ == __c.__end_as_link())
785 {
786 __cn2->__add(*__p);
787 if (--__cn1->end_ != __p)
788 _VSTD::memmove(__p, __p+1, (__cn1->end_ - __p)*sizeof(__i_node*));
789 }
790 else
791 (*__p)->__c_ = __cn1;
792 }
793 for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)
794 {
795 --__p;
796 const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
797 if (__i->__ptr_ == __end_as_link())
798 {
799 __cn1->__add(*__p);
800 if (--__cn2->end_ != __p)
801 _VSTD::memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));
802 }
803 else
804 (*__p)->__c_ = __cn2;
805 }
806 __db->unlock();
807#endif
808714}
809715
810716template <class _Tp, class _Alloc /*= allocator<_Tp>*/>
......@@ -824,7 +730,7 @@ public:
824730 typedef _Tp value_type;
825731 typedef _Alloc allocator_type;
826732 static_assert((is_same<value_type, typename allocator_type::value_type>::value),
827 "Invalid allocator::value_type");
733 "Allocator::value_type must be same type as value_type");
828734 typedef value_type& reference;
829735 typedef const value_type& const_reference;
830736 typedef typename base::pointer pointer;
......@@ -835,7 +741,7 @@ public:
835741 typedef typename base::const_iterator const_iterator;
836742 typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
837743 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
838#if _LIBCPP_STD_VER > 17
744#if _LIBCPP_STD_VER >= 20
839745 typedef size_type __remove_return_type;
840746#else
841747 typedef void __remove_return_type;
......@@ -849,40 +755,45 @@ public:
849755 list()
850756 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
851757 {
852 _VSTD::__debug_db_insert_c(this);
853758 }
854759 _LIBCPP_INLINE_VISIBILITY
855760 explicit list(const allocator_type& __a) : base(__a)
856761 {
857 _VSTD::__debug_db_insert_c(this);
858762 }
859 explicit list(size_type __n);
860#if _LIBCPP_STD_VER > 11
861 explicit list(size_type __n, const allocator_type& __a);
763 _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n);
764#if _LIBCPP_STD_VER >= 14
765 _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n, const allocator_type& __a);
862766#endif
863 list(size_type __n, const value_type& __x);
767 _LIBCPP_HIDE_FROM_ABI list(size_type __n, const value_type& __x);
864768 template <class = __enable_if_t<__is_allocator<_Alloc>::value> >
865 list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a)
769 _LIBCPP_HIDE_FROM_ABI list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a)
866770 {
867 _VSTD::__debug_db_insert_c(this);
868771 for (; __n > 0; --__n)
869772 push_back(__x);
870773 }
871774
872775 template <class _InpIter>
873 list(_InpIter __f, _InpIter __l,
874 __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0);
776 _LIBCPP_HIDE_FROM_ABI list(_InpIter __f, _InpIter __l,
777 __enable_if_t<__has_input_iterator_category<_InpIter>::value>* = 0);
875778 template <class _InpIter>
876 list(_InpIter __f, _InpIter __l, const allocator_type& __a,
877 __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0);
779 _LIBCPP_HIDE_FROM_ABI list(_InpIter __f, _InpIter __l, const allocator_type& __a,
780 __enable_if_t<__has_input_iterator_category<_InpIter>::value>* = 0);
781
782#if _LIBCPP_STD_VER >= 23
783 template <_ContainerCompatibleRange<_Tp> _Range>
784 _LIBCPP_HIDE_FROM_ABI list(from_range_t, _Range&& __range,
785 const allocator_type& __a = allocator_type()) : base(__a) {
786 prepend_range(std::forward<_Range>(__range));
787 }
788#endif
878789
879 list(const list& __c);
880 list(const list& __c, const __type_identity_t<allocator_type>& __a);
790 _LIBCPP_HIDE_FROM_ABI list(const list& __c);
791 _LIBCPP_HIDE_FROM_ABI list(const list& __c, const __type_identity_t<allocator_type>& __a);
881792 _LIBCPP_INLINE_VISIBILITY
882793 list& operator=(const list& __c);
883794#ifndef _LIBCPP_CXX03_LANG
884 list(initializer_list<value_type> __il);
885 list(initializer_list<value_type> __il, const allocator_type& __a);
795 _LIBCPP_HIDE_FROM_ABI list(initializer_list<value_type> __il);
796 _LIBCPP_HIDE_FROM_ABI list(initializer_list<value_type> __il, const allocator_type& __a);
886797
887798 _LIBCPP_INLINE_VISIBILITY
888799 list(list&& __c)
......@@ -905,9 +816,18 @@ public:
905816#endif // _LIBCPP_CXX03_LANG
906817
907818 template <class _InpIter>
908 void assign(_InpIter __f, _InpIter __l,
909 __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0);
910 void assign(size_type __n, const value_type& __x);
819 _LIBCPP_HIDE_FROM_ABI void assign(_InpIter __f, _InpIter __l,
820 __enable_if_t<__has_input_iterator_category<_InpIter>::value>* = 0);
821
822#if _LIBCPP_STD_VER >= 23
823 template <_ContainerCompatibleRange<_Tp> _Range>
824 _LIBCPP_HIDE_FROM_ABI
825 void assign_range(_Range&& __range) {
826 __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
827 }
828#endif
829
830 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __x);
911831
912832 _LIBCPP_INLINE_VISIBILITY
913833 allocator_type get_allocator() const _NOEXCEPT;
......@@ -959,56 +879,70 @@ public:
959879 _LIBCPP_INLINE_VISIBILITY
960880 reference front()
961881 {
962 _LIBCPP_ASSERT(!empty(), "list::front called on empty list");
882 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list");
963883 return base::__end_.__next_->__as_node()->__value_;
964884 }
965885 _LIBCPP_INLINE_VISIBILITY
966886 const_reference front() const
967887 {
968 _LIBCPP_ASSERT(!empty(), "list::front called on empty list");
888 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list");
969889 return base::__end_.__next_->__as_node()->__value_;
970890 }
971891 _LIBCPP_INLINE_VISIBILITY
972892 reference back()
973893 {
974 _LIBCPP_ASSERT(!empty(), "list::back called on empty list");
894 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list");
975895 return base::__end_.__prev_->__as_node()->__value_;
976896 }
977897 _LIBCPP_INLINE_VISIBILITY
978898 const_reference back() const
979899 {
980 _LIBCPP_ASSERT(!empty(), "list::back called on empty list");
900 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list");
981901 return base::__end_.__prev_->__as_node()->__value_;
982902 }
983903
984904#ifndef _LIBCPP_CXX03_LANG
985 void push_front(value_type&& __x);
986 void push_back(value_type&& __x);
905 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __x);
906 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x);
907
908#if _LIBCPP_STD_VER >= 23
909 template <_ContainerCompatibleRange<_Tp> _Range>
910 _LIBCPP_HIDE_FROM_ABI
911 void prepend_range(_Range&& __range) {
912 insert_range(begin(), std::forward<_Range>(__range));
913 }
914
915 template <_ContainerCompatibleRange<_Tp> _Range>
916 _LIBCPP_HIDE_FROM_ABI
917 void append_range(_Range&& __range) {
918 insert_range(end(), std::forward<_Range>(__range));
919 }
920#endif
987921
988922 template <class... _Args>
989#if _LIBCPP_STD_VER > 14
990 reference emplace_front(_Args&&... __args);
923#if _LIBCPP_STD_VER >= 17
924 _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args);
991925#else
992 void emplace_front(_Args&&... __args);
926 _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args);
993927#endif
994928 template <class... _Args>
995#if _LIBCPP_STD_VER > 14
996 reference emplace_back(_Args&&... __args);
929#if _LIBCPP_STD_VER >= 17
930 _LIBCPP_HIDE_FROM_ABI reference emplace_back(_Args&&... __args);
997931#else
998 void emplace_back(_Args&&... __args);
932 _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args);
999933#endif
1000934 template <class... _Args>
1001 iterator emplace(const_iterator __p, _Args&&... __args);
935 _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args);
1002936
1003 iterator insert(const_iterator __p, value_type&& __x);
937 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __x);
1004938
1005939 _LIBCPP_INLINE_VISIBILITY
1006940 iterator insert(const_iterator __p, initializer_list<value_type> __il)
1007941 {return insert(__p, __il.begin(), __il.end());}
1008942#endif // _LIBCPP_CXX03_LANG
1009943
1010 void push_front(const value_type& __x);
1011 void push_back(const value_type& __x);
944 _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __x);
945 _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __x);
1012946
1013947#ifndef _LIBCPP_CXX03_LANG
1014948 template <class _Arg>
......@@ -1019,11 +953,19 @@ public:
1019953 void __emplace_back(value_type const& __arg) { push_back(__arg); }
1020954#endif
1021955
1022 iterator insert(const_iterator __p, const value_type& __x);
1023 iterator insert(const_iterator __p, size_type __n, const value_type& __x);
956 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __x);
957 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __x);
1024958 template <class _InpIter>
1025 iterator insert(const_iterator __p, _InpIter __f, _InpIter __l,
1026 __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0);
959 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InpIter __f, _InpIter __l,
960 __enable_if_t<__has_input_iterator_category<_InpIter>::value>* = 0);
961
962#if _LIBCPP_STD_VER >= 23
963 template <_ContainerCompatibleRange<_Tp> _Range>
964 _LIBCPP_HIDE_FROM_ABI
965 iterator insert_range(const_iterator __position, _Range&& __range) {
966 return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
967 }
968#endif
1027969
1028970 _LIBCPP_INLINE_VISIBILITY
1029971 void swap(list& __c)
......@@ -1037,16 +979,16 @@ public:
1037979 _LIBCPP_INLINE_VISIBILITY
1038980 void clear() _NOEXCEPT {base::clear();}
1039981
1040 void pop_front();
1041 void pop_back();
982 _LIBCPP_HIDE_FROM_ABI void pop_front();
983 _LIBCPP_HIDE_FROM_ABI void pop_back();
1042984
1043 iterator erase(const_iterator __p);
1044 iterator erase(const_iterator __f, const_iterator __l);
985 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
986 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l);
1045987
1046 void resize(size_type __n);
1047 void resize(size_type __n, const value_type& __x);
988 _LIBCPP_HIDE_FROM_ABI void resize(size_type __n);
989 _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __x);
1048990
1049 void splice(const_iterator __p, list& __c);
991 _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c);
1050992#ifndef _LIBCPP_CXX03_LANG
1051993 _LIBCPP_INLINE_VISIBILITY
1052994 void splice(const_iterator __p, list&& __c) {splice(__p, __c);}
......@@ -1057,15 +999,16 @@ public:
1057999 void splice(const_iterator __p, list&& __c, const_iterator __f, const_iterator __l)
10581000 {splice(__p, __c, __f, __l);}
10591001#endif
1060 void splice(const_iterator __p, list& __c, const_iterator __i);
1061 void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l);
1002 _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c, const_iterator __i);
1003 _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l);
10621004
1063 __remove_return_type remove(const value_type& __x);
1064 template <class _Pred> __remove_return_type remove_if(_Pred __pred);
1005 _LIBCPP_HIDE_FROM_ABI __remove_return_type remove(const value_type& __x);
1006 template <class _Pred>
1007 _LIBCPP_HIDE_FROM_ABI __remove_return_type remove_if(_Pred __pred);
10651008 _LIBCPP_INLINE_VISIBILITY
10661009 __remove_return_type unique() { return unique(__equal_to()); }
10671010 template <class _BinaryPred>
1068 __remove_return_type unique(_BinaryPred __binary_pred);
1011 _LIBCPP_HIDE_FROM_ABI __remove_return_type unique(_BinaryPred __binary_pred);
10691012 _LIBCPP_INLINE_VISIBILITY
10701013 void merge(list& __c);
10711014#ifndef _LIBCPP_CXX03_LANG
......@@ -1077,7 +1020,7 @@ public:
10771020 void merge(list&& __c, _Comp __comp) {merge(__c, __comp);}
10781021#endif
10791022 template <class _Comp>
1080 void merge(list& __c, _Comp __comp);
1023 _LIBCPP_HIDE_FROM_ABI void merge(list& __c, _Comp __comp);
10811024
10821025 _LIBCPP_INLINE_VISIBILITY
10831026 void sort();
......@@ -1085,9 +1028,9 @@ public:
10851028 _LIBCPP_INLINE_VISIBILITY
10861029 void sort(_Comp __comp);
10871030
1088 void reverse() _NOEXCEPT;
1031 _LIBCPP_HIDE_FROM_ABI void reverse() _NOEXCEPT;
10891032
1090 bool __invariants() const;
1033 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
10911034
10921035 typedef __allocator_destructor<__node_allocator> __node_destructor;
10931036 typedef unique_ptr<__node, __node_destructor> __hold_pointer;
......@@ -1099,35 +1042,35 @@ public:
10991042 return __hold_pointer(__p, __node_destructor(__na, 1));
11001043 }
11011044
1102#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1103
1104 bool __dereferenceable(const const_iterator* __i) const;
1105 bool __decrementable(const const_iterator* __i) const;
1106 bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
1107 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
1045private:
1046 template <class _Iterator, class _Sentinel>
1047 _LIBCPP_HIDE_FROM_ABI
1048 void __assign_with_sentinel(_Iterator __f, _Sentinel __l);
11081049
1109#endif // _LIBCPP_ENABLE_DEBUG_MODE
1050 template <class _Iterator, class _Sentinel>
1051 _LIBCPP_HIDE_FROM_ABI
1052 iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l);
11101053
1111private:
11121054 _LIBCPP_INLINE_VISIBILITY
11131055 static void __link_nodes (__link_pointer __p, __link_pointer __f, __link_pointer __l);
11141056 _LIBCPP_INLINE_VISIBILITY
11151057 void __link_nodes_at_front(__link_pointer __f, __link_pointer __l);
11161058 _LIBCPP_INLINE_VISIBILITY
11171059 void __link_nodes_at_back (__link_pointer __f, __link_pointer __l);
1118 iterator __iterator(size_type __n);
1060 _LIBCPP_HIDE_FROM_ABI iterator __iterator(size_type __n);
1061 // TODO: Make this _LIBCPP_HIDE_FROM_ABI
11191062 template <class _Comp>
1120 static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp);
1063 _LIBCPP_HIDDEN static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp);
11211064
1122 void __move_assign(list& __c, true_type)
1065 _LIBCPP_HIDE_FROM_ABI void __move_assign(list& __c, true_type)
11231066 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value);
1124 void __move_assign(list& __c, false_type);
1067 _LIBCPP_HIDE_FROM_ABI void __move_assign(list& __c, false_type);
11251068};
11261069
11271070#if _LIBCPP_STD_VER >= 17
11281071template<class _InputIterator,
11291072 class _Alloc = allocator<__iter_value_type<_InputIterator>>,
1130 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1073 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
11311074 class = enable_if_t<__is_allocator<_Alloc>::value>
11321075 >
11331076list(_InputIterator, _InputIterator)
......@@ -1135,13 +1078,22 @@ list(_InputIterator, _InputIterator)
11351078
11361079template<class _InputIterator,
11371080 class _Alloc,
1138 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1081 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
11391082 class = enable_if_t<__is_allocator<_Alloc>::value>
11401083 >
11411084list(_InputIterator, _InputIterator, _Alloc)
11421085 -> list<__iter_value_type<_InputIterator>, _Alloc>;
11431086#endif
11441087
1088#if _LIBCPP_STD_VER >= 23
1089template <ranges::input_range _Range,
1090 class _Alloc = allocator<ranges::range_value_t<_Range>>,
1091 class = enable_if_t<__is_allocator<_Alloc>::value>
1092 >
1093list(from_range_t, _Range&&, _Alloc = _Alloc())
1094 -> list<ranges::range_value_t<_Range>, _Alloc>;
1095#endif
1096
11451097// Link in nodes [__f, __l] just prior to __p
11461098template <class _Tp, class _Alloc>
11471099inline
......@@ -1191,7 +1143,6 @@ list<_Tp, _Alloc>::__iterator(size_type __n)
11911143template <class _Tp, class _Alloc>
11921144list<_Tp, _Alloc>::list(size_type __n)
11931145{
1194 _VSTD::__debug_db_insert_c(this);
11951146 for (; __n > 0; --__n)
11961147#ifndef _LIBCPP_CXX03_LANG
11971148 emplace_back();
......@@ -1200,11 +1151,10 @@ list<_Tp, _Alloc>::list(size_type __n)
12001151#endif
12011152}
12021153
1203#if _LIBCPP_STD_VER > 11
1154#if _LIBCPP_STD_VER >= 14
12041155template <class _Tp, class _Alloc>
12051156list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a)
12061157{
1207 _VSTD::__debug_db_insert_c(this);
12081158 for (; __n > 0; --__n)
12091159 emplace_back();
12101160}
......@@ -1213,7 +1163,6 @@ list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a)
12131163template <class _Tp, class _Alloc>
12141164list<_Tp, _Alloc>::list(size_type __n, const value_type& __x)
12151165{
1216 _VSTD::__debug_db_insert_c(this);
12171166 for (; __n > 0; --__n)
12181167 push_back(__x);
12191168}
......@@ -1221,9 +1170,8 @@ list<_Tp, _Alloc>::list(size_type __n, const value_type& __x)
12211170template <class _Tp, class _Alloc>
12221171template <class _InpIter>
12231172list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l,
1224 __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*)
1173 __enable_if_t<__has_input_iterator_category<_InpIter>::value>*)
12251174{
1226 _VSTD::__debug_db_insert_c(this);
12271175 for (; __f != __l; ++__f)
12281176 __emplace_back(*__f);
12291177}
......@@ -1231,10 +1179,9 @@ list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l,
12311179template <class _Tp, class _Alloc>
12321180template <class _InpIter>
12331181list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a,
1234 __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*)
1182 __enable_if_t<__has_input_iterator_category<_InpIter>::value>*)
12351183 : base(__a)
12361184{
1237 _VSTD::__debug_db_insert_c(this);
12381185 for (; __f != __l; ++__f)
12391186 __emplace_back(*__f);
12401187}
......@@ -1243,7 +1190,6 @@ template <class _Tp, class _Alloc>
12431190list<_Tp, _Alloc>::list(const list& __c)
12441191 : base(__node_alloc_traits::select_on_container_copy_construction(
12451192 __c.__node_alloc())) {
1246 _VSTD::__debug_db_insert_c(this);
12471193 for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i)
12481194 push_back(*__i);
12491195}
......@@ -1252,7 +1198,6 @@ template <class _Tp, class _Alloc>
12521198list<_Tp, _Alloc>::list(const list& __c, const __type_identity_t<allocator_type>& __a)
12531199 : base(__a)
12541200{
1255 _VSTD::__debug_db_insert_c(this);
12561201 for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i)
12571202 push_back(*__i);
12581203}
......@@ -1263,7 +1208,6 @@ template <class _Tp, class _Alloc>
12631208list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& __a)
12641209 : base(__a)
12651210{
1266 _VSTD::__debug_db_insert_c(this);
12671211 for (typename initializer_list<value_type>::const_iterator __i = __il.begin(),
12681212 __e = __il.end(); __i != __e; ++__i)
12691213 push_back(*__i);
......@@ -1272,7 +1216,6 @@ list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type&
12721216template <class _Tp, class _Alloc>
12731217list<_Tp, _Alloc>::list(initializer_list<value_type> __il)
12741218{
1275 _VSTD::__debug_db_insert_c(this);
12761219 for (typename initializer_list<value_type>::const_iterator __i = __il.begin(),
12771220 __e = __il.end(); __i != __e; ++__i)
12781221 push_back(*__i);
......@@ -1282,7 +1225,6 @@ template <class _Tp, class _Alloc>
12821225inline list<_Tp, _Alloc>::list(list&& __c)
12831226 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
12841227 : base(_VSTD::move(__c.__node_alloc())) {
1285 _VSTD::__debug_db_insert_c(this);
12861228 splice(end(), __c);
12871229}
12881230
......@@ -1291,7 +1233,6 @@ inline
12911233list<_Tp, _Alloc>::list(list&& __c, const __type_identity_t<allocator_type>& __a)
12921234 : base(__a)
12931235{
1294 _VSTD::__debug_db_insert_c(this);
12951236 if (__a == __c.get_allocator())
12961237 splice(end(), __c);
12971238 else
......@@ -1356,17 +1297,23 @@ template <class _Tp, class _Alloc>
13561297template <class _InpIter>
13571298void
13581299list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l,
1359 __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*)
1300 __enable_if_t<__has_input_iterator_category<_InpIter>::value>*)
13601301{
1302 __assign_with_sentinel(__f, __l);
1303}
1304
1305template <class _Tp, class _Alloc>
1306template <class _Iterator, class _Sentinel>
1307_LIBCPP_HIDE_FROM_ABI
1308void list<_Tp, _Alloc>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) {
13611309 iterator __i = begin();
13621310 iterator __e = end();
13631311 for (; __f != __l && __i != __e; ++__f, (void) ++__i)
13641312 *__i = *__f;
13651313 if (__i == __e)
1366 insert(__e, __f, __l);
1314 __insert_with_sentinel(__e, std::move(__f), std::move(__l));
13671315 else
13681316 erase(__i, __e);
1369 std::__debug_db_invalidate_all(this);
13701317}
13711318
13721319template <class _Tp, class _Alloc>
......@@ -1381,7 +1328,6 @@ list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x)
13811328 insert(__e, __n, __x);
13821329 else
13831330 erase(__i, __e);
1384 std::__debug_db_invalidate_all(this);
13851331}
13861332
13871333template <class _Tp, class _Alloc>
......@@ -1396,23 +1342,19 @@ template <class _Tp, class _Alloc>
13961342typename list<_Tp, _Alloc>::iterator
13971343list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x)
13981344{
1399 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1400 "list::insert(iterator, x) called with an iterator not referring to this list");
14011345 __node_allocator& __na = base::__node_alloc();
14021346 __hold_pointer __hold = __allocate_node(__na);
14031347 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
14041348 __link_nodes(__p.__ptr_, __hold->__as_link(), __hold->__as_link());
14051349 ++base::__sz();
1406 return iterator(__hold.release()->__as_link(), this);
1350 return iterator(__hold.release()->__as_link());
14071351}
14081352
14091353template <class _Tp, class _Alloc>
14101354typename list<_Tp, _Alloc>::iterator
14111355list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x)
14121356{
1413 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1414 "list::insert(iterator, n, x) called with an iterator not referring to this list");
1415 iterator __r(__p.__ptr_, this);
1357 iterator __r(__p.__ptr_);
14161358 if (__n > 0)
14171359 {
14181360 size_type __ds = 0;
......@@ -1420,13 +1362,13 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
14201362 __hold_pointer __hold = __allocate_node(__na);
14211363 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
14221364 ++__ds;
1423 __r = iterator(__hold->__as_link(), this);
1365 __r = iterator(__hold->__as_link());
14241366 __hold.release();
14251367 iterator __e = __r;
1426#ifndef _LIBCPP_NO_EXCEPTIONS
1368#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
14271369 try
14281370 {
1429#endif // _LIBCPP_NO_EXCEPTIONS
1371#endif // _LIBCPP_HAS_NO_EXCEPTIONS
14301372 for (--__n; __n != 0; --__n, (void) ++__e, ++__ds)
14311373 {
14321374 __hold.reset(__node_alloc_traits::allocate(__na, 1));
......@@ -1435,7 +1377,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
14351377 __hold->__prev_ = __e.__ptr_;
14361378 __hold.release();
14371379 }
1438#ifndef _LIBCPP_NO_EXCEPTIONS
1380#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
14391381 }
14401382 catch (...)
14411383 {
......@@ -1446,11 +1388,11 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
14461388 __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
14471389 if (__prev == 0)
14481390 break;
1449 __e = iterator(__prev, this);
1391 __e = iterator(__prev);
14501392 }
14511393 throw;
14521394 }
1453#endif // _LIBCPP_NO_EXCEPTIONS
1395#endif // _LIBCPP_HAS_NO_EXCEPTIONS
14541396 __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);
14551397 base::__sz() += __ds;
14561398 }
......@@ -1461,11 +1403,17 @@ template <class _Tp, class _Alloc>
14611403template <class _InpIter>
14621404typename list<_Tp, _Alloc>::iterator
14631405list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
1464 __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*)
1406 __enable_if_t<__has_input_iterator_category<_InpIter>::value>*)
14651407{
1466 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1467 "list::insert(iterator, range) called with an iterator not referring to this list");
1468 iterator __r(__p.__ptr_, this);
1408 return __insert_with_sentinel(__p, __f, __l);
1409}
1410
1411template <class _Tp, class _Alloc>
1412template <class _Iterator, class _Sentinel>
1413_LIBCPP_HIDE_FROM_ABI
1414typename list<_Tp, _Alloc>::iterator
1415list<_Tp, _Alloc>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) {
1416 iterator __r(__p.__ptr_);
14691417 if (__f != __l)
14701418 {
14711419 size_type __ds = 0;
......@@ -1473,13 +1421,13 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
14731421 __hold_pointer __hold = __allocate_node(__na);
14741422 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f);
14751423 ++__ds;
1476 __r = iterator(__hold.get()->__as_link(), this);
1424 __r = iterator(__hold.get()->__as_link());
14771425 __hold.release();
14781426 iterator __e = __r;
1479#ifndef _LIBCPP_NO_EXCEPTIONS
1427#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
14801428 try
14811429 {
1482#endif // _LIBCPP_NO_EXCEPTIONS
1430#endif // _LIBCPP_HAS_NO_EXCEPTIONS
14831431 for (++__f; __f != __l; ++__f, (void) ++__e, ++__ds)
14841432 {
14851433 __hold.reset(__node_alloc_traits::allocate(__na, 1));
......@@ -1488,7 +1436,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
14881436 __hold->__prev_ = __e.__ptr_;
14891437 __hold.release();
14901438 }
1491#ifndef _LIBCPP_NO_EXCEPTIONS
1439#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
14921440 }
14931441 catch (...)
14941442 {
......@@ -1499,11 +1447,11 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
14991447 __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
15001448 if (__prev == 0)
15011449 break;
1502 __e = iterator(__prev, this);
1450 __e = iterator(__prev);
15031451 }
15041452 throw;
15051453 }
1506#endif // _LIBCPP_NO_EXCEPTIONS
1454#endif // _LIBCPP_HAS_NO_EXCEPTIONS
15071455 __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);
15081456 base::__sz() += __ds;
15091457 }
......@@ -1563,7 +1511,7 @@ list<_Tp, _Alloc>::push_back(value_type&& __x)
15631511
15641512template <class _Tp, class _Alloc>
15651513template <class... _Args>
1566#if _LIBCPP_STD_VER > 14
1514#if _LIBCPP_STD_VER >= 17
15671515typename list<_Tp, _Alloc>::reference
15681516#else
15691517void
......@@ -1575,7 +1523,7 @@ list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
15751523 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
15761524 __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link());
15771525 ++base::__sz();
1578#if _LIBCPP_STD_VER > 14
1526#if _LIBCPP_STD_VER >= 17
15791527 return __hold.release()->__value_;
15801528#else
15811529 __hold.release();
......@@ -1584,7 +1532,7 @@ list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
15841532
15851533template <class _Tp, class _Alloc>
15861534template <class... _Args>
1587#if _LIBCPP_STD_VER > 14
1535#if _LIBCPP_STD_VER >= 17
15881536typename list<_Tp, _Alloc>::reference
15891537#else
15901538void
......@@ -1597,7 +1545,7 @@ list<_Tp, _Alloc>::emplace_back(_Args&&... __args)
15971545 __link_pointer __nl = __hold->__as_link();
15981546 __link_nodes_at_back(__nl, __nl);
15991547 ++base::__sz();
1600#if _LIBCPP_STD_VER > 14
1548#if _LIBCPP_STD_VER >= 17
16011549 return __hold.release()->__value_;
16021550#else
16031551 __hold.release();
......@@ -1609,8 +1557,6 @@ template <class... _Args>
16091557typename list<_Tp, _Alloc>::iterator
16101558list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args)
16111559{
1612 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1613 "list::emplace(iterator, args...) called with an iterator not referring to this list");
16141560 __node_allocator& __na = base::__node_alloc();
16151561 __hold_pointer __hold = __allocate_node(__na);
16161562 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
......@@ -1618,15 +1564,13 @@ list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args)
16181564 __link_nodes(__p.__ptr_, __nl, __nl);
16191565 ++base::__sz();
16201566 __hold.release();
1621 return iterator(__nl, this);
1567 return iterator(__nl);
16221568}
16231569
16241570template <class _Tp, class _Alloc>
16251571typename list<_Tp, _Alloc>::iterator
16261572list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x)
16271573{
1628 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1629 "list::insert(iterator, x) called with an iterator not referring to this list");
16301574 __node_allocator& __na = base::__node_alloc();
16311575 __hold_pointer __hold = __allocate_node(__na);
16321576 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
......@@ -1634,7 +1578,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x)
16341578 __link_nodes(__p.__ptr_, __nl, __nl);
16351579 ++base::__sz();
16361580 __hold.release();
1637 return iterator(__nl, this);
1581 return iterator(__nl);
16381582}
16391583
16401584#endif // _LIBCPP_CXX03_LANG
......@@ -1643,26 +1587,11 @@ template <class _Tp, class _Alloc>
16431587void
16441588list<_Tp, _Alloc>::pop_front()
16451589{
1646 _LIBCPP_ASSERT(!empty(), "list::pop_front() called with empty list");
1590 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::pop_front() called with empty list");
16471591 __node_allocator& __na = base::__node_alloc();
16481592 __link_pointer __n = base::__end_.__next_;
16491593 base::__unlink_nodes(__n, __n);
16501594 --base::__sz();
1651#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1652 __c_node* __c = __get_db()->__find_c_and_lock(this);
1653 for (__i_node** __p = __c->end_; __p != __c->beg_; )
1654 {
1655 --__p;
1656 iterator* __i = static_cast<iterator*>((*__p)->__i_);
1657 if (__i->__ptr_ == __n)
1658 {
1659 (*__p)->__c_ = nullptr;
1660 if (--__c->end_ != __p)
1661 _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
1662 }
1663 }
1664 __get_db()->unlock();
1665#endif
16661595 __node_pointer __np = __n->__as_node();
16671596 __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
16681597 __node_alloc_traits::deallocate(__na, __np, 1);
......@@ -1672,26 +1601,11 @@ template <class _Tp, class _Alloc>
16721601void
16731602list<_Tp, _Alloc>::pop_back()
16741603{
1675 _LIBCPP_ASSERT(!empty(), "list::pop_back() called on an empty list");
1604 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::pop_back() called on an empty list");
16761605 __node_allocator& __na = base::__node_alloc();
16771606 __link_pointer __n = base::__end_.__prev_;
16781607 base::__unlink_nodes(__n, __n);
16791608 --base::__sz();
1680#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1681 __c_node* __c = __get_db()->__find_c_and_lock(this);
1682 for (__i_node** __p = __c->end_; __p != __c->beg_; )
1683 {
1684 --__p;
1685 iterator* __i = static_cast<iterator*>((*__p)->__i_);
1686 if (__i->__ptr_ == __n)
1687 {
1688 (*__p)->__c_ = nullptr;
1689 if (--__c->end_ != __p)
1690 _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
1691 }
1692 }
1693 __get_db()->unlock();
1694#endif
16951609 __node_pointer __np = __n->__as_node();
16961610 __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
16971611 __node_alloc_traits::deallocate(__na, __np, 1);
......@@ -1701,44 +1615,23 @@ template <class _Tp, class _Alloc>
17011615typename list<_Tp, _Alloc>::iterator
17021616list<_Tp, _Alloc>::erase(const_iterator __p)
17031617{
1704 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1705 "list::erase(iterator) called with an iterator not referring to this list");
1706 _LIBCPP_ASSERT(__p != end(),
1618 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p != end(),
17071619 "list::erase(iterator) called with a non-dereferenceable iterator");
17081620 __node_allocator& __na = base::__node_alloc();
17091621 __link_pointer __n = __p.__ptr_;
17101622 __link_pointer __r = __n->__next_;
17111623 base::__unlink_nodes(__n, __n);
17121624 --base::__sz();
1713#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1714 __c_node* __c = __get_db()->__find_c_and_lock(this);
1715 for (__i_node** __ip = __c->end_; __ip != __c->beg_; )
1716 {
1717 --__ip;
1718 iterator* __i = static_cast<iterator*>((*__ip)->__i_);
1719 if (__i->__ptr_ == __n)
1720 {
1721 (*__ip)->__c_ = nullptr;
1722 if (--__c->end_ != __ip)
1723 _VSTD::memmove(__ip, __ip+1, (__c->end_ - __ip)*sizeof(__i_node*));
1724 }
1725 }
1726 __get_db()->unlock();
1727#endif
17281625 __node_pointer __np = __n->__as_node();
17291626 __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
17301627 __node_alloc_traits::deallocate(__na, __np, 1);
1731 return iterator(__r, this);
1628 return iterator(__r);
17321629}
17331630
17341631template <class _Tp, class _Alloc>
17351632typename list<_Tp, _Alloc>::iterator
17361633list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l)
17371634{
1738 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == this,
1739 "list::erase(iterator, iterator) called with an iterator not referring to this list");
1740 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == this,
1741 "list::erase(iterator, iterator) called with an iterator not referring to this list");
17421635 if (__f != __l)
17431636 {
17441637 __node_allocator& __na = base::__node_alloc();
......@@ -1748,27 +1641,12 @@ list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l)
17481641 __link_pointer __n = __f.__ptr_;
17491642 ++__f;
17501643 --base::__sz();
1751#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1752 __c_node* __c = __get_db()->__find_c_and_lock(this);
1753 for (__i_node** __p = __c->end_; __p != __c->beg_; )
1754 {
1755 --__p;
1756 iterator* __i = static_cast<iterator*>((*__p)->__i_);
1757 if (__i->__ptr_ == __n)
1758 {
1759 (*__p)->__c_ = nullptr;
1760 if (--__c->end_ != __p)
1761 _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
1762 }
1763 }
1764 __get_db()->unlock();
1765#endif
17661644 __node_pointer __np = __n->__as_node();
17671645 __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
17681646 __node_alloc_traits::deallocate(__na, __np, 1);
17691647 }
17701648 }
1771 return iterator(__l.__ptr_, this);
1649 return iterator(__l.__ptr_);
17721650}
17731651
17741652template <class _Tp, class _Alloc>
......@@ -1785,12 +1663,12 @@ list<_Tp, _Alloc>::resize(size_type __n)
17851663 __hold_pointer __hold = __allocate_node(__na);
17861664 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_));
17871665 ++__ds;
1788 iterator __r = iterator(__hold.release()->__as_link(), this);
1666 iterator __r = iterator(__hold.release()->__as_link());
17891667 iterator __e = __r;
1790#ifndef _LIBCPP_NO_EXCEPTIONS
1668#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
17911669 try
17921670 {
1793#endif // _LIBCPP_NO_EXCEPTIONS
1671#endif // _LIBCPP_HAS_NO_EXCEPTIONS
17941672 for (--__n; __n != 0; --__n, (void) ++__e, ++__ds)
17951673 {
17961674 __hold.reset(__node_alloc_traits::allocate(__na, 1));
......@@ -1799,7 +1677,7 @@ list<_Tp, _Alloc>::resize(size_type __n)
17991677 __hold->__prev_ = __e.__ptr_;
18001678 __hold.release();
18011679 }
1802#ifndef _LIBCPP_NO_EXCEPTIONS
1680#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
18031681 }
18041682 catch (...)
18051683 {
......@@ -1810,11 +1688,11 @@ list<_Tp, _Alloc>::resize(size_type __n)
18101688 __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
18111689 if (__prev == 0)
18121690 break;
1813 __e = iterator(__prev, this);
1691 __e = iterator(__prev);
18141692 }
18151693 throw;
18161694 }
1817#endif // _LIBCPP_NO_EXCEPTIONS
1695#endif // _LIBCPP_HAS_NO_EXCEPTIONS
18181696 __link_nodes_at_back(__r.__ptr_, __e.__ptr_);
18191697 base::__sz() += __ds;
18201698 }
......@@ -1835,12 +1713,12 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
18351713 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
18361714 ++__ds;
18371715 __link_pointer __nl = __hold.release()->__as_link();
1838 iterator __r = iterator(__nl, this);
1716 iterator __r = iterator(__nl);
18391717 iterator __e = __r;
1840#ifndef _LIBCPP_NO_EXCEPTIONS
1718#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
18411719 try
18421720 {
1843#endif // _LIBCPP_NO_EXCEPTIONS
1721#endif // _LIBCPP_HAS_NO_EXCEPTIONS
18441722 for (--__n; __n != 0; --__n, (void) ++__e, ++__ds)
18451723 {
18461724 __hold.reset(__node_alloc_traits::allocate(__na, 1));
......@@ -1849,7 +1727,7 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
18491727 __hold->__prev_ = __e.__ptr_;
18501728 __hold.release();
18511729 }
1852#ifndef _LIBCPP_NO_EXCEPTIONS
1730#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
18531731 }
18541732 catch (...)
18551733 {
......@@ -1860,11 +1738,11 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
18601738 __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
18611739 if (__prev == 0)
18621740 break;
1863 __e = iterator(__prev, this);
1741 __e = iterator(__prev);
18641742 }
18651743 throw;
18661744 }
1867#endif // _LIBCPP_NO_EXCEPTIONS
1745#endif // _LIBCPP_HAS_NO_EXCEPTIONS
18681746 __link_nodes(base::__end_as_link(), __r.__ptr_, __e.__ptr_);
18691747 base::__sz() += __ds;
18701748 }
......@@ -1874,10 +1752,8 @@ template <class _Tp, class _Alloc>
18741752void
18751753list<_Tp, _Alloc>::splice(const_iterator __p, list& __c)
18761754{
1877 _LIBCPP_ASSERT(this != _VSTD::addressof(__c),
1878 "list::splice(iterator, list) called with this == &list");
1879 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1880 "list::splice(iterator, list) called with an iterator not referring to this list");
1755 _LIBCPP_ASSERT_VALID_INPUT_RANGE(this != _VSTD::addressof(__c),
1756 "list::splice(iterator, list) called with this == &list");
18811757 if (!__c.empty())
18821758 {
18831759 __link_pointer __f = __c.__end_.__next_;
......@@ -1886,26 +1762,6 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c)
18861762 __link_nodes(__p.__ptr_, __f, __l);
18871763 base::__sz() += __c.__sz();
18881764 __c.__sz() = 0;
1889#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1890 if (_VSTD::addressof(__c) != this) {
1891 __libcpp_db* __db = __get_db();
1892 __c_node* __cn1 = __db->__find_c_and_lock(this);
1893 __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c));
1894 for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;)
1895 {
1896 --__ip;
1897 iterator* __i = static_cast<iterator*>((*__ip)->__i_);
1898 if (__i->__ptr_ != __c.__end_as_link())
1899 {
1900 __cn1->__add(*__ip);
1901 (*__ip)->__c_ = __cn1;
1902 if (--__cn2->end_ != __ip)
1903 _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*));
1904 }
1905 }
1906 __db->unlock();
1907 }
1908#endif
19091765 }
19101766}
19111767
......@@ -1913,13 +1769,6 @@ template <class _Tp, class _Alloc>
19131769void
19141770list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i)
19151771{
1916 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1917 "list::splice(iterator, list, iterator) called with the first iterator not referring to this list");
1918 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__i)) == _VSTD::addressof(__c),
1919 "list::splice(iterator, list, iterator) called with the second iterator not referring to the list argument");
1920 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(_VSTD::addressof(__i)),
1921 "list::splice(iterator, list, iterator) called with the second iterator not dereferenceable");
1922
19231772 if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_)
19241773 {
19251774 __link_pointer __f = __i.__ptr_;
......@@ -1927,26 +1776,6 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i)
19271776 __link_nodes(__p.__ptr_, __f, __f);
19281777 --__c.__sz();
19291778 ++base::__sz();
1930#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1931 if (_VSTD::addressof(__c) != this) {
1932 __libcpp_db* __db = __get_db();
1933 __c_node* __cn1 = __db->__find_c_and_lock(this);
1934 __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c));
1935 for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;)
1936 {
1937 --__ip;
1938 iterator* __j = static_cast<iterator*>((*__ip)->__i_);
1939 if (__j->__ptr_ == __f)
1940 {
1941 __cn1->__add(*__ip);
1942 (*__ip)->__c_ = __cn1;
1943 if (--__cn2->end_ != __ip)
1944 _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*));
1945 }
1946 }
1947 __db->unlock();
1948 }
1949#endif
19501779 }
19511780}
19521781
......@@ -1965,16 +1794,6 @@ template <class _Tp, class _Alloc>
19651794void
19661795list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l)
19671796{
1968 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1969 "list::splice(iterator, list, iterator, iterator) called with first iterator not referring to this list");
1970 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == _VSTD::addressof(__c),
1971 "list::splice(iterator, list, iterator, iterator) called with second iterator not referring to the list argument");
1972 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == _VSTD::addressof(__c),
1973 "list::splice(iterator, list, iterator, iterator) called with third iterator not referring to the list argument");
1974 _LIBCPP_DEBUG_ASSERT(this != std::addressof(__c) || !std::__iterator_in_range(__f, __l, __p),
1975 "list::splice(iterator, list, iterator, iterator)"
1976 " called with the first iterator within the range of the second and third iterators");
1977
19781797 if (__f != __l)
19791798 {
19801799 __link_pointer __first = __f.__ptr_;
......@@ -1988,30 +1807,6 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, con
19881807 }
19891808 base::__unlink_nodes(__first, __last);
19901809 __link_nodes(__p.__ptr_, __first, __last);
1991#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1992 if (_VSTD::addressof(__c) != this) {
1993 __libcpp_db* __db = __get_db();
1994 __c_node* __cn1 = __db->__find_c_and_lock(this);
1995 __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c));
1996 for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;)
1997 {
1998 --__ip;
1999 iterator* __j = static_cast<iterator*>((*__ip)->__i_);
2000 for (__link_pointer __k = __f.__ptr_;
2001 __k != __l.__ptr_; __k = __k->__next_)
2002 {
2003 if (__j->__ptr_ == __k)
2004 {
2005 __cn1->__add(*__ip);
2006 (*__ip)->__c_ = __cn1;
2007 if (--__cn2->end_ != __ip)
2008 _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*));
2009 }
2010 }
2011 }
2012 __db->unlock();
2013 }
2014#endif
20151810 }
20161811}
20171812
......@@ -2089,7 +1884,7 @@ inline
20891884void
20901885list<_Tp, _Alloc>::merge(list& __c)
20911886{
2092 merge(__c, __less<value_type>());
1887 merge(__c, __less<>());
20931888}
20941889
20951890template <class _Tp, class _Alloc>
......@@ -2125,24 +1920,6 @@ list<_Tp, _Alloc>::merge(list& __c, _Comp __comp)
21251920 ++__f1;
21261921 }
21271922 splice(__e1, __c);
2128#ifdef _LIBCPP_ENABLE_DEBUG_MODE
2129 __libcpp_db* __db = __get_db();
2130 __c_node* __cn1 = __db->__find_c_and_lock(this);
2131 __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c));
2132 for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)
2133 {
2134 --__p;
2135 iterator* __i = static_cast<iterator*>((*__p)->__i_);
2136 if (__i->__ptr_ != __c.__end_as_link())
2137 {
2138 __cn1->__add(*__p);
2139 (*__p)->__c_ = __cn1;
2140 if (--__cn2->end_ != __p)
2141 _VSTD::memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));
2142 }
2143 }
2144 __db->unlock();
2145#endif
21461923 }
21471924}
21481925
......@@ -2151,7 +1928,7 @@ inline
21511928void
21521929list<_Tp, _Alloc>::sort()
21531930{
2154 sort(__less<value_type>());
1931 sort(__less<>());
21551932}
21561933
21571934template <class _Tp, class _Alloc>
......@@ -2249,38 +2026,6 @@ list<_Tp, _Alloc>::__invariants() const
22492026 return size() == _VSTD::distance(begin(), end());
22502027}
22512028
2252#ifdef _LIBCPP_ENABLE_DEBUG_MODE
2253
2254template <class _Tp, class _Alloc>
2255bool
2256list<_Tp, _Alloc>::__dereferenceable(const const_iterator* __i) const
2257{
2258 return __i->__ptr_ != this->__end_as_link();
2259}
2260
2261template <class _Tp, class _Alloc>
2262bool
2263list<_Tp, _Alloc>::__decrementable(const const_iterator* __i) const
2264{
2265 return !empty() && __i->__ptr_ != base::__end_.__next_;
2266}
2267
2268template <class _Tp, class _Alloc>
2269bool
2270list<_Tp, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const
2271{
2272 return false;
2273}
2274
2275template <class _Tp, class _Alloc>
2276bool
2277list<_Tp, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const
2278{
2279 return false;
2280}
2281
2282#endif // _LIBCPP_ENABLE_DEBUG_MODE
2283
22842029template <class _Tp, class _Alloc>
22852030inline _LIBCPP_INLINE_VISIBILITY
22862031bool
......@@ -2289,6 +2034,8 @@ operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
22892034 return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
22902035}
22912036
2037#if _LIBCPP_STD_VER <= 17
2038
22922039template <class _Tp, class _Alloc>
22932040inline _LIBCPP_INLINE_VISIBILITY
22942041bool
......@@ -2329,6 +2076,17 @@ operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
23292076 return !(__y < __x);
23302077}
23312078
2079#else // _LIBCPP_STD_VER <= 17
2080
2081template <class _Tp, class _Allocator>
2082_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp>
2083operator<=>(const list<_Tp, _Allocator>& __x, const list<_Tp, _Allocator>& __y) {
2084 return std::lexicographical_compare_three_way(
2085 __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>);
2086}
2087
2088#endif // _LIBCPP_STD_VER <= 17
2089
23322090template <class _Tp, class _Alloc>
23332091inline _LIBCPP_INLINE_VISIBILITY
23342092void
......@@ -2338,7 +2096,7 @@ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
23382096 __x.swap(__y);
23392097}
23402098
2341#if _LIBCPP_STD_VER > 17
2099#if _LIBCPP_STD_VER >= 20
23422100template <class _Tp, class _Allocator, class _Predicate>
23432101inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type
23442102erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) {
......@@ -2358,15 +2116,15 @@ template <>
23582116inline constexpr bool __format::__enable_insertable<std::list<wchar_t>> = true;
23592117#endif
23602118
2361#endif // _LIBCPP_STD_VER > 17
2119#endif // _LIBCPP_STD_VER >= 20
23622120
23632121_LIBCPP_END_NAMESPACE_STD
23642122
2365#if _LIBCPP_STD_VER > 14
2123#if _LIBCPP_STD_VER >= 17
23662124_LIBCPP_BEGIN_NAMESPACE_STD
23672125namespace pmr {
23682126template <class _ValueT>
2369using list = std::list<_ValueT, polymorphic_allocator<_ValueT>>;
2127using list _LIBCPP_AVAILABILITY_PMR = std::list<_ValueT, polymorphic_allocator<_ValueT>>;
23702128} // namespace pmr
23712129_LIBCPP_END_NAMESPACE_STD
23722130#endif
......@@ -2377,9 +2135,11 @@ _LIBCPP_POP_MACROS
23772135# include <algorithm>
23782136# include <atomic>
23792137# include <concepts>
2138# include <cstdlib>
23802139# include <functional>
23812140# include <iosfwd>
23822141# include <iterator>
2142# include <type_traits>
23832143# include <typeinfo>
23842144#endif
23852145
lib/libcxx/include/locale+86-91
......@@ -53,7 +53,7 @@ public:
5353 // locale operations:
5454 basic_string<char> name() const;
5555 bool operator==(const locale& other) const;
56 bool operator!=(const locale& other) const;
56 bool operator!=(const locale& other) const; // removed C++20
5757 template <class charT, class Traits, class Allocator>
5858 bool operator()(const basic_string<charT,Traits,Allocator>& s1,
5959 const basic_string<charT,Traits,Allocator>& s2) const;
......@@ -195,13 +195,14 @@ template <class charT> class messages_byname;
195195#include <__algorithm/unwrap_iter.h>
196196#include <__assert> // all public C++ headers provide the assertion handler
197197#include <__config>
198#include <__debug>
199198#include <__iterator/access.h>
200199#include <__iterator/back_insert_iterator.h>
201200#include <__iterator/istreambuf_iterator.h>
202201#include <__iterator/ostreambuf_iterator.h>
203202#include <__locale>
204203#include <__memory/unique_ptr.h>
204#include <__type_traits/make_unsigned.h>
205#include <cerrno>
205206#include <cstdio>
206207#include <cstdlib>
207208#include <ctime>
......@@ -223,9 +224,9 @@ template <class charT> class messages_byname;
223224#endif
224225
225226#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
226#include <__bsd_locale_defaults.h>
227# include <__locale_dir/locale_base_api/bsd_locale_defaults.h>
227228#else
228#include <__bsd_locale_fallbacks.h>
229# include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
229230#endif
230231
231232#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -245,7 +246,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
245246#else
246247# define _LIBCPP_GET_C_LOCALE __cloc()
247248 // Get the C locale object
248 _LIBCPP_FUNC_VIS locale_t __cloc();
249 _LIBCPP_EXPORTED_FROM_ABI locale_t __cloc();
249250#define __cloc_defined
250251#endif
251252
......@@ -377,7 +378,7 @@ __scan_keyword(_InputIterator& __b, _InputIterator __e,
377378 return __kb;
378379}
379380
380struct _LIBCPP_TYPE_VIS __num_get_base
381struct _LIBCPP_EXPORTED_FROM_ABI __num_get_base
381382{
382383 static const int __num_get_buf_sz = 40;
383384
......@@ -385,8 +386,7 @@ struct _LIBCPP_TYPE_VIS __num_get_base
385386 static const char __src[33];
386387};
387388
388_LIBCPP_FUNC_VIS
389void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
389_LIBCPP_EXPORTED_FROM_ABI void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
390390 ios_base::iostate& __err);
391391
392392template <class _CharT>
......@@ -1126,7 +1126,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>;
11261126extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<wchar_t>;
11271127#endif
11281128
1129struct _LIBCPP_TYPE_VIS __num_put_base
1129struct _LIBCPP_EXPORTED_FROM_ABI __num_put_base
11301130{
11311131protected:
11321132 static void __format_int(char* __fmt, const char* __len, bool __signd,
......@@ -1464,12 +1464,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
14641464 return do_put(__s, __iob, __fl, (unsigned long)__v);
14651465 const numpunct<char_type>& __np = std::use_facet<numpunct<char_type> >(__iob.getloc());
14661466 typedef typename numpunct<char_type>::string_type string_type;
1467#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1468 string_type __tmp(__v ? __np.truename() : __np.falsename());
1469 string_type __nm = _VSTD::move(__tmp);
1470#else
14711467 string_type __nm = __v ? __np.truename() : __np.falsename();
1472#endif
14731468 for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
14741469 *__s = *__i;
14751470 return __s;
......@@ -1681,7 +1676,7 @@ __get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
16811676 return __r;
16821677}
16831678
1684class _LIBCPP_TYPE_VIS time_base
1679class _LIBCPP_EXPORTED_FROM_ABI time_base
16851680{
16861681public:
16871682 enum dateorder {no_order, dmy, mdy, ymd, ydm};
......@@ -1705,22 +1700,22 @@ protected:
17051700 ~__time_get_c_storage() {}
17061701};
17071702
1708template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__weeks() const;
1709template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__months() const;
1710template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__am_pm() const;
1711template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__c() const;
1712template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__r() const;
1713template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__x() const;
1714template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__X() const;
1703template <> _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__weeks() const;
1704template <> _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__months() const;
1705template <> _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__am_pm() const;
1706template <> _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__c() const;
1707template <> _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__r() const;
1708template <> _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__x() const;
1709template <> _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__X() const;
17151710
17161711#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1717template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__weeks() const;
1718template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__months() const;
1719template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__am_pm() const;
1720template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__c() const;
1721template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__r() const;
1722template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__x() const;
1723template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__X() const;
1712template <> _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__weeks() const;
1713template <> _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__months() const;
1714template <> _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__am_pm() const;
1715template <> _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__c() const;
1716template <> _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__r() const;
1717template <> _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__x() const;
1718template <> _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__X() const;
17241719#endif
17251720
17261721template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
......@@ -2337,7 +2332,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>;
23372332extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>;
23382333#endif
23392334
2340class _LIBCPP_TYPE_VIS __time_get
2335class _LIBCPP_EXPORTED_FROM_ABI __time_get
23412336{
23422337protected:
23432338 locale_t __loc_;
......@@ -2375,16 +2370,16 @@ private:
23752370};
23762371
23772372#define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \
2378template <> _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
2379template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
2380template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
2381template <> _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
2382template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
2383extern template _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
2384extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
2385extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
2386extern template _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
2387extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
2373template <> _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
2374template <> _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*); \
2375template <> _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \
2376template <> _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
2377template <> _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
2378extern template _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
2379extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*); \
2380extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \
2381extern template _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
2382extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
23882383/**/
23892384
23902385_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char)
......@@ -2432,7 +2427,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>;
24322427extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>;
24332428#endif
24342429
2435class _LIBCPP_TYPE_VIS __time_put
2430class _LIBCPP_EXPORTED_FROM_ABI __time_put
24362431{
24372432 locale_t __loc_;
24382433protected:
......@@ -2572,7 +2567,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>;
25722567
25732568// money_base
25742569
2575class _LIBCPP_TYPE_VIS money_base
2570class _LIBCPP_EXPORTED_FROM_ABI money_base
25762571{
25772572public:
25782573 enum part {none, space, symbol, sign, value};
......@@ -2686,14 +2681,14 @@ private:
26862681 void init(const char*);
26872682};
26882683
2689template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, false>::init(const char*);
2690template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, true>::init(const char*);
2684template<> _LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<char, false>::init(const char*);
2685template<> _LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<char, true>::init(const char*);
26912686extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>;
26922687extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>;
26932688
26942689#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
2695template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, false>::init(const char*);
2696template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, true>::init(const char*);
2690template<> _LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<wchar_t, false>::init(const char*);
2691template<> _LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<wchar_t, true>::init(const char*);
26972692extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>;
26982693extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>;
26992694#endif
......@@ -2810,7 +2805,7 @@ template <class _CharT, class _InputIterator>
28102805locale::id
28112806money_get<_CharT, _InputIterator>::id;
28122807
2813_LIBCPP_FUNC_VIS void __do_nothing(void*);
2808_LIBCPP_EXPORTED_FROM_ABI void __do_nothing(void*);
28142809
28152810template <class _Tp>
28162811_LIBCPP_HIDE_FROM_ABI
......@@ -3457,7 +3452,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>;
34573452
34583453// messages
34593454
3460class _LIBCPP_TYPE_VIS messages_base
3455class _LIBCPP_EXPORTED_FROM_ABI messages_base
34613456{
34623457public:
34633458 typedef ptrdiff_t catalog;
......@@ -3598,15 +3593,15 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>;
35983593#endif
35993594
36003595template<class _Codecvt, class _Elem = wchar_t,
3601 class _Wide_alloc = allocator<_Elem>,
3602 class _Byte_alloc = allocator<char> >
3596 class _WideAlloc = allocator<_Elem>,
3597 class _ByteAlloc = allocator<char> >
36033598class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert
36043599{
36053600public:
3606 typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string;
3607 typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
3608 typedef typename _Codecvt::state_type state_type;
3609 typedef typename wide_string::traits_type::int_type int_type;
3601 typedef basic_string<char, char_traits<char>, _ByteAlloc> byte_string;
3602 typedef basic_string<_Elem, char_traits<_Elem>, _WideAlloc> wide_string;
3603 typedef typename _Codecvt::state_type state_type;
3604 typedef typename wide_string::traits_type::int_type int_type;
36103605
36113606private:
36123607 byte_string __byte_err_string_;
......@@ -3625,19 +3620,19 @@ public:
36253620 explicit wstring_convert(_Codecvt* __pcvt);
36263621#else
36273622 _LIBCPP_INLINE_VISIBILITY
3628 _LIBCPP_EXPLICIT_AFTER_CXX11
3623 _LIBCPP_EXPLICIT_SINCE_CXX14
36293624 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
36303625#endif
36313626
36323627 _LIBCPP_INLINE_VISIBILITY
36333628 wstring_convert(_Codecvt* __pcvt, state_type __state);
3634 _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
3629 _LIBCPP_EXPLICIT_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI wstring_convert(const byte_string& __byte_err,
36353630 const wide_string& __wide_err = wide_string());
36363631#ifndef _LIBCPP_CXX03_LANG
36373632 _LIBCPP_INLINE_VISIBILITY
36383633 wstring_convert(wstring_convert&& __wc);
36393634#endif
3640 ~wstring_convert();
3635 _LIBCPP_HIDE_FROM_ABI ~wstring_convert();
36413636
36423637 _LIBCPP_INLINE_VISIBILITY
36433638 wide_string from_bytes(char __byte)
......@@ -3648,7 +3643,7 @@ public:
36483643 _LIBCPP_INLINE_VISIBILITY
36493644 wide_string from_bytes(const byte_string& __str)
36503645 {return from_bytes(__str.data(), __str.data() + __str.size());}
3651 wide_string from_bytes(const char* __first, const char* __last);
3646 _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const char* __first, const char* __last);
36523647
36533648 _LIBCPP_INLINE_VISIBILITY
36543649 byte_string to_bytes(_Elem __wchar)
......@@ -3659,7 +3654,7 @@ public:
36593654 _LIBCPP_INLINE_VISIBILITY
36603655 byte_string to_bytes(const wide_string& __wstr)
36613656 {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
3662 byte_string to_bytes(const _Elem* __first, const _Elem* __last);
3657 _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const _Elem* __first, const _Elem* __last);
36633658
36643659 _LIBCPP_INLINE_VISIBILITY
36653660 size_t converted() const _NOEXCEPT {return __cvtcount_;}
......@@ -3668,25 +3663,25 @@ public:
36683663};
36693664
36703665_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3671template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3666template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
36723667inline
3673wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3668wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::
36743669 wstring_convert(_Codecvt* __pcvt)
36753670 : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
36763671{
36773672}
36783673_LIBCPP_SUPPRESS_DEPRECATED_POP
36793674
3680template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3675template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
36813676inline
3682wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3677wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::
36833678 wstring_convert(_Codecvt* __pcvt, state_type __state)
36843679 : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
36853680{
36863681}
36873682
3688template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3689wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3683template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
3684wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::
36903685 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
36913686 : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
36923687 __cvtstate_(), __cvtcount_(0)
......@@ -3696,9 +3691,9 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
36963691
36973692#ifndef _LIBCPP_CXX03_LANG
36983693
3699template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3694template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
37003695inline
3701wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3696wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::
37023697 wstring_convert(wstring_convert&& __wc)
37033698 : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
37043699 __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
......@@ -3711,15 +3706,15 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
37113706#endif // _LIBCPP_CXX03_LANG
37123707
37133708_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3714template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3715wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
3709template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
3710wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::~wstring_convert()
37163711{
37173712 delete __cvtptr_;
37183713}
37193714
3720template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3721typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
3722wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3715template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
3716typename wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wide_string
3717wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::
37233718 from_bytes(const char* __frm, const char* __frm_end)
37243719{
37253720_LIBCPP_SUPPRESS_DEPRECATED_POP
......@@ -3779,9 +3774,9 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
37793774 return __wide_err_string_;
37803775}
37813776
3782template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3783typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
3784wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3777template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
3778typename wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::byte_string
3779wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::
37853780 to_bytes(const _Elem* __frm, const _Elem* __frm_end)
37863781{
37873782 __cvtcount_ = 0;
......@@ -3902,18 +3897,18 @@ private:
39023897
39033898public:
39043899#ifndef _LIBCPP_CXX03_LANG
3905 wbuffer_convert() : wbuffer_convert(nullptr) {}
3906 explicit wbuffer_convert(streambuf* __bytebuf,
3900 _LIBCPP_HIDE_FROM_ABI wbuffer_convert() : wbuffer_convert(nullptr) {}
3901 explicit _LIBCPP_HIDE_FROM_ABI wbuffer_convert(streambuf* __bytebuf,
39073902 _Codecvt* __pcvt = new _Codecvt,
39083903 state_type __state = state_type());
39093904#else
3910 _LIBCPP_EXPLICIT_AFTER_CXX11
3905 _LIBCPP_EXPLICIT_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
39113906 wbuffer_convert(streambuf* __bytebuf = nullptr,
39123907 _Codecvt* __pcvt = new _Codecvt,
39133908 state_type __state = state_type());
39143909#endif
39153910
3916 ~wbuffer_convert();
3911 _LIBCPP_HIDE_FROM_ABI ~wbuffer_convert();
39173912
39183913 _LIBCPP_INLINE_VISIBILITY
39193914 streambuf* rdbuf() const {return __bufptr_;}
......@@ -3929,21 +3924,21 @@ public:
39293924 state_type state() const {return __st_;}
39303925
39313926protected:
3932 virtual int_type underflow();
3933 virtual int_type pbackfail(int_type __c = traits_type::eof());
3934 virtual int_type overflow (int_type __c = traits_type::eof());
3935 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
3927 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type underflow();
3928 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type pbackfail(int_type __c = traits_type::eof());
3929 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type overflow (int_type __c = traits_type::eof());
3930 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
39363931 streamsize __n);
3937 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
3932 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
39383933 ios_base::openmode __wch = ios_base::in | ios_base::out);
3939 virtual pos_type seekpos(pos_type __sp,
3934 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual pos_type seekpos(pos_type __sp,
39403935 ios_base::openmode __wch = ios_base::in | ios_base::out);
3941 virtual int sync();
3936 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int sync();
39423937
39433938private:
3944 bool __read_mode();
3945 void __write_mode();
3946 wbuffer_convert* __close();
3939 _LIBCPP_HIDE_FROM_ABI_VIRTUAL bool __read_mode();
3940 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __write_mode();
3941 _LIBCPP_HIDE_FROM_ABI_VIRTUAL wbuffer_convert* __close();
39473942};
39483943
39493944_LIBCPP_SUPPRESS_DEPRECATED_PUSH
......@@ -4009,8 +4004,8 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
40094004 else
40104005 {
40114006 if (__extbufend_ != __extbufnext_) {
4012 _LIBCPP_ASSERT(__extbufnext_ != nullptr, "underflow moving from nullptr");
4013 _LIBCPP_ASSERT(__extbuf_ != nullptr, "underflow moving into nullptr");
4007 _LIBCPP_ASSERT_UNCATEGORIZED(__extbufnext_ != nullptr, "underflow moving from nullptr");
4008 _LIBCPP_ASSERT_UNCATEGORIZED(__extbuf_ != nullptr, "underflow moving into nullptr");
40144009 _VSTD::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
40154010 }
40164011 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
lib/libcxx/include/map+250-76
......@@ -70,6 +70,8 @@ public:
7070 template <class InputIterator>
7171 map(InputIterator first, InputIterator last,
7272 const key_compare& comp, const allocator_type& a);
73 template<container-compatible-range<value_type> R>
74 map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
7375 map(const map& m);
7476 map(map&& m)
7577 noexcept(
......@@ -83,6 +85,9 @@ public:
8385 template <class InputIterator>
8486 map(InputIterator first, InputIterator last, const allocator_type& a)
8587 : map(first, last, Compare(), a) {} // C++14
88 template<container-compatible-range<value_type> R>
89 map(from_range_t, R&& rg, const Allocator& a))
90 : map(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
8691 map(initializer_list<value_type> il, const allocator_type& a)
8792 : map(il, Compare(), a) {} // C++14
8893 ~map();
......@@ -138,6 +143,8 @@ public:
138143 iterator insert(const_iterator position, P&& p);
139144 template <class InputIterator>
140145 void insert(InputIterator first, InputIterator last);
146 template<container-compatible-range<value_type> R>
147 void insert_range(R&& rg); // C++23
141148 void insert(initializer_list<value_type> il);
142149
143150 node_type extract(const_iterator position); // C++17
......@@ -229,6 +236,11 @@ template <class InputIterator,
229236map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
230237 -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17
231238
239template<ranges::input_range R, class Compare = less<range-key-type<R>,
240 class Allocator = allocator<range-to-alloc-type<R>>>
241 map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
242 -> map<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23
243
232244template<class Key, class T, class Compare = less<Key>,
233245 class Allocator = allocator<pair<const Key, T>>>
234246map(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
......@@ -239,6 +251,10 @@ map(InputIterator, InputIterator, Allocator)
239251 -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, less<iter_key_t<InputIterator>>,
240252 Allocator>; // C++17
241253
254template<ranges::input_range R, class Allocator>
255 map(from_range_t, R&&, Allocator)
256 -> map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23
257
242258template<class Key, class T, class Allocator>
243259map(initializer_list<pair<const Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>; // C++17
244260
......@@ -250,27 +266,32 @@ operator==(const map<Key, T, Compare, Allocator>& x,
250266template <class Key, class T, class Compare, class Allocator>
251267bool
252268operator< (const map<Key, T, Compare, Allocator>& x,
253 const map<Key, T, Compare, Allocator>& y);
269 const map<Key, T, Compare, Allocator>& y); // removed in C++20
254270
255271template <class Key, class T, class Compare, class Allocator>
256272bool
257273operator!=(const map<Key, T, Compare, Allocator>& x,
258 const map<Key, T, Compare, Allocator>& y);
274 const map<Key, T, Compare, Allocator>& y); // removed in C++20
259275
260276template <class Key, class T, class Compare, class Allocator>
261277bool
262278operator> (const map<Key, T, Compare, Allocator>& x,
263 const map<Key, T, Compare, Allocator>& y);
279 const map<Key, T, Compare, Allocator>& y); // removed in C++20
264280
265281template <class Key, class T, class Compare, class Allocator>
266282bool
267283operator>=(const map<Key, T, Compare, Allocator>& x,
268 const map<Key, T, Compare, Allocator>& y);
284 const map<Key, T, Compare, Allocator>& y); // removed in C++20
269285
270286template <class Key, class T, class Compare, class Allocator>
271287bool
272288operator<=(const map<Key, T, Compare, Allocator>& x,
273 const map<Key, T, Compare, Allocator>& y);
289 const map<Key, T, Compare, Allocator>& y); // removed in C++20
290
291template<class Key, class T, class Compare, class Allocator>
292 synth-three-way-result<pair<const Key, T>>
293 operator<=>(const map<Key, T, Compare, Allocator>& x,
294 const map<Key, T, Compare, Allocator>& y); // since C++20
274295
275296// specialized algorithms:
276297template <class Key, class T, class Compare, class Allocator>
......@@ -333,6 +354,9 @@ public:
333354 template <class InputIterator>
334355 multimap(InputIterator first, InputIterator last, const key_compare& comp,
335356 const allocator_type& a);
357 template<container-compatible-range<value_type> R>
358 multimap(from_range_t, R&& rg,
359 const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
336360 multimap(const multimap& m);
337361 multimap(multimap&& m)
338362 noexcept(
......@@ -347,6 +371,9 @@ public:
347371 template <class InputIterator>
348372 multimap(InputIterator first, InputIterator last, const allocator_type& a)
349373 : multimap(first, last, Compare(), a) {} // C++14
374 template<container-compatible-range<value_type> R>
375 multimap(from_range_t, R&& rg, const Allocator& a))
376 : multimap(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
350377 multimap(initializer_list<value_type> il, const allocator_type& a)
351378 : multimap(il, Compare(), a) {} // C++14
352379 ~multimap();
......@@ -395,6 +422,8 @@ public:
395422 iterator insert(const_iterator position, P&& p);
396423 template <class InputIterator>
397424 void insert(InputIterator first, InputIterator last);
425 template<container-compatible-range<value_type> R>
426 void insert_range(R&& rg); // C++23
398427 void insert(initializer_list<value_type> il);
399428
400429 node_type extract(const_iterator position); // C++17
......@@ -469,6 +498,11 @@ template <class InputIterator,
469498multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
470499 -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17
471500
501template<ranges::input_range R, class Compare = less<range-key-type<R>>,
502 class Allocator = allocator<range-to-alloc-type<R>>>
503 multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
504 -> multimap<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23
505
472506template<class Key, class T, class Compare = less<Key>,
473507 class Allocator = allocator<pair<const Key, T>>>
474508multimap(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
......@@ -479,6 +513,10 @@ multimap(InputIterator, InputIterator, Allocator)
479513 -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
480514 less<iter_key_t<InputIterator>>, Allocator>; // C++17
481515
516template<ranges::input_range R, class Allocator>
517 multimap(from_range_t, R&&, Allocator)
518 -> multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23
519
482520template<class Key, class T, class Allocator>
483521multimap(initializer_list<pair<const Key, T>>, Allocator)
484522 -> multimap<Key, T, less<Key>, Allocator>; // C++17
......@@ -491,27 +529,32 @@ operator==(const multimap<Key, T, Compare, Allocator>& x,
491529template <class Key, class T, class Compare, class Allocator>
492530bool
493531operator< (const multimap<Key, T, Compare, Allocator>& x,
494 const multimap<Key, T, Compare, Allocator>& y);
532 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20
495533
496534template <class Key, class T, class Compare, class Allocator>
497535bool
498536operator!=(const multimap<Key, T, Compare, Allocator>& x,
499 const multimap<Key, T, Compare, Allocator>& y);
537 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20
500538
501539template <class Key, class T, class Compare, class Allocator>
502540bool
503541operator> (const multimap<Key, T, Compare, Allocator>& x,
504 const multimap<Key, T, Compare, Allocator>& y);
542 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20
505543
506544template <class Key, class T, class Compare, class Allocator>
507545bool
508546operator>=(const multimap<Key, T, Compare, Allocator>& x,
509 const multimap<Key, T, Compare, Allocator>& y);
547 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20
510548
511549template <class Key, class T, class Compare, class Allocator>
512550bool
513551operator<=(const multimap<Key, T, Compare, Allocator>& x,
514 const multimap<Key, T, Compare, Allocator>& y);
552 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20
553
554template<class Key, class T, class Compare, class Allocator>
555 synth-three-way-result<pair<const Key, T>>
556 operator<=>(const multimap<Key, T, Compare, Allocator>& x,
557 const multimap<Key, T, Compare, Allocator>& y); // since c++20
515558
516559// specialized algorithms:
517560template <class Key, class T, class Compare, class Allocator>
......@@ -530,24 +573,30 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
530573
531574#include <__algorithm/equal.h>
532575#include <__algorithm/lexicographical_compare.h>
576#include <__algorithm/lexicographical_compare_three_way.h>
533577#include <__assert> // all public C++ headers provide the assertion handler
578#include <__availability>
534579#include <__config>
535580#include <__functional/binary_function.h>
536581#include <__functional/is_transparent.h>
537582#include <__functional/operations.h>
538583#include <__iterator/erase_if_container.h>
539584#include <__iterator/iterator_traits.h>
585#include <__iterator/ranges_iterator_traits.h>
540586#include <__iterator/reverse_iterator.h>
587#include <__memory/addressof.h>
541588#include <__memory/allocator.h>
542589#include <__memory_resource/polymorphic_allocator.h>
543590#include <__node_handle>
591#include <__ranges/concepts.h>
592#include <__ranges/container_compatible_range.h>
593#include <__ranges/from_range.h>
544594#include <__tree>
545595#include <__type_traits/is_allocator.h>
546596#include <__utility/forward.h>
547597#include <__utility/piecewise_construct.h>
548598#include <__utility/swap.h>
549599#include <tuple>
550#include <type_traits>
551600#include <version>
552601
553602// standard-mandated includes
......@@ -594,14 +643,14 @@ public:
594643 _LIBCPP_INLINE_VISIBILITY
595644 bool operator()(const _Key& __x, const _CP& __y) const
596645 {return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);}
597 void swap(__map_value_compare& __y)
646 _LIBCPP_HIDE_FROM_ABI void swap(__map_value_compare& __y)
598647 _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
599648 {
600649 using _VSTD::swap;
601650 swap(static_cast<_Compare&>(*this), static_cast<_Compare&>(__y));
602651 }
603652
604#if _LIBCPP_STD_VER > 11
653#if _LIBCPP_STD_VER >= 14
605654 template <typename _K2>
606655 _LIBCPP_INLINE_VISIBILITY
607656 bool operator()(const _K2& __x, const _CP& __y) const
......@@ -647,7 +696,7 @@ public:
647696 swap(__comp_, __y.__comp_);
648697 }
649698
650#if _LIBCPP_STD_VER > 11
699#if _LIBCPP_STD_VER >= 14
651700 template <typename _K2>
652701 _LIBCPP_INLINE_VISIBILITY
653702 bool operator()(const _K2& __x, const _CP& __y) const
......@@ -742,7 +791,7 @@ public:
742791 _LIBCPP_INLINE_VISIBILITY
743792 value_type& __get_value()
744793 {
745#if _LIBCPP_STD_VER > 14
794#if _LIBCPP_STD_VER >= 17
746795 return *_VSTD::launder(_VSTD::addressof(__cc_));
747796#else
748797 return __cc_;
......@@ -752,7 +801,7 @@ public:
752801 _LIBCPP_INLINE_VISIBILITY
753802 const value_type& __get_value() const
754803 {
755#if _LIBCPP_STD_VER > 14
804#if _LIBCPP_STD_VER >= 17
756805 return *_VSTD::launder(_VSTD::addressof(__cc_));
757806#else
758807 return __cc_;
......@@ -1020,7 +1069,7 @@ public:
10201069 typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
10211070 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
10221071
1023#if _LIBCPP_STD_VER > 14
1072#if _LIBCPP_STD_VER >= 17
10241073 typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
10251074 typedef __insert_return_type<iterator, node_type> insert_return_type;
10261075#endif
......@@ -1067,13 +1116,30 @@ public:
10671116 insert(__f, __l);
10681117 }
10691118
1070#if _LIBCPP_STD_VER > 11
1119#if _LIBCPP_STD_VER >= 23
1120 template <_ContainerCompatibleRange<value_type> _Range>
1121 _LIBCPP_HIDE_FROM_ABI
1122 map(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(),
1123 const allocator_type& __a = allocator_type())
1124 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
1125 insert_range(std::forward<_Range>(__range));
1126 }
1127#endif
1128
1129#if _LIBCPP_STD_VER >= 14
10711130 template <class _InputIterator>
10721131 _LIBCPP_INLINE_VISIBILITY
10731132 map(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
10741133 : map(__f, __l, key_compare(), __a) {}
10751134#endif
10761135
1136#if _LIBCPP_STD_VER >= 23
1137 template <_ContainerCompatibleRange<value_type> _Range>
1138 _LIBCPP_HIDE_FROM_ABI
1139 map(from_range_t, _Range&& __range, const allocator_type& __a)
1140 : map(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
1141#endif
1142
10771143 _LIBCPP_INLINE_VISIBILITY
10781144 map(const map& __m)
10791145 : __tree_(__m.__tree_)
......@@ -1106,7 +1172,7 @@ public:
11061172 {
11071173 }
11081174
1109 map(map&& __m, const allocator_type& __a);
1175 _LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a);
11101176
11111177 _LIBCPP_INLINE_VISIBILITY
11121178 map& operator=(map&& __m)
......@@ -1130,7 +1196,7 @@ public:
11301196 insert(__il.begin(), __il.end());
11311197 }
11321198
1133#if _LIBCPP_STD_VER > 11
1199#if _LIBCPP_STD_VER >= 14
11341200 _LIBCPP_INLINE_VISIBILITY
11351201 map(initializer_list<value_type> __il, const allocator_type& __a)
11361202 : map(__il, key_compare(), __a) {}
......@@ -1200,13 +1266,13 @@ public:
12001266 _LIBCPP_INLINE_VISIBILITY
12011267 size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
12021268
1203 mapped_type& operator[](const key_type& __k);
1269 _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
12041270#ifndef _LIBCPP_CXX03_LANG
1205 mapped_type& operator[](key_type&& __k);
1271 _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k);
12061272#endif
12071273
1208 mapped_type& at(const key_type& __k);
1209 const mapped_type& at(const key_type& __k) const;
1274 _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k);
1275 _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;
12101276
12111277 _LIBCPP_INLINE_VISIBILITY
12121278 allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());}
......@@ -1273,7 +1339,18 @@ public:
12731339 insert(__e.__i_, *__f);
12741340 }
12751341
1276#if _LIBCPP_STD_VER > 14
1342#if _LIBCPP_STD_VER >= 23
1343 template <_ContainerCompatibleRange<value_type> _Range>
1344 _LIBCPP_HIDE_FROM_ABI
1345 void insert_range(_Range&& __range) {
1346 const_iterator __end = cend();
1347 for (auto&& __element : __range) {
1348 insert(__end.__i_, std::forward<decltype(__element)>(__element));
1349 }
1350 }
1351#endif
1352
1353#if _LIBCPP_STD_VER >= 17
12771354
12781355 template <class... _Args>
12791356 _LIBCPP_INLINE_VISIBILITY
......@@ -1367,7 +1444,7 @@ public:
13671444 return __r;
13681445 }
13691446
1370#endif // _LIBCPP_STD_VER > 14
1447#endif // _LIBCPP_STD_VER >= 17
13711448
13721449 _LIBCPP_INLINE_VISIBILITY
13731450 iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
......@@ -1382,11 +1459,11 @@ public:
13821459 _LIBCPP_INLINE_VISIBILITY
13831460 void clear() _NOEXCEPT {__tree_.clear();}
13841461
1385#if _LIBCPP_STD_VER > 14
1462#if _LIBCPP_STD_VER >= 17
13861463 _LIBCPP_INLINE_VISIBILITY
13871464 insert_return_type insert(node_type&& __nh)
13881465 {
1389 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1466 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
13901467 "node_type with incompatible allocator passed to map::insert()");
13911468 return __tree_.template __node_handle_insert_unique<
13921469 node_type, insert_return_type>(_VSTD::move(__nh));
......@@ -1394,7 +1471,7 @@ public:
13941471 _LIBCPP_INLINE_VISIBILITY
13951472 iterator insert(const_iterator __hint, node_type&& __nh)
13961473 {
1397 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1474 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
13981475 "node_type with incompatible allocator passed to map::insert()");
13991476 return __tree_.template __node_handle_insert_unique<node_type>(
14001477 __hint.__i_, _VSTD::move(__nh));
......@@ -1413,32 +1490,32 @@ public:
14131490 _LIBCPP_INLINE_VISIBILITY
14141491 void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
14151492 {
1416 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1417 "merging container with incompatible allocator");
1493 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1494 "merging container with incompatible allocator");
14181495 __tree_.__node_handle_merge_unique(__source.__tree_);
14191496 }
14201497 template <class _Compare2>
14211498 _LIBCPP_INLINE_VISIBILITY
14221499 void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
14231500 {
1424 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1425 "merging container with incompatible allocator");
1501 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1502 "merging container with incompatible allocator");
14261503 __tree_.__node_handle_merge_unique(__source.__tree_);
14271504 }
14281505 template <class _Compare2>
14291506 _LIBCPP_INLINE_VISIBILITY
14301507 void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
14311508 {
1432 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1433 "merging container with incompatible allocator");
1509 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1510 "merging container with incompatible allocator");
14341511 __tree_.__node_handle_merge_unique(__source.__tree_);
14351512 }
14361513 template <class _Compare2>
14371514 _LIBCPP_INLINE_VISIBILITY
14381515 void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
14391516 {
1440 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1441 "merging container with incompatible allocator");
1517 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1518 "merging container with incompatible allocator");
14421519 __tree_.__node_handle_merge_unique(__source.__tree_);
14431520 }
14441521#endif
......@@ -1452,7 +1529,7 @@ public:
14521529 iterator find(const key_type& __k) {return __tree_.find(__k);}
14531530 _LIBCPP_INLINE_VISIBILITY
14541531 const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
1455#if _LIBCPP_STD_VER > 11
1532#if _LIBCPP_STD_VER >= 14
14561533 template <typename _K2>
14571534 _LIBCPP_INLINE_VISIBILITY
14581535 __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
......@@ -1466,21 +1543,21 @@ public:
14661543 _LIBCPP_INLINE_VISIBILITY
14671544 size_type count(const key_type& __k) const
14681545 {return __tree_.__count_unique(__k);}
1469#if _LIBCPP_STD_VER > 11
1546#if _LIBCPP_STD_VER >= 14
14701547 template <typename _K2>
14711548 _LIBCPP_INLINE_VISIBILITY
14721549 __enable_if_t<__is_transparent<_Compare, _K2>::value, size_type>
14731550 count(const _K2& __k) const {return __tree_.__count_multi(__k);}
14741551#endif
14751552
1476#if _LIBCPP_STD_VER > 17
1553#if _LIBCPP_STD_VER >= 20
14771554 _LIBCPP_INLINE_VISIBILITY
14781555 bool contains(const key_type& __k) const {return find(__k) != end();}
14791556 template <typename _K2>
14801557 _LIBCPP_INLINE_VISIBILITY
14811558 __enable_if_t<__is_transparent<_Compare, _K2>::value, bool>
14821559 contains(const _K2& __k) const { return find(__k) != end(); }
1483#endif // _LIBCPP_STD_VER > 17
1560#endif // _LIBCPP_STD_VER >= 20
14841561
14851562 _LIBCPP_INLINE_VISIBILITY
14861563 iterator lower_bound(const key_type& __k)
......@@ -1488,7 +1565,7 @@ public:
14881565 _LIBCPP_INLINE_VISIBILITY
14891566 const_iterator lower_bound(const key_type& __k) const
14901567 {return __tree_.lower_bound(__k);}
1491#if _LIBCPP_STD_VER > 11
1568#if _LIBCPP_STD_VER >= 14
14921569 template <typename _K2>
14931570 _LIBCPP_INLINE_VISIBILITY
14941571 __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
......@@ -1506,7 +1583,7 @@ public:
15061583 _LIBCPP_INLINE_VISIBILITY
15071584 const_iterator upper_bound(const key_type& __k) const
15081585 {return __tree_.upper_bound(__k);}
1509#if _LIBCPP_STD_VER > 11
1586#if _LIBCPP_STD_VER >= 14
15101587 template <typename _K2>
15111588 _LIBCPP_INLINE_VISIBILITY
15121589 __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
......@@ -1523,7 +1600,7 @@ public:
15231600 _LIBCPP_INLINE_VISIBILITY
15241601 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
15251602 {return __tree_.__equal_range_unique(__k);}
1526#if _LIBCPP_STD_VER > 11
1603#if _LIBCPP_STD_VER >= 14
15271604 template <typename _K2>
15281605 _LIBCPP_INLINE_VISIBILITY
15291606 __enable_if_t<__is_transparent<_Compare, _K2>::value, pair<iterator,iterator>>
......@@ -1545,19 +1622,28 @@ private:
15451622 typedef unique_ptr<__node, _Dp> __node_holder;
15461623
15471624#ifdef _LIBCPP_CXX03_LANG
1548 __node_holder __construct_node_with_key(const key_type& __k);
1625 _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_with_key(const key_type& __k);
15491626#endif
15501627};
15511628
15521629#if _LIBCPP_STD_VER >= 17
15531630template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>,
15541631 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
1555 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
1632 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
15561633 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
15571634 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
15581635map(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
15591636 -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;
15601637
1638#if _LIBCPP_STD_VER >= 23
1639template <ranges::input_range _Range, class _Compare = less<__range_key_type<_Range>>,
1640 class _Allocator = allocator<__range_to_alloc_type<_Range>>,
1641 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
1642 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1643map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
1644 -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;
1645#endif
1646
15611647template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>,
15621648 class _Allocator = allocator<pair<const _Key, _Tp>>,
15631649 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
......@@ -1566,12 +1652,19 @@ map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allo
15661652 -> map<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
15671653
15681654template<class _InputIterator, class _Allocator,
1569 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
1655 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
15701656 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
15711657map(_InputIterator, _InputIterator, _Allocator)
15721658 -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
15731659 less<__iter_key_type<_InputIterator>>, _Allocator>;
15741660
1661#if _LIBCPP_STD_VER >= 23
1662template <ranges::input_range _Range, class _Allocator,
1663 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1664map(from_range_t, _Range&&, _Allocator)
1665 -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;
1666#endif
1667
15751668template<class _Key, class _Tp, class _Allocator,
15761669 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
15771670map(initializer_list<pair<_Key, _Tp>>, _Allocator)
......@@ -1677,6 +1770,8 @@ operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x,
16771770 return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
16781771}
16791772
1773#if _LIBCPP_STD_VER <= 17
1774
16801775template <class _Key, class _Tp, class _Compare, class _Allocator>
16811776inline _LIBCPP_INLINE_VISIBILITY
16821777bool
......@@ -1722,6 +1817,21 @@ operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
17221817 return !(__y < __x);
17231818}
17241819
1820#else // #if _LIBCPP_STD_VER <= 17
1821
1822template <class _Key, class _Tp, class _Compare, class _Allocator>
1823_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>>
1824operator<=>(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
1825 return std::lexicographical_compare_three_way(
1826 __x.begin(),
1827 __x.end(),
1828 __y.begin(),
1829 __y.end(),
1830 std::__synth_three_way<pair<const _Key, _Tp>, pair<const _Key, _Tp>>);
1831}
1832
1833#endif // #if _LIBCPP_STD_VER <= 17
1834
17251835template <class _Key, class _Tp, class _Compare, class _Allocator>
17261836inline _LIBCPP_INLINE_VISIBILITY
17271837void
......@@ -1732,7 +1842,7 @@ swap(map<_Key, _Tp, _Compare, _Allocator>& __x,
17321842 __x.swap(__y);
17331843}
17341844
1735#if _LIBCPP_STD_VER > 17
1845#if _LIBCPP_STD_VER >= 20
17361846template <class _Key, class _Tp, class _Compare, class _Allocator,
17371847 class _Predicate>
17381848inline _LIBCPP_INLINE_VISIBILITY
......@@ -1800,7 +1910,7 @@ public:
18001910 typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
18011911 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
18021912
1803#if _LIBCPP_STD_VER > 14
1913#if _LIBCPP_STD_VER >= 17
18041914 typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
18051915#endif
18061916
......@@ -1846,13 +1956,30 @@ public:
18461956 insert(__f, __l);
18471957 }
18481958
1849#if _LIBCPP_STD_VER > 11
1959#if _LIBCPP_STD_VER >= 23
1960 template <_ContainerCompatibleRange<value_type> _Range>
1961 _LIBCPP_HIDE_FROM_ABI
1962 multimap(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(),
1963 const allocator_type& __a = allocator_type())
1964 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
1965 insert_range(std::forward<_Range>(__range));
1966 }
1967#endif
1968
1969#if _LIBCPP_STD_VER >= 14
18501970 template <class _InputIterator>
18511971 _LIBCPP_INLINE_VISIBILITY
18521972 multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
18531973 : multimap(__f, __l, key_compare(), __a) {}
18541974#endif
18551975
1976#if _LIBCPP_STD_VER >= 23
1977 template <_ContainerCompatibleRange<value_type> _Range>
1978 _LIBCPP_HIDE_FROM_ABI
1979 multimap(from_range_t, _Range&& __range, const allocator_type& __a)
1980 : multimap(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
1981#endif
1982
18561983 _LIBCPP_INLINE_VISIBILITY
18571984 multimap(const multimap& __m)
18581985 : __tree_(__m.__tree_.value_comp(),
......@@ -1886,7 +2013,7 @@ public:
18862013 {
18872014 }
18882015
1889 multimap(multimap&& __m, const allocator_type& __a);
2016 _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a);
18902017
18912018 _LIBCPP_INLINE_VISIBILITY
18922019 multimap& operator=(multimap&& __m)
......@@ -1910,7 +2037,7 @@ public:
19102037 insert(__il.begin(), __il.end());
19112038 }
19122039
1913#if _LIBCPP_STD_VER > 11
2040#if _LIBCPP_STD_VER >= 14
19142041 _LIBCPP_INLINE_VISIBILITY
19152042 multimap(initializer_list<value_type> __il, const allocator_type& __a)
19162043 : multimap(__il, key_compare(), __a) {}
......@@ -2043,6 +2170,17 @@ public:
20432170 __tree_.__insert_multi(__e.__i_, *__f);
20442171 }
20452172
2173#if _LIBCPP_STD_VER >= 23
2174 template <_ContainerCompatibleRange<value_type> _Range>
2175 _LIBCPP_HIDE_FROM_ABI
2176 void insert_range(_Range&& __range) {
2177 const_iterator __end = cend();
2178 for (auto&& __element : __range) {
2179 __tree_.__insert_multi(__end.__i_, std::forward<decltype(__element)>(__element));
2180 }
2181 }
2182#endif
2183
20462184 _LIBCPP_INLINE_VISIBILITY
20472185 iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
20482186 _LIBCPP_INLINE_VISIBILITY
......@@ -2053,11 +2191,11 @@ public:
20532191 iterator erase(const_iterator __f, const_iterator __l)
20542192 {return __tree_.erase(__f.__i_, __l.__i_);}
20552193
2056#if _LIBCPP_STD_VER > 14
2194#if _LIBCPP_STD_VER >= 17
20572195 _LIBCPP_INLINE_VISIBILITY
20582196 iterator insert(node_type&& __nh)
20592197 {
2060 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
2198 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
20612199 "node_type with incompatible allocator passed to multimap::insert()");
20622200 return __tree_.template __node_handle_insert_multi<node_type>(
20632201 _VSTD::move(__nh));
......@@ -2065,7 +2203,7 @@ public:
20652203 _LIBCPP_INLINE_VISIBILITY
20662204 iterator insert(const_iterator __hint, node_type&& __nh)
20672205 {
2068 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
2206 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
20692207 "node_type with incompatible allocator passed to multimap::insert()");
20702208 return __tree_.template __node_handle_insert_multi<node_type>(
20712209 __hint.__i_, _VSTD::move(__nh));
......@@ -2085,32 +2223,32 @@ public:
20852223 _LIBCPP_INLINE_VISIBILITY
20862224 void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
20872225 {
2088 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
2089 "merging container with incompatible allocator");
2226 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
2227 "merging container with incompatible allocator");
20902228 return __tree_.__node_handle_merge_multi(__source.__tree_);
20912229 }
20922230 template <class _Compare2>
20932231 _LIBCPP_INLINE_VISIBILITY
20942232 void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
20952233 {
2096 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
2097 "merging container with incompatible allocator");
2234 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
2235 "merging container with incompatible allocator");
20982236 return __tree_.__node_handle_merge_multi(__source.__tree_);
20992237 }
21002238 template <class _Compare2>
21012239 _LIBCPP_INLINE_VISIBILITY
21022240 void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
21032241 {
2104 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
2105 "merging container with incompatible allocator");
2242 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
2243 "merging container with incompatible allocator");
21062244 return __tree_.__node_handle_merge_multi(__source.__tree_);
21072245 }
21082246 template <class _Compare2>
21092247 _LIBCPP_INLINE_VISIBILITY
21102248 void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
21112249 {
2112 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
2113 "merging container with incompatible allocator");
2250 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
2251 "merging container with incompatible allocator");
21142252 return __tree_.__node_handle_merge_multi(__source.__tree_);
21152253 }
21162254#endif
......@@ -2127,7 +2265,7 @@ public:
21272265 iterator find(const key_type& __k) {return __tree_.find(__k);}
21282266 _LIBCPP_INLINE_VISIBILITY
21292267 const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
2130#if _LIBCPP_STD_VER > 11
2268#if _LIBCPP_STD_VER >= 14
21312269 template <typename _K2>
21322270 _LIBCPP_INLINE_VISIBILITY
21332271 __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
......@@ -2141,21 +2279,21 @@ public:
21412279 _LIBCPP_INLINE_VISIBILITY
21422280 size_type count(const key_type& __k) const
21432281 {return __tree_.__count_multi(__k);}
2144#if _LIBCPP_STD_VER > 11
2282#if _LIBCPP_STD_VER >= 14
21452283 template <typename _K2>
21462284 _LIBCPP_INLINE_VISIBILITY
21472285 __enable_if_t<__is_transparent<_Compare, _K2>::value, size_type>
21482286 count(const _K2& __k) const {return __tree_.__count_multi(__k);}
21492287#endif
21502288
2151#if _LIBCPP_STD_VER > 17
2289#if _LIBCPP_STD_VER >= 20
21522290 _LIBCPP_INLINE_VISIBILITY
21532291 bool contains(const key_type& __k) const {return find(__k) != end();}
21542292 template <typename _K2>
21552293 _LIBCPP_INLINE_VISIBILITY
21562294 __enable_if_t<__is_transparent<_Compare, _K2>::value, bool>
21572295 contains(const _K2& __k) const { return find(__k) != end(); }
2158#endif // _LIBCPP_STD_VER > 17
2296#endif // _LIBCPP_STD_VER >= 20
21592297
21602298 _LIBCPP_INLINE_VISIBILITY
21612299 iterator lower_bound(const key_type& __k)
......@@ -2163,7 +2301,7 @@ public:
21632301 _LIBCPP_INLINE_VISIBILITY
21642302 const_iterator lower_bound(const key_type& __k) const
21652303 {return __tree_.lower_bound(__k);}
2166#if _LIBCPP_STD_VER > 11
2304#if _LIBCPP_STD_VER >= 14
21672305 template <typename _K2>
21682306 _LIBCPP_INLINE_VISIBILITY
21692307 __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
......@@ -2181,7 +2319,7 @@ public:
21812319 _LIBCPP_INLINE_VISIBILITY
21822320 const_iterator upper_bound(const key_type& __k) const
21832321 {return __tree_.upper_bound(__k);}
2184#if _LIBCPP_STD_VER > 11
2322#if _LIBCPP_STD_VER >= 14
21852323 template <typename _K2>
21862324 _LIBCPP_INLINE_VISIBILITY
21872325 __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
......@@ -2198,7 +2336,7 @@ public:
21982336 _LIBCPP_INLINE_VISIBILITY
21992337 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
22002338 {return __tree_.__equal_range_multi(__k);}
2201#if _LIBCPP_STD_VER > 11
2339#if _LIBCPP_STD_VER >= 14
22022340 template <typename _K2>
22032341 _LIBCPP_INLINE_VISIBILITY
22042342 __enable_if_t<__is_transparent<_Compare, _K2>::value, pair<iterator,iterator>>
......@@ -2221,12 +2359,21 @@ private:
22212359#if _LIBCPP_STD_VER >= 17
22222360template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>,
22232361 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
2224 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
2362 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
22252363 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
22262364 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
22272365multimap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
22282366 -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;
22292367
2368#if _LIBCPP_STD_VER >= 23
2369template <ranges::input_range _Range, class _Compare = less<__range_key_type<_Range>>,
2370 class _Allocator = allocator<__range_to_alloc_type<_Range>>,
2371 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
2372 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2373multimap(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
2374 -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;
2375#endif
2376
22302377template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>,
22312378 class _Allocator = allocator<pair<const _Key, _Tp>>,
22322379 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
......@@ -2235,12 +2382,19 @@ multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator =
22352382 -> multimap<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
22362383
22372384template<class _InputIterator, class _Allocator,
2238 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
2385 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
22392386 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
22402387multimap(_InputIterator, _InputIterator, _Allocator)
22412388 -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
22422389 less<__iter_key_type<_InputIterator>>, _Allocator>;
22432390
2391#if _LIBCPP_STD_VER >= 23
2392template <ranges::input_range _Range, class _Allocator,
2393 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2394multimap(from_range_t, _Range&&, _Allocator)
2395 -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;
2396#endif
2397
22442398template<class _Key, class _Tp, class _Allocator,
22452399 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
22462400multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
......@@ -2271,6 +2425,8 @@ operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
22712425 return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
22722426}
22732427
2428#if _LIBCPP_STD_VER <= 17
2429
22742430template <class _Key, class _Tp, class _Compare, class _Allocator>
22752431inline _LIBCPP_INLINE_VISIBILITY
22762432bool
......@@ -2316,6 +2472,22 @@ operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
23162472 return !(__y < __x);
23172473}
23182474
2475#else // #if _LIBCPP_STD_VER <= 17
2476
2477template <class _Key, class _Tp, class _Compare, class _Allocator>
2478_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>>
2479operator<=>(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2480 const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {
2481 return std::lexicographical_compare_three_way(
2482 __x.begin(),
2483 __x.end(),
2484 __y.begin(),
2485 __y.end(),
2486 std::__synth_three_way<pair<const _Key, _Tp>, pair<const _Key, _Tp>>);
2487}
2488
2489#endif // #if _LIBCPP_STD_VER <= 17
2490
23192491template <class _Key, class _Tp, class _Compare, class _Allocator>
23202492inline _LIBCPP_INLINE_VISIBILITY
23212493void
......@@ -2326,7 +2498,7 @@ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x,
23262498 __x.swap(__y);
23272499}
23282500
2329#if _LIBCPP_STD_VER > 17
2501#if _LIBCPP_STD_VER >= 20
23302502template <class _Key, class _Tp, class _Compare, class _Allocator,
23312503 class _Predicate>
23322504inline _LIBCPP_INLINE_VISIBILITY
......@@ -2339,22 +2511,24 @@ inline _LIBCPP_INLINE_VISIBILITY
23392511
23402512_LIBCPP_END_NAMESPACE_STD
23412513
2342#if _LIBCPP_STD_VER > 14
2514#if _LIBCPP_STD_VER >= 17
23432515_LIBCPP_BEGIN_NAMESPACE_STD
23442516namespace pmr {
23452517template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>
2346using map = std::map<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
2518using map _LIBCPP_AVAILABILITY_PMR = std::map<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
23472519
23482520template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>
2349using multimap = std::multimap<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
2521using multimap _LIBCPP_AVAILABILITY_PMR = std::multimap<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
23502522} // namespace pmr
23512523_LIBCPP_END_NAMESPACE_STD
23522524#endif
23532525
23542526#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
23552527# include <concepts>
2528# include <cstdlib>
23562529# include <functional>
23572530# include <iterator>
2531# include <type_traits>
23582532# include <utility>
23592533#endif
23602534
lib/libcxx/include/math.h-44
......@@ -554,7 +554,6 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2
554554
555555// acos
556556
557# if !defined(__sun__)
558557inline _LIBCPP_HIDE_FROM_ABI float acos(float __x) _NOEXCEPT {return __builtin_acosf(__x);}
559558
560559template <class = int>
......@@ -563,7 +562,6 @@ _LIBCPP_HIDE_FROM_ABI double acos(double __x) _NOEXCEPT {
563562}
564563
565564inline _LIBCPP_HIDE_FROM_ABI long double acos(long double __x) _NOEXCEPT {return __builtin_acosl(__x);}
566# endif
567565
568566template <class _A1>
569567inline _LIBCPP_HIDE_FROM_ABI
......@@ -572,7 +570,6 @@ acos(_A1 __x) _NOEXCEPT {return __builtin_acos((double)__x);}
572570
573571// asin
574572
575# if !defined(__sun__)
576573inline _LIBCPP_HIDE_FROM_ABI float asin(float __x) _NOEXCEPT {return __builtin_asinf(__x);}
577574
578575template <class = int>
......@@ -581,7 +578,6 @@ _LIBCPP_HIDE_FROM_ABI double asin(double __x) _NOEXCEPT {
581578}
582579
583580inline _LIBCPP_HIDE_FROM_ABI long double asin(long double __x) _NOEXCEPT {return __builtin_asinl(__x);}
584# endif
585581
586582template <class _A1>
587583inline _LIBCPP_HIDE_FROM_ABI
......@@ -590,7 +586,6 @@ asin(_A1 __x) _NOEXCEPT {return __builtin_asin((double)__x);}
590586
591587// atan
592588
593# if !defined(__sun__)
594589inline _LIBCPP_HIDE_FROM_ABI float atan(float __x) _NOEXCEPT {return __builtin_atanf(__x);}
595590
596591template <class = int>
......@@ -599,7 +594,6 @@ _LIBCPP_HIDE_FROM_ABI double atan(double __x) _NOEXCEPT {
599594}
600595
601596inline _LIBCPP_HIDE_FROM_ABI long double atan(long double __x) _NOEXCEPT {return __builtin_atanl(__x);}
602# endif
603597
604598template <class _A1>
605599inline _LIBCPP_HIDE_FROM_ABI
......@@ -608,7 +602,6 @@ atan(_A1 __x) _NOEXCEPT {return __builtin_atan((double)__x);}
608602
609603// atan2
610604
611# if !defined(__sun__)
612605inline _LIBCPP_HIDE_FROM_ABI float atan2(float __y, float __x) _NOEXCEPT {return __builtin_atan2f(__y, __x);}
613606
614607template <class = int>
......@@ -617,7 +610,6 @@ _LIBCPP_HIDE_FROM_ABI double atan2(double __x, double __y) _NOEXCEPT {
617610}
618611
619612inline _LIBCPP_HIDE_FROM_ABI long double atan2(long double __y, long double __x) _NOEXCEPT {return __builtin_atan2l(__y, __x);}
620# endif
621613
622614template <class _A1, class _A2>
623615inline _LIBCPP_HIDE_FROM_ABI
......@@ -637,7 +629,6 @@ atan2(_A1 __y, _A2 __x) _NOEXCEPT
637629
638630// ceil
639631
640# if !defined(__sun__)
641632_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float ceil(float __x) _NOEXCEPT {return __builtin_ceilf(__x);}
642633
643634template <class = int>
......@@ -646,7 +637,6 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double ceil(double __x) _NOEXCEPT {
646637}
647638
648639_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double ceil(long double __x) _NOEXCEPT {return __builtin_ceill(__x);}
649# endif
650640
651641template <class _A1>
652642_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
......@@ -655,7 +645,6 @@ ceil(_A1 __x) _NOEXCEPT {return __builtin_ceil((double)__x);}
655645
656646// cos
657647
658# if !defined(__sun__)
659648inline _LIBCPP_HIDE_FROM_ABI float cos(float __x) _NOEXCEPT {return __builtin_cosf(__x);}
660649
661650template <class = int>
......@@ -664,7 +653,6 @@ _LIBCPP_HIDE_FROM_ABI double cos(double __x) _NOEXCEPT {
664653}
665654
666655inline _LIBCPP_HIDE_FROM_ABI long double cos(long double __x) _NOEXCEPT {return __builtin_cosl(__x);}
667# endif
668656
669657template <class _A1>
670658inline _LIBCPP_HIDE_FROM_ABI
......@@ -673,7 +661,6 @@ cos(_A1 __x) _NOEXCEPT {return __builtin_cos((double)__x);}
673661
674662// cosh
675663
676# if !defined(__sun__)
677664inline _LIBCPP_HIDE_FROM_ABI float cosh(float __x) _NOEXCEPT {return __builtin_coshf(__x);}
678665
679666template <class = int>
......@@ -682,7 +669,6 @@ _LIBCPP_HIDE_FROM_ABI double cosh(double __x) _NOEXCEPT {
682669}
683670
684671inline _LIBCPP_HIDE_FROM_ABI long double cosh(long double __x) _NOEXCEPT {return __builtin_coshl(__x);}
685# endif
686672
687673template <class _A1>
688674inline _LIBCPP_HIDE_FROM_ABI
......@@ -691,7 +677,6 @@ cosh(_A1 __x) _NOEXCEPT {return __builtin_cosh((double)__x);}
691677
692678// exp
693679
694# if !defined(__sun__)
695680inline _LIBCPP_HIDE_FROM_ABI float exp(float __x) _NOEXCEPT {return __builtin_expf(__x);}
696681
697682template <class = int>
......@@ -700,7 +685,6 @@ _LIBCPP_HIDE_FROM_ABI double exp(double __x) _NOEXCEPT {
700685}
701686
702687inline _LIBCPP_HIDE_FROM_ABI long double exp(long double __x) _NOEXCEPT {return __builtin_expl(__x);}
703# endif
704688
705689template <class _A1>
706690inline _LIBCPP_HIDE_FROM_ABI
......@@ -709,7 +693,6 @@ exp(_A1 __x) _NOEXCEPT {return __builtin_exp((double)__x);}
709693
710694// fabs
711695
712# if !defined(__sun__)
713696_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fabs(float __x) _NOEXCEPT {return __builtin_fabsf(__x);}
714697
715698template <class = int>
......@@ -718,7 +701,6 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fabs(double __x) _NOEXCEPT {
718701}
719702
720703_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fabs(long double __x) _NOEXCEPT {return __builtin_fabsl(__x);}
721# endif
722704
723705template <class _A1>
724706_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
......@@ -727,7 +709,6 @@ fabs(_A1 __x) _NOEXCEPT {return __builtin_fabs((double)__x);}
727709
728710// floor
729711
730# if !defined(__sun__)
731712_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float floor(float __x) _NOEXCEPT {return __builtin_floorf(__x);}
732713
733714template <class = int>
......@@ -736,7 +717,6 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double floor(double __x) _NOEXCEPT {
736717}
737718
738719_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double floor(long double __x) _NOEXCEPT {return __builtin_floorl(__x);}
739# endif
740720
741721template <class _A1>
742722_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
......@@ -745,7 +725,6 @@ floor(_A1 __x) _NOEXCEPT {return __builtin_floor((double)__x);}
745725
746726// fmod
747727
748# if !defined(__sun__)
749728inline _LIBCPP_HIDE_FROM_ABI float fmod(float __x, float __y) _NOEXCEPT {return __builtin_fmodf(__x, __y);}
750729
751730template <class = int>
......@@ -754,7 +733,6 @@ _LIBCPP_HIDE_FROM_ABI double fmod(double __x, double __y) _NOEXCEPT {
754733}
755734
756735inline _LIBCPP_HIDE_FROM_ABI long double fmod(long double __x, long double __y) _NOEXCEPT {return __builtin_fmodl(__x, __y);}
757# endif
758736
759737template <class _A1, class _A2>
760738inline _LIBCPP_HIDE_FROM_ABI
......@@ -774,7 +752,6 @@ fmod(_A1 __x, _A2 __y) _NOEXCEPT
774752
775753// frexp
776754
777# if !defined(__sun__)
778755inline _LIBCPP_HIDE_FROM_ABI float frexp(float __x, int* __e) _NOEXCEPT {return __builtin_frexpf(__x, __e);}
779756
780757template <class = int>
......@@ -783,7 +760,6 @@ _LIBCPP_HIDE_FROM_ABI double frexp(double __x, int* __e) _NOEXCEPT {
783760}
784761
785762inline _LIBCPP_HIDE_FROM_ABI long double frexp(long double __x, int* __e) _NOEXCEPT {return __builtin_frexpl(__x, __e);}
786# endif
787763
788764template <class _A1>
789765inline _LIBCPP_HIDE_FROM_ABI
......@@ -792,7 +768,6 @@ frexp(_A1 __x, int* __e) _NOEXCEPT {return __builtin_frexp((double)__x, __e);}
792768
793769// ldexp
794770
795# if !defined(__sun__)
796771inline _LIBCPP_HIDE_FROM_ABI float ldexp(float __x, int __e) _NOEXCEPT {return __builtin_ldexpf(__x, __e);}
797772
798773template <class = int>
......@@ -801,7 +776,6 @@ _LIBCPP_HIDE_FROM_ABI double ldexp(double __x, int __e) _NOEXCEPT {
801776}
802777
803778inline _LIBCPP_HIDE_FROM_ABI long double ldexp(long double __x, int __e) _NOEXCEPT {return __builtin_ldexpl(__x, __e);}
804# endif
805779
806780template <class _A1>
807781inline _LIBCPP_HIDE_FROM_ABI
......@@ -810,7 +784,6 @@ ldexp(_A1 __x, int __e) _NOEXCEPT {return __builtin_ldexp((double)__x, __e);}
810784
811785// log
812786
813# if !defined(__sun__)
814787inline _LIBCPP_HIDE_FROM_ABI float log(float __x) _NOEXCEPT {return __builtin_logf(__x);}
815788
816789template <class = int>
......@@ -819,7 +792,6 @@ _LIBCPP_HIDE_FROM_ABI double log(double __x) _NOEXCEPT {
819792}
820793
821794inline _LIBCPP_HIDE_FROM_ABI long double log(long double __x) _NOEXCEPT {return __builtin_logl(__x);}
822# endif
823795
824796template <class _A1>
825797inline _LIBCPP_HIDE_FROM_ABI
......@@ -828,7 +800,6 @@ log(_A1 __x) _NOEXCEPT {return __builtin_log((double)__x);}
828800
829801// log10
830802
831# if !defined(__sun__)
832803inline _LIBCPP_HIDE_FROM_ABI float log10(float __x) _NOEXCEPT {return __builtin_log10f(__x);}
833804
834805
......@@ -838,7 +809,6 @@ _LIBCPP_HIDE_FROM_ABI double log10(double __x) _NOEXCEPT {
838809}
839810
840811inline _LIBCPP_HIDE_FROM_ABI long double log10(long double __x) _NOEXCEPT {return __builtin_log10l(__x);}
841# endif
842812
843813template <class _A1>
844814inline _LIBCPP_HIDE_FROM_ABI
......@@ -847,7 +817,6 @@ log10(_A1 __x) _NOEXCEPT {return __builtin_log10((double)__x);}
847817
848818// modf
849819
850# if !defined(__sun__)
851820inline _LIBCPP_HIDE_FROM_ABI float modf(float __x, float* __y) _NOEXCEPT {return __builtin_modff(__x, __y);}
852821
853822template <class = int>
......@@ -856,11 +825,9 @@ _LIBCPP_HIDE_FROM_ABI double modf(double __x, double* __y) _NOEXCEPT {
856825}
857826
858827inline _LIBCPP_HIDE_FROM_ABI long double modf(long double __x, long double* __y) _NOEXCEPT {return __builtin_modfl(__x, __y);}
859# endif
860828
861829// pow
862830
863# if !defined(__sun__)
864831inline _LIBCPP_HIDE_FROM_ABI float pow(float __x, float __y) _NOEXCEPT {return __builtin_powf(__x, __y);}
865832
866833template <class = int>
......@@ -869,7 +836,6 @@ _LIBCPP_HIDE_FROM_ABI double pow(double __x, double __y) _NOEXCEPT {
869836}
870837
871838inline _LIBCPP_HIDE_FROM_ABI long double pow(long double __x, long double __y) _NOEXCEPT {return __builtin_powl(__x, __y);}
872# endif
873839
874840template <class _A1, class _A2>
875841inline _LIBCPP_HIDE_FROM_ABI
......@@ -889,7 +855,6 @@ pow(_A1 __x, _A2 __y) _NOEXCEPT
889855
890856// sin
891857
892# if !defined(__sun__)
893858inline _LIBCPP_HIDE_FROM_ABI float sin(float __x) _NOEXCEPT {return __builtin_sinf(__x);}
894859
895860template <class = int>
......@@ -898,7 +863,6 @@ _LIBCPP_HIDE_FROM_ABI double sin(double __x) _NOEXCEPT {
898863}
899864
900865inline _LIBCPP_HIDE_FROM_ABI long double sin(long double __x) _NOEXCEPT {return __builtin_sinl(__x);}
901#endif
902866
903867template <class _A1>
904868inline _LIBCPP_HIDE_FROM_ABI
......@@ -907,7 +871,6 @@ sin(_A1 __x) _NOEXCEPT {return __builtin_sin((double)__x);}
907871
908872// sinh
909873
910# if !defined(__sun__)
911874inline _LIBCPP_HIDE_FROM_ABI float sinh(float __x) _NOEXCEPT {return __builtin_sinhf(__x);}
912875
913876template <class = int>
......@@ -916,7 +879,6 @@ _LIBCPP_HIDE_FROM_ABI double sinh(double __x) _NOEXCEPT {
916879}
917880
918881inline _LIBCPP_HIDE_FROM_ABI long double sinh(long double __x) _NOEXCEPT {return __builtin_sinhl(__x);}
919# endif
920882
921883template <class _A1>
922884inline _LIBCPP_HIDE_FROM_ABI
......@@ -925,7 +887,6 @@ sinh(_A1 __x) _NOEXCEPT {return __builtin_sinh((double)__x);}
925887
926888// sqrt
927889
928# if !defined(__sun__)
929890inline _LIBCPP_HIDE_FROM_ABI float sqrt(float __x) _NOEXCEPT {return __builtin_sqrtf(__x);}
930891
931892template <class = int>
......@@ -934,7 +895,6 @@ _LIBCPP_HIDE_FROM_ABI double sqrt(double __x) _NOEXCEPT {
934895}
935896
936897inline _LIBCPP_HIDE_FROM_ABI long double sqrt(long double __x) _NOEXCEPT {return __builtin_sqrtl(__x);}
937# endif
938898
939899template <class _A1>
940900inline _LIBCPP_HIDE_FROM_ABI
......@@ -943,7 +903,6 @@ sqrt(_A1 __x) _NOEXCEPT {return __builtin_sqrt((double)__x);}
943903
944904// tan
945905
946# if !defined(__sun__)
947906inline _LIBCPP_HIDE_FROM_ABI float tan(float __x) _NOEXCEPT {return __builtin_tanf(__x);}
948907
949908template <class = int>
......@@ -952,7 +911,6 @@ _LIBCPP_HIDE_FROM_ABI double tan(double __x) _NOEXCEPT {
952911}
953912
954913inline _LIBCPP_HIDE_FROM_ABI long double tan(long double __x) _NOEXCEPT {return __builtin_tanl(__x);}
955# endif
956914
957915template <class _A1>
958916inline _LIBCPP_HIDE_FROM_ABI
......@@ -961,7 +919,6 @@ tan(_A1 __x) _NOEXCEPT {return __builtin_tan((double)__x);}
961919
962920// tanh
963921
964# if !defined(__sun__)
965922inline _LIBCPP_HIDE_FROM_ABI float tanh(float __x) _NOEXCEPT {return __builtin_tanhf(__x);}
966923
967924template <class = int>
......@@ -970,7 +927,6 @@ _LIBCPP_HIDE_FROM_ABI double tanh(double __x) _NOEXCEPT {
970927}
971928
972929inline _LIBCPP_HIDE_FROM_ABI long double tanh(long double __x) _NOEXCEPT {return __builtin_tanhl(__x);}
973# endif
974930
975931template <class _A1>
976932inline _LIBCPP_HIDE_FROM_ABI
lib/libcxx/include/mdspan created+357
......@@ -0,0 +1,357 @@
1// -*-C++ - *-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===---------------------------------------------------------------------===//
9
10/*
11
12// Overall mdspan synopsis
13
14namespace std {
15 // [mdspan.extents], class template extents
16 template<class IndexType, size_t... Extents>
17 class extents;
18
19 // [mdspan.extents.dextents], alias template dextents
20 template<class IndexType, size_t Rank>
21 using dextents = see below;
22
23 // [mdspan.layout], layout mapping
24 struct layout_left;
25 struct layout_right;
26 struct layout_stride; // not implemented yet
27
28 // [mdspan.accessor.default], class template default_accessor
29 template<class ElementType>
30 class default_accessor;
31
32 // [mdspan.mdspan], class template mdspan
33 template<class ElementType, class Extents, class LayoutPolicy = layout_right,
34 class AccessorPolicy = default_accessor<ElementType>>
35 class mdspan; // not implemented yet
36}
37
38// extents synopsis
39
40namespace std {
41 template<class _IndexType, size_t... _Extents>
42 class extents {
43 public:
44 using index_type = _IndexType;
45 using size_type = make_unsigned_t<index_type>;
46 using rank_type = size_t;
47
48 // [mdspan.extents.obs], observers of the multidimensional index space
49 static constexpr rank_type rank() noexcept { return sizeof...(_Extents); }
50 static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); }
51 static constexpr size_t static_extent(rank_type) noexcept;
52 constexpr index_type extent(rank_type) const noexcept;
53
54 // [mdspan.extents.cons], constructors
55 constexpr extents() noexcept = default;
56
57 template<class _OtherIndexType, size_t... _OtherExtents>
58 constexpr explicit(see below)
59 extents(const extents<_OtherIndexType, _OtherExtents...>&) noexcept;
60 template<class... _OtherIndexTypes>
61 constexpr explicit extents(_OtherIndexTypes...) noexcept;
62 template<class _OtherIndexType, size_t N>
63 constexpr explicit(N != rank_dynamic())
64 extents(span<_OtherIndexType, N>) noexcept;
65 template<class _OtherIndexType, size_t N>
66 constexpr explicit(N != rank_dynamic())
67 extents(const array<_OtherIndexType, N>&) noexcept;
68
69 // [mdspan.extents.cmp], comparison operators
70 template<class _OtherIndexType, size_t... _OtherExtents>
71 friend constexpr bool operator==(const extents&,
72 const extents<_OtherIndexType, _OtherExtents...>&) noexcept;
73
74 private:
75 // libcxx note: we do not use an array here, but we need to preserve the as-if behavior
76 // for example the default constructor must zero initialize dynamic extents
77 array<index_type, rank_dynamic()> dynamic-extents{}; // exposition only
78 };
79
80 template<class... Integrals>
81 explicit extents(Integrals...)
82 -> see below;
83}
84
85// layout_left synopsis
86
87namespace std {
88 template<class Extents>
89 class layout_left::mapping {
90 public:
91 using extents_type = Extents;
92 using index_type = typename extents_type::index_type;
93 using size_type = typename extents_type::size_type;
94 using rank_type = typename extents_type::rank_type;
95 using layout_type = layout_left;
96
97 // [mdspan.layout.right.cons], constructors
98 constexpr mapping() noexcept = default;
99 constexpr mapping(const mapping&) noexcept = default;
100 constexpr mapping(const extents_type&) noexcept;
101 template<class OtherExtents>
102 constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
103 mapping(const mapping<OtherExtents>&) noexcept;
104 template<class OtherExtents>
105 constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
106 mapping(const layout_right::mapping<OtherExtents>&) noexcept;
107 template<class OtherExtents>
108 constexpr explicit(extents_type::rank() > 0)
109 mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
110
111 constexpr mapping& operator=(const mapping&) noexcept = default;
112
113 // [mdspan.layout.right.obs], observers
114 constexpr const extents_type& extents() const noexcept { return extents_; }
115
116 constexpr index_type required_span_size() const noexcept;
117
118 template<class... Indices>
119 constexpr index_type operator()(Indices...) const noexcept;
120
121 static constexpr bool is_always_unique() noexcept { return true; }
122 static constexpr bool is_always_exhaustive() noexcept { return true; }
123 static constexpr bool is_always_strided() noexcept { return true; }
124
125 static constexpr bool is_unique() noexcept { return true; }
126 static constexpr bool is_exhaustive() noexcept { return true; }
127 static constexpr bool is_strided() noexcept { return true; }
128
129 constexpr index_type stride(rank_type) const noexcept;
130
131 template<class OtherExtents>
132 friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
133
134 private:
135 extents_type extents_{}; // exposition only
136 };
137}
138
139// layout_right synopsis
140
141namespace std {
142 template<class Extents>
143 class layout_right::mapping {
144 public:
145 using extents_type = Extents;
146 using index_type = typename extents_type::index_type;
147 using size_type = typename extents_type::size_type;
148 using rank_type = typename extents_type::rank_type;
149 using layout_type = layout_right;
150
151 // [mdspan.layout.right.cons], constructors
152 constexpr mapping() noexcept = default;
153 constexpr mapping(const mapping&) noexcept = default;
154 constexpr mapping(const extents_type&) noexcept;
155 template<class OtherExtents>
156 constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
157 mapping(const mapping<OtherExtents>&) noexcept;
158 template<class OtherExtents>
159 constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
160 mapping(const layout_left::mapping<OtherExtents>&) noexcept;
161 template<class OtherExtents>
162 constexpr explicit(extents_type::rank() > 0)
163 mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
164
165 constexpr mapping& operator=(const mapping&) noexcept = default;
166
167 // [mdspan.layout.right.obs], observers
168 constexpr const extents_type& extents() const noexcept { return extents_; }
169
170 constexpr index_type required_span_size() const noexcept;
171
172 template<class... Indices>
173 constexpr index_type operator()(Indices...) const noexcept;
174
175 static constexpr bool is_always_unique() noexcept { return true; }
176 static constexpr bool is_always_exhaustive() noexcept { return true; }
177 static constexpr bool is_always_strided() noexcept { return true; }
178
179 static constexpr bool is_unique() noexcept { return true; }
180 static constexpr bool is_exhaustive() noexcept { return true; }
181 static constexpr bool is_strided() noexcept { return true; }
182
183 constexpr index_type stride(rank_type) const noexcept;
184
185 template<class OtherExtents>
186 friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
187
188 private:
189 extents_type extents_{}; // exposition only
190 };
191}
192
193// default_accessor synopsis
194
195namespace std {
196 template<class ElementType>
197 struct default_accessor {
198 using offset_policy = default_accessor;
199 using element_type = ElementType;
200 using reference = ElementType&;
201 using data_handle_type = ElementType*;
202
203 constexpr default_accessor() noexcept = default;
204 template<class OtherElementType>
205 constexpr default_accessor(default_accessor<OtherElementType>) noexcept;
206 constexpr reference access(data_handle_type p, size_t i) const noexcept;
207 constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
208 };
209}
210
211// mdspan synopsis
212
213namespace std {
214 template<class ElementType, class Extents, class LayoutPolicy = layout_right,
215 class AccessorPolicy = default_accessor<ElementType>>
216 class mdspan {
217 public:
218 using extents_type = Extents;
219 using layout_type = LayoutPolicy;
220 using accessor_type = AccessorPolicy;
221 using mapping_type = typename layout_type::template mapping<extents_type>;
222 using element_type = ElementType;
223 using value_type = remove_cv_t<element_type>;
224 using index_type = typename extents_type::index_type;
225 using size_type = typename extents_type::size_type;
226 using rank_type = typename extents_type::rank_type;
227 using data_handle_type = typename accessor_type::data_handle_type;
228 using reference = typename accessor_type::reference;
229
230 static constexpr rank_type rank() noexcept { return extents_type::rank(); }
231 static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
232 static constexpr size_t static_extent(rank_type r) noexcept
233 { return extents_type::static_extent(r); }
234 constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); }
235
236 // [mdspan.mdspan.cons], constructors
237 constexpr mdspan();
238 constexpr mdspan(const mdspan& rhs) = default;
239 constexpr mdspan(mdspan&& rhs) = default;
240
241 template<class... OtherIndexTypes>
242 constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts);
243 template<class OtherIndexType, size_t N>
244 constexpr explicit(N != rank_dynamic())
245 mdspan(data_handle_type p, span<OtherIndexType, N> exts);
246 template<class OtherIndexType, size_t N>
247 constexpr explicit(N != rank_dynamic())
248 mdspan(data_handle_type p, const array<OtherIndexType, N>& exts);
249 constexpr mdspan(data_handle_type p, const extents_type& ext);
250 constexpr mdspan(data_handle_type p, const mapping_type& m);
251 constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
252
253 template<class OtherElementType, class OtherExtents,
254 class OtherLayoutPolicy, class OtherAccessorPolicy>
255 constexpr explicit(see below)
256 mdspan(const mdspan<OtherElementType, OtherExtents,
257 OtherLayoutPolicy, OtherAccessorPolicy>& other);
258
259 constexpr mdspan& operator=(const mdspan& rhs) = default;
260 constexpr mdspan& operator=(mdspan&& rhs) = default;
261
262 // [mdspan.mdspan.members], members
263 template<class... OtherIndexTypes>
264 constexpr reference operator[](OtherIndexTypes... indices) const;
265 template<class OtherIndexType>
266 constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
267 template<class OtherIndexType>
268 constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
269
270 constexpr size_type size() const noexcept;
271 [[nodiscard]] constexpr bool empty() const noexcept;
272
273 friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
274
275 constexpr const extents_type& extents() const noexcept { return map_.extents(); }
276 constexpr const data_handle_type& data_handle() const noexcept { return ptr_; }
277 constexpr const mapping_type& mapping() const noexcept { return map_; }
278 constexpr const accessor_type& accessor() const noexcept { return acc_; }
279
280 static constexpr bool is_always_unique()
281 { return mapping_type::is_always_unique(); }
282 static constexpr bool is_always_exhaustive()
283 { return mapping_type::is_always_exhaustive(); }
284 static constexpr bool is_always_strided()
285 { return mapping_type::is_always_strided(); }
286
287 constexpr bool is_unique() const
288 { return map_.is_unique(); }
289 constexpr bool is_exhaustive() const
290 { return map_.is_exhaustive(); }
291 constexpr bool is_strided() const
292 { return map_.is_strided(); }
293 constexpr index_type stride(rank_type r) const
294 { return map_.stride(r); }
295
296 private:
297 accessor_type acc_; // exposition only
298 mapping_type map_; // exposition only
299 data_handle_type ptr_; // exposition only
300 };
301
302 template<class CArray>
303 requires(is_array_v<CArray> && rank_v<CArray> == 1)
304 mdspan(CArray&)
305 -> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>;
306
307 template<class Pointer>
308 requires(is_pointer_v<remove_reference_t<Pointer>>)
309 mdspan(Pointer&&)
310 -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>;
311
312 template<class ElementType, class... Integrals>
313 requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)
314 explicit mdspan(ElementType*, Integrals...)
315 -> mdspan<ElementType, dextents<size_t, sizeof...(Integrals)>>;
316
317 template<class ElementType, class OtherIndexType, size_t N>
318 mdspan(ElementType*, span<OtherIndexType, N>)
319 -> mdspan<ElementType, dextents<size_t, N>>;
320
321 template<class ElementType, class OtherIndexType, size_t N>
322 mdspan(ElementType*, const array<OtherIndexType, N>&)
323 -> mdspan<ElementType, dextents<size_t, N>>;
324
325 template<class ElementType, class IndexType, size_t... ExtentsPack>
326 mdspan(ElementType*, const extents<IndexType, ExtentsPack...>&)
327 -> mdspan<ElementType, extents<IndexType, ExtentsPack...>>;
328
329 template<class ElementType, class MappingType>
330 mdspan(ElementType*, const MappingType&)
331 -> mdspan<ElementType, typename MappingType::extents_type,
332 typename MappingType::layout_type>;
333
334 template<class MappingType, class AccessorType>
335 mdspan(const typename AccessorType::data_handle_type&, const MappingType&,
336 const AccessorType&)
337 -> mdspan<typename AccessorType::element_type, typename MappingType::extents_type,
338 typename MappingType::layout_type, AccessorType>;
339}
340*/
341
342#ifndef _LIBCPP_MDSPAN
343#define _LIBCPP_MDSPAN
344
345#include <__config>
346#include <__fwd/mdspan.h>
347#include <__mdspan/default_accessor.h>
348#include <__mdspan/extents.h>
349#include <__mdspan/layout_left.h>
350#include <__mdspan/layout_right.h>
351#include <__mdspan/mdspan.h>
352
353#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
354# pragma GCC system_header
355#endif
356
357#endif // _LIBCPP_MDSPAN
lib/libcxx/include/memory+3-5
......@@ -160,7 +160,7 @@ template <class T, class U>
160160bool operator==(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20
161161
162162template <class T, class U>
163bool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20
163bool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // removed in C++20
164164
165165template <class OutputIterator, class T>
166166class raw_storage_iterator // deprecated in C++17, removed in C++20
......@@ -912,14 +912,12 @@ template<size_t N, class T>
912912# pragma GCC system_header
913913#endif
914914
915#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
916# include <__pstl_memory>
917#endif
918
919915#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
916# include <atomic>
920917# include <concepts>
921918# include <cstddef>
922919# include <cstdint>
920# include <cstdlib>
923921# include <cstring>
924922# include <iosfwd>
925923# include <iterator>
lib/libcxx/include/memory_resource+2-2
......@@ -22,7 +22,7 @@ namespace std::pmr {
2222 bool operator==(const memory_resource& a,
2323 const memory_resource& b) noexcept;
2424 bool operator!=(const memory_resource& a,
25 const memory_resource& b) noexcept;
25 const memory_resource& b) noexcept; // removed in C++20
2626
2727 template <class Tp> class polymorphic_allocator;
2828
......@@ -31,7 +31,7 @@ namespace std::pmr {
3131 const polymorphic_allocator<T2>& b) noexcept;
3232 template <class T1, class T2>
3333 bool operator!=(const polymorphic_allocator<T1>& a,
34 const polymorphic_allocator<T2>& b) noexcept;
34 const polymorphic_allocator<T2>& b) noexcept; // removed in C++20
3535
3636 // Global memory resources
3737 memory_resource* set_default_resource(memory_resource* r) noexcept;
lib/libcxx/include/mutex+32-17
......@@ -187,12 +187,20 @@ template<class Callable, class ...Args>
187187*/
188188
189189#include <__assert> // all public C++ headers provide the assertion handler
190#include <__chrono/steady_clock.h>
191#include <__chrono/time_point.h>
192#include <__condition_variable/condition_variable.h>
190193#include <__config>
191194#include <__memory/shared_ptr.h>
192#include <__mutex_base>
195#include <__mutex/lock_guard.h>
196#include <__mutex/mutex.h>
197#include <__mutex/tag_types.h>
198#include <__mutex/unique_lock.h>
199#include <__thread/id.h>
193200#include <__threading_support>
194201#include <__utility/forward.h>
195202#include <cstdint>
203#include <limits>
196204#ifndef _LIBCPP_CXX03_LANG
197205# include <tuple>
198206#endif
......@@ -210,7 +218,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
210218
211219#ifndef _LIBCPP_HAS_NO_THREADS
212220
213class _LIBCPP_TYPE_VIS recursive_mutex
221class _LIBCPP_EXPORTED_FROM_ABI recursive_mutex
214222{
215223 __libcpp_recursive_mutex_t __m_;
216224
......@@ -231,7 +239,7 @@ public:
231239 native_handle_type native_handle() {return &__m_;}
232240};
233241
234class _LIBCPP_TYPE_VIS timed_mutex
242class _LIBCPP_EXPORTED_FROM_ABI timed_mutex
235243{
236244 mutex __m_;
237245 condition_variable __cv_;
......@@ -262,9 +270,9 @@ timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
262270{
263271 using namespace chrono;
264272 unique_lock<mutex> __lk(__m_);
265 bool no_timeout = _Clock::now() < __t;
266 while (no_timeout && __locked_)
267 no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
273 bool __no_timeout = _Clock::now() < __t;
274 while (__no_timeout && __locked_)
275 __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
268276 if (!__locked_)
269277 {
270278 __locked_ = true;
......@@ -273,7 +281,7 @@ timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
273281 return false;
274282}
275283
276class _LIBCPP_TYPE_VIS recursive_timed_mutex
284class _LIBCPP_EXPORTED_FROM_ABI recursive_timed_mutex
277285{
278286 mutex __m_;
279287 condition_variable __cv_;
......@@ -304,7 +312,7 @@ recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration
304312{
305313 using namespace chrono;
306314 __thread_id __id = this_thread::get_id();
307 unique_lock<mutex> lk(__m_);
315 unique_lock<mutex> __lk(__m_);
308316 if (__id == __id_)
309317 {
310318 if (__count_ == numeric_limits<size_t>::max())
......@@ -312,9 +320,9 @@ recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration
312320 ++__count_;
313321 return true;
314322 }
315 bool no_timeout = _Clock::now() < __t;
316 while (no_timeout && __count_ != 0)
317 no_timeout = __cv_.wait_until(lk, __t) == cv_status::no_timeout;
323 bool __no_timeout = _Clock::now() < __t;
324 while (__no_timeout && __count_ != 0)
325 __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
318326 if (__count_ == 0)
319327 {
320328 __count_ = 1;
......@@ -328,7 +336,7 @@ template <class _L0, class _L1>
328336_LIBCPP_HIDE_FROM_ABI int
329337try_lock(_L0& __l0, _L1& __l1)
330338{
331 unique_lock<_L0> __u0(__l0, try_to_lock);
339 unique_lock<_L0> __u0(__l0, try_to_lock_t());
332340 if (__u0.owns_lock())
333341 {
334342 if (__l1.try_lock())
......@@ -467,7 +475,7 @@ void __unlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
467475
468476#endif // _LIBCPP_CXX03_LANG
469477
470#if _LIBCPP_STD_VER > 14
478#if _LIBCPP_STD_VER >= 17
471479template <class ..._Mutexes>
472480class _LIBCPP_TEMPLATE_VIS scoped_lock;
473481
......@@ -544,7 +552,7 @@ private:
544552};
545553_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(scoped_lock);
546554
547#endif // _LIBCPP_STD_VER > 14
555#endif // _LIBCPP_STD_VER >= 17
548556#endif // !_LIBCPP_HAS_NO_THREADS
549557
550558struct _LIBCPP_TEMPLATE_VIS once_flag;
......@@ -652,8 +660,7 @@ __call_once_proxy(void* __vp)
652660 (*__p)();
653661}
654662
655_LIBCPP_FUNC_VIS void __call_once(volatile once_flag::_State_type&, void*,
656 void (*)(void*));
663_LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile once_flag::_State_type&, void*, void (*)(void*));
657664
658665#ifndef _LIBCPP_CXX03_LANG
659666
......@@ -704,9 +711,17 @@ _LIBCPP_END_NAMESPACE_STD
704711_LIBCPP_POP_MACROS
705712
706713#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
714# include <atomic>
707715# include <concepts>
708# include <functional>
716# include <cstdlib>
717# include <cstring>
718# include <ctime>
719# include <initializer_list>
720# include <new>
721# include <stdexcept>
722# include <system_error>
709723# include <type_traits>
724# include <typeinfo>
710725#endif
711726
712727#endif // _LIBCPP_MUTEX
lib/libcxx/include/new+18-55
......@@ -89,12 +89,14 @@ void operator delete[](void* ptr, void*) noexcept;
8989#include <__assert> // all public C++ headers provide the assertion handler
9090#include <__availability>
9191#include <__config>
92#include <__exception/exception.h>
93#include <__type_traits/alignment_of.h>
9294#include <__type_traits/is_function.h>
9395#include <__type_traits/is_same.h>
9496#include <__type_traits/remove_cv.h>
97#include <__verbose_abort>
9598#include <cstddef>
9699#include <cstdlib>
97#include <exception>
98100#include <version>
99101
100102#if defined(_LIBCPP_ABI_VCRUNTIME)
......@@ -123,10 +125,10 @@ namespace std // purposefully not using versioning namespace
123125{
124126
125127#if !defined(_LIBCPP_ABI_VCRUNTIME)
126struct _LIBCPP_TYPE_VIS nothrow_t { explicit nothrow_t() = default; };
127extern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
128struct _LIBCPP_EXPORTED_FROM_ABI nothrow_t { explicit nothrow_t() = default; };
129extern _LIBCPP_EXPORTED_FROM_ABI const nothrow_t nothrow;
128130
129class _LIBCPP_EXCEPTION_ABI bad_alloc
131class _LIBCPP_EXPORTED_FROM_ABI bad_alloc
130132 : public exception
131133{
132134public:
......@@ -135,7 +137,7 @@ public:
135137 const char* what() const _NOEXCEPT override;
136138};
137139
138class _LIBCPP_EXCEPTION_ABI bad_array_new_length
140class _LIBCPP_EXPORTED_FROM_ABI bad_array_new_length
139141 : public bad_alloc
140142{
141143public:
......@@ -145,8 +147,8 @@ public:
145147};
146148
147149typedef void (*new_handler)();
148_LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT;
149_LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT;
150_LIBCPP_EXPORTED_FROM_ABI new_handler set_new_handler(new_handler) _NOEXCEPT;
151_LIBCPP_EXPORTED_FROM_ABI new_handler get_new_handler() _NOEXCEPT;
150152
151153#elif defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 // !_LIBCPP_ABI_VCRUNTIME
152154
......@@ -168,15 +170,15 @@ public:
168170};
169171#endif // defined(_LIBCPP_ABI_VCRUNTIME) && defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0
170172
171_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec
173_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_bad_alloc(); // not in C++ spec
172174
173175_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
174176void __throw_bad_array_new_length()
175177{
176#ifndef _LIBCPP_NO_EXCEPTIONS
178#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
177179 throw bad_array_new_length();
178180#else
179 _VSTD::abort();
181 _LIBCPP_VERBOSE_ABORT("bad_array_new_length was thrown in -fno-exceptions mode");
180182#endif
181183}
182184
......@@ -189,14 +191,14 @@ enum align_val_t { __zero = 0, __max = (size_t)-1 };
189191#endif
190192#endif
191193
192#if _LIBCPP_STD_VER > 17
194#if _LIBCPP_STD_VER >= 20
193195// Enable the declaration even if the compiler doesn't support the language
194196// feature.
195197struct destroying_delete_t {
196198 explicit destroying_delete_t() = default;
197199};
198200inline constexpr destroying_delete_t destroying_delete{};
199#endif // _LIBCPP_STD_VER > 17
201#endif // _LIBCPP_STD_VER >= 20
200202
201203} // namespace std
202204
......@@ -332,46 +334,6 @@ inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, s
332334#endif
333335}
334336
335#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
336// Low-level helpers to call the aligned allocation and deallocation functions
337// on the target platform. This is used to implement libc++'s own memory
338// allocation routines -- if you need to allocate memory inside the library,
339// chances are that you want to use `__libcpp_allocate` instead.
340//
341// Returns the allocated memory, or `nullptr` on failure.
342inline _LIBCPP_INLINE_VISIBILITY void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
343# if defined(_LIBCPP_MSVCRT_LIKE)
344 return ::_aligned_malloc(__size, __alignment);
345# elif _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC)
346 // aligned_alloc() requires that __size is a multiple of __alignment,
347 // but for C++ [new.delete.general], only states "if the value of an
348 // alignment argument passed to any of these functions is not a valid
349 // alignment value, the behavior is undefined".
350 // To handle calls such as ::operator new(1, std::align_val_t(128)), we
351 // round __size up to the next multiple of __alignment.
352 size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
353 // Rounding up could have wrapped around to zero, so we have to add another
354 // max() ternary to the actual call site to avoid succeeded in that case.
355 return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
356# else
357 void* __result = nullptr;
358 (void)::posix_memalign(&__result, __alignment, __size);
359 // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
360 return __result;
361# endif
362}
363
364inline _LIBCPP_INLINE_VISIBILITY
365void __libcpp_aligned_free(void* __ptr) {
366#if defined(_LIBCPP_MSVCRT_LIKE)
367 ::_aligned_free(__ptr);
368#else
369 ::free(__ptr);
370#endif
371}
372#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION
373
374
375337template <class _Tp>
376338_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
377339_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
......@@ -381,7 +343,7 @@ _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
381343 return __builtin_launder(__p);
382344}
383345
384#if _LIBCPP_STD_VER > 14
346#if _LIBCPP_STD_VER >= 17
385347template <class _Tp>
386348_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
387349constexpr _Tp* launder(_Tp* __p) noexcept
......@@ -390,7 +352,7 @@ constexpr _Tp* launder(_Tp* __p) noexcept
390352}
391353#endif
392354
393#if _LIBCPP_STD_VER > 14
355#if _LIBCPP_STD_VER >= 17
394356
395357#if defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
396358
......@@ -399,11 +361,12 @@ inline constexpr size_t hardware_constructive_interference_size = __GCC_CONSTRUC
399361
400362#endif // defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
401363
402#endif // _LIBCPP_STD_VER > 14
364#endif // _LIBCPP_STD_VER >= 17
403365
404366_LIBCPP_END_NAMESPACE_STD
405367
406368#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
369# include <exception>
407370# include <type_traits>
408371#endif
409372
lib/libcxx/include/numbers+2-2
......@@ -63,7 +63,7 @@ namespace std::numbers {
6363#include <__config>
6464#include <version>
6565
66#if _LIBCPP_STD_VER > 17
66#if _LIBCPP_STD_VER >= 20
6767
6868#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
6969# pragma GCC system_header
......@@ -128,7 +128,7 @@ inline constexpr double phi = phi_v<double>;
128128
129129_LIBCPP_END_NAMESPACE_STD
130130
131#endif // _LIBCPP_STD_VER > 17
131#endif // _LIBCPP_STD_VER >= 20
132132
133133#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
134134# include <concepts>
lib/libcxx/include/numeric+2-4
......@@ -158,6 +158,8 @@ template<class T>
158158#include <__numeric/iota.h>
159159#include <__numeric/midpoint.h>
160160#include <__numeric/partial_sum.h>
161#include <__numeric/pstl_reduce.h>
162#include <__numeric/pstl_transform_reduce.h>
161163#include <__numeric/reduce.h>
162164#include <__numeric/transform_exclusive_scan.h>
163165#include <__numeric/transform_inclusive_scan.h>
......@@ -167,10 +169,6 @@ template<class T>
167169# pragma GCC system_header
168170#endif
169171
170#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
171# include <__pstl_numeric>
172#endif
173
174172#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
175173# include <concepts>
176174# include <functional>
lib/libcxx/include/optional+208-107
......@@ -16,107 +16,126 @@
1616// C++1z
1717
1818namespace std {
19 // 23.6.3, optional for object types
20 template <class T> class optional;
19 // [optional.optional], class template optional
20 template <class T>
21 class optional;
2122
22 // 23.6.4, no-value state indicator
23 template<class T>
24 concept is-derived-from-optional = requires(const T& t) { // exposition only
25 []<class U>(const optional<U>&){ }(t);
26 };
27
28 // [optional.nullopt], no-value state indicator
2329 struct nullopt_t{see below };
2430 inline constexpr nullopt_t nullopt(unspecified );
2531
26 // 23.6.5, class bad_optional_access
32 // [optional.bad.access], class bad_optional_access
2733 class bad_optional_access;
2834
29 // 23.6.6, relational operators
35 // [optional.relops], relational operators
3036 template <class T, class U>
31 constexpr bool operator==(const optional<T>&, const optional<U>&);
37 constexpr bool operator==(const optional<T>&, const optional<U>&);
3238 template <class T, class U>
33 constexpr bool operator!=(const optional<T>&, const optional<U>&);
39 constexpr bool operator!=(const optional<T>&, const optional<U>&);
3440 template <class T, class U>
35 constexpr bool operator<(const optional<T>&, const optional<U>&);
41 constexpr bool operator<(const optional<T>&, const optional<U>&);
3642 template <class T, class U>
37 constexpr bool operator>(const optional<T>&, const optional<U>&);
43 constexpr bool operator>(const optional<T>&, const optional<U>&);
3844 template <class T, class U>
39 constexpr bool operator<=(const optional<T>&, const optional<U>&);
45 constexpr bool operator<=(const optional<T>&, const optional<U>&);
4046 template <class T, class U>
41 constexpr bool operator>=(const optional<T>&, const optional<U>&);
42
43 // 23.6.7 comparison with nullopt
44 template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
45 template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
46 template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
47 template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
48 template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
49 template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
50 template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
51 template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
52 template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
53 template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
54 template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
55 template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
56
57 // 23.6.8, comparison with T
58 template <class T, class U> constexpr bool operator==(const optional<T>&, const U&);
59 template <class T, class U> constexpr bool operator==(const T&, const optional<U>&);
60 template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
61 template <class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
62 template <class T, class U> constexpr bool operator<(const optional<T>&, const U&);
63 template <class T, class U> constexpr bool operator<(const T&, const optional<U>&);
64 template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
65 template <class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
66 template <class T, class U> constexpr bool operator>(const optional<T>&, const U&);
67 template <class T, class U> constexpr bool operator>(const T&, const optional<U>&);
68 template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
69 template <class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
70
71 // 23.6.9, specialized algorithms
72 template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
73 template <class T> constexpr optional<see below > make_optional(T&&);
74 template <class T, class... Args>
47 constexpr bool operator>=(const optional<T>&, const optional<U>&);
48 template<class T, three_way_comparable_with<T> U>
49 constexpr compare_three_way_result_t<T, U>
50 operator<=>(const optional<T>&, const optional<U>&); // since C++20
51
52 // [optional.nullops], comparison with nullopt
53 template<class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
54 template<class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; // until C++17
55 template<class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; // until C++17
56 template<class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; // until C++17
57 template<class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; // until C++17
58 template<class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; // until C++17
59 template<class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; // until C++17
60 template<class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; // until C++17
61 template<class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; // until C++17
62 template<class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; // until C++17
63 template<class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; // until C++17
64 template<class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; // until C++17
65 template<class T>
66 constexpr strong_ordering operator<=>(const optional<T>&, nullopt_t) noexcept; // since C++20
67
68 // [optional.comp.with.t], comparison with T
69 template<class T, class U> constexpr bool operator==(const optional<T>&, const U&);
70 template<class T, class U> constexpr bool operator==(const T&, const optional<U>&);
71 template<class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
72 template<class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
73 template<class T, class U> constexpr bool operator<(const optional<T>&, const U&);
74 template<class T, class U> constexpr bool operator<(const T&, const optional<U>&);
75 template<class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
76 template<class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
77 template<class T, class U> constexpr bool operator>(const optional<T>&, const U&);
78 template<class T, class U> constexpr bool operator>(const T&, const optional<U>&);
79 template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
80 template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
81 template<class T, class U>
82 requires (!is-derived-from-optional<U>) && three_way_comparable_with<T, U>
83 constexpr compare_three_way_result_t<T, U>
84 operator<=>(const optional<T>&, const U&); // since C++20
85
86 // [optional.specalg], specialized algorithms
87 template<class T>
88 void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
89
90 template<class T>
91 constexpr optional<see below > make_optional(T&&);
92 template<class T, class... Args>
7593 constexpr optional<T> make_optional(Args&&... args);
76 template <class T, class U, class... Args>
94 template<class T, class U, class... Args>
7795 constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
7896
79 // 23.6.10, hash support
80 template <class T> struct hash;
81 template <class T> struct hash<optional<T>>;
97 // [optional.hash], hash support
98 template<class T> struct hash;
99 template<class T> struct hash<optional<T>>;
82100
83 template <class T> class optional {
101 template<class T>
102 class optional {
84103 public:
85104 using value_type = T;
86105
87 // 23.6.3.1, constructors
106 // [optional.ctor], constructors
88107 constexpr optional() noexcept;
89108 constexpr optional(nullopt_t) noexcept;
90109 constexpr optional(const optional &);
91110 constexpr optional(optional &&) noexcept(see below);
92 template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
93 template <class U, class... Args>
111 template<class... Args>
112 constexpr explicit optional(in_place_t, Args &&...);
113 template<class U, class... Args>
94114 constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
95 template <class U = T>
115 template<class U = T>
96116 constexpr explicit(see-below) optional(U &&);
97 template <class U>
98 explicit(see-below) optional(const optional<U> &); // constexpr in C++20
99 template <class U>
100 explicit(see-below) optional(optional<U> &&); // constexpr in C++20
117 template<class U>
118 explicit(see-below) optional(const optional<U> &); // constexpr in C++20
119 template<class U>
120 explicit(see-below) optional(optional<U> &&); // constexpr in C++20
101121
102 // 23.6.3.2, destructor
122 // [optional.dtor], destructor
103123 ~optional(); // constexpr in C++20
104124
105 // 23.6.3.3, assignment
106 optional &operator=(nullopt_t) noexcept; // constexpr in C++20
125 // [optional.assign], assignment
126 optional &operator=(nullopt_t) noexcept; // constexpr in C++20
107127 constexpr optional &operator=(const optional &);
108128 constexpr optional &operator=(optional &&) noexcept(see below);
109 template <class U = T> optional &operator=(U &&); // constexpr in C++20
110 template <class U> optional &operator=(const optional<U> &); // constexpr in C++20
111 template <class U> optional &operator=(optional<U> &&); // constexpr in C++20
112 template <class... Args> T& emplace(Args &&...); // constexpr in C++20
113 template <class U, class... Args>
114 T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20
115
116 // 23.6.3.4, swap
129 template<class U = T> optional &operator=(U &&); // constexpr in C++20
130 template<class U> optional &operator=(const optional<U> &); // constexpr in C++20
131 template<class U> optional &operator=(optional<U> &&); // constexpr in C++20
132 template<class... Args> T& emplace(Args &&...); // constexpr in C++20
133 template<class U, class... Args> T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20
134
135 // [optional.swap], swap
117136 void swap(optional &) noexcept(see below ); // constexpr in C++20
118137
119 // 23.6.3.5, observers
138 // [optional.observe], observers
120139 constexpr T const *operator->() const;
121140 constexpr T *operator->();
122141 constexpr T const &operator*() const &;
......@@ -129,8 +148,8 @@ namespace std {
129148 constexpr T &value() &;
130149 constexpr T &&value() &&;
131150 constexpr const T &&value() const &&;
132 template <class U> constexpr T value_or(U &&) const &;
133 template <class U> constexpr T value_or(U &&) &&;
151 template<class U> constexpr T value_or(U &&) const &;
152 template<class U> constexpr T value_or(U &&) &&;
134153
135154 // [optional.monadic], monadic operations
136155 template<class F> constexpr auto and_then(F&& f) &; // since C++23
......@@ -144,15 +163,15 @@ namespace std {
144163 template<class F> constexpr optional or_else(F&& f) &&; // since C++23
145164 template<class F> constexpr optional or_else(F&& f) const&; // since C++23
146165
147 // 23.6.3.6, modifiers
148 void reset() noexcept; // constexpr in C++20
166 // [optional.mod], modifiers
167 void reset() noexcept; // constexpr in C++20
149168
150169 private:
151 T *val; // exposition only
170 T *val; // exposition only
152171 };
153172
154template<class T>
155 optional(T) -> optional<T>;
173 template<class T>
174 optional(T) -> optional<T>;
156175
157176} // namespace std
158177
......@@ -160,21 +179,55 @@ template<class T>
160179
161180#include <__assert> // all public C++ headers provide the assertion handler
162181#include <__availability>
182#include <__compare/compare_three_way_result.h>
183#include <__compare/three_way_comparable.h>
163184#include <__concepts/invocable.h>
164185#include <__config>
165186#include <__functional/hash.h>
166187#include <__functional/invoke.h>
188#include <__functional/reference_wrapper.h>
167189#include <__functional/unary_function.h>
190#include <__memory/addressof.h>
168191#include <__memory/construct_at.h>
169#include <__tuple_dir/sfinae_helpers.h>
192#include <__tuple/sfinae_helpers.h>
193#include <__type_traits/add_pointer.h>
194#include <__type_traits/conditional.h>
195#include <__type_traits/conjunction.h>
196#include <__type_traits/decay.h>
197#include <__type_traits/disjunction.h>
198#include <__type_traits/is_array.h>
199#include <__type_traits/is_assignable.h>
200#include <__type_traits/is_constructible.h>
201#include <__type_traits/is_convertible.h>
202#include <__type_traits/is_copy_assignable.h>
203#include <__type_traits/is_copy_constructible.h>
204#include <__type_traits/is_destructible.h>
205#include <__type_traits/is_move_assignable.h>
206#include <__type_traits/is_move_constructible.h>
207#include <__type_traits/is_nothrow_move_assignable.h>
208#include <__type_traits/is_nothrow_move_constructible.h>
209#include <__type_traits/is_object.h>
210#include <__type_traits/is_reference.h>
211#include <__type_traits/is_scalar.h>
212#include <__type_traits/is_swappable.h>
213#include <__type_traits/is_trivially_copy_assignable.h>
214#include <__type_traits/is_trivially_copy_constructible.h>
215#include <__type_traits/is_trivially_destructible.h>
216#include <__type_traits/is_trivially_move_assignable.h>
217#include <__type_traits/is_trivially_move_constructible.h>
218#include <__type_traits/negation.h>
219#include <__type_traits/remove_const.h>
220#include <__type_traits/remove_cvref.h>
221#include <__type_traits/remove_reference.h>
222#include <__utility/declval.h>
170223#include <__utility/forward.h>
171224#include <__utility/in_place.h>
172225#include <__utility/move.h>
173226#include <__utility/swap.h>
227#include <__verbose_abort>
174228#include <initializer_list>
175229#include <new>
176230#include <stdexcept>
177#include <type_traits>
178231#include <version>
179232
180233// standard-mandated includes
......@@ -186,10 +239,13 @@ template<class T>
186239# pragma GCC system_header
187240#endif
188241
242_LIBCPP_PUSH_MACROS
243#include <__undef_macros>
244
189245namespace std // purposefully not using versioning namespace
190246{
191247
192class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
248class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
193249 : public exception
194250{
195251public:
......@@ -200,7 +256,7 @@ public:
200256
201257} // namespace std
202258
203#if _LIBCPP_STD_VER > 14
259#if _LIBCPP_STD_VER >= 17
204260
205261_LIBCPP_BEGIN_NAMESPACE_STD
206262
......@@ -208,16 +264,16 @@ _LIBCPP_NORETURN
208264inline _LIBCPP_INLINE_VISIBILITY
209265_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
210266void __throw_bad_optional_access() {
211#ifndef _LIBCPP_NO_EXCEPTIONS
267#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
212268 throw bad_optional_access();
213269#else
214 _VSTD::abort();
270 _LIBCPP_VERBOSE_ABORT("bad_optional_access was thrown in -fno-exceptions mode");
215271#endif
216272}
217273
218274struct nullopt_t
219275{
220 struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
276 struct __secret_tag { explicit __secret_tag() = default; };
221277 _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
222278};
223279
......@@ -259,7 +315,7 @@ struct __optional_destruct_base<_Tp, false>
259315 : __val_(_VSTD::forward<_Args>(__args)...),
260316 __engaged_(true) {}
261317
262#if _LIBCPP_STD_VER > 20
318#if _LIBCPP_STD_VER >= 23
263319 template <class _Fp, class... _Args>
264320 _LIBCPP_HIDE_FROM_ABI
265321 constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
......@@ -301,7 +357,7 @@ struct __optional_destruct_base<_Tp, true>
301357 : __val_(_VSTD::forward<_Args>(__args)...),
302358 __engaged_(true) {}
303359
304#if _LIBCPP_STD_VER > 20
360#if _LIBCPP_STD_VER >= 23
305361 template <class _Fp, class... _Args>
306362 _LIBCPP_HIDE_FROM_ABI
307363 constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
......@@ -356,8 +412,8 @@ struct __optional_storage_base : __optional_destruct_base<_Tp>
356412 _LIBCPP_INLINE_VISIBILITY
357413 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args)
358414 {
359 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
360#if _LIBCPP_STD_VER > 17
415 _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
416#if _LIBCPP_STD_VER >= 20
361417 _VSTD::construct_at(_VSTD::addressof(this->__val_), _VSTD::forward<_Args>(__args)...);
362418#else
363419 ::new ((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
......@@ -403,7 +459,7 @@ struct __optional_storage_base<_Tp, true>
403459 __raw_type* __value_;
404460
405461 template <class _Up>
406 static constexpr bool __can_bind_reference() {
462 static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
407463 using _RawUp = __libcpp_remove_reference_t<_Up>;
408464 using _UpPtr = _RawUp*;
409465 using _RawTp = __libcpp_remove_reference_t<_Tp>;
......@@ -451,7 +507,7 @@ struct __optional_storage_base<_Tp, true>
451507 _LIBCPP_INLINE_VISIBILITY
452508 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val)
453509 {
454 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
510 _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
455511 static_assert(__can_bind_reference<_UArg>(),
456512 "Attempted to construct a reference element in tuple from a "
457513 "possible temporary");
......@@ -623,12 +679,20 @@ using __optional_sfinae_assign_base_t = __sfinae_assign_base<
623679
624680template<class _Tp>
625681class optional;
682
683#if _LIBCPP_STD_VER >= 20
684
685template <class _Tp>
686concept __is_derived_from_optional = requires(const _Tp& __t) { []<class _Up>(const optional<_Up>&) {}(__t); };
687
688# endif // _LIBCPP_STD_VER >= 20
689
626690template <class _Tp>
627691struct __is_std_optional : false_type {};
628692template <class _Tp> struct __is_std_optional<optional<_Tp>> : true_type {};
629693
630694template <class _Tp>
631class optional
695class _LIBCPP_DECLSPEC_EMPTY_BASES optional
632696 : private __optional_move_assign_base<_Tp>
633697 , private __optional_sfinae_ctor_base_t<_Tp>
634698 , private __optional_sfinae_assign_base_t<_Tp>
......@@ -653,13 +717,13 @@ private:
653717 // LWG2756: conditionally explicit conversion from _Up
654718 struct _CheckOptionalArgsConstructor {
655719 template <class _Up>
656 static constexpr bool __enable_implicit() {
720 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
657721 return is_constructible_v<_Tp, _Up&&> &&
658722 is_convertible_v<_Up&&, _Tp>;
659723 }
660724
661725 template <class _Up>
662 static constexpr bool __enable_explicit() {
726 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
663727 return is_constructible_v<_Tp, _Up&&> &&
664728 !is_convertible_v<_Up&&, _Tp>;
665729 }
......@@ -692,17 +756,17 @@ private:
692756 is_assignable<_Tp&, _Opt const&&>
693757 >;
694758 template <class _Up, class _QUp = _QualUp>
695 static constexpr bool __enable_implicit() {
759 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
696760 return is_convertible<_QUp, _Tp>::value &&
697761 !__check_constructible_from_opt<_Up>::value;
698762 }
699763 template <class _Up, class _QUp = _QualUp>
700 static constexpr bool __enable_explicit() {
764 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
701765 return !is_convertible<_QUp, _Tp>::value &&
702766 !__check_constructible_from_opt<_Up>::value;
703767 }
704768 template <class _Up, class _QUp = _QualUp>
705 static constexpr bool __enable_assign() {
769 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_assign() {
706770 // Construction and assignability of _QUp to _Tp has already been
707771 // checked.
708772 return !__check_constructible_from_opt<_Up>::value &&
......@@ -805,7 +869,7 @@ public:
805869 this->__construct_from(_VSTD::move(__v));
806870 }
807871
808#if _LIBCPP_STD_VER > 20
872#if _LIBCPP_STD_VER >= 23
809873 template<class _Fp, class... _Args>
810874 _LIBCPP_HIDE_FROM_ABI
811875 constexpr explicit optional(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
......@@ -820,8 +884,8 @@ public:
820884 return *this;
821885 }
822886
823 constexpr optional& operator=(const optional&) = default;
824 constexpr optional& operator=(optional&&) = default;
887 _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(const optional&) = default;
888 _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default;
825889
826890 // LWG2756
827891 template <class _Up = value_type,
......@@ -932,7 +996,7 @@ public:
932996 add_pointer_t<value_type const>
933997 operator->() const
934998 {
935 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
999 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
9361000 return _VSTD::addressof(this->__get());
9371001 }
9381002
......@@ -941,7 +1005,7 @@ public:
9411005 add_pointer_t<value_type>
9421006 operator->()
9431007 {
944 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
1008 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
9451009 return _VSTD::addressof(this->__get());
9461010 }
9471011
......@@ -950,7 +1014,7 @@ public:
9501014 const value_type&
9511015 operator*() const& noexcept
9521016 {
953 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
1017 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
9541018 return this->__get();
9551019 }
9561020
......@@ -959,7 +1023,7 @@ public:
9591023 value_type&
9601024 operator*() & noexcept
9611025 {
962 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
1026 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
9631027 return this->__get();
9641028 }
9651029
......@@ -968,7 +1032,7 @@ public:
9681032 value_type&&
9691033 operator*() && noexcept
9701034 {
971 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
1035 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
9721036 return _VSTD::move(this->__get());
9731037 }
9741038
......@@ -977,7 +1041,7 @@ public:
9771041 const value_type&&
9781042 operator*() const&& noexcept
9791043 {
980 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
1044 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
9811045 return _VSTD::move(this->__get());
9821046 }
9831047
......@@ -1047,7 +1111,7 @@ public:
10471111 static_cast<value_type>(_VSTD::forward<_Up>(__v));
10481112 }
10491113
1050#if _LIBCPP_STD_VER > 20
1114#if _LIBCPP_STD_VER >= 23
10511115 template<class _Func>
10521116 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
10531117 constexpr auto and_then(_Func&& __f) & {
......@@ -1171,7 +1235,7 @@ public:
11711235 return _VSTD::move(*this);
11721236 return _VSTD::forward<_Func>(__f)();
11731237 }
1174#endif // _LIBCPP_STD_VER > 20
1238#endif // _LIBCPP_STD_VER >= 23
11751239
11761240 using __base::reset;
11771241};
......@@ -1278,6 +1342,18 @@ operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
12781342 return *__x >= *__y;
12791343}
12801344
1345#if _LIBCPP_STD_VER >= 20
1346
1347template <class _Tp, three_way_comparable_with<_Tp> _Up>
1348_LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
1349operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) {
1350 if (__x && __y)
1351 return *__x <=> *__y;
1352 return __x.has_value() <=> __y.has_value();
1353}
1354
1355#endif // _LIBCPP_STD_VER >= 20
1356
12811357// Comparisons with nullopt
12821358template <class _Tp>
12831359_LIBCPP_INLINE_VISIBILITY constexpr
......@@ -1287,6 +1363,8 @@ operator==(const optional<_Tp>& __x, nullopt_t) noexcept
12871363 return !static_cast<bool>(__x);
12881364}
12891365
1366#if _LIBCPP_STD_VER <= 17
1367
12901368template <class _Tp>
12911369_LIBCPP_INLINE_VISIBILITY constexpr
12921370bool
......@@ -1375,6 +1453,15 @@ operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
13751453 return !static_cast<bool>(__x);
13761454}
13771455
1456#else // _LIBCPP_STD_VER <= 17
1457
1458template <class _Tp>
1459_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept {
1460 return __x.has_value() <=> false;
1461}
1462
1463#endif // _LIBCPP_STD_VER <= 17
1464
13781465// Comparisons with T
13791466template <class _Tp, class _Up>
13801467_LIBCPP_INLINE_VISIBILITY constexpr
......@@ -1520,6 +1607,17 @@ operator>=(const _Tp& __v, const optional<_Up>& __x)
15201607 return static_cast<bool>(__x) ? __v >= *__x : true;
15211608}
15221609
1610#if _LIBCPP_STD_VER >= 20
1611
1612template <class _Tp, class _Up>
1613 requires(!__is_derived_from_optional<_Up>) && three_way_comparable_with<_Tp, _Up>
1614_LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
1615operator<=>(const optional<_Tp>& __x, const _Up& __v) {
1616 return __x.has_value() ? *__x <=> __v : strong_ordering::less;
1617}
1618
1619#endif // _LIBCPP_STD_VER >= 20
1620
15231621
15241622template <class _Tp>
15251623inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -1572,7 +1670,9 @@ struct _LIBCPP_TEMPLATE_VIS hash<
15721670
15731671_LIBCPP_END_NAMESPACE_STD
15741672
1575#endif // _LIBCPP_STD_VER > 14
1673#endif // _LIBCPP_STD_VER >= 17
1674
1675_LIBCPP_POP_MACROS
15761676
15771677#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
15781678# include <atomic>
......@@ -1583,6 +1683,7 @@ _LIBCPP_END_NAMESPACE_STD
15831683# include <memory>
15841684# include <ratio>
15851685# include <tuple>
1686# include <type_traits>
15861687# include <typeinfo>
15871688# include <utility>
15881689# include <variant>
lib/libcxx/include/ostream+102-92
......@@ -165,8 +165,16 @@ basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, cons
165165
166166#include <__assert> // all public C++ headers provide the assertion handler
167167#include <__config>
168#include <__exception/operations.h>
169#include <__fwd/ostream.h>
168170#include <__memory/shared_ptr.h>
169171#include <__memory/unique_ptr.h>
172#include <__system_error/error_code.h>
173#include <__type_traits/conjunction.h>
174#include <__type_traits/enable_if.h>
175#include <__type_traits/is_base_of.h>
176#include <__type_traits/void_t.h>
177#include <__utility/declval.h>
170178#include <bitset>
171179#include <ios>
172180#include <locale>
......@@ -244,7 +252,7 @@ public:
244252 basic_ostream& operator<<(long double __f);
245253 basic_ostream& operator<<(const void* __p);
246254
247#if _LIBCPP_STD_VER > 20
255#if _LIBCPP_STD_VER >= 23
248256 _LIBCPP_HIDE_FROM_ABI
249257 basic_ostream& operator<<(const volatile void* __p) {
250258 return operator<<(const_cast<const void*>(__p));
......@@ -253,7 +261,7 @@ public:
253261
254262 basic_ostream& operator<<(basic_streambuf<char_type, traits_type>* __sb);
255263
256#if _LIBCPP_STD_VER > 14
264#if _LIBCPP_STD_VER >= 17
257265// LWG 2221 - nullptr. This is not backported to older standards modes.
258266// See https://reviews.llvm.org/D127033 for more info on the rationale.
259267 _LIBCPP_INLINE_VISIBILITY
......@@ -314,18 +322,18 @@ basic_ostream<_CharT, _Traits>::sentry::~sentry()
314322 if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf)
315323 && !uncaught_exception())
316324 {
317#ifndef _LIBCPP_NO_EXCEPTIONS
325#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
318326 try
319327 {
320#endif // _LIBCPP_NO_EXCEPTIONS
328#endif // _LIBCPP_HAS_NO_EXCEPTIONS
321329 if (__os_.rdbuf()->pubsync() == -1)
322330 __os_.setstate(ios_base::badbit);
323#ifndef _LIBCPP_NO_EXCEPTIONS
331#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
324332 }
325333 catch (...)
326334 {
327335 }
328#endif // _LIBCPP_NO_EXCEPTIONS
336#endif // _LIBCPP_HAS_NO_EXCEPTIONS
329337 }
330338}
331339
......@@ -352,19 +360,19 @@ template <class _CharT, class _Traits>
352360basic_ostream<_CharT, _Traits>&
353361basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_type>* __sb)
354362{
355#ifndef _LIBCPP_NO_EXCEPTIONS
363#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
356364 try
357365 {
358#endif // _LIBCPP_NO_EXCEPTIONS
366#endif // _LIBCPP_HAS_NO_EXCEPTIONS
359367 sentry __s(*this);
360368 if (__s)
361369 {
362370 if (__sb)
363371 {
364#ifndef _LIBCPP_NO_EXCEPTIONS
372#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
365373 try
366374 {
367#endif // _LIBCPP_NO_EXCEPTIONS
375#endif // _LIBCPP_HAS_NO_EXCEPTIONS
368376 typedef istreambuf_iterator<_CharT, _Traits> _Ip;
369377 typedef ostreambuf_iterator<_CharT, _Traits> _Op;
370378 _Ip __i(__sb);
......@@ -379,24 +387,24 @@ basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_typ
379387 }
380388 if (__c == 0)
381389 this->setstate(ios_base::failbit);
382#ifndef _LIBCPP_NO_EXCEPTIONS
390#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
383391 }
384392 catch (...)
385393 {
386394 this->__set_failbit_and_consider_rethrow();
387395 }
388#endif // _LIBCPP_NO_EXCEPTIONS
396#endif // _LIBCPP_HAS_NO_EXCEPTIONS
389397 }
390398 else
391399 this->setstate(ios_base::badbit);
392400 }
393#ifndef _LIBCPP_NO_EXCEPTIONS
401#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
394402 }
395403 catch (...)
396404 {
397405 this->__set_badbit_and_consider_rethrow();
398406 }
399#endif // _LIBCPP_NO_EXCEPTIONS
407#endif // _LIBCPP_HAS_NO_EXCEPTIONS
400408 return *this;
401409}
402410
......@@ -404,10 +412,10 @@ template <class _CharT, class _Traits>
404412basic_ostream<_CharT, _Traits>&
405413basic_ostream<_CharT, _Traits>::operator<<(bool __n)
406414{
407#ifndef _LIBCPP_NO_EXCEPTIONS
415#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
408416 try
409417 {
410#endif // _LIBCPP_NO_EXCEPTIONS
418#endif // _LIBCPP_HAS_NO_EXCEPTIONS
411419 sentry __s(*this);
412420 if (__s)
413421 {
......@@ -416,13 +424,13 @@ basic_ostream<_CharT, _Traits>::operator<<(bool __n)
416424 if (__f.put(*this, *this, this->fill(), __n).failed())
417425 this->setstate(ios_base::badbit | ios_base::failbit);
418426 }
419#ifndef _LIBCPP_NO_EXCEPTIONS
427#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
420428 }
421429 catch (...)
422430 {
423431 this->__set_badbit_and_consider_rethrow();
424432 }
425#endif // _LIBCPP_NO_EXCEPTIONS
433#endif // _LIBCPP_HAS_NO_EXCEPTIONS
426434 return *this;
427435}
428436
......@@ -430,10 +438,10 @@ template <class _CharT, class _Traits>
430438basic_ostream<_CharT, _Traits>&
431439basic_ostream<_CharT, _Traits>::operator<<(short __n)
432440{
433#ifndef _LIBCPP_NO_EXCEPTIONS
441#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
434442 try
435443 {
436#endif // _LIBCPP_NO_EXCEPTIONS
444#endif // _LIBCPP_HAS_NO_EXCEPTIONS
437445 sentry __s(*this);
438446 if (__s)
439447 {
......@@ -446,13 +454,13 @@ basic_ostream<_CharT, _Traits>::operator<<(short __n)
446454 static_cast<long>(__n)).failed())
447455 this->setstate(ios_base::badbit | ios_base::failbit);
448456 }
449#ifndef _LIBCPP_NO_EXCEPTIONS
457#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
450458 }
451459 catch (...)
452460 {
453461 this->__set_badbit_and_consider_rethrow();
454462 }
455#endif // _LIBCPP_NO_EXCEPTIONS
463#endif // _LIBCPP_HAS_NO_EXCEPTIONS
456464 return *this;
457465}
458466
......@@ -460,10 +468,10 @@ template <class _CharT, class _Traits>
460468basic_ostream<_CharT, _Traits>&
461469basic_ostream<_CharT, _Traits>::operator<<(unsigned short __n)
462470{
463#ifndef _LIBCPP_NO_EXCEPTIONS
471#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
464472 try
465473 {
466#endif // _LIBCPP_NO_EXCEPTIONS
474#endif // _LIBCPP_HAS_NO_EXCEPTIONS
467475 sentry __s(*this);
468476 if (__s)
469477 {
......@@ -472,13 +480,13 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned short __n)
472480 if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed())
473481 this->setstate(ios_base::badbit | ios_base::failbit);
474482 }
475#ifndef _LIBCPP_NO_EXCEPTIONS
483#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
476484 }
477485 catch (...)
478486 {
479487 this->__set_badbit_and_consider_rethrow();
480488 }
481#endif // _LIBCPP_NO_EXCEPTIONS
489#endif // _LIBCPP_HAS_NO_EXCEPTIONS
482490 return *this;
483491}
484492
......@@ -486,10 +494,10 @@ template <class _CharT, class _Traits>
486494basic_ostream<_CharT, _Traits>&
487495basic_ostream<_CharT, _Traits>::operator<<(int __n)
488496{
489#ifndef _LIBCPP_NO_EXCEPTIONS
497#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
490498 try
491499 {
492#endif // _LIBCPP_NO_EXCEPTIONS
500#endif // _LIBCPP_HAS_NO_EXCEPTIONS
493501 sentry __s(*this);
494502 if (__s)
495503 {
......@@ -502,13 +510,13 @@ basic_ostream<_CharT, _Traits>::operator<<(int __n)
502510 static_cast<long>(__n)).failed())
503511 this->setstate(ios_base::badbit | ios_base::failbit);
504512 }
505#ifndef _LIBCPP_NO_EXCEPTIONS
513#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
506514 }
507515 catch (...)
508516 {
509517 this->__set_badbit_and_consider_rethrow();
510518 }
511#endif // _LIBCPP_NO_EXCEPTIONS
519#endif // _LIBCPP_HAS_NO_EXCEPTIONS
512520 return *this;
513521}
514522
......@@ -516,10 +524,10 @@ template <class _CharT, class _Traits>
516524basic_ostream<_CharT, _Traits>&
517525basic_ostream<_CharT, _Traits>::operator<<(unsigned int __n)
518526{
519#ifndef _LIBCPP_NO_EXCEPTIONS
527#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
520528 try
521529 {
522#endif // _LIBCPP_NO_EXCEPTIONS
530#endif // _LIBCPP_HAS_NO_EXCEPTIONS
523531 sentry __s(*this);
524532 if (__s)
525533 {
......@@ -528,13 +536,13 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned int __n)
528536 if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed())
529537 this->setstate(ios_base::badbit | ios_base::failbit);
530538 }
531#ifndef _LIBCPP_NO_EXCEPTIONS
539#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
532540 }
533541 catch (...)
534542 {
535543 this->__set_badbit_and_consider_rethrow();
536544 }
537#endif // _LIBCPP_NO_EXCEPTIONS
545#endif // _LIBCPP_HAS_NO_EXCEPTIONS
538546 return *this;
539547}
540548
......@@ -542,10 +550,10 @@ template <class _CharT, class _Traits>
542550basic_ostream<_CharT, _Traits>&
543551basic_ostream<_CharT, _Traits>::operator<<(long __n)
544552{
545#ifndef _LIBCPP_NO_EXCEPTIONS
553#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
546554 try
547555 {
548#endif // _LIBCPP_NO_EXCEPTIONS
556#endif // _LIBCPP_HAS_NO_EXCEPTIONS
549557 sentry __s(*this);
550558 if (__s)
551559 {
......@@ -554,13 +562,13 @@ basic_ostream<_CharT, _Traits>::operator<<(long __n)
554562 if (__f.put(*this, *this, this->fill(), __n).failed())
555563 this->setstate(ios_base::badbit | ios_base::failbit);
556564 }
557#ifndef _LIBCPP_NO_EXCEPTIONS
565#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
558566 }
559567 catch (...)
560568 {
561569 this->__set_badbit_and_consider_rethrow();
562570 }
563#endif // _LIBCPP_NO_EXCEPTIONS
571#endif // _LIBCPP_HAS_NO_EXCEPTIONS
564572 return *this;
565573}
566574
......@@ -568,10 +576,10 @@ template <class _CharT, class _Traits>
568576basic_ostream<_CharT, _Traits>&
569577basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n)
570578{
571#ifndef _LIBCPP_NO_EXCEPTIONS
579#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
572580 try
573581 {
574#endif // _LIBCPP_NO_EXCEPTIONS
582#endif // _LIBCPP_HAS_NO_EXCEPTIONS
575583 sentry __s(*this);
576584 if (__s)
577585 {
......@@ -580,13 +588,13 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n)
580588 if (__f.put(*this, *this, this->fill(), __n).failed())
581589 this->setstate(ios_base::badbit | ios_base::failbit);
582590 }
583#ifndef _LIBCPP_NO_EXCEPTIONS
591#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
584592 }
585593 catch (...)
586594 {
587595 this->__set_badbit_and_consider_rethrow();
588596 }
589#endif // _LIBCPP_NO_EXCEPTIONS
597#endif // _LIBCPP_HAS_NO_EXCEPTIONS
590598 return *this;
591599}
592600
......@@ -594,10 +602,10 @@ template <class _CharT, class _Traits>
594602basic_ostream<_CharT, _Traits>&
595603basic_ostream<_CharT, _Traits>::operator<<(long long __n)
596604{
597#ifndef _LIBCPP_NO_EXCEPTIONS
605#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
598606 try
599607 {
600#endif // _LIBCPP_NO_EXCEPTIONS
608#endif // _LIBCPP_HAS_NO_EXCEPTIONS
601609 sentry __s(*this);
602610 if (__s)
603611 {
......@@ -606,13 +614,13 @@ basic_ostream<_CharT, _Traits>::operator<<(long long __n)
606614 if (__f.put(*this, *this, this->fill(), __n).failed())
607615 this->setstate(ios_base::badbit | ios_base::failbit);
608616 }
609#ifndef _LIBCPP_NO_EXCEPTIONS
617#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
610618 }
611619 catch (...)
612620 {
613621 this->__set_badbit_and_consider_rethrow();
614622 }
615#endif // _LIBCPP_NO_EXCEPTIONS
623#endif // _LIBCPP_HAS_NO_EXCEPTIONS
616624 return *this;
617625}
618626
......@@ -620,10 +628,10 @@ template <class _CharT, class _Traits>
620628basic_ostream<_CharT, _Traits>&
621629basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n)
622630{
623#ifndef _LIBCPP_NO_EXCEPTIONS
631#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
624632 try
625633 {
626#endif // _LIBCPP_NO_EXCEPTIONS
634#endif // _LIBCPP_HAS_NO_EXCEPTIONS
627635 sentry __s(*this);
628636 if (__s)
629637 {
......@@ -632,13 +640,13 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n)
632640 if (__f.put(*this, *this, this->fill(), __n).failed())
633641 this->setstate(ios_base::badbit | ios_base::failbit);
634642 }
635#ifndef _LIBCPP_NO_EXCEPTIONS
643#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
636644 }
637645 catch (...)
638646 {
639647 this->__set_badbit_and_consider_rethrow();
640648 }
641#endif // _LIBCPP_NO_EXCEPTIONS
649#endif // _LIBCPP_HAS_NO_EXCEPTIONS
642650 return *this;
643651}
644652
......@@ -646,10 +654,10 @@ template <class _CharT, class _Traits>
646654basic_ostream<_CharT, _Traits>&
647655basic_ostream<_CharT, _Traits>::operator<<(float __n)
648656{
649#ifndef _LIBCPP_NO_EXCEPTIONS
657#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
650658 try
651659 {
652#endif // _LIBCPP_NO_EXCEPTIONS
660#endif // _LIBCPP_HAS_NO_EXCEPTIONS
653661 sentry __s(*this);
654662 if (__s)
655663 {
......@@ -658,13 +666,13 @@ basic_ostream<_CharT, _Traits>::operator<<(float __n)
658666 if (__f.put(*this, *this, this->fill(), static_cast<double>(__n)).failed())
659667 this->setstate(ios_base::badbit | ios_base::failbit);
660668 }
661#ifndef _LIBCPP_NO_EXCEPTIONS
669#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
662670 }
663671 catch (...)
664672 {
665673 this->__set_badbit_and_consider_rethrow();
666674 }
667#endif // _LIBCPP_NO_EXCEPTIONS
675#endif // _LIBCPP_HAS_NO_EXCEPTIONS
668676 return *this;
669677}
670678
......@@ -672,10 +680,10 @@ template <class _CharT, class _Traits>
672680basic_ostream<_CharT, _Traits>&
673681basic_ostream<_CharT, _Traits>::operator<<(double __n)
674682{
675#ifndef _LIBCPP_NO_EXCEPTIONS
683#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
676684 try
677685 {
678#endif // _LIBCPP_NO_EXCEPTIONS
686#endif // _LIBCPP_HAS_NO_EXCEPTIONS
679687 sentry __s(*this);
680688 if (__s)
681689 {
......@@ -684,13 +692,13 @@ basic_ostream<_CharT, _Traits>::operator<<(double __n)
684692 if (__f.put(*this, *this, this->fill(), __n).failed())
685693 this->setstate(ios_base::badbit | ios_base::failbit);
686694 }
687#ifndef _LIBCPP_NO_EXCEPTIONS
695#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
688696 }
689697 catch (...)
690698 {
691699 this->__set_badbit_and_consider_rethrow();
692700 }
693#endif // _LIBCPP_NO_EXCEPTIONS
701#endif // _LIBCPP_HAS_NO_EXCEPTIONS
694702 return *this;
695703}
696704
......@@ -698,10 +706,10 @@ template <class _CharT, class _Traits>
698706basic_ostream<_CharT, _Traits>&
699707basic_ostream<_CharT, _Traits>::operator<<(long double __n)
700708{
701#ifndef _LIBCPP_NO_EXCEPTIONS
709#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
702710 try
703711 {
704#endif // _LIBCPP_NO_EXCEPTIONS
712#endif // _LIBCPP_HAS_NO_EXCEPTIONS
705713 sentry __s(*this);
706714 if (__s)
707715 {
......@@ -710,13 +718,13 @@ basic_ostream<_CharT, _Traits>::operator<<(long double __n)
710718 if (__f.put(*this, *this, this->fill(), __n).failed())
711719 this->setstate(ios_base::badbit | ios_base::failbit);
712720 }
713#ifndef _LIBCPP_NO_EXCEPTIONS
721#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
714722 }
715723 catch (...)
716724 {
717725 this->__set_badbit_and_consider_rethrow();
718726 }
719#endif // _LIBCPP_NO_EXCEPTIONS
727#endif // _LIBCPP_HAS_NO_EXCEPTIONS
720728 return *this;
721729}
722730
......@@ -724,10 +732,10 @@ template <class _CharT, class _Traits>
724732basic_ostream<_CharT, _Traits>&
725733basic_ostream<_CharT, _Traits>::operator<<(const void* __n)
726734{
727#ifndef _LIBCPP_NO_EXCEPTIONS
735#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
728736 try
729737 {
730#endif // _LIBCPP_NO_EXCEPTIONS
738#endif // _LIBCPP_HAS_NO_EXCEPTIONS
731739 sentry __s(*this);
732740 if (__s)
733741 {
......@@ -736,13 +744,13 @@ basic_ostream<_CharT, _Traits>::operator<<(const void* __n)
736744 if (__f.put(*this, *this, this->fill(), __n).failed())
737745 this->setstate(ios_base::badbit | ios_base::failbit);
738746 }
739#ifndef _LIBCPP_NO_EXCEPTIONS
747#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
740748 }
741749 catch (...)
742750 {
743751 this->__set_badbit_and_consider_rethrow();
744752 }
745#endif // _LIBCPP_NO_EXCEPTIONS
753#endif // _LIBCPP_HAS_NO_EXCEPTIONS
746754 return *this;
747755}
748756
......@@ -751,10 +759,10 @@ _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
751759__put_character_sequence(basic_ostream<_CharT, _Traits>& __os,
752760 const _CharT* __str, size_t __len)
753761{
754#ifndef _LIBCPP_NO_EXCEPTIONS
762#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
755763 try
756764 {
757#endif // _LIBCPP_NO_EXCEPTIONS
765#endif // _LIBCPP_HAS_NO_EXCEPTIONS
758766 typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
759767 if (__s)
760768 {
......@@ -769,13 +777,13 @@ __put_character_sequence(basic_ostream<_CharT, _Traits>& __os,
769777 __os.fill()).failed())
770778 __os.setstate(ios_base::badbit | ios_base::failbit);
771779 }
772#ifndef _LIBCPP_NO_EXCEPTIONS
780#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
773781 }
774782 catch (...)
775783 {
776784 __os.__set_badbit_and_consider_rethrow();
777785 }
778#endif // _LIBCPP_NO_EXCEPTIONS
786#endif // _LIBCPP_HAS_NO_EXCEPTIONS
779787 return __os;
780788}
781789
......@@ -791,10 +799,10 @@ template<class _CharT, class _Traits>
791799_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
792800operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)
793801{
794#ifndef _LIBCPP_NO_EXCEPTIONS
802#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
795803 try
796804 {
797#endif // _LIBCPP_NO_EXCEPTIONS
805#endif // _LIBCPP_HAS_NO_EXCEPTIONS
798806 typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
799807 if (__s)
800808 {
......@@ -810,13 +818,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)
810818 __os.fill()).failed())
811819 __os.setstate(ios_base::badbit | ios_base::failbit);
812820 }
813#ifndef _LIBCPP_NO_EXCEPTIONS
821#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
814822 }
815823 catch (...)
816824 {
817825 __os.__set_badbit_and_consider_rethrow();
818826 }
819#endif // _LIBCPP_NO_EXCEPTIONS
827#endif // _LIBCPP_HAS_NO_EXCEPTIONS
820828 return __os;
821829}
822830
......@@ -852,10 +860,10 @@ template<class _CharT, class _Traits>
852860_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
853861operator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn)
854862{
855#ifndef _LIBCPP_NO_EXCEPTIONS
863#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
856864 try
857865 {
858#endif // _LIBCPP_NO_EXCEPTIONS
866#endif // _LIBCPP_HAS_NO_EXCEPTIONS
859867 typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
860868 if (__s)
861869 {
......@@ -884,13 +892,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn)
884892 __os.fill()).failed())
885893 __os.setstate(ios_base::badbit | ios_base::failbit);
886894 }
887#ifndef _LIBCPP_NO_EXCEPTIONS
895#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
888896 }
889897 catch (...)
890898 {
891899 __os.__set_badbit_and_consider_rethrow();
892900 }
893#endif // _LIBCPP_NO_EXCEPTIONS
901#endif // _LIBCPP_HAS_NO_EXCEPTIONS
894902 return __os;
895903}
896904
......@@ -921,10 +929,10 @@ template <class _CharT, class _Traits>
921929basic_ostream<_CharT, _Traits>&
922930basic_ostream<_CharT, _Traits>::put(char_type __c)
923931{
924#ifndef _LIBCPP_NO_EXCEPTIONS
932#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
925933 try
926934 {
927#endif // _LIBCPP_NO_EXCEPTIONS
935#endif // _LIBCPP_HAS_NO_EXCEPTIONS
928936 sentry __s(*this);
929937 if (__s)
930938 {
......@@ -934,13 +942,13 @@ basic_ostream<_CharT, _Traits>::put(char_type __c)
934942 if (__o.failed())
935943 this->setstate(ios_base::badbit);
936944 }
937#ifndef _LIBCPP_NO_EXCEPTIONS
945#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
938946 }
939947 catch (...)
940948 {
941949 this->__set_badbit_and_consider_rethrow();
942950 }
943#endif // _LIBCPP_NO_EXCEPTIONS
951#endif // _LIBCPP_HAS_NO_EXCEPTIONS
944952 return *this;
945953}
946954
......@@ -948,23 +956,23 @@ template <class _CharT, class _Traits>
948956basic_ostream<_CharT, _Traits>&
949957basic_ostream<_CharT, _Traits>::write(const char_type* __s, streamsize __n)
950958{
951#ifndef _LIBCPP_NO_EXCEPTIONS
959#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
952960 try
953961 {
954#endif // _LIBCPP_NO_EXCEPTIONS
962#endif // _LIBCPP_HAS_NO_EXCEPTIONS
955963 sentry __sen(*this);
956964 if (__sen && __n)
957965 {
958966 if (this->rdbuf()->sputn(__s, __n) != __n)
959967 this->setstate(ios_base::badbit);
960968 }
961#ifndef _LIBCPP_NO_EXCEPTIONS
969#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
962970 }
963971 catch (...)
964972 {
965973 this->__set_badbit_and_consider_rethrow();
966974 }
967#endif // _LIBCPP_NO_EXCEPTIONS
975#endif // _LIBCPP_HAS_NO_EXCEPTIONS
968976 return *this;
969977}
970978
......@@ -972,10 +980,10 @@ template <class _CharT, class _Traits>
972980basic_ostream<_CharT, _Traits>&
973981basic_ostream<_CharT, _Traits>::flush()
974982{
975#ifndef _LIBCPP_NO_EXCEPTIONS
983#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
976984 try
977985 {
978#endif // _LIBCPP_NO_EXCEPTIONS
986#endif // _LIBCPP_HAS_NO_EXCEPTIONS
979987 if (this->rdbuf())
980988 {
981989 sentry __s(*this);
......@@ -985,13 +993,13 @@ basic_ostream<_CharT, _Traits>::flush()
985993 this->setstate(ios_base::badbit);
986994 }
987995 }
988#ifndef _LIBCPP_NO_EXCEPTIONS
996#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
989997 }
990998 catch (...)
991999 {
9921000 this->__set_badbit_and_consider_rethrow();
9931001 }
994#endif // _LIBCPP_NO_EXCEPTIONS
1002#endif // _LIBCPP_HAS_NO_EXCEPTIONS
9951003 return *this;
9961004}
9971005
......@@ -1130,7 +1138,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x)
11301138 std::use_facet<ctype<_CharT> >(__os.getloc()).widen('1'));
11311139}
11321140
1133#if _LIBCPP_STD_VER > 17
1141#if _LIBCPP_STD_VER >= 20
11341142
11351143#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
11361144template <class _Traits>
......@@ -1179,7 +1187,7 @@ basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const ch
11791187template <class _Traits>
11801188basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const char32_t*) = delete;
11811189
1182#endif // _LIBCPP_STD_VER > 17
1190#endif // _LIBCPP_STD_VER >= 20
11831191
11841192extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<char>;
11851193#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
......@@ -1189,7 +1197,9 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wchar_t>;
11891197_LIBCPP_END_NAMESPACE_STD
11901198
11911199#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1200# include <atomic>
11921201# include <concepts>
1202# include <cstdlib>
11931203# include <iterator>
11941204# include <type_traits>
11951205#endif
lib/libcxx/include/print created+389
......@@ -0,0 +1,389 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_PRINT
11#define _LIBCPP_PRINT
12
13/*
14namespace std {
15 // [print.fun], print functions
16 template<class... Args>
17 void print(format_string<Args...> fmt, Args&&... args);
18 template<class... Args>
19 void print(FILE* stream, format_string<Args...> fmt, Args&&... args);
20
21 template<class... Args>
22 void println(format_string<Args...> fmt, Args&&... args);
23 template<class... Args>
24 void println(FILE* stream, format_string<Args...> fmt, Args&&... args);
25
26 void vprint_unicode(string_view fmt, format_args args);
27 void vprint_unicode(FILE* stream, string_view fmt, format_args args);
28
29 void vprint_nonunicode(string_view fmt, format_args args);
30 void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);
31}
32*/
33
34#include <__assert> // all public C++ headers provide the assertion handler
35#include <__concepts/same_as.h>
36#include <__config>
37#include <__format/buffer.h>
38#include <__format/format_arg_store.h>
39#include <__format/format_args.h>
40#include <__format/format_context.h>
41#include <__format/format_error.h>
42#include <__format/format_functions.h>
43#include <__format/unicode.h>
44#include <__system_error/system_error.h>
45#include <__utility/forward.h>
46#include <cerrno>
47#include <cstdio>
48#include <string>
49#include <string_view>
50#include <version>
51
52#if __has_include(<unistd.h>)
53# include <unistd.h>
54#endif
55
56#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
57# pragma GCC system_header
58#endif
59
60_LIBCPP_BEGIN_NAMESPACE_STD
61
62#ifdef _WIN32
63_LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream);
64
65# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
66// A wrapper for WriteConsoleW which is used to write to the Windows
67// console. This function is in the dylib to avoid pulling in windows.h
68// in the library headers. The function itself uses some private parts
69// of the dylib too.
70//
71// The function does not depend on the language standard used. Guarding
72// it with C++23 would fail since the dylib is currently built using C++20.
73//
74// Note the function is only implemented on the Windows platform.
75_LIBCPP_EXPORTED_FROM_ABI void __write_to_windows_console(FILE* __stream, wstring_view __view);
76# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
77
78#endif // _WIN32
79
80#if _LIBCPP_STD_VER >= 23
81
82# ifndef _LIBCPP_HAS_NO_UNICODE
83// This is the code to transcode UTF-8 to UTF-16. This is used on
84// Windows for the native Unicode API. The code is modeled to make it
85// easier to extend to
86//
87// P2728R0 Unicode in the Library, Part 1: UTF Transcoding
88//
89// This paper is still under heavy development so it makes no sense yet
90// to strictly follow the paper.
91namespace __unicode {
92
93// The names of these concepts are modelled after P2728R0, but the
94// implementation is not. char16_t may contain 32-bits so depending on the
95// number of bits is an issue.
96# ifdef _LIBCPP_SHORT_WCHAR
97template <class _Tp>
98concept __utf16_code_unit =
99 same_as<_Tp, char16_t>
100# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
101 || same_as<_Tp, wchar_t>
102# endif
103 ;
104template <class _Tp>
105concept __utf32_code_unit = same_as<_Tp, char32_t>;
106# else // _LIBCPP_SHORT_WCHAR
107template <class _Tp>
108concept __utf16_code_unit = same_as<_Tp, char16_t>;
109template <class _Tp>
110concept __utf32_code_unit =
111 same_as<_Tp, char32_t>
112# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
113 || same_as<_Tp, wchar_t>
114# endif
115 ;
116# endif // _LIBCPP_SHORT_WCHAR
117
118// Pass by reference since an output_iterator may not be copyable.
119template <class _OutIt>
120_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt&, char32_t) = delete;
121
122template <class _OutIt>
123 requires __utf16_code_unit<iter_value_t<_OutIt>>
124_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) {
125 _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-16");
126
127 if (__value < 0x10000) {
128 *__out_it++ = __value;
129 return;
130 }
131
132 __value -= 0x10000;
133 *__out_it++ = 0xd800 + (__value >> 10);
134 *__out_it++ = 0xdc00 + (__value & 0x3FF);
135}
136
137template <class _OutIt>
138 requires __utf32_code_unit<iter_value_t<_OutIt>>
139_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) {
140 _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-32");
141 *__out_it++ = __value;
142}
143
144template <class _OutIt, input_iterator _InIt>
145 requires output_iterator<_OutIt, const iter_value_t<_OutIt>&> && (!same_as<iter_value_t<_OutIt>, iter_value_t<_InIt>>)
146_LIBCPP_HIDE_FROM_ABI constexpr _OutIt __transcode(_InIt __first, _InIt __last, _OutIt __out_it) {
147 // The __code_point_view has a basic_string_view interface.
148 // When transcoding becomes part of the standard we probably want to
149 // look at smarter algorithms.
150 // For example, when processing a code point that is encoded in
151 // 1 to 3 code units in UTF-8, the result will always be encoded
152 // in 1 code unit in UTF-16 (code points that require 4 code
153 // units in UTF-8 will require 2 code units in UTF-16).
154 //
155 // Note if P2728 is accepted types like int may become valid. In that case
156 // the __code_point_view should use a span. Libc++ will remove support for
157 // char_traits<int>.
158
159 // TODO PRINT Validate with clang-tidy
160 // NOLINTNEXTLINE(bugprone-dangling-handle)
161 basic_string_view<iter_value_t<_InIt>> __data{__first, __last};
162 __code_point_view<iter_value_t<_InIt>> __view{__data.begin(), __data.end()};
163 while (!__view.__at_end())
164 __unicode::__encode(__out_it, __view.__consume().__code_point);
165 return __out_it;
166}
167
168} // namespace __unicode
169
170# endif // _LIBCPP_HAS_NO_UNICODE
171
172namespace __print {
173
174// [print.fun]/2
175// Effects: If the ordinary literal encoding ([lex.charset]) is UTF-8, equivalent to:
176// vprint_unicode(stream, fmt.str, make_format_args(args...));
177// Otherwise, equivalent to:
178// vprint_nonunicode(stream, fmt.str, make_format_args(args...));
179//
180// Based on the compiler and its compilation flags this value is or is
181// not true. As mentioned in P2093R14 this only affects Windows. The
182// test below could also be done for
183// - GCC using __GNUC_EXECUTION_CHARSET_NAME
184// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
185// - Clang using __clang_literal_encoding__
186// https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros
187// (note at the time of writing Clang is hard-coded to UTF-8.)
188//
189
190# ifdef _LIBCPP_HAS_NO_UNICODE
191inline constexpr bool __use_unicode = false;
192# elif defined(_MSVC_EXECUTION_CHARACTER_SET)
193// This is the same test MSVC STL uses in their implementation of <print>
194// See: https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
195inline constexpr bool __use_unicode = _MSVC_EXECUTION_CHARACTER_SET == 65001;
196# else
197inline constexpr bool __use_unicode = true;
198# endif
199
200_LIBCPP_HIDE_FROM_ABI inline bool __is_terminal(FILE* __stream) {
201# ifdef _WIN32
202 return std::__is_windows_terminal(__stream);
203# elif __has_include(<unistd.h>)
204 return isatty(fileno(__stream));
205# else
206# error "Provide a way to determine whether a FILE* is a terminal"
207# endif
208}
209
210template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
211_LIBCPP_HIDE_FROM_ABI inline void
212__vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl) {
213 _LIBCPP_ASSERT_UNCATEGORIZED(__stream, "__stream is a valid pointer to an output C stream");
214 string __str = std::vformat(__fmt, __args);
215 if (__write_nl)
216 __str.push_back('\n');
217
218 size_t __size = fwrite(__str.data(), 1, __str.size(), __stream);
219 if (__size < __str.size()) {
220 if (std::feof(__stream))
221 std::__throw_system_error(EIO, "EOF while writing the formatted output");
222 std::__throw_system_error(std::ferror(__stream), "failed to write formatted output");
223 }
224}
225
226# ifndef _LIBCPP_HAS_NO_UNICODE
227
228// Note these helper functions are mainly used to aid testing.
229// On POSIX systems and Windows the output is no longer considered a
230// terminal when the output is redirected. Typically during testing the
231// output is redirected to be able to capture it. This makes it hard to
232// test this code path.
233template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
234_LIBCPP_HIDE_FROM_ABI inline void
235__vprint_unicode_posix(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) {
236 // TODO PRINT Should flush errors throw too?
237 if (__is_terminal)
238 std::fflush(__stream);
239
240 __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl);
241}
242
243# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
244template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
245_LIBCPP_HIDE_FROM_ABI inline void
246__vprint_unicode_windows(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) {
247 if (!__is_terminal)
248 return __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl);
249
250 // TODO PRINT Should flush errors throw too?
251 std::fflush(__stream);
252
253 string __str = std::vformat(__fmt, __args);
254 // UTF-16 uses the same number or less code units than UTF-8.
255 // However the size of the code unit is 16 bits instead of 8 bits.
256 //
257 // The buffer uses the worst-case estimate and should never resize.
258 // However when the string is large this could lead to OOM. Using a
259 // smaller size might work, but since the buffer uses a grow factor
260 // the final size might be larger when the estimate is wrong.
261 //
262 // TODO PRINT profile and improve the speed of this code.
263 __format::__retarget_buffer<wchar_t> __buffer{__str.size()};
264 __unicode::__transcode(__str.begin(), __str.end(), __buffer.__make_output_iterator());
265 if (__write_nl)
266 __buffer.push_back(L'\n');
267
268 [[maybe_unused]] wstring_view __view = __buffer.__view();
269
270 // The macro _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION is used to change
271 // the behavior in the test. This is not part of the public API.
272# ifdef _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION
273 _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION(__stream, __view);
274# elif defined(_WIN32)
275 std::__write_to_windows_console(__stream, __view);
276# else
277 std::__throw_runtime_error("No defintion of _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION and "
278 "__write_to_windows_console is not available.");
279# endif
280}
281# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
282
283template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
284_LIBCPP_HIDE_FROM_ABI inline void
285__vprint_unicode([[maybe_unused]] FILE* __stream,
286 [[maybe_unused]] string_view __fmt,
287 [[maybe_unused]] format_args __args,
288 [[maybe_unused]] bool __write_nl) {
289 _LIBCPP_ASSERT_UNCATEGORIZED(__stream, "__stream is a valid pointer to an output C stream");
290
291 // [print.fun]
292 // 7 - Effects: If stream refers to a terminal capable of displaying
293 // Unicode, writes out to the terminal using the native Unicode
294 // API; if out contains invalid code units, the behavior is
295 // undefined and implementations are encouraged to diagnose it.
296 // Otherwise writes out to stream unchanged. If the native
297 // Unicode API is used, the function flushes stream before
298 // writing out.
299 // 8 - Throws: Any exception thrown by the call to vformat
300 // ([format.err.report]). system_error if writing to the terminal
301 // or stream fails. May throw bad_alloc.
302 // 9 - Recommended practice: If invoking the native Unicode API
303 // requires transcoding, implementations should substitute
304 // invalid code units with U+FFFD replacement character per the
305 // Unicode Standard, Chapter 3.9 U+FFFD Substitution in
306 // Conversion.
307
308 // On non-Windows platforms the Unicode API is the normal file I/O API
309 // so there the call can be forwarded to the non_unicode API. On
310 // Windows there is a different API. This API requires transcoding.
311
312# ifndef _WIN32
313 __print::__vprint_unicode_posix(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream));
314# elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
315 __print::__vprint_unicode_windows(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream));
316# else
317# error "Windows builds with wchar_t disabled are not supported."
318# endif
319}
320
321# endif // _LIBCPP_HAS_NO_UNICODE
322
323} // namespace __print
324
325template <class... _Args>
326_LIBCPP_HIDE_FROM_ABI void print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
327# ifndef _LIBCPP_HAS_NO_UNICODE
328 if constexpr (__print::__use_unicode)
329 __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
330 else
331 __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
332# else // _LIBCPP_HAS_NO_UNICODE
333 __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
334# endif // _LIBCPP_HAS_NO_UNICODE
335}
336
337template <class... _Args>
338_LIBCPP_HIDE_FROM_ABI void print(format_string<_Args...> __fmt, _Args&&... __args) {
339 std::print(stdout, __fmt, std::forward<_Args>(__args)...);
340}
341
342template <class... _Args>
343_LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
344# ifndef _LIBCPP_HAS_NO_UNICODE
345 // Note the wording in the Standard is inefficient. The output of
346 // std::format is a std::string which is then copied. This solution
347 // just appends a newline at the end of the output.
348 if constexpr (__print::__use_unicode)
349 __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
350 else
351 __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
352# else // _LIBCPP_HAS_NO_UNICODE
353 __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
354# endif // _LIBCPP_HAS_NO_UNICODE
355}
356
357template <class... _Args>
358_LIBCPP_HIDE_FROM_ABI void println(format_string<_Args...> __fmt, _Args&&... __args) {
359 std::println(stdout, __fmt, std::forward<_Args>(__args)...);
360}
361
362# ifndef _LIBCPP_HAS_NO_UNICODE
363template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
364_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(FILE* __stream, string_view __fmt, format_args __args) {
365 __print::__vprint_unicode(__stream, __fmt, __args, false);
366}
367
368template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
369_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(string_view __fmt, format_args __args) {
370 std::vprint_unicode(stdout, __fmt, __args);
371}
372
373# endif // _LIBCPP_HAS_NO_UNICODE
374
375template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
376_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args) {
377 __print::__vprint_nonunicode(__stream, __fmt, __args, false);
378}
379
380template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
381_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(string_view __fmt, format_args __args) {
382 std::vprint_nonunicode(stdout, __fmt, __args);
383}
384
385#endif // _LIBCPP_STD_VER >= 23
386
387_LIBCPP_END_NAMESPACE_STD
388
389#endif // _LIBCPP_PRINT
lib/libcxx/include/queue+193-24
......@@ -43,6 +43,7 @@ public:
4343 explicit queue(container_type&& c)
4444 template<class InputIterator>
4545 queue(InputIterator first, InputIterator last); // since C++23
46 template<container-compatible-range<T> R> queue(from_range_t, R&& rg); // since C++23
4647 template <class Alloc>
4748 explicit queue(const Alloc& a);
4849 template <class Alloc>
......@@ -55,6 +56,8 @@ public:
5556 queue(queue&& q, const Alloc& a);
5657 template <class InputIterator, class Alloc>
5758 queue(InputIterator first, InputIterator last, const Alloc&); // since C++23
59 template<container-compatible-range<T> R, class Alloc>
60 queue(from_range_t, R&& rg, const Alloc&); // since C++23
5861
5962 bool empty() const;
6063 size_type size() const;
......@@ -66,6 +69,8 @@ public:
6669
6770 void push(const value_type& v);
6871 void push(value_type&& v);
72 template<container-compatible-range<T> R>
73 void push_range(R&& rg); // C++23
6974 template <class... Args> reference emplace(Args&&... args); // reference in C++17
7075 void pop();
7176
......@@ -78,6 +83,9 @@ template<class Container>
7883template<class InputIterator>
7984 queue(InputIterator, InputIterator) -> queue<iter-value-type<InputIterator>>; // since C++23
8085
86template<ranges::input_range R>
87 queue(from_range_t, R&&) -> queue<ranges::range_value_t<R>>; // since C++23
88
8189template<class Container, class Allocator>
8290 queue(Container, Allocator) -> queue<typename Container::value_type, Container>; // C++17
8391
......@@ -86,6 +94,10 @@ template<class InputIterator, class Allocator>
8694 -> queue<iter-value-type<InputIterator>,
8795 deque<iter-value-type<InputIterator>, Allocator>>; // since C++23
8896
97template<ranges::input_range R, class Allocator>
98 queue(from_range_t, R&&, Allocator)
99 -> queue<ranges::range_value_t<R>, deque<ranges::range_value_t<R>, Allocator>>; // since C++23
100
89101template <class T, class Container>
90102 bool operator==(const queue<T, Container>& x,const queue<T, Container>& y);
91103
......@@ -104,6 +116,10 @@ template <class T, class Container>
104116template <class T, class Container>
105117 bool operator<=(const queue<T, Container>& x,const queue<T, Container>& y);
106118
119template<class T, three_way_comparable Container>
120 compare_three_way_result_t<Container>
121 operator<=>(const queue<T, Container>& x, const queue<T, Container>& y); // since C++20
122
107123template <class T, class Container>
108124 void swap(queue<T, Container>& x, queue<T, Container>& y)
109125 noexcept(noexcept(x.swap(y)));
......@@ -138,6 +154,8 @@ public:
138154 template <class InputIterator>
139155 priority_queue(InputIterator first, InputIterator last,
140156 const Compare& comp, Container&& c);
157 template <container-compatible-range<T> R>
158 priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); // since C++23
141159 template <class Alloc>
142160 explicit priority_queue(const Alloc& a);
143161 template <class Alloc>
......@@ -160,6 +178,10 @@ public:
160178 template <class InputIterator>
161179 priority_queue(InputIterator first, InputIterator last,
162180 const Compare& comp, Container&& c, const Alloc& a);
181 template <container-compatible-range<T> R, class Alloc>
182 priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&); // since C++23
183 template <container-compatible-range<T> R, class Alloc>
184 priority_queue(from_range_t, R&& rg, const Alloc&); // since C++23
163185 template <class Alloc>
164186 priority_queue(const priority_queue& q, const Alloc& a);
165187 template <class Alloc>
......@@ -171,6 +193,8 @@ public:
171193
172194 void push(const value_type& v);
173195 void push(value_type&& v);
196 template<container-compatible-range<T> R>
197 void push_range(R&& rg); // C++23
174198 template <class... Args> void emplace(Args&&... args);
175199 void pop();
176200
......@@ -189,6 +213,10 @@ template<class InputIterator,
189213priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container())
190214 -> priority_queue<iter-value-type<InputIterator>, Container, Compare>; // C++17
191215
216template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>>
217 priority_queue(from_range_t, R&&, Compare = Compare())
218 -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>>, Compare>; // C++23
219
192220template<class Compare, class Container, class Allocator>
193221priority_queue(Compare, Container, Allocator)
194222 -> priority_queue<typename Container::value_type, Container, Compare>; // C++17
......@@ -208,6 +236,15 @@ template<class InputIterator, class Compare, class Container, class Allocator>
208236priority_queue(InputIterator, InputIterator, Compare, Container, Allocator)
209237 -> priority_queue<typename Container::value_type, Container, Compare>; // C++17
210238
239template<ranges::input_range R, class Compare, class Allocator>
240 priority_queue(from_range_t, R&&, Compare, Allocator)
241 -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>,
242 Compare>; // C++23
243
244template<ranges::input_range R, class Allocator>
245 priority_queue(from_range_t, R&&, Allocator)
246 -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>>; // C++23
247
211248template <class T, class Container, class Compare>
212249 void swap(priority_queue<T, Container, Compare>& x,
213250 priority_queue<T, Container, Compare>& y)
......@@ -220,14 +257,19 @@ template <class T, class Container, class Compare>
220257#include <__algorithm/make_heap.h>
221258#include <__algorithm/pop_heap.h>
222259#include <__algorithm/push_heap.h>
260#include <__algorithm/ranges_copy.h>
223261#include <__assert> // all public C++ headers provide the assertion handler
224262#include <__config>
225263#include <__functional/operations.h>
264#include <__iterator/back_insert_iterator.h>
226265#include <__iterator/iterator_traits.h>
227266#include <__memory/uses_allocator.h>
267#include <__ranges/access.h>
268#include <__ranges/concepts.h>
269#include <__ranges/container_compatible_range.h>
270#include <__ranges/from_range.h>
228271#include <__utility/forward.h>
229272#include <deque>
230#include <type_traits>
231273#include <vector>
232274#include <version>
233275
......@@ -278,18 +320,30 @@ public:
278320 _LIBCPP_INLINE_VISIBILITY
279321 queue(const queue& __q) : c(__q.c) {}
280322
281#if _LIBCPP_STD_VER > 20
323#if _LIBCPP_STD_VER >= 23
282324 template <class _InputIterator,
283 class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
325 class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>>
284326 _LIBCPP_HIDE_FROM_ABI
285327 queue(_InputIterator __first, _InputIterator __last) : c(__first, __last) {}
286328
329 template <_ContainerCompatibleRange<_Tp> _Range>
330 _LIBCPP_HIDE_FROM_ABI
331 queue(from_range_t, _Range&& __range) : c(from_range, std::forward<_Range>(__range)) {}
332
287333 template <class _InputIterator,
288334 class _Alloc,
289 class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
335 class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
290336 class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
291337 _LIBCPP_HIDE_FROM_ABI
292338 queue(_InputIterator __first, _InputIterator __second, const _Alloc& __alloc) : c(__first, __second, __alloc) {}
339
340 template <_ContainerCompatibleRange<_Tp> _Range,
341 class _Alloc,
342 class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
343 _LIBCPP_HIDE_FROM_ABI
344 queue(from_range_t, _Range&& __range, const _Alloc& __alloc)
345 : c(from_range, std::forward<_Range>(__range), __alloc) {}
346
293347#endif
294348
295349 _LIBCPP_INLINE_VISIBILITY
......@@ -361,9 +415,24 @@ public:
361415#ifndef _LIBCPP_CXX03_LANG
362416 _LIBCPP_INLINE_VISIBILITY
363417 void push(value_type&& __v) {c.push_back(_VSTD::move(__v));}
418
419#if _LIBCPP_STD_VER >= 23
420 template <_ContainerCompatibleRange<_Tp> _Range>
421 _LIBCPP_HIDE_FROM_ABI
422 void push_range(_Range&& __range) {
423 if constexpr (requires (container_type& __c) {
424 __c.append_range(std::forward<_Range>(__range));
425 }) {
426 c.append_range(std::forward<_Range>(__range));
427 } else {
428 ranges::copy(std::forward<_Range>(__range), std::back_inserter(c));
429 }
430 }
431#endif
432
364433 template <class... _Args>
365434 _LIBCPP_INLINE_VISIBILITY
366#if _LIBCPP_STD_VER > 14
435#if _LIBCPP_STD_VER >= 17
367436 decltype(auto) emplace(_Args&&... __args)
368437 { return c.emplace_back(_VSTD::forward<_Args>(__args)...);}
369438#else
......@@ -384,20 +453,20 @@ public:
384453
385454 _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
386455
387 template <class _T1, class _C1>
456 template <class _T1, class _OtherContainer>
388457 friend
389458 _LIBCPP_INLINE_VISIBILITY
390459 bool
391 operator==(const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y);
460 operator==(const queue<_T1, _OtherContainer>& __x,const queue<_T1, _OtherContainer>& __y);
392461
393 template <class _T1, class _C1>
462 template <class _T1, class _OtherContainer>
394463 friend
395464 _LIBCPP_INLINE_VISIBILITY
396465 bool
397 operator< (const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y);
466 operator< (const queue<_T1, _OtherContainer>& __x,const queue<_T1, _OtherContainer>& __y);
398467};
399468
400#if _LIBCPP_STD_VER > 14
469#if _LIBCPP_STD_VER >= 17
401470template<class _Container,
402471 class = enable_if_t<!__is_allocator<_Container>::value>
403472>
......@@ -413,18 +482,28 @@ queue(_Container, _Alloc)
413482 -> queue<typename _Container::value_type, _Container>;
414483#endif
415484
416#if _LIBCPP_STD_VER > 20
485#if _LIBCPP_STD_VER >= 23
417486template <class _InputIterator,
418 class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
487 class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>>
419488queue(_InputIterator, _InputIterator)
420489 -> queue<__iter_value_type<_InputIterator>>;
421490
491template <ranges::input_range _Range>
492queue(from_range_t, _Range&&)
493 -> queue<ranges::range_value_t<_Range>>;
494
422495template <class _InputIterator,
423496 class _Alloc,
424 class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
497 class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
425498 class = __enable_if_t<__is_allocator<_Alloc>::value>>
426499queue(_InputIterator, _InputIterator, _Alloc)
427500 -> queue<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>;
501
502template <ranges::input_range _Range,
503 class _Alloc,
504 class = __enable_if_t<__is_allocator<_Alloc>::value>>
505queue(from_range_t, _Range&&, _Alloc)
506 -> queue<ranges::range_value_t<_Range>, deque<ranges::range_value_t<_Range>, _Alloc>>;
428507#endif
429508
430509template <class _Tp, class _Container>
......@@ -475,6 +554,17 @@ operator<=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
475554 return !(__y < __x);
476555}
477556
557#if _LIBCPP_STD_VER >= 20
558
559template <class _Tp, three_way_comparable _Container>
560_LIBCPP_HIDE_FROM_ABI compare_three_way_result_t<_Container>
561operator<=>(const queue<_Tp, _Container>& __x, const queue<_Tp, _Container>& __y) {
562 // clang 16 bug: declaring `friend operator<=>` causes "use of overloaded operator '*' is ambiguous" errors
563 return __x.__get_container() <=> __y.__get_container();
564}
565
566#endif
567
478568template <class _Tp, class _Container>
479569inline _LIBCPP_INLINE_VISIBILITY
480570__enable_if_t<__is_swappable<_Container>::value, void>
......@@ -544,20 +634,31 @@ public:
544634 _LIBCPP_INLINE_VISIBILITY
545635 priority_queue(const value_compare& __comp, container_type&& __c);
546636#endif
547 template <class _InputIter, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
637 template <class _InputIter, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
548638 _LIBCPP_INLINE_VISIBILITY
549639 priority_queue(_InputIter __f, _InputIter __l,
550640 const value_compare& __comp = value_compare());
551 template <class _InputIter, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
641 template <class _InputIter, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
552642 _LIBCPP_INLINE_VISIBILITY
553643 priority_queue(_InputIter __f, _InputIter __l,
554644 const value_compare& __comp, const container_type& __c);
555645#ifndef _LIBCPP_CXX03_LANG
556 template <class _InputIter, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
646 template <class _InputIter, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
557647 _LIBCPP_INLINE_VISIBILITY
558648 priority_queue(_InputIter __f, _InputIter __l,
559649 const value_compare& __comp, container_type&& __c);
560650#endif // _LIBCPP_CXX03_LANG
651
652#if _LIBCPP_STD_VER >= 23
653 template <_ContainerCompatibleRange<_Tp> _Range>
654 _LIBCPP_HIDE_FROM_ABI
655 priority_queue(from_range_t, _Range&& __range, const value_compare& __comp = value_compare())
656 : c(from_range, std::forward<_Range>(__range)),
657 comp(__comp) {
658 std::make_heap(c.begin(), c.end(), comp);
659 }
660#endif
661
561662 template <class _Alloc>
562663 _LIBCPP_INLINE_VISIBILITY
563664 explicit priority_queue(const _Alloc& __a,
......@@ -587,31 +688,55 @@ public:
587688 __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
588689#endif // _LIBCPP_CXX03_LANG
589690
590 template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
691 template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
591692 _LIBCPP_INLINE_VISIBILITY
592693 priority_queue(_InputIter __f, _InputIter __l, const _Alloc& __a,
593694 __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
594695
595 template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
696 template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
596697 _LIBCPP_INLINE_VISIBILITY
597698 priority_queue(_InputIter __f, _InputIter __l,
598699 const value_compare& __comp, const _Alloc& __a,
599700 __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
600701
601 template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
702 template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
602703 _LIBCPP_INLINE_VISIBILITY
603704 priority_queue(_InputIter __f, _InputIter __l,
604705 const value_compare& __comp, const container_type& __c, const _Alloc& __a,
605706 __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
606707
607708#ifndef _LIBCPP_CXX03_LANG
608 template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> >
709 template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> >
609710 _LIBCPP_INLINE_VISIBILITY
610711 priority_queue(_InputIter __f, _InputIter __l,
611712 const value_compare& __comp, container_type&& __c, const _Alloc& __a,
612713 __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0);
613714#endif // _LIBCPP_CXX03_LANG
614715
716#if _LIBCPP_STD_VER >= 23
717
718 template <_ContainerCompatibleRange<_Tp> _Range,
719 class _Alloc,
720 class = enable_if_t<uses_allocator<_Container, _Alloc>::value>>
721 _LIBCPP_HIDE_FROM_ABI
722 priority_queue(from_range_t, _Range&& __range, const value_compare& __comp, const _Alloc& __a)
723 : c(from_range, std::forward<_Range>(__range), __a),
724 comp(__comp) {
725 std::make_heap(c.begin(), c.end(), comp);
726 }
727
728 template <_ContainerCompatibleRange<_Tp> _Range,
729 class _Alloc,
730 class = enable_if_t<uses_allocator<_Container, _Alloc>::value>>
731 _LIBCPP_HIDE_FROM_ABI
732 priority_queue(from_range_t, _Range&& __range, const _Alloc& __a)
733 : c(from_range, std::forward<_Range>(__range), __a),
734 comp() {
735 std::make_heap(c.begin(), c.end(), comp);
736 }
737
738#endif
739
615740 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
616741 bool empty() const {return c.empty();}
617742 _LIBCPP_INLINE_VISIBILITY
......@@ -624,6 +749,23 @@ public:
624749#ifndef _LIBCPP_CXX03_LANG
625750 _LIBCPP_INLINE_VISIBILITY
626751 void push(value_type&& __v);
752
753#if _LIBCPP_STD_VER >= 23
754 template <_ContainerCompatibleRange<_Tp> _Range>
755 _LIBCPP_HIDE_FROM_ABI
756 void push_range(_Range&& __range) {
757 if constexpr (requires (container_type& __c) {
758 __c.append_range(std::forward<_Range>(__range));
759 }) {
760 c.append_range(std::forward<_Range>(__range));
761 } else {
762 ranges::copy(std::forward<_Range>(__range), std::back_inserter(c));
763 }
764
765 std::make_heap(c.begin(), c.end(), comp);
766 }
767#endif
768
627769 template <class... _Args>
628770 _LIBCPP_INLINE_VISIBILITY
629771 void emplace(_Args&&... __args);
......@@ -651,7 +793,7 @@ priority_queue(_Compare, _Container)
651793template<class _InputIterator,
652794 class _Compare = less<__iter_value_type<_InputIterator>>,
653795 class _Container = vector<__iter_value_type<_InputIterator>>,
654 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
796 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
655797 class = enable_if_t<!__is_allocator<_Compare>::value>,
656798 class = enable_if_t<!__is_allocator<_Container>::value>
657799>
......@@ -669,7 +811,7 @@ priority_queue(_Compare, _Container, _Alloc)
669811 -> priority_queue<typename _Container::value_type, _Container, _Compare>;
670812
671813template<class _InputIterator, class _Allocator,
672 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
814 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
673815 class = enable_if_t<__is_allocator<_Allocator>::value>
674816>
675817priority_queue(_InputIterator, _InputIterator, _Allocator)
......@@ -678,7 +820,7 @@ priority_queue(_InputIterator, _InputIterator, _Allocator)
678820 less<__iter_value_type<_InputIterator>>>;
679821
680822template<class _InputIterator, class _Compare, class _Allocator,
681 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
823 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
682824 class = enable_if_t<!__is_allocator<_Compare>::value>,
683825 class = enable_if_t<__is_allocator<_Allocator>::value>
684826>
......@@ -687,7 +829,7 @@ priority_queue(_InputIterator, _InputIterator, _Compare, _Allocator)
687829 vector<__iter_value_type<_InputIterator>, _Allocator>, _Compare>;
688830
689831template<class _InputIterator, class _Compare, class _Container, class _Alloc,
690 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
832 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
691833 class = enable_if_t<!__is_allocator<_Compare>::value>,
692834 class = enable_if_t<!__is_allocator<_Container>::value>,
693835 class = enable_if_t<uses_allocator<_Container, _Alloc>::value>
......@@ -696,6 +838,31 @@ priority_queue(_InputIterator, _InputIterator, _Compare, _Container, _Alloc)
696838 -> priority_queue<typename _Container::value_type, _Container, _Compare>;
697839#endif
698840
841#if _LIBCPP_STD_VER >= 23
842
843template <ranges::input_range _Range,
844 class _Compare = less<ranges::range_value_t<_Range>>,
845 class = enable_if_t<!__is_allocator<_Compare>::value>>
846priority_queue(from_range_t, _Range&&, _Compare = _Compare())
847 -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>>, _Compare>;
848
849template <ranges::input_range _Range,
850 class _Compare,
851 class _Alloc,
852 class = enable_if_t<!__is_allocator<_Compare>::value>,
853 class = enable_if_t<__is_allocator<_Alloc>::value>>
854priority_queue(from_range_t, _Range&&, _Compare, _Alloc)
855 -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>,
856 _Compare>;
857
858template <ranges::input_range _Range,
859 class _Alloc,
860 class = enable_if_t<__is_allocator<_Alloc>::value>>
861priority_queue(from_range_t, _Range&&, _Alloc)
862 -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>>;
863
864#endif
865
699866template <class _Tp, class _Container, class _Compare>
700867inline
701868priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp,
......@@ -964,7 +1131,9 @@ _LIBCPP_END_NAMESPACE_STD
9641131
9651132#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
9661133# include <concepts>
1134# include <cstdlib>
9671135# include <functional>
1136# include <type_traits>
9681137#endif
9691138
9701139#endif // _LIBCPP_QUEUE
lib/libcxx/include/random+1
......@@ -1734,6 +1734,7 @@ class piecewise_linear_distribution
17341734# include <concepts>
17351735# include <cstddef>
17361736# include <cstdint>
1737# include <cstdlib>
17371738# include <iosfwd>
17381739# include <limits>
17391740# include <numeric>
lib/libcxx/include/ranges+41-6
......@@ -49,6 +49,8 @@ namespace std::ranges {
4949 using range_reference_t = iter_reference_t<iterator_t<R>>;
5050 template<range R>
5151 using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
52 template <range R>
53 using range_common_reference_t = iter_common_reference_t<iterator_t<R>>;
5254
5355 // [range.sized], sized ranges
5456 template<class>
......@@ -136,6 +138,16 @@ namespace std::ranges {
136138 inline constexpr auto values = elements<1>;
137139 }
138140
141 // [range.utility.conv], range conversions
142 template<class C, input_range R, class... Args> requires (!view<C>)
143 constexpr C to(R&& r, Args&&... args); // Since C++23
144 template<template<class...> class C, input_range R, class... Args>
145 constexpr auto to(R&& r, Args&&... args); // Since C++23
146 template<class C, class... Args> requires (!view<C>)
147 constexpr auto to(Args&&... args); // Since C++23
148 template<template<class...> class C, class... Args>
149 constexpr auto to(Args&&... args); // Since C++23
150
139151 // [range.empty], empty view
140152 template<class T>
141153 requires is_object_v<T>
......@@ -250,6 +262,19 @@ namespace std::ranges {
250262 template<class W, class Bound>
251263 inline constexpr bool enable_borrowed_range<iota_view<W, Bound>> = true;
252264
265 // [range.repeat], repeat view
266 template<class T>
267 concept integer-like-with-usable-difference-type = // exposition only
268 is-signed-integer-like<T> || (is-integer-like<T> && weakly_incrementable<T>);
269
270 template<move_constructible T, semiregular Bound = unreachable_sentinel_t>
271 requires (is_object_v<T> && same_as<T, remove_cv_t<T>> &&
272 (integer-like-with-usable-difference-type<Bound> ||
273 same_as<Bound, unreachable_sentinel_t>))
274 class repeat_view;
275
276 namespace views { inline constexpr unspecified repeat = unspecified; }
277
253278 // [range.join], join view
254279 template<input_range V>
255280 requires view<V> && input_range<range_reference_t<V>>
......@@ -292,13 +317,13 @@ namespace std::ranges {
292317 // [range.zip], zip view
293318 template<input_range... Views>
294319 requires (view<Views> && ...) && (sizeof...(Views) > 0)
295 class zip_view; // C++2b
320 class zip_view; // C++23
296321
297322 template<class... Views>
298 inline constexpr bool enable_borrowed_range<zip_view<Views...>> = // C++2b
323 inline constexpr bool enable_borrowed_range<zip_view<Views...>> = // C++23
299324 (enable_borrowed_range<Views> && ...);
300325
301 namespace views { inline constexpr unspecified zip = unspecified; } // C++2b
326 namespace views { inline constexpr unspecified zip = unspecified; } // C++23
302327
303328 // [range.as.rvalue]
304329 template <view V>
......@@ -337,6 +362,9 @@ namespace std {
337362 struct tuple_element<1, const ranges::subrange<I, S, K>> {
338363 using type = S;
339364 };
365
366 struct from_range_t { explicit from_range_t() = default; }; // Since C++23
367 inline constexpr from_range_t from_range{}; // Since C++23
340368}
341369*/
342370
......@@ -358,12 +386,14 @@ namespace std {
358386#include <__ranges/enable_borrowed_range.h>
359387#include <__ranges/enable_view.h>
360388#include <__ranges/filter_view.h>
389#include <__ranges/from_range.h>
361390#include <__ranges/iota_view.h>
362391#include <__ranges/join_view.h>
363392#include <__ranges/lazy_split_view.h>
364393#include <__ranges/rbegin.h>
365394#include <__ranges/ref_view.h>
366395#include <__ranges/rend.h>
396#include <__ranges/repeat_view.h>
367397#include <__ranges/reverse_view.h>
368398#include <__ranges/single_view.h>
369399#include <__ranges/size.h>
......@@ -371,11 +401,11 @@ namespace std {
371401#include <__ranges/subrange.h>
372402#include <__ranges/take_view.h>
373403#include <__ranges/take_while_view.h>
404#include <__ranges/to.h>
374405#include <__ranges/transform_view.h>
375406#include <__ranges/view_interface.h>
376407#include <__ranges/views.h>
377408#include <__ranges/zip_view.h>
378#include <type_traits>
379409#include <version>
380410
381411#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
......@@ -390,11 +420,16 @@ namespace std {
390420#include <iterator>
391421
392422// [tuple.helper]
393#include <__tuple_dir/tuple_element.h>
394#include <__tuple_dir/tuple_size.h>
423#include <__tuple/tuple_element.h>
424#include <__tuple/tuple_size.h>
395425
396426#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
397427# pragma GCC system_header
398428#endif
399429
430#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
431# include <cstdlib>
432# include <type_traits>
433#endif
434
400435#endif // _LIBCPP_RANGES
lib/libcxx/include/ratio+5-1
......@@ -40,6 +40,8 @@ template <class R1, class R2> struct ratio_greater;
4040template <class R1, class R2> struct ratio_greater_equal;
4141
4242// convenience SI typedefs
43using quecto = ratio <1, 1'000'000'000'000'000'000'000'000'000'000>; // Since C++26; not supported
44using ronto = ratio <1, 1'000'000'000'000'000'000'000'000'000>; // Since C++26; not supported
4345typedef ratio<1, 1000000000000000000000000> yocto; // not supported
4446typedef ratio<1, 1000000000000000000000> zepto; // not supported
4547typedef ratio<1, 1000000000000000000> atto;
......@@ -60,6 +62,8 @@ typedef ratio< 1000000000000000, 1> peta;
6062typedef ratio< 1000000000000000000, 1> exa;
6163typedef ratio< 1000000000000000000000, 1> zetta; // not supported
6264typedef ratio<1000000000000000000000000, 1> yotta; // not supported
65using ronna = ratio <1'000'000'000'000'000'000'000'000'000, 1>; // Since C++26; not supported
66using quetta = ratio <1'000'000'000'000'000'000'000'000'000'000, 1>; // Since C++26; not supported
6367
6468 // 20.11.5, ratio comparison
6569 template <class R1, class R2> inline constexpr bool ratio_equal_v
......@@ -501,7 +505,7 @@ struct __ratio_gcd
501505 __static_lcm<_R1::den, _R2::den>::value> type;
502506};
503507
504#if _LIBCPP_STD_VER > 14
508#if _LIBCPP_STD_VER >= 17
505509template <class _R1, class _R2>
506510inline constexpr bool ratio_equal_v = ratio_equal<_R1, _R2>::value;
507511
lib/libcxx/include/regex+202-112
......@@ -13,6 +13,7 @@
1313/*
1414 regex synopsis
1515
16#include <compare>
1617#include <initializer_list>
1718
1819namespace std
......@@ -225,6 +226,8 @@ public:
225226 int compare(const sub_match& s) const;
226227 int compare(const string_type& s) const;
227228 int compare(const value_type* s) const;
229
230 void swap(sub_match& s) noexcept(see below);
228231};
229232
230233typedef sub_match<const char*> csub_match;
......@@ -237,50 +240,54 @@ template <class BiIter>
237240 operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
238241
239242template <class BiIter>
243 auto
244 operator<=>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); // Since C++20
245
246 template <class BiIter> // Removed in C++20
240247 bool
241248 operator!=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
242249
243template <class BiIter>
250template <class BiIter> // Removed in C++20
244251 bool
245252 operator<(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
246253
247template <class BiIter>
254template <class BiIter> // Removed in C++20
248255 bool
249256 operator<=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
250257
251template <class BiIter>
258template <class BiIter> // Removed in C++20
252259 bool
253260 operator>=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
254261
255template <class BiIter>
262template <class BiIter> // Removed in C++20
256263 bool
257264 operator>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
258265
259template <class BiIter, class ST, class SA>
266template <class BiIter, class ST, class SA> // Removed in C++20
260267 bool
261268 operator==(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
262269 const sub_match<BiIter>& rhs);
263270
264template <class BiIter, class ST, class SA>
271template <class BiIter, class ST, class SA> // Removed in C++20
265272 bool
266273 operator!=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
267274 const sub_match<BiIter>& rhs);
268275
269template <class BiIter, class ST, class SA>
276template <class BiIter, class ST, class SA> // Removed in C++20
270277 bool
271278 operator<(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
272279 const sub_match<BiIter>& rhs);
273280
274template <class BiIter, class ST, class SA>
281template <class BiIter, class ST, class SA> // Removed in C++20
275282 bool
276283 operator>(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
277284 const sub_match<BiIter>& rhs);
278285
279template <class BiIter, class ST, class SA>
286template <class BiIter, class ST, class SA> // Removed in C++20
280287 bool operator>=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
281288 const sub_match<BiIter>& rhs);
282289
283template <class BiIter, class ST, class SA>
290template <class BiIter, class ST, class SA> // Removed in C++20
284291 bool
285292 operator<=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
286293 const sub_match<BiIter>& rhs);
......@@ -290,56 +297,62 @@ template <class BiIter, class ST, class SA>
290297 operator==(const sub_match<BiIter>& lhs,
291298 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
292299
293template <class BiIter, class ST, class SA>
300template <class BiIter, class ST, class SA> // Since C++20
301 auto
302 operator<=>(const sub_match<BiIter>& lhs,
303 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
304
305template <class BiIter, class ST, class SA> // Removed in C++20
294306 bool
295307 operator!=(const sub_match<BiIter>& lhs,
296308 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
297309
298template <class BiIter, class ST, class SA>
310template <class BiIter, class ST, class SA> // Removed in C++20
299311 bool
300312 operator<(const sub_match<BiIter>& lhs,
301313 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
302314
303template <class BiIter, class ST, class SA>
304 bool operator>(const sub_match<BiIter>& lhs,
315template <class BiIter, class ST, class SA> // Removed in C++20
316 bool
317 operator>(const sub_match<BiIter>& lhs,
305318 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
306319
307template <class BiIter, class ST, class SA>
320template <class BiIter, class ST, class SA> // Removed in C++20
308321 bool
309322 operator>=(const sub_match<BiIter>& lhs,
310323 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
311324
312template <class BiIter, class ST, class SA>
325template <class BiIter, class ST, class SA> // Removed in C++20
313326 bool
314327 operator<=(const sub_match<BiIter>& lhs,
315328 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
316329
317template <class BiIter>
330template <class BiIter> // Removed in C++20
318331 bool
319332 operator==(typename iterator_traits<BiIter>::value_type const* lhs,
320333 const sub_match<BiIter>& rhs);
321334
322template <class BiIter>
335template <class BiIter> // Removed in C++20
323336 bool
324337 operator!=(typename iterator_traits<BiIter>::value_type const* lhs,
325338 const sub_match<BiIter>& rhs);
326339
327template <class BiIter>
340template <class BiIter> // Removed in C++20
328341 bool
329342 operator<(typename iterator_traits<BiIter>::value_type const* lhs,
330343 const sub_match<BiIter>& rhs);
331344
332template <class BiIter>
345template <class BiIter> // Removed in C++20
333346 bool
334347 operator>(typename iterator_traits<BiIter>::value_type const* lhs,
335348 const sub_match<BiIter>& rhs);
336349
337template <class BiIter>
350template <class BiIter> // Removed in C++20
338351 bool
339352 operator>=(typename iterator_traits<BiIter>::value_type const* lhs,
340353 const sub_match<BiIter>& rhs);
341354
342template <class BiIter>
355template <class BiIter> // Removed in C++20
343356 bool
344357 operator<=(typename iterator_traits<BiIter>::value_type const* lhs,
345358 const sub_match<BiIter>& rhs);
......@@ -349,57 +362,62 @@ template <class BiIter>
349362 operator==(const sub_match<BiIter>& lhs,
350363 typename iterator_traits<BiIter>::value_type const* rhs);
351364
352template <class BiIter>
365template <class BiIter> // Since C++20
366 auto
367 operator<=>(const sub_match<BiIter>& lhs,
368 typename iterator_traits<BiIter>::value_type const* rhs);
369
370template <class BiIter, class ST, class SA> // Removed in C++20
353371 bool
354372 operator!=(const sub_match<BiIter>& lhs,
355373 typename iterator_traits<BiIter>::value_type const* rhs);
356374
357template <class BiIter>
375template <class BiIter> // Removed in C++20
358376 bool
359377 operator<(const sub_match<BiIter>& lhs,
360378 typename iterator_traits<BiIter>::value_type const* rhs);
361379
362template <class BiIter>
380template <class BiIter> // Removed in C++20
363381 bool
364382 operator>(const sub_match<BiIter>& lhs,
365383 typename iterator_traits<BiIter>::value_type const* rhs);
366384
367template <class BiIter>
385template <class BiIter> // Removed in C++20
368386 bool
369387 operator>=(const sub_match<BiIter>& lhs,
370388 typename iterator_traits<BiIter>::value_type const* rhs);
371389
372template <class BiIter>
390template <class BiIter> // Removed in C++20
373391 bool
374392 operator<=(const sub_match<BiIter>& lhs,
375393 typename iterator_traits<BiIter>::value_type const* rhs);
376394
377template <class BiIter>
395template <class BiIter> // Removed in C++20
378396 bool
379397 operator==(typename iterator_traits<BiIter>::value_type const& lhs,
380398 const sub_match<BiIter>& rhs);
381399
382template <class BiIter>
400template <class BiIter> // Removed in C++20
383401 bool
384402 operator!=(typename iterator_traits<BiIter>::value_type const& lhs,
385403 const sub_match<BiIter>& rhs);
386404
387template <class BiIter>
405template <class BiIter> // Removed in C++20
388406 bool
389407 operator<(typename iterator_traits<BiIter>::value_type const& lhs,
390408 const sub_match<BiIter>& rhs);
391409
392template <class BiIter>
410template <class BiIter> // Removed in C++20
393411 bool
394412 operator>(typename iterator_traits<BiIter>::value_type const& lhs,
395413 const sub_match<BiIter>& rhs);
396414
397template <class BiIter>
415template <class BiIter> // Removed in C++20
398416 bool
399417 operator>=(typename iterator_traits<BiIter>::value_type const& lhs,
400418 const sub_match<BiIter>& rhs);
401419
402template <class BiIter>
420template <class BiIter> // Removed in C++20
403421 bool
404422 operator<=(typename iterator_traits<BiIter>::value_type const& lhs,
405423 const sub_match<BiIter>& rhs);
......@@ -409,27 +427,32 @@ template <class BiIter>
409427 operator==(const sub_match<BiIter>& lhs,
410428 typename iterator_traits<BiIter>::value_type const& rhs);
411429
412template <class BiIter>
430template <class BiIter> // Since C++20
431 auto
432 operator<=>(const sub_match<BiIter>& lhs,
433 typename iterator_traits<BiIter>::value_type const& rhs);
434
435template <class BiIter> // Removed in C++20
413436 bool
414437 operator!=(const sub_match<BiIter>& lhs,
415438 typename iterator_traits<BiIter>::value_type const& rhs);
416439
417template <class BiIter>
440template <class BiIter> // Removed in C++20
418441 bool
419442 operator<(const sub_match<BiIter>& lhs,
420443 typename iterator_traits<BiIter>::value_type const& rhs);
421444
422template <class BiIter>
445template <class BiIter> // Removed in C++20
423446 bool
424447 operator>(const sub_match<BiIter>& lhs,
425448 typename iterator_traits<BiIter>::value_type const& rhs);
426449
427template <class BiIter>
450template <class BiIter> // Removed in C++20
428451 bool
429452 operator>=(const sub_match<BiIter>& lhs,
430453 typename iterator_traits<BiIter>::value_type const& rhs);
431454
432template <class BiIter>
455template <class BiIter> // Removed in C++20
433456 bool
434457 operator<=(const sub_match<BiIter>& lhs,
435458 typename iterator_traits<BiIter>::value_type const& rhs);
......@@ -520,7 +543,7 @@ template <class BidirectionalIterator, class Allocator>
520543 operator==(const match_results<BidirectionalIterator, Allocator>& m1,
521544 const match_results<BidirectionalIterator, Allocator>& m2);
522545
523template <class BidirectionalIterator, class Allocator>
546template <class BidirectionalIterator, class Allocator> // Removed in C++20
524547 bool
525548 operator!=(const match_results<BidirectionalIterator, Allocator>& m1,
526549 const match_results<BidirectionalIterator, Allocator>& m2);
......@@ -687,7 +710,8 @@ public:
687710 regex_iterator& operator=(const regex_iterator&);
688711
689712 bool operator==(const regex_iterator&) const;
690 bool operator!=(const regex_iterator&) const;
713 bool operator==(default_sentinel_t) const { return *this == regex_iterator(); } // since C++20
714 bool operator!=(const regex_iterator&) const; // Removed in C++20
691715
692716 const value_type& operator*() const;
693717 const value_type* operator->() const;
......@@ -745,7 +769,8 @@ public:
745769 regex_token_iterator& operator=(const regex_token_iterator&);
746770
747771 bool operator==(const regex_token_iterator&) const;
748 bool operator!=(const regex_token_iterator&) const;
772 bool operator==(default_sentinel_t) const { return *this == regex_token_iterator(); } // since C++20
773 bool operator!=(const regex_token_iterator&) const; // Removed in C++20
749774
750775 const value_type& operator*() const;
751776 const value_type* operator->() const;
......@@ -765,15 +790,19 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
765790#include <__algorithm/find.h>
766791#include <__algorithm/search.h>
767792#include <__assert> // all public C++ headers provide the assertion handler
793#include <__availability>
768794#include <__config>
769795#include <__iterator/back_insert_iterator.h>
796#include <__iterator/default_sentinel.h>
770797#include <__iterator/wrap_iter.h>
771798#include <__locale>
799#include <__memory/shared_ptr.h>
772800#include <__memory_resource/polymorphic_allocator.h>
801#include <__type_traits/is_swappable.h>
773802#include <__utility/move.h>
774803#include <__utility/pair.h>
775804#include <__utility/swap.h>
776#include <cstring>
805#include <__verbose_abort>
777806#include <deque>
778807#include <stdexcept>
779808#include <string>
......@@ -996,13 +1025,13 @@ enum error_type
9961025
9971026} // namespace regex_constants
9981027
999class _LIBCPP_EXCEPTION_ABI regex_error
1028class _LIBCPP_EXPORTED_FROM_ABI regex_error
10001029 : public runtime_error
10011030{
10021031 regex_constants::error_type __code_;
10031032public:
10041033 explicit regex_error(regex_constants::error_type __ecode);
1005 regex_error(const regex_error&) _NOEXCEPT = default;
1034 _LIBCPP_HIDE_FROM_ABI regex_error(const regex_error&) _NOEXCEPT = default;
10061035 ~regex_error() _NOEXCEPT override;
10071036 _LIBCPP_INLINE_VISIBILITY
10081037 regex_constants::error_type code() const {return __code_;}
......@@ -1012,10 +1041,10 @@ template <regex_constants::error_type _Ev>
10121041_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
10131042void __throw_regex_error()
10141043{
1015#ifndef _LIBCPP_NO_EXCEPTIONS
1044#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
10161045 throw regex_error(_Ev);
10171046#else
1018 _VSTD::abort();
1047 _LIBCPP_VERBOSE_ABORT("regex_error was thrown in -fno-exceptions mode");
10191048#endif
10201049}
10211050
......@@ -1221,7 +1250,7 @@ regex_traits<_CharT>::__transform_primary(_ForwardIterator __f,
12211250
12221251// lookup_collatename is very FreeBSD-specific
12231252
1224_LIBCPP_FUNC_VIS string __get_collation_name(const char* __s);
1253_LIBCPP_EXPORTED_FROM_ABI string __get_collation_name(const char* __s);
12251254
12261255template <class _CharT>
12271256template <class _ForwardIterator>
......@@ -1284,8 +1313,7 @@ regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f,
12841313
12851314// lookup_classname
12861315
1287regex_traits<char>::char_class_type _LIBCPP_FUNC_VIS
1288__get_classname(const char* __s, bool __icase);
1316regex_traits<char>::char_class_type _LIBCPP_EXPORTED_FROM_ABI __get_classname(const char* __s, bool __icase);
12891317
12901318template <class _CharT>
12911319template <class _ForwardIterator>
......@@ -1467,7 +1495,7 @@ public:
14671495 _LIBCPP_INLINE_VISIBILITY
14681496 __end_state() {}
14691497
1470 virtual void __exec(__state&) const;
1498 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
14711499};
14721500
14731501template <class _CharT>
......@@ -1533,7 +1561,7 @@ public:
15331561 explicit __empty_state(__node<_CharT>* __s)
15341562 : base(__s) {}
15351563
1536 virtual void __exec(__state&) const;
1564 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
15371565};
15381566
15391567template <class _CharT>
......@@ -1559,7 +1587,7 @@ public:
15591587 explicit __empty_non_own_state(__node<_CharT>* __s)
15601588 : base(__s) {}
15611589
1562 virtual void __exec(__state&) const;
1590 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
15631591};
15641592
15651593template <class _CharT>
......@@ -1585,7 +1613,7 @@ public:
15851613 explicit __repeat_one_loop(__node<_CharT>* __s)
15861614 : base(__s) {}
15871615
1588 virtual void __exec(__state&) const;
1616 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
15891617};
15901618
15911619template <class _CharT>
......@@ -1611,7 +1639,7 @@ public:
16111639 explicit __owns_two_states(__node<_CharT>* __s1, base* __s2)
16121640 : base(__s1), __second_(__s2) {}
16131641
1614 virtual ~__owns_two_states();
1642 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__owns_two_states();
16151643
16161644 _LIBCPP_INLINE_VISIBILITY
16171645 base* second() const {return __second_;}
......@@ -1654,8 +1682,8 @@ public:
16541682 __mexp_begin_(__mexp_begin), __mexp_end_(__mexp_end),
16551683 __greedy_(__greedy) {}
16561684
1657 virtual void __exec(__state& __s) const;
1658 virtual void __exec_split(bool __second, __state& __s) const;
1685 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state& __s) const;
1686 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec_split(bool __second, __state& __s) const;
16591687
16601688private:
16611689 _LIBCPP_INLINE_VISIBILITY
......@@ -1747,8 +1775,8 @@ public:
17471775 __owns_one_state<_CharT>* __s2)
17481776 : base(__s1, __s2) {}
17491777
1750 virtual void __exec(__state& __s) const;
1751 virtual void __exec_split(bool __second, __state& __s) const;
1778 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state& __s) const;
1779 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec_split(bool __second, __state& __s) const;
17521780};
17531781
17541782template <class _CharT>
......@@ -1785,7 +1813,7 @@ public:
17851813 explicit __begin_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)
17861814 : base(__s), __mexp_(__mexp) {}
17871815
1788 virtual void __exec(__state&) const;
1816 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
17891817};
17901818
17911819template <class _CharT>
......@@ -1813,7 +1841,7 @@ public:
18131841 explicit __end_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)
18141842 : base(__s), __mexp_(__mexp) {}
18151843
1816 virtual void __exec(__state&) const;
1844 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
18171845};
18181846
18191847template <class _CharT>
......@@ -1842,7 +1870,7 @@ public:
18421870 explicit __back_ref(unsigned __mexp, __node<_CharT>* __s)
18431871 : base(__s), __mexp_(__mexp) {}
18441872
1845 virtual void __exec(__state&) const;
1873 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
18461874};
18471875
18481876template <class _CharT>
......@@ -1893,7 +1921,7 @@ public:
18931921 __node<_CharT>* __s)
18941922 : base(__s), __traits_(__traits), __mexp_(__mexp) {}
18951923
1896 virtual void __exec(__state&) const;
1924 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
18971925};
18981926
18991927template <class _CharT, class _Traits>
......@@ -1948,7 +1976,7 @@ public:
19481976 __node<_CharT>* __s)
19491977 : base(__s), __traits_(__traits), __mexp_(__mexp) {}
19501978
1951 virtual void __exec(__state&) const;
1979 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
19521980};
19531981
19541982template <class _CharT, class _Traits>
......@@ -2003,7 +2031,7 @@ public:
20032031 __node<_CharT>* __s)
20042032 : base(__s), __traits_(__traits), __invert_(__invert) {}
20052033
2006 virtual void __exec(__state&) const;
2034 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
20072035};
20082036
20092037template <class _CharT, class _Traits>
......@@ -2079,7 +2107,7 @@ public:
20792107 __l_anchor_multiline(bool __multiline, __node<_CharT>* __s)
20802108 : base(__s), __multiline_(__multiline) {}
20812109
2082 virtual void __exec(__state&) const;
2110 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
20832111};
20842112
20852113template <class _CharT>
......@@ -2123,7 +2151,7 @@ public:
21232151 __r_anchor_multiline(bool __multiline, __node<_CharT>* __s)
21242152 : base(__s), __multiline_(__multiline) {}
21252153
2126 virtual void __exec(__state&) const;
2154 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
21272155};
21282156
21292157template <class _CharT>
......@@ -2163,7 +2191,7 @@ public:
21632191 __match_any(__node<_CharT>* __s)
21642192 : base(__s) {}
21652193
2166 virtual void __exec(__state&) const;
2194 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
21672195};
21682196
21692197template <class _CharT>
......@@ -2201,9 +2229,9 @@ public:
22012229 void __exec(__state&) const override;
22022230};
22032231
2204template <> _LIBCPP_FUNC_VIS void __match_any_but_newline<char>::__exec(__state&) const;
2232template <> _LIBCPP_EXPORTED_FROM_ABI void __match_any_but_newline<char>::__exec(__state&) const;
22052233#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
2206template <> _LIBCPP_FUNC_VIS void __match_any_but_newline<wchar_t>::__exec(__state&) const;
2234template <> _LIBCPP_EXPORTED_FROM_ABI void __match_any_but_newline<wchar_t>::__exec(__state&) const;
22072235#endif
22082236
22092237// __match_char
......@@ -2225,7 +2253,7 @@ public:
22252253 __match_char(_CharT __c, __node<_CharT>* __s)
22262254 : base(__s), __c_(__c) {}
22272255
2228 virtual void __exec(__state&) const;
2256 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
22292257};
22302258
22312259template <class _CharT>
......@@ -2265,7 +2293,7 @@ public:
22652293 __match_char_icase(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)
22662294 : base(__s), __traits_(__traits), __c_(__traits.translate_nocase(__c)) {}
22672295
2268 virtual void __exec(__state&) const;
2296 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
22692297};
22702298
22712299template <class _CharT, class _Traits>
......@@ -2306,7 +2334,7 @@ public:
23062334 __match_char_collate(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)
23072335 : base(__s), __traits_(__traits), __c_(__traits.translate(__c)) {}
23082336
2309 virtual void __exec(__state&) const;
2337 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
23102338};
23112339
23122340template <class _CharT, class _Traits>
......@@ -2361,7 +2389,7 @@ public:
23612389 __negate_(__negate), __icase_(__icase), __collate_(__collate),
23622390 __might_have_digraph_(__traits_.getloc().name() != "C") {}
23632391
2364 virtual void __exec(__state&) const;
2392 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
23652393
23662394 _LIBCPP_INLINE_VISIBILITY
23672395 bool __negated() const {return __negate_;}
......@@ -2750,7 +2778,7 @@ public:
27502778
27512779 template <class _InputIterator>
27522780 _LIBCPP_INLINE_VISIBILITY
2753 typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value, basic_regex&>::type
2781 typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value, basic_regex&>::type
27542782 assign(_InputIterator __first, _InputIterator __last,
27552783 flag_type __f = regex_constants::ECMAScript)
27562784 {
......@@ -2774,7 +2802,7 @@ public:
27742802 _LIBCPP_INLINE_VISIBILITY
27752803 typename enable_if
27762804 <
2777 __is_cpp17_forward_iterator<_ForwardIterator>::value,
2805 __has_forward_iterator_category<_ForwardIterator>::value,
27782806 basic_regex&
27792807 >::type
27802808 assign(_ForwardIterator __first, _ForwardIterator __last,
......@@ -3082,7 +3110,7 @@ private:
30823110
30833111#if _LIBCPP_STD_VER >= 17
30843112template <class _ForwardIterator,
3085 class = typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value, nullptr_t>::type
3113 class = typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value, nullptr_t>::type
30863114>
30873115basic_regex(_ForwardIterator, _ForwardIterator,
30883116 regex_constants::syntax_option_type = regex_constants::ECMAScript)
......@@ -3153,7 +3181,7 @@ public:
31533181 __lookahead(const basic_regex<_CharT, _Traits>& __exp, bool __invert, __node<_CharT>* __s, unsigned __mexp)
31543182 : base(__s), __exp_(__exp), __mexp_(__mexp), __invert_(__invert) {}
31553183
3156 virtual void __exec(__state&) const;
3184 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
31573185};
31583186
31593187template <class _CharT, class _Traits>
......@@ -4131,9 +4159,9 @@ basic_regex<_CharT, _Traits>::__parse_equivalence_class(_ForwardIterator __first
41314159{
41324160 // Found [=
41334161 // This means =] must exist
4134 value_type _Equal_close[2] = {'=', ']'};
4135 _ForwardIterator __temp = _VSTD::search(__first, __last, _Equal_close,
4136 _Equal_close+2);
4162 value_type __equal_close[2] = {'=', ']'};
4163 _ForwardIterator __temp = _VSTD::search(__first, __last, __equal_close,
4164 __equal_close+2);
41374165 if (__temp == __last)
41384166 __throw_regex_error<regex_constants::error_brack>();
41394167 // [__first, __temp) contains all text in [= ... =]
......@@ -4173,9 +4201,9 @@ basic_regex<_CharT, _Traits>::__parse_character_class(_ForwardIterator __first,
41734201{
41744202 // Found [:
41754203 // This means :] must exist
4176 value_type _Colon_close[2] = {':', ']'};
4177 _ForwardIterator __temp = _VSTD::search(__first, __last, _Colon_close,
4178 _Colon_close+2);
4204 value_type __colon_close[2] = {':', ']'};
4205 _ForwardIterator __temp = _VSTD::search(__first, __last, __colon_close,
4206 __colon_close+2);
41794207 if (__temp == __last)
41804208 __throw_regex_error<regex_constants::error_brack>();
41814209 // [__first, __temp) contains all text in [: ... :]
......@@ -4198,9 +4226,9 @@ basic_regex<_CharT, _Traits>::__parse_collating_symbol(_ForwardIterator __first,
41984226{
41994227 // Found [.
42004228 // This means .] must exist
4201 value_type _Dot_close[2] = {'.', ']'};
4202 _ForwardIterator __temp = _VSTD::search(__first, __last, _Dot_close,
4203 _Dot_close+2);
4229 value_type __dot_close[2] = {'.', ']'};
4230 _ForwardIterator __temp = _VSTD::search(__first, __last, __dot_close,
4231 __dot_close+2);
42044232 if (__temp == __last)
42054233 __throw_regex_error<regex_constants::error_brack>();
42064234 // [__first, __temp) contains all text in [. ... .]
......@@ -5009,6 +5037,16 @@ public:
50095037 _LIBCPP_INLINE_VISIBILITY
50105038 int compare(const value_type* __s) const
50115039 {return str().compare(__s);}
5040
5041 _LIBCPP_HIDE_FROM_ABI
5042 void swap(sub_match& __s)
5043#ifndef _LIBCPP_CXX03_LANG
5044 _NOEXCEPT(__is_nothrow_swappable<_BidirectionalIterator>::value)
5045#endif // _LIBCPP_CXX03_LANG
5046 {
5047 this->pair<_BidirectionalIterator, _BidirectionalIterator>::swap(__s);
5048 std::swap(matched, __s.matched);
5049 }
50125050};
50135051
50145052template <class _BiIter>
......@@ -5019,6 +5057,15 @@ operator==(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
50195057 return __x.compare(__y) == 0;
50205058}
50215059
5060#if _LIBCPP_STD_VER >= 20
5061template<class _BiIter>
5062using __sub_match_cat = compare_three_way_result_t<basic_string<typename iterator_traits<_BiIter>::value_type>>;
5063
5064template <class _BiIter>
5065_LIBCPP_HIDE_FROM_ABI auto operator<=>(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) {
5066 return static_cast<__sub_match_cat<_BiIter>>(__x.compare(__y) <=> 0);
5067}
5068#else // _LIBCPP_STD_VER >= 20
50225069template <class _BiIter>
50235070inline _LIBCPP_INLINE_VISIBILITY
50245071bool
......@@ -5111,6 +5158,7 @@ operator<=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST
51115158{
51125159 return !(__y < __x);
51135160}
5161#endif // _LIBCPP_STD_VER >= 20
51145162
51155163template <class _BiIter, class _ST, class _SA>
51165164inline _LIBCPP_INLINE_VISIBILITY
......@@ -5121,6 +5169,14 @@ operator==(const sub_match<_BiIter>& __x,
51215169 return __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) == 0;
51225170}
51235171
5172#if _LIBCPP_STD_VER >= 20
5173template <class _BiIter, class _ST, class _SA>
5174_LIBCPP_HIDE_FROM_ABI auto operator<=>(
5175 const sub_match<_BiIter>& __x, const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y) {
5176 return static_cast<__sub_match_cat<_BiIter>>(
5177 __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) <=> 0);
5178}
5179#else // _LIBCPP_STD_VER >= 20
51245180template <class _BiIter, class _ST, class _SA>
51255181inline _LIBCPP_INLINE_VISIBILITY
51265182bool
......@@ -5218,6 +5274,7 @@ operator<=(typename iterator_traits<_BiIter>::value_type const* __x,
52185274{
52195275 return !(__y < __x);
52205276}
5277#endif // _LIBCPP_STD_VER >= 20
52215278
52225279template <class _BiIter>
52235280inline _LIBCPP_INLINE_VISIBILITY
......@@ -5228,6 +5285,13 @@ operator==(const sub_match<_BiIter>& __x,
52285285 return __x.compare(__y) == 0;
52295286}
52305287
5288#if _LIBCPP_STD_VER >= 20
5289template <class _BiIter>
5290_LIBCPP_HIDE_FROM_ABI auto
5291operator<=>(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const* __y) {
5292 return static_cast<__sub_match_cat<_BiIter>>(__x.compare(__y) <=> 0);
5293}
5294#else // _LIBCPP_STD_VER >= 20
52315295template <class _BiIter>
52325296inline _LIBCPP_INLINE_VISIBILITY
52335297bool
......@@ -5328,6 +5392,7 @@ operator<=(typename iterator_traits<_BiIter>::value_type const& __x,
53285392{
53295393 return !(__y < __x);
53305394}
5395#endif // _LIBCPP_STD_VER >= 20
53315396
53325397template <class _BiIter>
53335398inline _LIBCPP_INLINE_VISIBILITY
......@@ -5339,6 +5404,14 @@ operator==(const sub_match<_BiIter>& __x,
53395404 return __x.compare(string_type(1, __y)) == 0;
53405405}
53415406
5407#if _LIBCPP_STD_VER >= 20
5408template <class _BiIter>
5409_LIBCPP_HIDE_FROM_ABI auto
5410operator<=>(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const& __y) {
5411 using string_type = basic_string<typename iterator_traits<_BiIter>::value_type>;
5412 return static_cast<__sub_match_cat<_BiIter>>(__x.compare(string_type(1, __y)) <=> 0);
5413}
5414#else // _LIBCPP_STD_VER >= 20
53425415template <class _BiIter>
53435416inline _LIBCPP_INLINE_VISIBILITY
53445417bool
......@@ -5384,6 +5457,7 @@ operator<=(const sub_match<_BiIter>& __x,
53845457{
53855458 return !(__y < __x);
53865459}
5460#endif // _LIBCPP_STD_VER >= 20
53875461
53885462template <class _CharT, class _ST, class _BiIter>
53895463inline _LIBCPP_INLINE_VISIBILITY
......@@ -5460,38 +5534,38 @@ public:
54605534 _LIBCPP_INLINE_VISIBILITY
54615535 difference_type length(size_type __sub = 0) const
54625536 {
5463 _LIBCPP_ASSERT(ready(), "match_results::length() called when not ready");
5537 _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::length() called when not ready");
54645538 return (*this)[__sub].length();
54655539 }
54665540 _LIBCPP_INLINE_VISIBILITY
54675541 difference_type position(size_type __sub = 0) const
54685542 {
5469 _LIBCPP_ASSERT(ready(), "match_results::position() called when not ready");
5543 _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::position() called when not ready");
54705544 return _VSTD::distance(__position_start_, (*this)[__sub].first);
54715545 }
54725546 _LIBCPP_INLINE_VISIBILITY
54735547 string_type str(size_type __sub = 0) const
54745548 {
5475 _LIBCPP_ASSERT(ready(), "match_results::str() called when not ready");
5549 _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::str() called when not ready");
54765550 return (*this)[__sub].str();
54775551 }
54785552 _LIBCPP_INLINE_VISIBILITY
54795553 const_reference operator[](size_type __n) const
54805554 {
5481 _LIBCPP_ASSERT(ready(), "match_results::operator[]() called when not ready");
5555 _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::operator[]() called when not ready");
54825556 return __n < __matches_.size() ? __matches_[__n] : __unmatched_;
54835557 }
54845558
54855559 _LIBCPP_INLINE_VISIBILITY
54865560 const_reference prefix() const
54875561 {
5488 _LIBCPP_ASSERT(ready(), "match_results::prefix() called when not ready");
5562 _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::prefix() called when not ready");
54895563 return __prefix_;
54905564 }
54915565 _LIBCPP_INLINE_VISIBILITY
54925566 const_reference suffix() const
54935567 {
5494 _LIBCPP_ASSERT(ready(), "match_results::suffix() called when not ready");
5568 _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::suffix() called when not ready");
54955569 return __suffix_;
54965570 }
54975571
......@@ -5631,7 +5705,7 @@ match_results<_BidirectionalIterator, _Allocator>::format(_OutputIter __output_i
56315705 const char_type* __fmt_first, const char_type* __fmt_last,
56325706 regex_constants::match_flag_type __flags) const
56335707{
5634 _LIBCPP_ASSERT(ready(), "match_results::format() called when not ready");
5708 _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::format() called when not ready");
56355709 if (__flags & regex_constants::format_sed)
56365710 {
56375711 for (; __fmt_first != __fmt_last; ++__fmt_first)
......@@ -5747,6 +5821,7 @@ operator==(const match_results<_BidirectionalIterator, _Allocator>& __x,
57475821 __x.__suffix_ == __y.__suffix_;
57485822}
57495823
5824#if _LIBCPP_STD_VER < 20
57505825template <class _BidirectionalIterator, class _Allocator>
57515826inline _LIBCPP_INLINE_VISIBILITY
57525827bool
......@@ -5755,6 +5830,7 @@ operator!=(const match_results<_BidirectionalIterator, _Allocator>& __x,
57555830{
57565831 return !(__x == __y);
57575832}
5833#endif
57585834
57595835template <class _BidirectionalIterator, class _Allocator>
57605836inline _LIBCPP_INLINE_VISIBILITY
......@@ -5861,7 +5937,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
58615937{
58625938 deque<__state> __states;
58635939 ptrdiff_t __highest_j = 0;
5864 ptrdiff_t _Np = _VSTD::distance(__first, __last);
5940 ptrdiff_t __np = _VSTD::distance(__first, __last);
58655941 __node* __st = __start_.get();
58665942 if (__st)
58675943 {
......@@ -5904,7 +5980,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
59045980 if (!__matched || __highest_j < __s.__current_ - __s.__first_)
59055981 __highest_j = __s.__current_ - __s.__first_;
59065982 __matched = true;
5907 if (__highest_j == _Np)
5983 if (__highest_j == __np)
59085984 __states.clear();
59095985 else
59105986 __states.pop_back();
......@@ -5956,7 +6032,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
59566032 vector<__state> __states;
59576033 __state __best_state;
59586034 ptrdiff_t __highest_j = 0;
5959 ptrdiff_t _Np = _VSTD::distance(__first, __last);
6035 ptrdiff_t __np = _VSTD::distance(__first, __last);
59606036 __node* __st = __start_.get();
59616037 if (__st)
59626038 {
......@@ -6008,7 +6084,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
60086084 __best_state = __s;
60096085 }
60106086 __matched = true;
6011 if (__highest_j == _Np)
6087 if (__highest_j == __np)
60126088 __states.clear();
60136089 else
60146090 __states.pop_back();
......@@ -6214,7 +6290,7 @@ regex_search(const basic_string<_CharT, _ST, _SA>& __s,
62146290 return __r;
62156291}
62166292
6217#if _LIBCPP_STD_VER > 11
6293#if _LIBCPP_STD_VER >= 14
62186294template <class _ST, class _SA, class _Ap, class _Cp, class _Tp>
62196295bool
62206296regex_search(const basic_string<_Cp, _ST, _SA>&& __s,
......@@ -6277,7 +6353,7 @@ regex_match(const basic_string<_CharT, _ST, _SA>& __s,
62776353 return _VSTD::regex_match(__s.begin(), __s.end(), __m, __e, __flags);
62786354}
62796355
6280#if _LIBCPP_STD_VER > 11
6356#if _LIBCPP_STD_VER >= 14
62816357template <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>
62826358inline _LIBCPP_INLINE_VISIBILITY
62836359bool
......@@ -6350,16 +6426,21 @@ public:
63506426 const regex_type& __re,
63516427 regex_constants::match_flag_type __m
63526428 = regex_constants::match_default);
6353#if _LIBCPP_STD_VER > 11
6429#if _LIBCPP_STD_VER >= 14
63546430 regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
63556431 const regex_type&& __re,
63566432 regex_constants::match_flag_type __m
63576433 = regex_constants::match_default) = delete;
63586434#endif
63596435
6360 bool operator==(const regex_iterator& __x) const;
6436 _LIBCPP_HIDE_FROM_ABI bool operator==(const regex_iterator& __x) const;
6437#if _LIBCPP_STD_VER >= 20
6438 _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const { return *this == regex_iterator(); }
6439#endif
6440#if _LIBCPP_STD_VER < 20
63616441 _LIBCPP_INLINE_VISIBILITY
63626442 bool operator!=(const regex_iterator& __x) const {return !(*this == __x);}
6443#endif
63636444
63646445 _LIBCPP_INLINE_VISIBILITY
63656446 reference operator*() const {return __match_;}
......@@ -6482,7 +6563,7 @@ public:
64826563 const regex_type& __re, int __submatch = 0,
64836564 regex_constants::match_flag_type __m =
64846565 regex_constants::match_default);
6485#if _LIBCPP_STD_VER > 11
6566#if _LIBCPP_STD_VER >= 14
64866567 regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
64876568 const regex_type&& __re, int __submatch = 0,
64886569 regex_constants::match_flag_type __m =
......@@ -6493,7 +6574,7 @@ public:
64936574 const regex_type& __re, const vector<int>& __submatches,
64946575 regex_constants::match_flag_type __m =
64956576 regex_constants::match_default);
6496#if _LIBCPP_STD_VER > 11
6577#if _LIBCPP_STD_VER >= 14
64976578 regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
64986579 const regex_type&& __re, const vector<int>& __submatches,
64996580 regex_constants::match_flag_type __m =
......@@ -6507,7 +6588,7 @@ public:
65076588 regex_constants::match_flag_type __m =
65086589 regex_constants::match_default);
65096590
6510#if _LIBCPP_STD_VER > 11
6591#if _LIBCPP_STD_VER >= 14
65116592 regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
65126593 const regex_type&& __re,
65136594 initializer_list<int> __submatches,
......@@ -6522,7 +6603,7 @@ public:
65226603 const int (&__submatches)[_Np],
65236604 regex_constants::match_flag_type __m =
65246605 regex_constants::match_default);
6525#if _LIBCPP_STD_VER > 11
6606#if _LIBCPP_STD_VER >= 14
65266607 template <size_t _Np>
65276608 regex_token_iterator(_BidirectionalIterator __a,
65286609 _BidirectionalIterator __b,
......@@ -6535,9 +6616,16 @@ public:
65356616 regex_token_iterator(const regex_token_iterator&);
65366617 regex_token_iterator& operator=(const regex_token_iterator&);
65376618
6538 bool operator==(const regex_token_iterator& __x) const;
6619 _LIBCPP_HIDE_FROM_ABI bool operator==(const regex_token_iterator& __x) const;
6620#if _LIBCPP_STD_VER >= 20
6621 _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const {
6622 return *this == regex_token_iterator();
6623 }
6624#endif
6625#if _LIBCPP_STD_VER < 20
65396626 _LIBCPP_INLINE_VISIBILITY
65406627 bool operator!=(const regex_token_iterator& __x) const {return !(*this == __x);}
6628#endif
65416629
65426630 _LIBCPP_INLINE_VISIBILITY
65436631 const value_type& operator*() const {return *__result_;}
......@@ -6844,18 +6932,18 @@ regex_replace(const _CharT* __s,
68446932
68456933_LIBCPP_END_NAMESPACE_STD
68466934
6847#if _LIBCPP_STD_VER > 14
6935#if _LIBCPP_STD_VER >= 17
68486936_LIBCPP_BEGIN_NAMESPACE_STD
68496937namespace pmr {
68506938template <class _BidirT>
6851using match_results = std::match_results<_BidirT, polymorphic_allocator<std::sub_match<_BidirT>>>;
6939using match_results _LIBCPP_AVAILABILITY_PMR = std::match_results<_BidirT, polymorphic_allocator<std::sub_match<_BidirT>>>;
68526940
6853using cmatch = match_results<const char*>;
6854using smatch = match_results<std::pmr::string::const_iterator>;
6941using cmatch _LIBCPP_AVAILABILITY_PMR = match_results<const char*>;
6942using smatch _LIBCPP_AVAILABILITY_PMR = match_results<std::pmr::string::const_iterator>;
68556943
68566944#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
6857using wcmatch = match_results<const wchar_t*>;
6858using wsmatch = match_results<std::pmr::wstring::const_iterator>;
6945using wcmatch _LIBCPP_AVAILABILITY_PMR = match_results<const wchar_t*>;
6946using wsmatch _LIBCPP_AVAILABILITY_PMR = match_results<std::pmr::wstring::const_iterator>;
68596947#endif
68606948} // namespace pmr
68616949_LIBCPP_END_NAMESPACE_STD
......@@ -6866,9 +6954,11 @@ _LIBCPP_POP_MACROS
68666954#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
68676955# include <atomic>
68686956# include <concepts>
6957# include <cstdlib>
68696958# include <iosfwd>
68706959# include <iterator>
68716960# include <new>
6961# include <type_traits>
68726962# include <typeinfo>
68736963# include <utility>
68746964#endif
lib/libcxx/include/scoped_allocator+16-7
......@@ -103,7 +103,7 @@ template <class OuterA1, class OuterA2, class... InnerAllocs>
103103template <class OuterA1, class OuterA2, class... InnerAllocs>
104104 bool
105105 operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
106 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
106 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; // removed in C++20
107107
108108} // std
109109
......@@ -130,6 +130,9 @@ template <class OuterA1, class OuterA2, class... InnerAllocs>
130130# pragma GCC system_header
131131#endif
132132
133_LIBCPP_PUSH_MACROS
134#include <__undef_macros>
135
133136_LIBCPP_BEGIN_NAMESPACE_STD
134137
135138#if !defined(_LIBCPP_CXX03_LANG)
......@@ -531,7 +534,7 @@ public:
531534 __p, _VSTD::forward<_Args>(__args)...);}
532535
533536 template <class _T1, class _T2, class... _Args1, class... _Args2>
534 void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
537 _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
535538 tuple<_Args1...> __x, tuple<_Args2...> __y)
536539 {
537540 typedef __outermost<outer_allocator_type> _OM;
......@@ -555,25 +558,25 @@ public:
555558 }
556559
557560 template <class _T1, class _T2>
558 void construct(pair<_T1, _T2>* __p)
561 _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p)
559562 { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); }
560563
561564 template <class _T1, class _T2, class _Up, class _Vp>
562 void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) {
565 _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) {
563566 construct(__p, piecewise_construct,
564567 _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)),
565568 _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y)));
566569 }
567570
568571 template <class _T1, class _T2, class _Up, class _Vp>
569 void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) {
572 _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) {
570573 construct(__p, piecewise_construct,
571574 _VSTD::forward_as_tuple(__x.first),
572575 _VSTD::forward_as_tuple(__x.second));
573576 }
574577
575578 template <class _T1, class _T2, class _Up, class _Vp>
576 void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) {
579 _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) {
577580 construct(__p, piecewise_construct,
578581 _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)),
579582 _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second)));
......@@ -678,7 +681,7 @@ private:
678681 template <class...> friend class __scoped_allocator_storage;
679682};
680683
681#if _LIBCPP_STD_VER > 14
684#if _LIBCPP_STD_VER >= 17
682685template<class _OuterAlloc, class... _InnerAllocs>
683686 scoped_allocator_adaptor(_OuterAlloc, _InnerAllocs...)
684687 -> scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>;
......@@ -703,6 +706,8 @@ operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>&
703706 __a.inner_allocator() == __b.inner_allocator();
704707}
705708
709#if _LIBCPP_STD_VER <= 17
710
706711template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
707712inline _LIBCPP_INLINE_VISIBILITY
708713bool
......@@ -712,10 +717,14 @@ operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
712717 return !(__a == __b);
713718}
714719
720#endif // _LIBCPP_STD_VER <= 17
721
715722#endif // !defined(_LIBCPP_CXX03_LANG)
716723
717724_LIBCPP_END_NAMESPACE_STD
718725
726_LIBCPP_POP_MACROS
727
719728#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
720729# include <atomic>
721730# include <climits>
lib/libcxx/include/semaphore+42-17
......@@ -46,12 +46,15 @@ using binary_semaphore = counting_semaphore<1>;
4646*/
4747
4848#include <__assert> // all public C++ headers provide the assertion handler
49#include <__atomic/atomic_base.h>
50#include <__atomic/atomic_sync.h>
51#include <__atomic/memory_order.h>
4952#include <__availability>
5053#include <__chrono/time_point.h>
5154#include <__config>
5255#include <__thread/timed_backoff_policy.h>
5356#include <__threading_support>
54#include <atomic>
57#include <cstddef>
5558#include <limits>
5659#include <version>
5760
......@@ -78,6 +81,8 @@ functions. It avoids contention against users' own use of those facilities.
7881
7982*/
8083
84#define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max())
85
8186class __atomic_semaphore_base
8287{
8388 __atomic_base<ptrdiff_t> __a_;
......@@ -90,9 +95,14 @@ public:
9095 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
9196 void release(ptrdiff_t __update = 1)
9297 {
93 if(0 < __a_.fetch_add(__update, memory_order_release))
94 ;
95 else if(__update > 1)
98 auto __old = __a_.fetch_add(__update, memory_order_release);
99 _LIBCPP_ASSERT_UNCATEGORIZED(__update <= _LIBCPP_SEMAPHORE_MAX - __old, "update is greater than the expected value");
100
101 if (__old > 0)
102 {
103 // Nothing to do
104 }
105 else if (__update > 1)
96106 __a_.notify_all();
97107 else
98108 __a_.notify_one();
......@@ -106,11 +116,11 @@ public:
106116 };
107117 __cxx_atomic_wait(&__a_.__a_, __test_fn);
108118 }
109 template <class Rep, class Period>
119 template <class _Rep, class _Period>
110120 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
111 bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time)
121 bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time)
112122 {
113 if (__rel_time == chrono::duration<Rep, Period>::zero())
123 if (__rel_time == chrono::duration<_Rep, _Period>::zero())
114124 return try_acquire();
115125 auto const __test_fn = [this]() { return try_acquire(); };
116126 return std::__libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time);
......@@ -128,20 +138,30 @@ public:
128138 }
129139};
130140
131#define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max())
132
133141template<ptrdiff_t __least_max_value = _LIBCPP_SEMAPHORE_MAX>
134142class counting_semaphore
135143{
136144 __atomic_semaphore_base __semaphore_;
137145
138146public:
147 static_assert(__least_max_value >= 0, "The least maximum value must be a positive number");
148
139149 static constexpr ptrdiff_t max() noexcept {
140150 return __least_max_value;
141151 }
142152
143153 _LIBCPP_INLINE_VISIBILITY
144 constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore_(__count) { }
154 constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore_(__count)
155 {
156 _LIBCPP_ASSERT_UNCATEGORIZED(
157 __count >= 0,
158 "counting_semaphore::counting_semaphore(ptrdiff_t): counting_semaphore cannot be "
159 "initialized with a negative value");
160 _LIBCPP_ASSERT_UNCATEGORIZED(
161 __count <= max(),
162 "counting_semaphore::counting_semaphore(ptrdiff_t): counting_semaphore cannot be "
163 "initialized with a value greater than max()");
164 }
145165 ~counting_semaphore() = default;
146166
147167 counting_semaphore(const counting_semaphore&) = delete;
......@@ -150,6 +170,7 @@ public:
150170 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
151171 void release(ptrdiff_t __update = 1)
152172 {
173 _LIBCPP_ASSERT_UNCATEGORIZED(__update >= 0, "counting_semaphore:release called with a negative value");
153174 __semaphore_.release(__update);
154175 }
155176 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
......@@ -157,9 +178,9 @@ public:
157178 {
158179 __semaphore_.acquire();
159180 }
160 template<class Rep, class Period>
181 template<class _Rep, class _Period>
161182 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
162 bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time)
183 bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time)
163184 {
164185 return __semaphore_.try_acquire_for(chrono::duration_cast<chrono::nanoseconds>(__rel_time));
165186 }
......@@ -168,15 +189,15 @@ public:
168189 {
169190 return __semaphore_.try_acquire();
170191 }
171 template <class Clock, class Duration>
192 template <class _Clock, class _Duration>
172193 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
173 bool try_acquire_until(chrono::time_point<Clock, Duration> const& __abs_time)
194 bool try_acquire_until(chrono::time_point<_Clock, _Duration> const& __abs_time)
174195 {
175 auto const current = Clock::now();
176 if (current >= __abs_time)
196 auto const __current = _Clock::now();
197 if (__current >= __abs_time)
177198 return try_acquire();
178199 else
179 return try_acquire_for(__abs_time - current);
200 return try_acquire_for(__abs_time - __current);
180201 }
181202};
182203
......@@ -188,4 +209,8 @@ _LIBCPP_END_NAMESPACE_STD
188209
189210_LIBCPP_POP_MACROS
190211
212#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
213# include <atomic>
214#endif
215
191216#endif //_LIBCPP_SEMAPHORE
lib/libcxx/include/set+216-55
......@@ -56,6 +56,8 @@ public:
5656 template <class InputIterator>
5757 set(InputIterator first, InputIterator last, const value_compare& comp,
5858 const allocator_type& a);
59 template<container-compatible-range<value_type> R>
60 set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
5961 set(const set& s);
6062 set(set&& s)
6163 noexcept(
......@@ -70,6 +72,9 @@ public:
7072 template <class InputIterator>
7173 set(InputIterator first, InputIterator last, const allocator_type& a)
7274 : set(first, last, Compare(), a) {} // C++14
75 template<container-compatible-range<value_type> R>
76 set(from_range_t, R&& rg, const Allocator& a))
77 : set(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
7378 set(initializer_list<value_type> il, const allocator_type& a)
7479 : set(il, Compare(), a) {} // C++14
7580 ~set();
......@@ -114,6 +119,8 @@ public:
114119 iterator insert(const_iterator position, value_type&& v);
115120 template <class InputIterator>
116121 void insert(InputIterator first, InputIterator last);
122 template<container-compatible-range<value_type> R>
123 void insert_range(R&& rg); // C++23
117124 void insert(initializer_list<value_type> il);
118125
119126 node_type extract(const_iterator position); // C++17
......@@ -190,6 +197,11 @@ set(InputIterator, InputIterator,
190197 Compare = Compare(), Allocator = Allocator())
191198 -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>; // C++17
192199
200template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
201 class Allocator = allocator<ranges::range_value_t<R>>>
202 set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
203 -> set<ranges::range_value_t<R>, Compare, Allocator>; // C++23
204
193205template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
194206set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
195207 -> set<Key, Compare, Allocator>; // C++17
......@@ -199,6 +211,10 @@ set(InputIterator, InputIterator, Allocator)
199211 -> set<typename iterator_traits<InputIterator>::value_type,
200212 less<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17
201213
214template<ranges::input_range R, class Allocator>
215 set(from_range_t, R&&, Allocator)
216 -> set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>; // C++23
217
202218template<class Key, class Allocator>
203219set(initializer_list<Key>, Allocator) -> set<Key, less<Key>, Allocator>; // C++17
204220
......@@ -210,27 +226,31 @@ operator==(const set<Key, Compare, Allocator>& x,
210226template <class Key, class Compare, class Allocator>
211227bool
212228operator< (const set<Key, Compare, Allocator>& x,
213 const set<Key, Compare, Allocator>& y);
229 const set<Key, Compare, Allocator>& y); // removed in C++20
214230
215231template <class Key, class Compare, class Allocator>
216232bool
217233operator!=(const set<Key, Compare, Allocator>& x,
218 const set<Key, Compare, Allocator>& y);
234 const set<Key, Compare, Allocator>& y); // removed in C++20
219235
220236template <class Key, class Compare, class Allocator>
221237bool
222238operator> (const set<Key, Compare, Allocator>& x,
223 const set<Key, Compare, Allocator>& y);
239 const set<Key, Compare, Allocator>& y); // removed in C++20
224240
225241template <class Key, class Compare, class Allocator>
226242bool
227243operator>=(const set<Key, Compare, Allocator>& x,
228 const set<Key, Compare, Allocator>& y);
244 const set<Key, Compare, Allocator>& y); // removed in C++20
229245
230246template <class Key, class Compare, class Allocator>
231247bool
232248operator<=(const set<Key, Compare, Allocator>& x,
233 const set<Key, Compare, Allocator>& y);
249 const set<Key, Compare, Allocator>& y); // removed in C++20
250
251template<class Key, class Compare, class Allocator>
252 synth-three-way-result<Key> operator<=>(const set<Key, Compare, Allocator>& x,
253 const set<Key, Compare, Allocator>& y); // since C++20
234254
235255// specialized algorithms:
236256template <class Key, class Compare, class Allocator>
......@@ -280,6 +300,9 @@ public:
280300 template <class InputIterator>
281301 multiset(InputIterator first, InputIterator last,
282302 const value_compare& comp, const allocator_type& a);
303 template<container-compatible-range<value_type> R>
304 multiset(from_range_t, R&& rg,
305 const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
283306 multiset(const multiset& s);
284307 multiset(multiset&& s)
285308 noexcept(
......@@ -294,6 +317,9 @@ public:
294317 template <class InputIterator>
295318 multiset(InputIterator first, InputIterator last, const allocator_type& a)
296319 : set(first, last, Compare(), a) {} // C++14
320 template<container-compatible-range<value_type> R>
321 multiset(from_range_t, R&& rg, const Allocator& a))
322 : multiset(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
297323 multiset(initializer_list<value_type> il, const allocator_type& a)
298324 : set(il, Compare(), a) {} // C++14
299325 ~multiset();
......@@ -338,6 +364,8 @@ public:
338364 iterator insert(const_iterator position, value_type&& v);
339365 template <class InputIterator>
340366 void insert(InputIterator first, InputIterator last);
367 template<container-compatible-range<value_type> R>
368 void insert_range(R&& rg); // C++23
341369 void insert(initializer_list<value_type> il);
342370
343371 node_type extract(const_iterator position); // C++17
......@@ -415,6 +443,11 @@ multiset(InputIterator, InputIterator,
415443 Compare = Compare(), Allocator = Allocator())
416444 -> multiset<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>; // C++17
417445
446template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
447 class Allocator = allocator<ranges::range_value_t<R>>>
448 multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
449 -> multiset<ranges::range_value_t<R>, Compare, Allocator>;
450
418451template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
419452multiset(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
420453 -> multiset<Key, Compare, Allocator>; // C++17
......@@ -424,6 +457,10 @@ multiset(InputIterator, InputIterator, Allocator)
424457 -> multiset<typename iterator_traits<InputIterator>::value_type,
425458 less<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17
426459
460template<ranges::input_range R, class Allocator>
461 multiset(from_range_t, R&&, Allocator)
462 -> multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>;
463
427464template<class Key, class Allocator>
428465multiset(initializer_list<Key>, Allocator) -> multiset<Key, less<Key>, Allocator>; // C++17
429466
......@@ -435,27 +472,31 @@ operator==(const multiset<Key, Compare, Allocator>& x,
435472template <class Key, class Compare, class Allocator>
436473bool
437474operator< (const multiset<Key, Compare, Allocator>& x,
438 const multiset<Key, Compare, Allocator>& y);
475 const multiset<Key, Compare, Allocator>& y); // removed in C++20
439476
440477template <class Key, class Compare, class Allocator>
441478bool
442479operator!=(const multiset<Key, Compare, Allocator>& x,
443 const multiset<Key, Compare, Allocator>& y);
480 const multiset<Key, Compare, Allocator>& y); // removed in C++20
444481
445482template <class Key, class Compare, class Allocator>
446483bool
447484operator> (const multiset<Key, Compare, Allocator>& x,
448 const multiset<Key, Compare, Allocator>& y);
485 const multiset<Key, Compare, Allocator>& y); // removed in C++20
449486
450487template <class Key, class Compare, class Allocator>
451488bool
452489operator>=(const multiset<Key, Compare, Allocator>& x,
453 const multiset<Key, Compare, Allocator>& y);
490 const multiset<Key, Compare, Allocator>& y); // removed in C++20
454491
455492template <class Key, class Compare, class Allocator>
456493bool
457494operator<=(const multiset<Key, Compare, Allocator>& x,
458 const multiset<Key, Compare, Allocator>& y);
495 const multiset<Key, Compare, Allocator>& y); // removed in C++20
496
497template<class Key, class Compare, class Allocator>
498 synth-three-way-result<Key> operator<=>(const multiset<Key, Compare, Allocator>& x,
499 const multiset<Key, Compare, Allocator>& y); // since C++20
459500
460501// specialized algorithms:
461502template <class Key, class Compare, class Allocator>
......@@ -473,16 +514,22 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
473514
474515#include <__algorithm/equal.h>
475516#include <__algorithm/lexicographical_compare.h>
517#include <__algorithm/lexicographical_compare_three_way.h>
476518#include <__assert> // all public C++ headers provide the assertion handler
519#include <__availability>
477520#include <__config>
478521#include <__functional/is_transparent.h>
479522#include <__functional/operations.h>
480523#include <__iterator/erase_if_container.h>
481524#include <__iterator/iterator_traits.h>
525#include <__iterator/ranges_iterator_traits.h>
482526#include <__iterator/reverse_iterator.h>
483527#include <__memory/allocator.h>
484528#include <__memory_resource/polymorphic_allocator.h>
485529#include <__node_handle>
530#include <__ranges/concepts.h>
531#include <__ranges/container_compatible_range.h>
532#include <__ranges/from_range.h>
486533#include <__tree>
487534#include <__type_traits/is_allocator.h>
488535#include <__utility/forward.h>
......@@ -547,7 +594,7 @@ public:
547594 typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
548595 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
549596
550#if _LIBCPP_STD_VER > 14
597#if _LIBCPP_STD_VER >= 17
551598 typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
552599 typedef __insert_return_type<iterator, node_type> insert_return_type;
553600#endif
......@@ -593,13 +640,30 @@ public:
593640 insert(__f, __l);
594641 }
595642
596#if _LIBCPP_STD_VER > 11
643#if _LIBCPP_STD_VER >= 23
644 template <_ContainerCompatibleRange<value_type> _Range>
645 _LIBCPP_HIDE_FROM_ABI
646 set(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(),
647 const allocator_type& __a = allocator_type())
648 : __tree_(__comp, __a) {
649 insert_range(std::forward<_Range>(__range));
650 }
651#endif
652
653#if _LIBCPP_STD_VER >= 14
597654 template <class _InputIterator>
598655 _LIBCPP_INLINE_VISIBILITY
599656 set(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
600657 : set(__f, __l, key_compare(), __a) {}
601658#endif
602659
660#if _LIBCPP_STD_VER >= 23
661 template <_ContainerCompatibleRange<value_type> _Range>
662 _LIBCPP_HIDE_FROM_ABI
663 set(from_range_t, _Range&& __range, const allocator_type& __a)
664 : set(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
665#endif
666
603667 _LIBCPP_INLINE_VISIBILITY
604668 set(const set& __s)
605669 : __tree_(__s.__tree_)
......@@ -633,7 +697,7 @@ public:
633697 }
634698
635699#ifndef _LIBCPP_CXX03_LANG
636 set(set&& __s, const allocator_type& __a);
700 _LIBCPP_HIDE_FROM_ABI set(set&& __s, const allocator_type& __a);
637701
638702 _LIBCPP_INLINE_VISIBILITY
639703 set(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
......@@ -650,7 +714,7 @@ public:
650714 insert(__il.begin(), __il.end());
651715 }
652716
653#if _LIBCPP_STD_VER > 11
717#if _LIBCPP_STD_VER >= 14
654718 _LIBCPP_INLINE_VISIBILITY
655719 set(initializer_list<value_type> __il, const allocator_type& __a)
656720 : set(__il, key_compare(), __a) {}
......@@ -742,6 +806,17 @@ public:
742806 __tree_.__insert_unique(__e, *__f);
743807 }
744808
809#if _LIBCPP_STD_VER >= 23
810 template <_ContainerCompatibleRange<value_type> _Range>
811 _LIBCPP_HIDE_FROM_ABI
812 void insert_range(_Range&& __range) {
813 const_iterator __end = cend();
814 for (auto&& __element : __range) {
815 __tree_.__insert_unique(__end, std::forward<decltype(__element)>(__element));
816 }
817 }
818#endif
819
745820#ifndef _LIBCPP_CXX03_LANG
746821 _LIBCPP_INLINE_VISIBILITY
747822 pair<iterator,bool> insert(value_type&& __v)
......@@ -767,11 +842,11 @@ public:
767842 _LIBCPP_INLINE_VISIBILITY
768843 void clear() _NOEXCEPT {__tree_.clear();}
769844
770#if _LIBCPP_STD_VER > 14
845#if _LIBCPP_STD_VER >= 17
771846 _LIBCPP_INLINE_VISIBILITY
772847 insert_return_type insert(node_type&& __nh)
773848 {
774 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
849 _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
775850 "node_type with incompatible allocator passed to set::insert()");
776851 return __tree_.template __node_handle_insert_unique<
777852 node_type, insert_return_type>(_VSTD::move(__nh));
......@@ -779,7 +854,7 @@ public:
779854 _LIBCPP_INLINE_VISIBILITY
780855 iterator insert(const_iterator __hint, node_type&& __nh)
781856 {
782 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
857 _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
783858 "node_type with incompatible allocator passed to set::insert()");
784859 return __tree_.template __node_handle_insert_unique<node_type>(
785860 __hint, _VSTD::move(__nh));
......@@ -798,7 +873,7 @@ public:
798873 _LIBCPP_INLINE_VISIBILITY
799874 void merge(set<key_type, _Compare2, allocator_type>& __source)
800875 {
801 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
876 _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
802877 "merging container with incompatible allocator");
803878 __tree_.__node_handle_merge_unique(__source.__tree_);
804879 }
......@@ -806,7 +881,7 @@ public:
806881 _LIBCPP_INLINE_VISIBILITY
807882 void merge(set<key_type, _Compare2, allocator_type>&& __source)
808883 {
809 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
884 _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
810885 "merging container with incompatible allocator");
811886 __tree_.__node_handle_merge_unique(__source.__tree_);
812887 }
......@@ -814,7 +889,7 @@ public:
814889 _LIBCPP_INLINE_VISIBILITY
815890 void merge(multiset<key_type, _Compare2, allocator_type>& __source)
816891 {
817 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
892 _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
818893 "merging container with incompatible allocator");
819894 __tree_.__node_handle_merge_unique(__source.__tree_);
820895 }
......@@ -822,7 +897,7 @@ public:
822897 _LIBCPP_INLINE_VISIBILITY
823898 void merge(multiset<key_type, _Compare2, allocator_type>&& __source)
824899 {
825 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
900 _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
826901 "merging container with incompatible allocator");
827902 __tree_.__node_handle_merge_unique(__source.__tree_);
828903 }
......@@ -844,7 +919,7 @@ public:
844919 iterator find(const key_type& __k) {return __tree_.find(__k);}
845920 _LIBCPP_INLINE_VISIBILITY
846921 const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
847#if _LIBCPP_STD_VER > 11
922#if _LIBCPP_STD_VER >= 14
848923 template <typename _K2>
849924 _LIBCPP_INLINE_VISIBILITY
850925 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
......@@ -858,21 +933,21 @@ public:
858933 _LIBCPP_INLINE_VISIBILITY
859934 size_type count(const key_type& __k) const
860935 {return __tree_.__count_unique(__k);}
861#if _LIBCPP_STD_VER > 11
936#if _LIBCPP_STD_VER >= 14
862937 template <typename _K2>
863938 _LIBCPP_INLINE_VISIBILITY
864939 typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
865940 count(const _K2& __k) const {return __tree_.__count_multi(__k);}
866941#endif
867942
868#if _LIBCPP_STD_VER > 17
943#if _LIBCPP_STD_VER >= 20
869944 _LIBCPP_INLINE_VISIBILITY
870945 bool contains(const key_type& __k) const {return find(__k) != end();}
871946 template <typename _K2>
872947 _LIBCPP_INLINE_VISIBILITY
873948 typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
874949 contains(const _K2& __k) const { return find(__k) != end(); }
875#endif // _LIBCPP_STD_VER > 17
950#endif // _LIBCPP_STD_VER >= 20
876951
877952 _LIBCPP_INLINE_VISIBILITY
878953 iterator lower_bound(const key_type& __k)
......@@ -880,7 +955,7 @@ public:
880955 _LIBCPP_INLINE_VISIBILITY
881956 const_iterator lower_bound(const key_type& __k) const
882957 {return __tree_.lower_bound(__k);}
883#if _LIBCPP_STD_VER > 11
958#if _LIBCPP_STD_VER >= 14
884959 template <typename _K2>
885960 _LIBCPP_INLINE_VISIBILITY
886961 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
......@@ -898,7 +973,7 @@ public:
898973 _LIBCPP_INLINE_VISIBILITY
899974 const_iterator upper_bound(const key_type& __k) const
900975 {return __tree_.upper_bound(__k);}
901#if _LIBCPP_STD_VER > 11
976#if _LIBCPP_STD_VER >= 14
902977 template <typename _K2>
903978 _LIBCPP_INLINE_VISIBILITY
904979 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
......@@ -915,7 +990,7 @@ public:
915990 _LIBCPP_INLINE_VISIBILITY
916991 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
917992 {return __tree_.__equal_range_unique(__k);}
918#if _LIBCPP_STD_VER > 11
993#if _LIBCPP_STD_VER >= 14
919994 template <typename _K2>
920995 _LIBCPP_INLINE_VISIBILITY
921996 typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
......@@ -931,12 +1006,21 @@ public:
9311006template<class _InputIterator,
9321007 class _Compare = less<__iter_value_type<_InputIterator>>,
9331008 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
934 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
1009 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
9351010 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
9361011 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
9371012set(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
9381013 -> set<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
9391014
1015#if _LIBCPP_STD_VER >= 23
1016template <ranges::input_range _Range, class _Compare = less<ranges::range_value_t<_Range>>,
1017 class _Allocator = allocator<ranges::range_value_t<_Range>>,
1018 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1019 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1020set(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
1021 -> set<ranges::range_value_t<_Range>, _Compare, _Allocator>;
1022#endif
1023
9401024template<class _Key, class _Compare = less<_Key>,
9411025 class _Allocator = allocator<_Key>,
9421026 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
......@@ -945,12 +1029,19 @@ set(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator())
9451029 -> set<_Key, _Compare, _Allocator>;
9461030
9471031template<class _InputIterator, class _Allocator,
948 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
1032 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
9491033 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
9501034set(_InputIterator, _InputIterator, _Allocator)
9511035 -> set<__iter_value_type<_InputIterator>,
9521036 less<__iter_value_type<_InputIterator>>, _Allocator>;
9531037
1038#if _LIBCPP_STD_VER >= 23
1039template <ranges::input_range _Range, class _Allocator,
1040 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1041set(from_range_t, _Range&&, _Allocator)
1042 -> set<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
1043#endif
1044
9541045template<class _Key, class _Allocator,
9551046 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
9561047set(initializer_list<_Key>, _Allocator)
......@@ -982,6 +1073,8 @@ operator==(const set<_Key, _Compare, _Allocator>& __x,
9821073 return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
9831074}
9841075
1076#if _LIBCPP_STD_VER <= 17
1077
9851078template <class _Key, class _Compare, class _Allocator>
9861079inline _LIBCPP_INLINE_VISIBILITY
9871080bool
......@@ -1027,6 +1120,17 @@ operator<=(const set<_Key, _Compare, _Allocator>& __x,
10271120 return !(__y < __x);
10281121}
10291122
1123#else // _LIBCPP_STD_VER <= 17
1124
1125template <class _Key, class _Allocator>
1126_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Key>
1127operator<=>(const set<_Key, _Allocator>& __x, const set<_Key, _Allocator>& __y) {
1128 return std::lexicographical_compare_three_way(
1129 __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Key, _Key>);
1130}
1131
1132#endif // _LIBCPP_STD_VER <= 17
1133
10301134// specialized algorithms:
10311135template <class _Key, class _Compare, class _Allocator>
10321136inline _LIBCPP_INLINE_VISIBILITY
......@@ -1038,7 +1142,7 @@ swap(set<_Key, _Compare, _Allocator>& __x,
10381142 __x.swap(__y);
10391143}
10401144
1041#if _LIBCPP_STD_VER > 17
1145#if _LIBCPP_STD_VER >= 20
10421146template <class _Key, class _Compare, class _Allocator, class _Predicate>
10431147inline _LIBCPP_INLINE_VISIBILITY
10441148 typename set<_Key, _Compare, _Allocator>::size_type
......@@ -1084,7 +1188,7 @@ public:
10841188 typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
10851189 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
10861190
1087#if _LIBCPP_STD_VER > 14
1191#if _LIBCPP_STD_VER >= 17
10881192 typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
10891193#endif
10901194
......@@ -1121,7 +1225,7 @@ public:
11211225 insert(__f, __l);
11221226 }
11231227
1124#if _LIBCPP_STD_VER > 11
1228#if _LIBCPP_STD_VER >= 14
11251229 template <class _InputIterator>
11261230 _LIBCPP_INLINE_VISIBILITY
11271231 multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
......@@ -1137,6 +1241,21 @@ public:
11371241 insert(__f, __l);
11381242 }
11391243
1244#if _LIBCPP_STD_VER >= 23
1245 template <_ContainerCompatibleRange<value_type> _Range>
1246 _LIBCPP_HIDE_FROM_ABI
1247 multiset(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(),
1248 const allocator_type& __a = allocator_type())
1249 : __tree_(__comp, __a) {
1250 insert_range(std::forward<_Range>(__range));
1251 }
1252
1253 template <_ContainerCompatibleRange<value_type> _Range>
1254 _LIBCPP_HIDE_FROM_ABI
1255 multiset(from_range_t, _Range&& __range, const allocator_type& __a)
1256 : multiset(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
1257#endif
1258
11401259 _LIBCPP_INLINE_VISIBILITY
11411260 multiset(const multiset& __s)
11421261 : __tree_(__s.__tree_.value_comp(),
......@@ -1158,7 +1277,7 @@ public:
11581277 _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
11591278 : __tree_(_VSTD::move(__s.__tree_)) {}
11601279
1161 multiset(multiset&& __s, const allocator_type& __a);
1280 _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s, const allocator_type& __a);
11621281#endif // _LIBCPP_CXX03_LANG
11631282 _LIBCPP_INLINE_VISIBILITY
11641283 explicit multiset(const allocator_type& __a)
......@@ -1186,7 +1305,7 @@ public:
11861305 insert(__il.begin(), __il.end());
11871306 }
11881307
1189#if _LIBCPP_STD_VER > 11
1308#if _LIBCPP_STD_VER >= 14
11901309 _LIBCPP_INLINE_VISIBILITY
11911310 multiset(initializer_list<value_type> __il, const allocator_type& __a)
11921311 : multiset(__il, key_compare(), __a) {}
......@@ -1278,6 +1397,17 @@ public:
12781397 __tree_.__insert_multi(__e, *__f);
12791398 }
12801399
1400#if _LIBCPP_STD_VER >= 23
1401 template <_ContainerCompatibleRange<value_type> _Range>
1402 _LIBCPP_HIDE_FROM_ABI
1403 void insert_range(_Range&& __range) {
1404 const_iterator __end = cend();
1405 for (auto&& __element : __range) {
1406 __tree_.__insert_multi(__end, std::forward<decltype(__element)>(__element));
1407 }
1408 }
1409#endif
1410
12811411#ifndef _LIBCPP_CXX03_LANG
12821412 _LIBCPP_INLINE_VISIBILITY
12831413 iterator insert(value_type&& __v)
......@@ -1302,11 +1432,11 @@ public:
13021432 _LIBCPP_INLINE_VISIBILITY
13031433 void clear() _NOEXCEPT {__tree_.clear();}
13041434
1305#if _LIBCPP_STD_VER > 14
1435#if _LIBCPP_STD_VER >= 17
13061436 _LIBCPP_INLINE_VISIBILITY
13071437 iterator insert(node_type&& __nh)
13081438 {
1309 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1439 _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
13101440 "node_type with incompatible allocator passed to multiset::insert()");
13111441 return __tree_.template __node_handle_insert_multi<node_type>(
13121442 _VSTD::move(__nh));
......@@ -1314,7 +1444,7 @@ public:
13141444 _LIBCPP_INLINE_VISIBILITY
13151445 iterator insert(const_iterator __hint, node_type&& __nh)
13161446 {
1317 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1447 _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(),
13181448 "node_type with incompatible allocator passed to multiset::insert()");
13191449 return __tree_.template __node_handle_insert_multi<node_type>(
13201450 __hint, _VSTD::move(__nh));
......@@ -1333,7 +1463,7 @@ public:
13331463 _LIBCPP_INLINE_VISIBILITY
13341464 void merge(multiset<key_type, _Compare2, allocator_type>& __source)
13351465 {
1336 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1466 _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
13371467 "merging container with incompatible allocator");
13381468 __tree_.__node_handle_merge_multi(__source.__tree_);
13391469 }
......@@ -1341,7 +1471,7 @@ public:
13411471 _LIBCPP_INLINE_VISIBILITY
13421472 void merge(multiset<key_type, _Compare2, allocator_type>&& __source)
13431473 {
1344 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1474 _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
13451475 "merging container with incompatible allocator");
13461476 __tree_.__node_handle_merge_multi(__source.__tree_);
13471477 }
......@@ -1349,7 +1479,7 @@ public:
13491479 _LIBCPP_INLINE_VISIBILITY
13501480 void merge(set<key_type, _Compare2, allocator_type>& __source)
13511481 {
1352 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1482 _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
13531483 "merging container with incompatible allocator");
13541484 __tree_.__node_handle_merge_multi(__source.__tree_);
13551485 }
......@@ -1357,7 +1487,7 @@ public:
13571487 _LIBCPP_INLINE_VISIBILITY
13581488 void merge(set<key_type, _Compare2, allocator_type>&& __source)
13591489 {
1360 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1490 _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(),
13611491 "merging container with incompatible allocator");
13621492 __tree_.__node_handle_merge_multi(__source.__tree_);
13631493 }
......@@ -1380,7 +1510,7 @@ public:
13801510 iterator find(const key_type& __k) {return __tree_.find(__k);}
13811511 _LIBCPP_INLINE_VISIBILITY
13821512 const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
1383#if _LIBCPP_STD_VER > 11
1513#if _LIBCPP_STD_VER >= 14
13841514 template <typename _K2>
13851515 _LIBCPP_INLINE_VISIBILITY
13861516 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
......@@ -1394,21 +1524,21 @@ public:
13941524 _LIBCPP_INLINE_VISIBILITY
13951525 size_type count(const key_type& __k) const
13961526 {return __tree_.__count_multi(__k);}
1397#if _LIBCPP_STD_VER > 11
1527#if _LIBCPP_STD_VER >= 14
13981528 template <typename _K2>
13991529 _LIBCPP_INLINE_VISIBILITY
14001530 typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
14011531 count(const _K2& __k) const {return __tree_.__count_multi(__k);}
14021532#endif
14031533
1404#if _LIBCPP_STD_VER > 17
1534#if _LIBCPP_STD_VER >= 20
14051535 _LIBCPP_INLINE_VISIBILITY
14061536 bool contains(const key_type& __k) const {return find(__k) != end();}
14071537 template <typename _K2>
14081538 _LIBCPP_INLINE_VISIBILITY
14091539 typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
14101540 contains(const _K2& __k) const { return find(__k) != end(); }
1411#endif // _LIBCPP_STD_VER > 17
1541#endif // _LIBCPP_STD_VER >= 20
14121542
14131543 _LIBCPP_INLINE_VISIBILITY
14141544 iterator lower_bound(const key_type& __k)
......@@ -1416,7 +1546,7 @@ public:
14161546 _LIBCPP_INLINE_VISIBILITY
14171547 const_iterator lower_bound(const key_type& __k) const
14181548 {return __tree_.lower_bound(__k);}
1419#if _LIBCPP_STD_VER > 11
1549#if _LIBCPP_STD_VER >= 14
14201550 template <typename _K2>
14211551 _LIBCPP_INLINE_VISIBILITY
14221552 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
......@@ -1434,7 +1564,7 @@ public:
14341564 _LIBCPP_INLINE_VISIBILITY
14351565 const_iterator upper_bound(const key_type& __k) const
14361566 {return __tree_.upper_bound(__k);}
1437#if _LIBCPP_STD_VER > 11
1567#if _LIBCPP_STD_VER >= 14
14381568 template <typename _K2>
14391569 _LIBCPP_INLINE_VISIBILITY
14401570 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
......@@ -1451,7 +1581,7 @@ public:
14511581 _LIBCPP_INLINE_VISIBILITY
14521582 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
14531583 {return __tree_.__equal_range_multi(__k);}
1454#if _LIBCPP_STD_VER > 11
1584#if _LIBCPP_STD_VER >= 14
14551585 template <typename _K2>
14561586 _LIBCPP_INLINE_VISIBILITY
14571587 typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
......@@ -1467,12 +1597,21 @@ public:
14671597template<class _InputIterator,
14681598 class _Compare = less<__iter_value_type<_InputIterator>>,
14691599 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
1470 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
1600 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
14711601 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
14721602 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
14731603multiset(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
14741604 -> multiset<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
14751605
1606#if _LIBCPP_STD_VER >= 23
1607template <ranges::input_range _Range, class _Compare = less<ranges::range_value_t<_Range>>,
1608 class _Allocator = allocator<ranges::range_value_t<_Range>>,
1609 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1610 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1611multiset(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
1612 -> multiset<ranges::range_value_t<_Range>, _Compare, _Allocator>;
1613#endif
1614
14761615template<class _Key, class _Compare = less<_Key>,
14771616 class _Allocator = allocator<_Key>,
14781617 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
......@@ -1481,12 +1620,19 @@ multiset(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator(
14811620 -> multiset<_Key, _Compare, _Allocator>;
14821621
14831622template<class _InputIterator, class _Allocator,
1484 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
1623 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
14851624 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
14861625multiset(_InputIterator, _InputIterator, _Allocator)
14871626 -> multiset<__iter_value_type<_InputIterator>,
14881627 less<__iter_value_type<_InputIterator>>, _Allocator>;
14891628
1629#if _LIBCPP_STD_VER >= 23
1630template <ranges::input_range _Range, class _Allocator,
1631 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1632multiset(from_range_t, _Range&&, _Allocator)
1633 -> multiset<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
1634#endif
1635
14901636template<class _Key, class _Allocator,
14911637 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
14921638multiset(initializer_list<_Key>, _Allocator)
......@@ -1518,6 +1664,8 @@ operator==(const multiset<_Key, _Compare, _Allocator>& __x,
15181664 return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
15191665}
15201666
1667#if _LIBCPP_STD_VER <= 17
1668
15211669template <class _Key, class _Compare, class _Allocator>
15221670inline _LIBCPP_INLINE_VISIBILITY
15231671bool
......@@ -1563,6 +1711,17 @@ operator<=(const multiset<_Key, _Compare, _Allocator>& __x,
15631711 return !(__y < __x);
15641712}
15651713
1714#else // _LIBCPP_STD_VER <= 17
1715
1716template <class _Key, class _Allocator>
1717_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Key>
1718operator<=>(const multiset<_Key, _Allocator>& __x, const multiset<_Key, _Allocator>& __y) {
1719 return std::lexicographical_compare_three_way(
1720 __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Key, _Key>);
1721}
1722
1723#endif // _LIBCPP_STD_VER <= 17
1724
15661725template <class _Key, class _Compare, class _Allocator>
15671726inline _LIBCPP_INLINE_VISIBILITY
15681727void
......@@ -1573,7 +1732,7 @@ swap(multiset<_Key, _Compare, _Allocator>& __x,
15731732 __x.swap(__y);
15741733}
15751734
1576#if _LIBCPP_STD_VER > 17
1735#if _LIBCPP_STD_VER >= 20
15771736template <class _Key, class _Compare, class _Allocator, class _Predicate>
15781737inline _LIBCPP_INLINE_VISIBILITY
15791738 typename multiset<_Key, _Compare, _Allocator>::size_type
......@@ -1584,22 +1743,24 @@ inline _LIBCPP_INLINE_VISIBILITY
15841743
15851744_LIBCPP_END_NAMESPACE_STD
15861745
1587#if _LIBCPP_STD_VER > 14
1746#if _LIBCPP_STD_VER >= 17
15881747_LIBCPP_BEGIN_NAMESPACE_STD
15891748namespace pmr {
15901749template <class _KeyT, class _CompareT = std::less<_KeyT>>
1591using set = std::set<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
1750using set _LIBCPP_AVAILABILITY_PMR = std::set<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
15921751
15931752template <class _KeyT, class _CompareT = std::less<_KeyT>>
1594using multiset = std::multiset<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
1753using multiset _LIBCPP_AVAILABILITY_PMR = std::multiset<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
15951754} // namespace pmr
15961755_LIBCPP_END_NAMESPACE_STD
15971756#endif
15981757
15991758#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
16001759# include <concepts>
1760# include <cstdlib>
16011761# include <functional>
16021762# include <iterator>
1763# include <type_traits>
16031764#endif
16041765
16051766#endif // _LIBCPP_SET
lib/libcxx/include/shared_mutex+262-305
......@@ -124,386 +124,343 @@ template <class Mutex>
124124
125125#include <__assert> // all public C++ headers provide the assertion handler
126126#include <__availability>
127#include <__chrono/duration.h>
128#include <__chrono/steady_clock.h>
129#include <__chrono/time_point.h>
130#include <__condition_variable/condition_variable.h>
127131#include <__config>
132#include <__memory/addressof.h>
133#include <__mutex/mutex.h>
134#include <__mutex/tag_types.h>
135#include <__mutex/unique_lock.h>
136#include <__system_error/system_error.h>
137#include <__utility/swap.h>
138#include <cerrno>
128139#include <version>
129140
130141_LIBCPP_PUSH_MACROS
131142#include <__undef_macros>
132143
144#if _LIBCPP_STD_VER >= 14
133145
134#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_LIBRARY)
146# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
147# pragma GCC system_header
148# endif
135149
136#include <__mutex_base>
137
138#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
139# pragma GCC system_header
140#endif
141
142#ifdef _LIBCPP_HAS_NO_THREADS
143# error "<shared_mutex> is not supported since libc++ has been configured without support for threads."
144#endif
150# ifdef _LIBCPP_HAS_NO_THREADS
151# error "<shared_mutex> is not supported since libc++ has been configured without support for threads."
152# endif
145153
146154_LIBCPP_BEGIN_NAMESPACE_STD
147155
148struct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("shared_mutex"))
149__shared_mutex_base
150{
151 mutex __mut_;
152 condition_variable __gate1_;
153 condition_variable __gate2_;
154 unsigned __state_;
156struct _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_SHARED_MUTEX __shared_mutex_base {
157 mutex __mut_;
158 condition_variable __gate1_;
159 condition_variable __gate2_;
160 unsigned __state_;
155161
156 static const unsigned __write_entered_ = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1);
157 static const unsigned __n_readers_ = ~__write_entered_;
162 static const unsigned __write_entered_ = 1U << (sizeof(unsigned) * __CHAR_BIT__ - 1);
163 static const unsigned __n_readers_ = ~__write_entered_;
158164
159 __shared_mutex_base();
160 _LIBCPP_INLINE_VISIBILITY ~__shared_mutex_base() = default;
165 __shared_mutex_base();
166 _LIBCPP_HIDE_FROM_ABI ~__shared_mutex_base() = default;
161167
162 __shared_mutex_base(const __shared_mutex_base&) = delete;
163 __shared_mutex_base& operator=(const __shared_mutex_base&) = delete;
168 __shared_mutex_base(const __shared_mutex_base&) = delete;
169 __shared_mutex_base& operator=(const __shared_mutex_base&) = delete;
164170
165 // Exclusive ownership
166 void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); // blocking
167 bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
168 void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
171 // Exclusive ownership
172 void lock(); // blocking
173 bool try_lock();
174 void unlock();
169175
170 // Shared ownership
171 void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_shared_capability()); // blocking
172 bool try_lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_shared_capability(true));
173 void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_shared_capability());
176 // Shared ownership
177 void lock_shared(); // blocking
178 bool try_lock_shared();
179 void unlock_shared();
174180
175// typedef implementation-defined native_handle_type; // See 30.2.3
176// native_handle_type native_handle(); // See 30.2.3
181 // typedef implementation-defined native_handle_type; // See 30.2.3
182 // native_handle_type native_handle(); // See 30.2.3
177183};
178184
185# if _LIBCPP_STD_VER >= 17
186class _LIBCPP_EXPORTED_FROM_ABI
187 _LIBCPP_AVAILABILITY_SHARED_MUTEX _LIBCPP_THREAD_SAFETY_ANNOTATION(__capability__("shared_mutex")) shared_mutex {
188 __shared_mutex_base __base_;
179189
180#if _LIBCPP_STD_VER > 14
181class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX shared_mutex
182{
183 __shared_mutex_base __base_;
184190public:
185 _LIBCPP_INLINE_VISIBILITY shared_mutex() : __base_() {}
186 _LIBCPP_INLINE_VISIBILITY ~shared_mutex() = default;
187
188 shared_mutex(const shared_mutex&) = delete;
189 shared_mutex& operator=(const shared_mutex&) = delete;
190
191 // Exclusive ownership
192 _LIBCPP_INLINE_VISIBILITY void lock() { return __base_.lock(); }
193 _LIBCPP_INLINE_VISIBILITY bool try_lock() { return __base_.try_lock(); }
194 _LIBCPP_INLINE_VISIBILITY void unlock() { return __base_.unlock(); }
195
196 // Shared ownership
197 _LIBCPP_INLINE_VISIBILITY void lock_shared() { return __base_.lock_shared(); }
198 _LIBCPP_INLINE_VISIBILITY bool try_lock_shared() { return __base_.try_lock_shared(); }
199 _LIBCPP_INLINE_VISIBILITY void unlock_shared() { return __base_.unlock_shared(); }
200
201// typedef __shared_mutex_base::native_handle_type native_handle_type;
202// _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() { return __base::unlock_shared(); }
191 _LIBCPP_HIDE_FROM_ABI shared_mutex() : __base_() {}
192 _LIBCPP_HIDE_FROM_ABI ~shared_mutex() = default;
193
194 shared_mutex(const shared_mutex&) = delete;
195 shared_mutex& operator=(const shared_mutex&) = delete;
196
197 // Exclusive ownership
198 _LIBCPP_HIDE_FROM_ABI void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_capability__()) {
199 return __base_.lock();
200 }
201 _LIBCPP_HIDE_FROM_ABI bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)) {
202 return __base_.try_lock();
203 }
204 _LIBCPP_HIDE_FROM_ABI void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_capability__()) {
205 return __base_.unlock();
206 }
207
208 // Shared ownership
209 _LIBCPP_HIDE_FROM_ABI void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_shared_capability__()) {
210 return __base_.lock_shared();
211 }
212 _LIBCPP_HIDE_FROM_ABI bool try_lock_shared()
213 _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)) {
214 return __base_.try_lock_shared();
215 }
216 _LIBCPP_HIDE_FROM_ABI void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_shared_capability__()) {
217 return __base_.unlock_shared();
218 }
219
220 // typedef __shared_mutex_base::native_handle_type native_handle_type;
221 // _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return __base::unlock_shared(); }
203222};
204#endif
223# endif
205224
225class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_SHARED_MUTEX _LIBCPP_THREAD_SAFETY_ANNOTATION(
226 __capability__("shared_timed_mutex")) shared_timed_mutex {
227 __shared_mutex_base __base_;
206228
207class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX shared_timed_mutex
208{
209 __shared_mutex_base __base_;
210229public:
211 shared_timed_mutex();
212 _LIBCPP_INLINE_VISIBILITY ~shared_timed_mutex() = default;
213
214 shared_timed_mutex(const shared_timed_mutex&) = delete;
215 shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
216
217 // Exclusive ownership
218 void lock();
219 bool try_lock();
220 template <class _Rep, class _Period>
221 _LIBCPP_INLINE_VISIBILITY
222 bool
223 try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)
224 {
225 return try_lock_until(chrono::steady_clock::now() + __rel_time);
226 }
227 template <class _Clock, class _Duration>
228 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
229 bool
230 try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
231 void unlock();
232
233 // Shared ownership
234 void lock_shared();
235 bool try_lock_shared();
236 template <class _Rep, class _Period>
237 _LIBCPP_INLINE_VISIBILITY
238 bool
239 try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time)
240 {
241 return try_lock_shared_until(chrono::steady_clock::now() + __rel_time);
242 }
243 template <class _Clock, class _Duration>
244 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
245 bool
246 try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
247 void unlock_shared();
230 shared_timed_mutex();
231 _LIBCPP_HIDE_FROM_ABI ~shared_timed_mutex() = default;
232
233 shared_timed_mutex(const shared_timed_mutex&) = delete;
234 shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
235
236 // Exclusive ownership
237 void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_capability__());
238 bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true));
239 template <class _Rep, class _Period>
240 _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)
241 _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)) {
242 return try_lock_until(chrono::steady_clock::now() + __rel_time);
243 }
244 template <class _Clock, class _Duration>
245 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
246 try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
247 _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true));
248 void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_capability__());
249
250 // Shared ownership
251 void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_shared_capability__());
252 bool try_lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true));
253 template <class _Rep, class _Period>
254 _LIBCPP_HIDE_FROM_ABI bool try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time)
255 _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)) {
256 return try_lock_shared_until(chrono::steady_clock::now() + __rel_time);
257 }
258 template <class _Clock, class _Duration>
259 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
260 try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
261 _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true));
262 void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_shared_capability__());
248263};
249264
250265template <class _Clock, class _Duration>
251bool
252shared_timed_mutex::try_lock_until(
253 const chrono::time_point<_Clock, _Duration>& __abs_time)
254{
255 unique_lock<mutex> __lk(__base_.__mut_);
256 if (__base_.__state_ & __base_.__write_entered_)
257 {
258 while (true)
259 {
260 cv_status __status = __base_.__gate1_.wait_until(__lk, __abs_time);
261 if ((__base_.__state_ & __base_.__write_entered_) == 0)
262 break;
263 if (__status == cv_status::timeout)
264 return false;
265 }
266bool shared_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) {
267 unique_lock<mutex> __lk(__base_.__mut_);
268 if (__base_.__state_ & __base_.__write_entered_) {
269 while (true) {
270 cv_status __status = __base_.__gate1_.wait_until(__lk, __abs_time);
271 if ((__base_.__state_ & __base_.__write_entered_) == 0)
272 break;
273 if (__status == cv_status::timeout)
274 return false;
266275 }
267 __base_.__state_ |= __base_.__write_entered_;
268 if (__base_.__state_ & __base_.__n_readers_)
269 {
270 while (true)
271 {
272 cv_status __status = __base_.__gate2_.wait_until(__lk, __abs_time);
273 if ((__base_.__state_ & __base_.__n_readers_) == 0)
274 break;
275 if (__status == cv_status::timeout)
276 {
277 __base_.__state_ &= ~__base_.__write_entered_;
278 __base_.__gate1_.notify_all();
279 return false;
280 }
281 }
276 }
277 __base_.__state_ |= __base_.__write_entered_;
278 if (__base_.__state_ & __base_.__n_readers_) {
279 while (true) {
280 cv_status __status = __base_.__gate2_.wait_until(__lk, __abs_time);
281 if ((__base_.__state_ & __base_.__n_readers_) == 0)
282 break;
283 if (__status == cv_status::timeout) {
284 __base_.__state_ &= ~__base_.__write_entered_;
285 __base_.__gate1_.notify_all();
286 return false;
287 }
282288 }
283 return true;
289 }
290 return true;
284291}
285292
286293template <class _Clock, class _Duration>
287bool
288shared_timed_mutex::try_lock_shared_until(
289 const chrono::time_point<_Clock, _Duration>& __abs_time)
290{
291 unique_lock<mutex> __lk(__base_.__mut_);
292 if ((__base_.__state_ & __base_.__write_entered_) || (__base_.__state_ & __base_.__n_readers_) == __base_.__n_readers_)
293 {
294 while (true)
295 {
296 cv_status status = __base_.__gate1_.wait_until(__lk, __abs_time);
297 if ((__base_.__state_ & __base_.__write_entered_) == 0 &&
298 (__base_.__state_ & __base_.__n_readers_) < __base_.__n_readers_)
299 break;
300 if (status == cv_status::timeout)
301 return false;
302 }
294bool shared_timed_mutex::try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time) {
295 unique_lock<mutex> __lk(__base_.__mut_);
296 if ((__base_.__state_ & __base_.__write_entered_) ||
297 (__base_.__state_ & __base_.__n_readers_) == __base_.__n_readers_) {
298 while (true) {
299 cv_status __status = __base_.__gate1_.wait_until(__lk, __abs_time);
300 if ((__base_.__state_ & __base_.__write_entered_) == 0 &&
301 (__base_.__state_ & __base_.__n_readers_) < __base_.__n_readers_)
302 break;
303 if (__status == cv_status::timeout)
304 return false;
303305 }
304 unsigned __num_readers = (__base_.__state_ & __base_.__n_readers_) + 1;
305 __base_.__state_ &= ~__base_.__n_readers_;
306 __base_.__state_ |= __num_readers;
307 return true;
306 }
307 unsigned __num_readers = (__base_.__state_ & __base_.__n_readers_) + 1;
308 __base_.__state_ &= ~__base_.__n_readers_;
309 __base_.__state_ |= __num_readers;
310 return true;
308311}
309312
310313template <class _Mutex>
311class shared_lock
312{
314class shared_lock {
313315public:
314 typedef _Mutex mutex_type;
316 typedef _Mutex mutex_type;
315317
316318private:
317 mutex_type* __m_;
318 bool __owns_;
319 mutex_type* __m_;
320 bool __owns_;
319321
320322public:
321 _LIBCPP_INLINE_VISIBILITY
322 shared_lock() _NOEXCEPT
323 : __m_(nullptr),
324 __owns_(false)
325 {}
326
327 _LIBCPP_INLINE_VISIBILITY
328 explicit shared_lock(mutex_type& __m)
329 : __m_(_VSTD::addressof(__m)),
330 __owns_(true)
331 {__m_->lock_shared();}
332
333 _LIBCPP_INLINE_VISIBILITY
334 shared_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT
335 : __m_(_VSTD::addressof(__m)),
336 __owns_(false)
337 {}
338
339 _LIBCPP_INLINE_VISIBILITY
340 shared_lock(mutex_type& __m, try_to_lock_t)
341 : __m_(_VSTD::addressof(__m)),
342 __owns_(__m.try_lock_shared())
343 {}
344
345 _LIBCPP_INLINE_VISIBILITY
346 shared_lock(mutex_type& __m, adopt_lock_t)
347 : __m_(_VSTD::addressof(__m)),
348 __owns_(true)
349 {}
350
351 template <class _Clock, class _Duration>
352 _LIBCPP_INLINE_VISIBILITY
353 shared_lock(mutex_type& __m,
354 const chrono::time_point<_Clock, _Duration>& __abs_time)
355 : __m_(_VSTD::addressof(__m)),
356 __owns_(__m.try_lock_shared_until(__abs_time))
357 {}
358
359 template <class _Rep, class _Period>
360 _LIBCPP_INLINE_VISIBILITY
361 shared_lock(mutex_type& __m,
362 const chrono::duration<_Rep, _Period>& __rel_time)
363 : __m_(_VSTD::addressof(__m)),
364 __owns_(__m.try_lock_shared_for(__rel_time))
365 {}
366
367 _LIBCPP_INLINE_VISIBILITY
368 ~shared_lock()
369 {
370 if (__owns_)
371 __m_->unlock_shared();
372 }
323 _LIBCPP_HIDE_FROM_ABI shared_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {}
373324
374 shared_lock(shared_lock const&) = delete;
375 shared_lock& operator=(shared_lock const&) = delete;
325 _LIBCPP_HIDE_FROM_ABI explicit shared_lock(mutex_type& __m) : __m_(_VSTD::addressof(__m)), __owns_(true) {
326 __m_->lock_shared();
327 }
376328
377 _LIBCPP_INLINE_VISIBILITY
378 shared_lock(shared_lock&& __u) _NOEXCEPT
379 : __m_(__u.__m_),
380 __owns_(__u.__owns_)
381 {
382 __u.__m_ = nullptr;
383 __u.__owns_ = false;
384 }
385
386 _LIBCPP_INLINE_VISIBILITY
387 shared_lock& operator=(shared_lock&& __u) _NOEXCEPT
388 {
389 if (__owns_)
390 __m_->unlock_shared();
391 __m_ = nullptr;
392 __owns_ = false;
393 __m_ = __u.__m_;
394 __owns_ = __u.__owns_;
395 __u.__m_ = nullptr;
396 __u.__owns_ = false;
397 return *this;
398 }
329 _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT
330 : __m_(_VSTD::addressof(__m)),
331 __owns_(false) {}
399332
400 void lock();
401 bool try_lock();
402 template <class Rep, class Period>
403 bool try_lock_for(const chrono::duration<Rep, Period>& __rel_time);
404 template <class Clock, class Duration>
405 bool try_lock_until(const chrono::time_point<Clock, Duration>& __abs_time);
406 void unlock();
333 _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, try_to_lock_t)
334 : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared()) {}
407335
408 // Setters
409 _LIBCPP_INLINE_VISIBILITY
410 void swap(shared_lock& __u) _NOEXCEPT
411 {
412 _VSTD::swap(__m_, __u.__m_);
413 _VSTD::swap(__owns_, __u.__owns_);
414 }
336 _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, adopt_lock_t) : __m_(_VSTD::addressof(__m)), __owns_(true) {}
415337
416 _LIBCPP_INLINE_VISIBILITY
417 mutex_type* release() _NOEXCEPT
418 {
419 mutex_type* __m = __m_;
420 __m_ = nullptr;
421 __owns_ = false;
422 return __m;
423 }
338 template <class _Clock, class _Duration>
339 _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __abs_time)
340 : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared_until(__abs_time)) {}
424341
425 // Getters
426 _LIBCPP_INLINE_VISIBILITY
427 bool owns_lock() const _NOEXCEPT {return __owns_;}
342 template <class _Rep, class _Period>
343 _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __rel_time)
344 : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared_for(__rel_time)) {}
428345
429 _LIBCPP_INLINE_VISIBILITY
430 explicit operator bool () const _NOEXCEPT {return __owns_;}
346 _LIBCPP_HIDE_FROM_ABI ~shared_lock() {
347 if (__owns_)
348 __m_->unlock_shared();
349 }
350
351 shared_lock(shared_lock const&) = delete;
352 shared_lock& operator=(shared_lock const&) = delete;
353
354 _LIBCPP_HIDE_FROM_ABI shared_lock(shared_lock&& __u) _NOEXCEPT : __m_(__u.__m_), __owns_(__u.__owns_) {
355 __u.__m_ = nullptr;
356 __u.__owns_ = false;
357 }
431358
432 _LIBCPP_INLINE_VISIBILITY
433 mutex_type* mutex() const _NOEXCEPT {return __m_;}
359 _LIBCPP_HIDE_FROM_ABI shared_lock& operator=(shared_lock&& __u) _NOEXCEPT {
360 if (__owns_)
361 __m_->unlock_shared();
362 __m_ = nullptr;
363 __owns_ = false;
364 __m_ = __u.__m_;
365 __owns_ = __u.__owns_;
366 __u.__m_ = nullptr;
367 __u.__owns_ = false;
368 return *this;
369 }
370
371 _LIBCPP_HIDE_FROM_ABI void lock();
372 _LIBCPP_HIDE_FROM_ABI bool try_lock();
373 template <class _Rep, class _Period>
374 _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time);
375 template <class _Clock, class _Duration>
376 _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
377 _LIBCPP_HIDE_FROM_ABI void unlock();
378
379 // Setters
380 _LIBCPP_HIDE_FROM_ABI void swap(shared_lock& __u) _NOEXCEPT {
381 _VSTD::swap(__m_, __u.__m_);
382 _VSTD::swap(__owns_, __u.__owns_);
383 }
384
385 _LIBCPP_HIDE_FROM_ABI mutex_type* release() _NOEXCEPT {
386 mutex_type* __m = __m_;
387 __m_ = nullptr;
388 __owns_ = false;
389 return __m;
390 }
391
392 // Getters
393 _LIBCPP_HIDE_FROM_ABI bool owns_lock() const _NOEXCEPT { return __owns_; }
394
395 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __owns_; }
396
397 _LIBCPP_HIDE_FROM_ABI mutex_type* mutex() const _NOEXCEPT { return __m_; }
434398};
435399_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(shared_lock);
436400
437401template <class _Mutex>
438void
439shared_lock<_Mutex>::lock()
440{
441 if (__m_ == nullptr)
442 __throw_system_error(EPERM, "shared_lock::lock: references null mutex");
443 if (__owns_)
444 __throw_system_error(EDEADLK, "shared_lock::lock: already locked");
445 __m_->lock_shared();
446 __owns_ = true;
402void shared_lock<_Mutex>::lock() {
403 if (__m_ == nullptr)
404 __throw_system_error(EPERM, "shared_lock::lock: references null mutex");
405 if (__owns_)
406 __throw_system_error(EDEADLK, "shared_lock::lock: already locked");
407 __m_->lock_shared();
408 __owns_ = true;
447409}
448410
449411template <class _Mutex>
450bool
451shared_lock<_Mutex>::try_lock()
452{
453 if (__m_ == nullptr)
454 __throw_system_error(EPERM, "shared_lock::try_lock: references null mutex");
455 if (__owns_)
456 __throw_system_error(EDEADLK, "shared_lock::try_lock: already locked");
457 __owns_ = __m_->try_lock_shared();
458 return __owns_;
412bool shared_lock<_Mutex>::try_lock() {
413 if (__m_ == nullptr)
414 __throw_system_error(EPERM, "shared_lock::try_lock: references null mutex");
415 if (__owns_)
416 __throw_system_error(EDEADLK, "shared_lock::try_lock: already locked");
417 __owns_ = __m_->try_lock_shared();
418 return __owns_;
459419}
460420
461421template <class _Mutex>
462422template <class _Rep, class _Period>
463bool
464shared_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d)
465{
466 if (__m_ == nullptr)
467 __throw_system_error(EPERM, "shared_lock::try_lock_for: references null mutex");
468 if (__owns_)
469 __throw_system_error(EDEADLK, "shared_lock::try_lock_for: already locked");
470 __owns_ = __m_->try_lock_shared_for(__d);
471 return __owns_;
423bool shared_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
424 if (__m_ == nullptr)
425 __throw_system_error(EPERM, "shared_lock::try_lock_for: references null mutex");
426 if (__owns_)
427 __throw_system_error(EDEADLK, "shared_lock::try_lock_for: already locked");
428 __owns_ = __m_->try_lock_shared_for(__d);
429 return __owns_;
472430}
473431
474432template <class _Mutex>
475433template <class _Clock, class _Duration>
476bool
477shared_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
478{
479 if (__m_ == nullptr)
480 __throw_system_error(EPERM, "shared_lock::try_lock_until: references null mutex");
481 if (__owns_)
482 __throw_system_error(EDEADLK, "shared_lock::try_lock_until: already locked");
483 __owns_ = __m_->try_lock_shared_until(__t);
484 return __owns_;
434bool shared_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
435 if (__m_ == nullptr)
436 __throw_system_error(EPERM, "shared_lock::try_lock_until: references null mutex");
437 if (__owns_)
438 __throw_system_error(EDEADLK, "shared_lock::try_lock_until: already locked");
439 __owns_ = __m_->try_lock_shared_until(__t);
440 return __owns_;
485441}
486442
487443template <class _Mutex>
488void
489shared_lock<_Mutex>::unlock()
490{
491 if (!__owns_)
492 __throw_system_error(EPERM, "shared_lock::unlock: not locked");
493 __m_->unlock_shared();
494 __owns_ = false;
444void shared_lock<_Mutex>::unlock() {
445 if (!__owns_)
446 __throw_system_error(EPERM, "shared_lock::unlock: not locked");
447 __m_->unlock_shared();
448 __owns_ = false;
495449}
496450
497451template <class _Mutex>
498inline _LIBCPP_INLINE_VISIBILITY
499void
500swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) _NOEXCEPT
501 {__x.swap(__y);}
452inline _LIBCPP_HIDE_FROM_ABI void swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) _NOEXCEPT {
453 __x.swap(__y);
454}
502455
503456_LIBCPP_END_NAMESPACE_STD
504457
505#endif // _LIBCPP_STD_VER > 11
458#endif // _LIBCPP_STD_VER >= 14
506459
507460_LIBCPP_POP_MACROS
508461
462#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
463# include <system_error>
464#endif
465
509466#endif // _LIBCPP_SHARED_MUTEX
lib/libcxx/include/span+57-50
......@@ -71,7 +71,6 @@ public:
7171 constexpr span(const span& other) noexcept = default;
7272 template <class OtherElementType, size_t OtherExtent>
7373 constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept;
74 ~span() noexcept = default;
7574 constexpr span& operator=(const span& other) noexcept = default;
7675
7776 // [span.sub], span subviews
......@@ -129,7 +128,6 @@ template<class R>
129128
130129#include <__assert> // all public C++ headers provide the assertion handler
131130#include <__config>
132#include <__debug>
133131#include <__fwd/span.h>
134132#include <__iterator/bounded_iter.h>
135133#include <__iterator/concepts.h>
......@@ -141,11 +139,14 @@ template<class R>
141139#include <__ranges/enable_borrowed_range.h>
142140#include <__ranges/enable_view.h>
143141#include <__ranges/size.h>
142#include <__type_traits/is_convertible.h>
143#include <__type_traits/remove_cvref.h>
144#include <__type_traits/remove_reference.h>
145#include <__type_traits/type_identity.h>
144146#include <__utility/forward.h>
145147#include <array> // for array
146148#include <cstddef> // for byte
147149#include <limits>
148#include <type_traits> // for remove_cv, etc
149150#include <version>
150151
151152// standard-mandated includes
......@@ -166,7 +167,7 @@ _LIBCPP_PUSH_MACROS
166167
167168_LIBCPP_BEGIN_NAMESPACE_STD
168169
169#if _LIBCPP_STD_VER > 17
170#if _LIBCPP_STD_VER >= 20
170171
171172template <class _Tp>
172173struct __is_std_array : false_type {};
......@@ -211,7 +212,7 @@ public:
211212 using const_pointer = const _Tp *;
212213 using reference = _Tp &;
213214 using const_reference = const _Tp &;
214#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
215#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
215216 using iterator = __bounded_iter<pointer>;
216217#else
217218 using iterator = __wrap_iter<pointer>;
......@@ -232,16 +233,18 @@ public:
232233 constexpr explicit span(_It __first, size_type __count)
233234 : __data_{_VSTD::to_address(__first)} {
234235 (void)__count;
235 _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (iterator, len)");
236 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __count, "size mismatch in span's constructor (iterator, len)");
236237 }
237238
238239 template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End>
239240 _LIBCPP_INLINE_VISIBILITY
240241 constexpr explicit span(_It __first, _End __last) : __data_{_VSTD::to_address(__first)} {
241 (void)__last;
242 _LIBCPP_ASSERT((__last - __first >= 0), "invalid range in span's constructor (iterator, sentinel)");
243 _LIBCPP_ASSERT(__last - __first == _Extent,
244 "invalid range in span's constructor (iterator, sentinel): last - first != extent");
242 // [span.cons]/10
243 // Throws: When and what last - first throws.
244 [[maybe_unused]] auto __dist = __last - __first;
245 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__dist >= 0, "invalid range in span's constructor (iterator, sentinel)");
246 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
247 __dist == _Extent, "invalid range in span's constructor (iterator, sentinel): last - first != extent");
245248 }
246249
247250 _LIBCPP_INLINE_VISIBILITY constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data_{__arr} {}
......@@ -258,7 +261,8 @@ public:
258261 template <__span_compatible_range<element_type> _Range>
259262 _LIBCPP_INLINE_VISIBILITY
260263 constexpr explicit span(_Range&& __r) : __data_{ranges::data(__r)} {
261 _LIBCPP_ASSERT(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)");
264 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
265 ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)");
262266 }
263267
264268 template <__span_array_convertible<element_type> _OtherElementType>
......@@ -269,10 +273,10 @@ public:
269273 template <__span_array_convertible<element_type> _OtherElementType>
270274 _LIBCPP_INLINE_VISIBILITY
271275 constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept
272 : __data_{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); }
273
274
275// ~span() noexcept = default;
276 : __data_{__other.data()} {
277 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
278 _Extent == __other.size(), "size mismatch in span's constructor (other span)");
279 }
276280
277281 template <size_t _Count>
278282 _LIBCPP_INLINE_VISIBILITY
......@@ -293,14 +297,14 @@ public:
293297 _LIBCPP_INLINE_VISIBILITY
294298 constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept
295299 {
296 _LIBCPP_ASSERT(__count <= size(), "span<T, N>::first(count): count out of range");
300 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range");
297301 return {data(), __count};
298302 }
299303
300304 _LIBCPP_INLINE_VISIBILITY
301305 constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept
302306 {
303 _LIBCPP_ASSERT(__count <= size(), "span<T, N>::last(count): count out of range");
307 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range");
304308 return {data() + size() - __count, __count};
305309 }
306310
......@@ -321,11 +325,12 @@ public:
321325 constexpr span<element_type, dynamic_extent>
322326 subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept
323327 {
324 _LIBCPP_ASSERT(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range");
325 _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "span<T, N>::subspan(offset, count): count out of range");
328 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
329 __offset <= size(), "span<T, N>::subspan(offset, count): offset out of range");
326330 if (__count == dynamic_extent)
327331 return {data() + __offset, size() - __offset};
328 _LIBCPP_ASSERT(__count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range");
332 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
333 __count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range");
329334 return {data() + __offset, __count};
330335 }
331336
......@@ -335,19 +340,19 @@ public:
335340
336341 _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
337342 {
338 _LIBCPP_ASSERT(__idx < size(), "span<T, N>::operator[](index): index out of range");
343 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range");
339344 return __data_[__idx];
340345 }
341346
342347 _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
343348 {
344 _LIBCPP_ASSERT(!empty(), "span<T, N>::front() on empty span");
349 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span");
345350 return __data_[0];
346351 }
347352
348353 _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
349354 {
350 _LIBCPP_ASSERT(!empty(), "span<T, N>::back() on empty span");
355 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span");
351356 return __data_[size()-1];
352357 }
353358
......@@ -355,17 +360,17 @@ public:
355360
356361// [span.iter], span iterator support
357362 _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept {
358#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
363#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
359364 return std::__make_bounded_iter(data(), data(), data() + size());
360365#else
361 return iterator(this, data());
366 return iterator(data());
362367#endif
363368 }
364369 _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept {
365#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
370#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
366371 return std::__make_bounded_iter(data() + size(), data(), data() + size());
367372#else
368 return iterator(this, data() + size());
373 return iterator(data() + size());
369374#endif
370375 }
371376 _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
......@@ -394,7 +399,7 @@ public:
394399 using const_pointer = const _Tp *;
395400 using reference = _Tp &;
396401 using const_reference = const _Tp &;
397#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
402#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
398403 using iterator = __bounded_iter<pointer>;
399404#else
400405 using iterator = __wrap_iter<pointer>;
......@@ -417,7 +422,8 @@ public:
417422 template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End>
418423 _LIBCPP_INLINE_VISIBILITY constexpr span(_It __first, _End __last)
419424 : __data_(_VSTD::to_address(__first)), __size_(__last - __first) {
420 _LIBCPP_ASSERT(__last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)");
425 _LIBCPP_ASSERT_VALID_INPUT_RANGE(
426 __last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)");
421427 }
422428
423429 template <size_t _Sz>
......@@ -442,13 +448,11 @@ public:
442448 constexpr span(const span<_OtherElementType, _OtherExtent>& __other) noexcept
443449 : __data_{__other.data()}, __size_{__other.size()} {}
444450
445// ~span() noexcept = default;
446
447451 template <size_t _Count>
448452 _LIBCPP_INLINE_VISIBILITY
449453 constexpr span<element_type, _Count> first() const noexcept
450454 {
451 _LIBCPP_ASSERT(_Count <= size(), "span<T>::first<Count>(): Count out of range");
455 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range");
452456 return span<element_type, _Count>{data(), _Count};
453457 }
454458
......@@ -456,21 +460,21 @@ public:
456460 _LIBCPP_INLINE_VISIBILITY
457461 constexpr span<element_type, _Count> last() const noexcept
458462 {
459 _LIBCPP_ASSERT(_Count <= size(), "span<T>::last<Count>(): Count out of range");
463 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range");
460464 return span<element_type, _Count>{data() + size() - _Count, _Count};
461465 }
462466
463467 _LIBCPP_INLINE_VISIBILITY
464468 constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept
465469 {
466 _LIBCPP_ASSERT(__count <= size(), "span<T>::first(count): count out of range");
470 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range");
467471 return {data(), __count};
468472 }
469473
470474 _LIBCPP_INLINE_VISIBILITY
471475 constexpr span<element_type, dynamic_extent> last (size_type __count) const noexcept
472476 {
473 _LIBCPP_ASSERT(__count <= size(), "span<T>::last(count): count out of range");
477 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range");
474478 return {data() + size() - __count, __count};
475479 }
476480
......@@ -478,8 +482,10 @@ public:
478482 _LIBCPP_INLINE_VISIBILITY
479483 constexpr span<element_type, _Count> subspan() const noexcept
480484 {
481 _LIBCPP_ASSERT(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range");
482 _LIBCPP_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, "span<T>::subspan<Offset, Count>(): Offset + Count out of range");
485 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
486 _Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range");
487 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset,
488 "span<T>::subspan<Offset, Count>(): Offset + Count out of range");
483489 return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
484490 }
485491
......@@ -487,11 +493,11 @@ public:
487493 _LIBCPP_INLINE_VISIBILITY
488494 subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept
489495 {
490 _LIBCPP_ASSERT(__offset <= size(), "span<T>::subspan(offset, count): offset out of range");
491 _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "span<T>::subspan(offset, count): count out of range");
496 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range");
492497 if (__count == dynamic_extent)
493498 return {data() + __offset, size() - __offset};
494 _LIBCPP_ASSERT(__count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range");
499 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
500 __count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range");
495501 return {data() + __offset, __count};
496502 }
497503
......@@ -501,19 +507,19 @@ public:
501507
502508 _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
503509 {
504 _LIBCPP_ASSERT(__idx < size(), "span<T>::operator[](index): index out of range");
510 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range");
505511 return __data_[__idx];
506512 }
507513
508514 _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
509515 {
510 _LIBCPP_ASSERT(!empty(), "span<T>::front() on empty span");
516 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span");
511517 return __data_[0];
512518 }
513519
514520 _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
515521 {
516 _LIBCPP_ASSERT(!empty(), "span<T>::back() on empty span");
522 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span");
517523 return __data_[size()-1];
518524 }
519525
......@@ -522,17 +528,17 @@ public:
522528
523529// [span.iter], span iterator support
524530 _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept {
525#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
531#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
526532 return std::__make_bounded_iter(data(), data(), data() + size());
527533#else
528 return iterator(this, data());
534 return iterator(data());
529535#endif
530536 }
531537 _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept {
532#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
538#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
533539 return std::__make_bounded_iter(data() + size(), data(), data() + size());
534540#else
535 return iterator(this, data() + size());
541 return iterator(data() + size());
536542#endif
537543 }
538544 _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
......@@ -566,10 +572,10 @@ _LIBCPP_INLINE_VISIBILITY
566572auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept
567573{ return __s.__as_writable_bytes(); }
568574
569#if _LIBCPP_STD_VER > 17
575#if _LIBCPP_STD_VER >= 20
570576template<contiguous_iterator _It, class _EndOrSize>
571577 span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>;
572#endif // _LIBCPP_STD_VER > 17
578#endif // _LIBCPP_STD_VER >= 20
573579
574580template<class _Tp, size_t _Sz>
575581 span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>;
......@@ -583,7 +589,7 @@ template<class _Tp, size_t _Sz>
583589template<ranges::contiguous_range _Range>
584590 span(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>;
585591
586#endif // _LIBCPP_STD_VER > 17
592#endif // _LIBCPP_STD_VER >= 20
587593
588594_LIBCPP_END_NAMESPACE_STD
589595
......@@ -593,6 +599,7 @@ _LIBCPP_POP_MACROS
593599# include <concepts>
594600# include <functional>
595601# include <iterator>
602# include <type_traits>
596603#endif
597604
598605#endif // _LIBCPP_SPAN
lib/libcxx/include/sstream+409-82
......@@ -30,17 +30,41 @@ public:
3030 explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out); // before C++20
3131 basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {} // C++20
3232 explicit basic_stringbuf(ios_base::openmode which); // C++20
33 explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& str,
33 explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& s,
3434 ios_base::openmode which = ios_base::in | ios_base::out);
35 explicit basic_stringbuf(const allocator_type& a)
36 : basic_stringbuf(ios_base::in | ios_base::out, a) {} // C++20
37 basic_stringbuf(ios_base::openmode which, const allocator_type& a); // C++20
38 explicit basic_stringbuf(basic_string<char_type, traits_type, allocator_type>&& s,
39 ios_base::openmode which = ios_base::in | ios_base::out); // C++20
40 template <class SAlloc>
41 basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
42 : basic_stringbuf(s, ios_base::in | ios_base::out, a) {} // C++20
43 template <class SAlloc>
44 basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s,
45 ios_base::openmode which, const allocator_type& a); // C++20
46 template <class SAlloc>
47 explicit basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s,
48 ios_base::openmode which = ios_base::in | ios_base::out); // C++20
3549 basic_stringbuf(basic_stringbuf&& rhs);
50 basic_stringbuf(basic_stringbuf&& rhs, const allocator_type& a); // C++20
3651
3752 // [stringbuf.assign] Assign and swap:
3853 basic_stringbuf& operator=(basic_stringbuf&& rhs);
39 void swap(basic_stringbuf& rhs);
54 void swap(basic_stringbuf& rhs) noexcept(see below); // conditionally noexcept since C++20
4055
4156 // [stringbuf.members] Member functions:
42 basic_string<char_type, traits_type, allocator_type> str() const;
57 allocator_type get_allocator() const noexcept; // C++20
58 basic_string<char_type, traits_type, allocator_type> str() const; // before C++20
59 basic_string<char_type, traits_type, allocator_type> str() const &; // C++20
60 template <class SAlloc>
61 basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const; // C++20
62 basic_string<char_type, traits_type, allocator_type> str() &&; // C++20
63 basic_string_view<char_type, traits_type> view() const noexcept; // C++20
4364 void str(const basic_string<char_type, traits_type, allocator_type>& s);
65 template <class SAlloc>
66 void str(const basic_string<char_type, traits_type, SAlloc>& s); // C++20
67 void str(basic_string<char_type, traits_type, allocator_type>&& s); // C++20
4468
4569protected:
4670 // [stringbuf.virtuals] Overridden virtual functions:
......@@ -56,8 +80,8 @@ protected:
5680
5781// [stringbuf.assign] non member swap
5882template <class charT, class traits, class Allocator>
59 void swap(basic_stringbuf<charT, traits, Allocator>& x,
60 basic_stringbuf<charT, traits, Allocator>& y);
83void swap(basic_stringbuf<charT, traits, Allocator>& x,
84 basic_stringbuf<charT, traits, Allocator>& y); // conditionally noexcept since C++20
6185
6286typedef basic_stringbuf<char> stringbuf;
6387typedef basic_stringbuf<wchar_t> wstringbuf;
......@@ -76,12 +100,23 @@ public:
76100 typedef Allocator allocator_type;
77101
78102 // [istringstream.cons] Constructors:
79 explicit basic_istringstream(ios_base::openmode which = ios_base::in); // before C++20
80 basic_istringstream() : basic_istringstream(ios_base::in) {} // C++20
81 explicit basic_istringstream(ios_base::openmode which); // C++20
82
83 explicit basic_istringstream(const basic_string<char_type, traits_type,allocator_type>& str,
103 explicit basic_istringstream(ios_base::openmode which = ios_base::in); // before C++20
104 basic_istringstream() : basic_istringstream(ios_base::in) {} // C++20
105 explicit basic_istringstream(ios_base::openmode which); // C++20
106 explicit basic_istringstream(const basic_string<char_type, traits_type, allocator_type>& s,
84107 ios_base::openmode which = ios_base::in);
108 basic_istringstream(ios_base::openmode which, const allocator_type& a); // C++20
109 explicit basic_istringstream(basic_string<char_type, traits_type, allocator_type>&& s,
110 ios_base::openmode which = ios_base::in); // C++20
111 template <class SAlloc>
112 basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
113 : basic_istringstream(s, ios_base::in, a) {} // C++20
114 template <class SAlloc>
115 basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s,
116 ios_base::openmode which, const allocator_type& a); // C++20
117 template <class SAlloc>
118 explicit basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s,
119 ios_base::openmode which = ios_base::in); // C++20
85120 basic_istringstream(basic_istringstream&& rhs);
86121
87122 // [istringstream.assign] Assign and swap:
......@@ -90,13 +125,21 @@ public:
90125
91126 // [istringstream.members] Member functions:
92127 basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
93 basic_string<char_type, traits_type, allocator_type> str() const;
128 basic_string<char_type, traits_type, allocator_type> str() const; // before C++20
129 basic_string<char_type, traits_type, allocator_type> str() const &; // C++20
130 template <class SAlloc>
131 basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const; // C++20
132 basic_string<char_type, traits_type, allocator_type> str() &&; // C++20
133 basic_string_view<char_type, traits_type> view() const noexcept; // C++20
94134 void str(const basic_string<char_type, traits_type, allocator_type>& s);
135 template <class SAlloc>
136 void str(const basic_string<char_type, traits_type, SAlloc>& s); // C++20
137 void str(basic_string<char_type, traits_type, allocator_type>&& s); // C++20
95138};
96139
97140template <class charT, class traits, class Allocator>
98 void swap(basic_istringstream<charT, traits, Allocator>& x,
99 basic_istringstream<charT, traits, Allocator>& y);
141void swap(basic_istringstream<charT, traits, Allocator>& x,
142 basic_istringstream<charT, traits, Allocator>& y);
100143
101144typedef basic_istringstream<char> istringstream;
102145typedef basic_istringstream<wchar_t> wistringstream;
......@@ -116,12 +159,23 @@ public:
116159 typedef Allocator allocator_type;
117160
118161 // [ostringstream.cons] Constructors:
119 explicit basic_ostringstream(ios_base::openmode which = ios_base::out); // before C++20
120 basic_ostringstream() : basic_ostringstream(ios_base::out) {} // C++20
121 explicit basic_ostringstream(ios_base::openmode which); // C++20
122
123 explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type>& str,
162 explicit basic_ostringstream(ios_base::openmode which = ios_base::out); // before C++20
163 basic_ostringstream() : basic_ostringstream(ios_base::out) {} // C++20
164 explicit basic_ostringstream(ios_base::openmode which); // C++20
165 explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type>& s,
124166 ios_base::openmode which = ios_base::out);
167 basic_ostringstream(ios_base::openmode which, const allocator_type& a); // C++20
168 explicit basic_ostringstream(basic_string<char_type, traits_type, allocator_type>&& s,
169 ios_base::openmode which = ios_base::out); // C++20
170 template <class SAlloc>
171 basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
172 : basic_ostringstream(s, ios_base::out, a) {} // C++20
173 template <class SAlloc>
174 basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s,
175 ios_base::openmode which, const allocator_type& a); // C++20
176 template <class SAlloc>
177 explicit basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s,
178 ios_base::openmode which = ios_base::out); // C++20
125179 basic_ostringstream(basic_ostringstream&& rhs);
126180
127181 // [ostringstream.assign] Assign and swap:
......@@ -130,13 +184,21 @@ public:
130184
131185 // [ostringstream.members] Member functions:
132186 basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
133 basic_string<char_type, traits_type, allocator_type> str() const;
187 basic_string<char_type, traits_type, allocator_type> str() const; // before C++20
188 basic_string<char_type, traits_type, allocator_type> str() const &; // C++20
189 template <class SAlloc>
190 basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const; // C++20
191 basic_string<char_type, traits_type, allocator_type> str() &&; // C++20
192 basic_string_view<char_type, traits_type> view() const noexcept; // C++20
134193 void str(const basic_string<char_type, traits_type, allocator_type>& s);
194 template <class SAlloc>
195 void str(const basic_string<char_type, traits_type, SAlloc>& s); // C++20
196 void str(basic_string<char_type, traits_type, allocator_type>&& s); // C++20
135197};
136198
137199template <class charT, class traits, class Allocator>
138 void swap(basic_ostringstream<charT, traits, Allocator>& x,
139 basic_ostringstream<charT, traits, Allocator>& y);
200void swap(basic_ostringstream<charT, traits, Allocator>& x,
201 basic_ostringstream<charT, traits, Allocator>& y);
140202
141203typedef basic_ostringstream<char> ostringstream;
142204typedef basic_ostringstream<wchar_t> wostringstream;
......@@ -159,9 +221,20 @@ public:
159221 explicit basic_stringstream(ios_base::openmode which = ios_base::out | ios_base::in); // before C++20
160222 basic_stringstream() : basic_stringstream(ios_base::out | ios_base::in) {} // C++20
161223 explicit basic_stringstream(ios_base::openmode which); // C++20
162
163 explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type>& str,
164 ios_base::openmode which = ios_base::out|ios_base::in);
224 explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type>& s,
225 ios_base::openmode which = ios_base::out | ios_base::in);
226 basic_stringstream(ios_base::openmode which, const allocator_type& a); // C++20
227 explicit basic_stringstream(basic_string<char_type, traits_type, allocator_type>&& s,
228 ios_base::openmode which = ios_base::out | ios_base::in); // C++20
229 template <class SAlloc>
230 basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
231 : basic_stringstream(s, ios_base::out | ios_base::in, a) {} // C++20
232 template <class SAlloc>
233 basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s,
234 ios_base::openmode which, const allocator_type& a); // C++20
235 template <class SAlloc>
236 explicit basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s,
237 ios_base::openmode which = ios_base::out | ios_base::in); // C++20
165238 basic_stringstream(basic_stringstream&& rhs);
166239
167240 // [stringstream.assign] Assign and swap:
......@@ -170,13 +243,21 @@ public:
170243
171244 // [stringstream.members] Member functions:
172245 basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
173 basic_string<char_type, traits_type, allocator_type> str() const;
174 void str(const basic_string<char_type, traits_type, allocator_type>& str);
246 basic_string<char_type, traits_type, allocator_type> str() const; // before C++20
247 basic_string<char_type, traits_type, allocator_type> str() const &; // C++20
248 template <class SAlloc>
249 basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const; // C++20
250 basic_string<char_type, traits_type, allocator_type> str() &&; // C++20
251 basic_string_view<char_type, traits_type> view() const noexcept; // C++20
252 void str(const basic_string<char_type, traits_type, allocator_type>& s);
253 template <class SAlloc>
254 void str(const basic_string<char_type, traits_type, SAlloc>& s); // C++20
255 void str(basic_string<char_type, traits_type, allocator_type>&& s); // C++20
175256};
176257
177258template <class charT, class traits, class Allocator>
178 void swap(basic_stringstream<charT, traits, Allocator>& x,
179 basic_stringstream<charT, traits, Allocator>& y);
259void swap(basic_stringstream<charT, traits, Allocator>& x,
260 basic_stringstream<charT, traits, Allocator>& y);
180261
181262typedef basic_stringstream<char> stringstream;
182263typedef basic_stringstream<wchar_t> wstringstream;
......@@ -187,6 +268,7 @@ typedef basic_stringstream<wchar_t> wstringstream;
187268
188269#include <__assert> // all public C++ headers provide the assertion handler
189270#include <__config>
271#include <__fwd/sstream.h>
190272#include <__utility/swap.h>
191273#include <istream>
192274#include <ostream>
......@@ -201,6 +283,14 @@ _LIBCPP_PUSH_MACROS
201283#include <__undef_macros>
202284
203285
286// TODO(LLVM-19): Remove this once we drop support for Clang 16,
287// which had this bug: https://github.com/llvm/llvm-project/issues/40363
288#ifdef _WIN32
289#define _LIBCPP_HIDE_FROM_ABI_SSTREAM _LIBCPP_ALWAYS_INLINE
290#else
291#define _LIBCPP_HIDE_FROM_ABI_SSTREAM _LIBCPP_HIDE_FROM_ABI
292#endif
293
204294_LIBCPP_BEGIN_NAMESPACE_STD
205295
206296// Class template basic_stringbuf [stringbuf]
......@@ -224,6 +314,8 @@ private:
224314 string_type __str_;
225315 mutable char_type* __hm_;
226316 ios_base::openmode __mode_;
317 _LIBCPP_HIDE_FROM_ABI void __init_buf_ptrs();
318 _LIBCPP_HIDE_FROM_ABI void __move_init(basic_stringbuf&& __rhs);
227319
228320public:
229321 // [stringbuf.cons] constructors:
......@@ -243,15 +335,110 @@ public:
243335 str(__s);
244336 }
245337
246 basic_stringbuf(basic_stringbuf&& __rhs);
338#if _LIBCPP_STD_VER >= 20
339 _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const allocator_type& __a)
340 : basic_stringbuf(ios_base::in | ios_base::out, __a) {}
341
342 _LIBCPP_HIDE_FROM_ABI basic_stringbuf(ios_base::openmode __wch, const allocator_type& __a)
343 : __str_(__a), __hm_(nullptr), __mode_(__wch) {}
344
345 _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(string_type&& __s,
346 ios_base::openmode __wch = ios_base::in | ios_base::out)
347 : __str_(std::move(__s)), __hm_(nullptr), __mode_(__wch) {
348 __init_buf_ptrs();
349 }
350
351 template <class _SAlloc>
352 _LIBCPP_HIDE_FROM_ABI
353 basic_stringbuf(const basic_string<char_type, traits_type, _SAlloc>& __s, const allocator_type& __a)
354 : basic_stringbuf(__s, ios_base::in | ios_base::out, __a) {}
355
356 template <class _SAlloc>
357 _LIBCPP_HIDE_FROM_ABI basic_stringbuf(
358 const basic_string<char_type, traits_type, _SAlloc>& __s, ios_base::openmode __wch, const allocator_type& __a)
359 : __str_(__s, __a), __hm_(nullptr), __mode_(__wch) {
360 __init_buf_ptrs();
361 }
362
363 template <class _SAlloc>
364 requires (!is_same_v<_SAlloc, allocator_type>)
365 _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const basic_string<char_type, traits_type, _SAlloc>& __s,
366 ios_base::openmode __wch = ios_base::in | ios_base::out)
367 : __str_(__s), __hm_(nullptr), __mode_(__wch) {
368 __init_buf_ptrs();
369 }
370#endif // _LIBCPP_STD_VER >= 20
371
372 basic_stringbuf(basic_stringbuf&& __rhs) : __mode_(__rhs.__mode_) { __move_init(std::move(__rhs)); }
373
374#if _LIBCPP_STD_VER >= 20
375 _LIBCPP_HIDE_FROM_ABI basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a)
376 : basic_stringbuf(__rhs.__mode_, __a) {
377 __move_init(std::move(__rhs));
378 }
379#endif
247380
248381 // [stringbuf.assign] Assign and swap:
249382 basic_stringbuf& operator=(basic_stringbuf&& __rhs);
250 void swap(basic_stringbuf& __rhs);
383 void swap(basic_stringbuf& __rhs)
384#if _LIBCPP_STD_VER >= 20
385 noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
386 allocator_traits<allocator_type>::is_always_equal::value)
387#endif
388 ;
251389
252390 // [stringbuf.members] Member functions:
391
392#if _LIBCPP_STD_VER >= 20
393 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
394#endif
395
396#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
253397 string_type str() const;
254 void str(const string_type& __s);
398#else
399 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return str(__str_.get_allocator()); }
400
401 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && {
402 string_type __result;
403 const basic_string_view<_CharT, _Traits> __view = view();
404 if (!__view.empty()) {
405 auto __pos = __view.data() - __str_.data();
406 __result.assign(std::move(__str_), __pos, __view.size());
407 }
408 __str_.clear();
409 __init_buf_ptrs();
410 return __result;
411 }
412#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
413
414#if _LIBCPP_STD_VER >= 20
415 template <class _SAlloc>
416 requires __is_allocator<_SAlloc>::value
417 _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
418 return basic_string<_CharT, _Traits, _SAlloc>(view(), __sa);
419 }
420
421 _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept;
422#endif // _LIBCPP_STD_VER >= 20
423
424 void str(const string_type& __s) {
425 __str_ = __s;
426 __init_buf_ptrs();
427 }
428
429#if _LIBCPP_STD_VER >= 20
430 template <class _SAlloc>
431 requires (!is_same_v<_SAlloc, allocator_type>)
432 _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
433 __str_ = __s;
434 __init_buf_ptrs();
435 }
436
437 _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) {
438 __str_ = std::move(__s);
439 __init_buf_ptrs();
440 }
441#endif // _LIBCPP_STD_VER >= 20
255442
256443protected:
257444 // [stringbuf.virtuals] Overridden virtual functions:
......@@ -268,9 +455,7 @@ protected:
268455};
269456
270457template <class _CharT, class _Traits, class _Allocator>
271basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(basic_stringbuf&& __rhs)
272 : __mode_(__rhs.__mode_)
273{
458_LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__move_init(basic_stringbuf&& __rhs) {
274459 char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
275460 ptrdiff_t __binp = -1;
276461 ptrdiff_t __ninp = -1;
......@@ -359,6 +544,10 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::operator=(basic_stringbuf&& __rhs)
359544template <class _CharT, class _Traits, class _Allocator>
360545void
361546basic_stringbuf<_CharT, _Traits, _Allocator>::swap(basic_stringbuf& __rhs)
547#if _LIBCPP_STD_VER >= 20
548 noexcept(allocator_traits<_Allocator>::propagate_on_container_swap::value ||
549 allocator_traits<_Allocator>::is_always_equal::value)
550#endif
362551{
363552 char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
364553 ptrdiff_t __rbinp = -1;
......@@ -438,49 +627,42 @@ inline _LIBCPP_INLINE_VISIBILITY
438627void
439628swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
440629 basic_stringbuf<_CharT, _Traits, _Allocator>& __y)
630#if _LIBCPP_STD_VER >= 20
631 noexcept(noexcept(__x.swap(__y)))
632#endif
441633{
442634 __x.swap(__y);
443635}
444636
637#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
445638template <class _CharT, class _Traits, class _Allocator>
446639basic_string<_CharT, _Traits, _Allocator>
447basic_stringbuf<_CharT, _Traits, _Allocator>::str() const
448{
449 if (__mode_ & ios_base::out)
450 {
640basic_stringbuf<_CharT, _Traits, _Allocator>::str() const {
641 if (__mode_ & ios_base::out) {
451642 if (__hm_ < this->pptr())
452643 __hm_ = this->pptr();
453644 return string_type(this->pbase(), __hm_, __str_.get_allocator());
454 }
455 else if (__mode_ & ios_base::in)
645 } else if (__mode_ & ios_base::in)
456646 return string_type(this->eback(), this->egptr(), __str_.get_allocator());
457647 return string_type(__str_.get_allocator());
458648}
649#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
459650
460651template <class _CharT, class _Traits, class _Allocator>
461void
462basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s)
463{
464 __str_ = __s;
652_LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__init_buf_ptrs() {
465653 __hm_ = nullptr;
466 if (__mode_ & ios_base::in)
467 {
468 __hm_ = const_cast<char_type*>(__str_.data()) + __str_.size();
469 this->setg(const_cast<char_type*>(__str_.data()),
470 const_cast<char_type*>(__str_.data()),
471 __hm_);
654 char_type* __data = const_cast<char_type*>(__str_.data());
655 typename string_type::size_type __sz = __str_.size();
656 if (__mode_ & ios_base::in) {
657 __hm_ = __data + __sz;
658 this->setg(__data, __data, __hm_);
472659 }
473 if (__mode_ & ios_base::out)
474 {
475 typename string_type::size_type __sz = __str_.size();
476 __hm_ = const_cast<char_type*>(__str_.data()) + __sz;
660 if (__mode_ & ios_base::out) {
661 __hm_ = __data + __sz;
477662 __str_.resize(__str_.capacity());
478 this->setp(const_cast<char_type*>(__str_.data()),
479 const_cast<char_type*>(__str_.data()) + __str_.size());
480 if (__mode_ & (ios_base::app | ios_base::ate))
481 {
482 while (__sz > INT_MAX)
483 {
663 this->setp(__data, __data + __str_.size());
664 if (__mode_ & (ios_base::app | ios_base::ate)) {
665 while (__sz > INT_MAX) {
484666 this->pbump(INT_MAX);
485667 __sz -= INT_MAX;
486668 }
......@@ -490,6 +672,20 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s)
490672 }
491673}
492674
675#if _LIBCPP_STD_VER >= 20
676template <class _CharT, class _Traits, class _Allocator>
677_LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT, _Traits>
678basic_stringbuf<_CharT, _Traits, _Allocator>::view() const noexcept {
679 if (__mode_ & ios_base::out) {
680 if (__hm_ < this->pptr())
681 __hm_ = this->pptr();
682 return basic_string_view<_CharT, _Traits>(this->pbase(), __hm_);
683 } else if (__mode_ & ios_base::in)
684 return basic_string_view<_CharT, _Traits>(this->eback(), this->egptr());
685 return basic_string_view<_CharT, _Traits>();
686}
687#endif // _LIBCPP_STD_VER >= 20
688
493689template <class _CharT, class _Traits, class _Allocator>
494690typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
495691basic_stringbuf<_CharT, _Traits, _Allocator>::underflow()
......@@ -536,16 +732,16 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c)
536732{
537733 if (!traits_type::eq_int_type(__c, traits_type::eof()))
538734 {
539 ptrdiff_t __ninp = this->gptr() - this->eback();
735 ptrdiff_t __ninp = this->gptr() - this->eback();
540736 if (this->pptr() == this->epptr())
541737 {
542738 if (!(__mode_ & ios_base::out))
543739 return traits_type::eof();
544#ifndef _LIBCPP_NO_EXCEPTIONS
740#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
545741 try
546742 {
547#endif // _LIBCPP_NO_EXCEPTIONS
548 ptrdiff_t __nout = this->pptr() - this->pbase();
743#endif // _LIBCPP_HAS_NO_EXCEPTIONS
744 ptrdiff_t __nout = this->pptr() - this->pbase();
549745 ptrdiff_t __hm = __hm_ - this->pbase();
550746 __str_.push_back(char_type());
551747 __str_.resize(__str_.capacity());
......@@ -553,13 +749,13 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c)
553749 this->setp(__p, __p + __str_.size());
554750 this->__pbump(__nout);
555751 __hm_ = this->pbase() + __hm;
556#ifndef _LIBCPP_NO_EXCEPTIONS
752#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
557753 }
558754 catch (...)
559755 {
560756 return traits_type::eof();
561757 }
562#endif // _LIBCPP_NO_EXCEPTIONS
758#endif // _LIBCPP_HAS_NO_EXCEPTIONS
563759 }
564760 __hm_ = _VSTD::max(this->pptr() + 1, __hm_);
565761 if (__mode_ & ios_base::in)
......@@ -619,7 +815,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off,
619815 if (__wch & ios_base::out)
620816 {
621817 this->setp(this->pbase(), this->epptr());
622 this->pbump(__noff);
818 this->__pbump(__noff);
623819 }
624820 return pos_type(__noff);
625821}
......@@ -660,6 +856,28 @@ public:
660856 , __sb_(__s, __wch | ios_base::in)
661857 { }
662858
859#if _LIBCPP_STD_VER >= 20
860 _LIBCPP_HIDE_FROM_ABI basic_istringstream(ios_base::openmode __wch, const _Allocator& __a)
861 : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::in, __a) {}
862
863 _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(string_type&& __s, ios_base::openmode __wch = ios_base::in)
864 : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch | ios_base::in) {}
865
866 template <class _SAlloc>
867 _LIBCPP_HIDE_FROM_ABI basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
868 : basic_istringstream(__s, ios_base::in, __a) {}
869
870 template <class _SAlloc>
871 _LIBCPP_HIDE_FROM_ABI basic_istringstream(
872 const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
873 : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in, __a) {}
874
875 template <class _SAlloc>
876 _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
877 ios_base::openmode __wch = ios_base::in)
878 : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in) {}
879#endif // _LIBCPP_STD_VER >= 20
880
663881 _LIBCPP_INLINE_VISIBILITY
664882 basic_istringstream(basic_istringstream&& __rhs)
665883 : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs))
......@@ -685,14 +903,35 @@ public:
685903 basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
686904 return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
687905 }
688 _LIBCPP_INLINE_VISIBILITY
689 string_type str() const {
690 return __sb_.str();
906
907#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
908 _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
909#else
910 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return __sb_.str(); }
911
912 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && { return std::move(__sb_).str(); }
913#endif
914
915#if _LIBCPP_STD_VER >= 20
916 template <class _SAlloc>
917 requires __is_allocator<_SAlloc>::value
918 _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
919 return __sb_.str(__sa);
691920 }
692 _LIBCPP_INLINE_VISIBILITY
693 void str(const string_type& __s) {
921
922 _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
923#endif // _LIBCPP_STD_VER >= 20
924
925 _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
926
927#if _LIBCPP_STD_VER >= 20
928 template <class _SAlloc>
929 _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
694930 __sb_.str(__s);
695931 }
932
933 _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
934#endif // _LIBCPP_STD_VER >= 20
696935};
697936
698937template <class _CharT, class _Traits, class _Allocator>
......@@ -740,6 +979,29 @@ public:
740979 , __sb_(__s, __wch | ios_base::out)
741980 { }
742981
982#if _LIBCPP_STD_VER >= 20
983 _LIBCPP_HIDE_FROM_ABI basic_ostringstream(ios_base::openmode __wch, const _Allocator& __a)
984 : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::out, __a) {}
985
986 _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(string_type&& __s, ios_base::openmode __wch = ios_base::out)
987 : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch | ios_base::out) {}
988
989 template <class _SAlloc>
990 _LIBCPP_HIDE_FROM_ABI basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
991 : basic_ostringstream(__s, ios_base::out, __a) {}
992
993 template <class _SAlloc>
994 _LIBCPP_HIDE_FROM_ABI basic_ostringstream(
995 const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
996 : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::out, __a) {}
997
998 template <class _SAlloc>
999 requires (!is_same_v<_SAlloc, allocator_type>)
1000 _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
1001 ios_base::openmode __wch = ios_base::out)
1002 : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::out) {}
1003#endif // _LIBCPP_STD_VER >= 20
1004
7431005 _LIBCPP_INLINE_VISIBILITY
7441006 basic_ostringstream(basic_ostringstream&& __rhs)
7451007 : basic_ostream<_CharT, _Traits>(_VSTD::move(__rhs))
......@@ -766,14 +1028,35 @@ public:
7661028 basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
7671029 return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
7681030 }
769 _LIBCPP_INLINE_VISIBILITY
770 string_type str() const {
771 return __sb_.str();
1031
1032#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
1033 _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
1034#else
1035 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return __sb_.str(); }
1036
1037 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && { return std::move(__sb_).str(); }
1038#endif
1039
1040#if _LIBCPP_STD_VER >= 20
1041 template <class _SAlloc>
1042 requires __is_allocator<_SAlloc>::value
1043 _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
1044 return __sb_.str(__sa);
7721045 }
773 _LIBCPP_INLINE_VISIBILITY
774 void str(const string_type& __s) {
1046
1047 _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
1048#endif // _LIBCPP_STD_VER >= 20
1049
1050 _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
1051
1052#if _LIBCPP_STD_VER >= 20
1053 template <class _SAlloc>
1054 _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
7751055 __sb_.str(__s);
7761056 }
1057
1058 _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
1059#endif // _LIBCPP_STD_VER >= 20
7771060};
7781061
7791062template <class _CharT, class _Traits, class _Allocator>
......@@ -821,6 +1104,29 @@ public:
8211104 , __sb_(__s, __wch)
8221105 { }
8231106
1107#if _LIBCPP_STD_VER >= 20
1108 _LIBCPP_HIDE_FROM_ABI basic_stringstream(ios_base::openmode __wch, const _Allocator& __a)
1109 : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch, __a) {}
1110
1111 _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(string_type&& __s, ios_base::openmode __wch = ios_base::out | ios_base::in)
1112 : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch) {}
1113
1114 template <class _SAlloc>
1115 _LIBCPP_HIDE_FROM_ABI basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
1116 : basic_stringstream(__s, ios_base::out | ios_base::in, __a) {}
1117
1118 template <class _SAlloc>
1119 _LIBCPP_HIDE_FROM_ABI basic_stringstream(
1120 const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
1121 : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch, __a) {}
1122
1123 template <class _SAlloc>
1124 requires (!is_same_v<_SAlloc, allocator_type>)
1125 _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
1126 ios_base::openmode __wch = ios_base::out | ios_base::in)
1127 : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch) {}
1128#endif // _LIBCPP_STD_VER >= 20
1129
8241130 _LIBCPP_INLINE_VISIBILITY
8251131 basic_stringstream(basic_stringstream&& __rhs)
8261132 : basic_iostream<_CharT, _Traits>(_VSTD::move(__rhs))
......@@ -846,14 +1152,35 @@ public:
8461152 basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
8471153 return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
8481154 }
849 _LIBCPP_INLINE_VISIBILITY
850 string_type str() const {
851 return __sb_.str();
1155
1156#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
1157 _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
1158#else
1159 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return __sb_.str(); }
1160
1161 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && { return std::move(__sb_).str(); }
1162#endif
1163
1164#if _LIBCPP_STD_VER >= 20
1165 template <class _SAlloc>
1166 requires __is_allocator<_SAlloc>::value
1167 _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
1168 return __sb_.str(__sa);
8521169 }
853 _LIBCPP_INLINE_VISIBILITY
854 void str(const string_type& __s) {
1170
1171 _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
1172#endif // _LIBCPP_STD_VER >= 20
1173
1174 _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
1175
1176#if _LIBCPP_STD_VER >= 20
1177 template <class _SAlloc>
1178 _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
8551179 __sb_.str(__s);
8561180 }
1181
1182 _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
1183#endif // _LIBCPP_STD_VER >= 20
8571184};
8581185
8591186template <class _CharT, class _Traits, class _Allocator>
lib/libcxx/include/stack+82-13
......@@ -42,6 +42,7 @@ public:
4242 explicit stack(const container_type& c);
4343 explicit stack(container_type&& c);
4444 template <class InputIterator> stack(InputIterator first, InputIterator last); // since C++23
45 template<container-compatible-range<T> R> stack(from_range_t, R&& rg); // since C++23
4546 template <class Alloc> explicit stack(const Alloc& a);
4647 template <class Alloc> stack(const container_type& c, const Alloc& a);
4748 template <class Alloc> stack(container_type&& c, const Alloc& a);
......@@ -49,6 +50,8 @@ public:
4950 template <class Alloc> stack(stack&& c, const Alloc& a);
5051 template<class InputIterator, class Alloc>
5152 stack(InputIterator first, InputIterator last, const Alloc&); // since C++23
53 template<container-compatible-range<T> R, class Alloc>
54 stack(from_range_t, R&& rg, const Alloc&); // since C++23
5255
5356 bool empty() const;
5457 size_type size() const;
......@@ -57,6 +60,8 @@ public:
5760
5861 void push(const value_type& x);
5962 void push(value_type&& x);
63 template<container-compatible-range<T> R>
64 void push_range(R&& rg); // C++23
6065 template <class... Args> reference emplace(Args&&... args); // reference in C++17
6166 void pop();
6267
......@@ -69,6 +74,9 @@ template<class Container>
6974template<class InputIterator>
7075 stack(InputIterator, InputIterator) -> stack<iter-value-type<InputIterator>>; // since C++23
7176
77template<ranges::input_range R>
78 stack(from_range_t, R&&) -> stack<ranges::range_value_t<R>>; // since C++23
79
7280template<class Container, class Allocator>
7381 stack(Container, Allocator) -> stack<typename Container::value_type, Container>; // C++17
7482
......@@ -77,6 +85,10 @@ template<class InputIterator, class Allocator>
7785 -> stack<iter-value-type<InputIterator>,
7886 deque<iter-value-type<InputIterator>, Allocator>>; // since C++23
7987
88template<ranges::input_range R, class Allocator>
89 stack(from_range_t, R&&, Allocator)
90 -> stack<ranges::range_value_t<R>, deque<ranges::range_value_t<R>, Allocator>>; // since C++23
91
8092template <class T, class Container>
8193 bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
8294template <class T, class Container>
......@@ -89,6 +101,9 @@ template <class T, class Container>
89101 bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
90102template <class T, class Container>
91103 bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
104template<class T, three_way_comparable Container>
105 compare_three_way_result_t<Container>
106 operator<=>(const stack<T, Container>& x, const stack<T, Container>& y); // since C++20
92107
93108template <class T, class Container>
94109 void swap(stack<T, Container>& x, stack<T, Container>& y)
......@@ -98,13 +113,19 @@ template <class T, class Container>
98113
99114*/
100115
116#include <__algorithm/ranges_copy.h>
101117#include <__assert> // all public C++ headers provide the assertion handler
102118#include <__config>
119#include <__iterator/back_insert_iterator.h>
103120#include <__iterator/iterator_traits.h>
104121#include <__memory/uses_allocator.h>
122#include <__ranges/access.h>
123#include <__ranges/concepts.h>
124#include <__ranges/container_compatible_range.h>
125#include <__ranges/from_range.h>
126#include <__type_traits/is_same.h>
105127#include <__utility/forward.h>
106128#include <deque>
107#include <type_traits>
108129#include <version>
109130
110131// standard-mandated includes
......@@ -204,18 +225,30 @@ public:
204225 : c(_VSTD::move(__s.c), __a) {}
205226#endif // _LIBCPP_CXX03_LANG
206227
207#if _LIBCPP_STD_VER > 20
228#if _LIBCPP_STD_VER >= 23
208229 template <class _InputIterator,
209 class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
230 class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>>
210231 _LIBCPP_HIDE_FROM_ABI
211232 stack(_InputIterator __first, _InputIterator __last) : c(__first, __last) {}
212233
234 template <_ContainerCompatibleRange<_Tp> _Range>
235 _LIBCPP_HIDE_FROM_ABI
236 stack(from_range_t, _Range&& __range) : c(from_range, std::forward<_Range>(__range)) {}
237
213238 template <class _InputIterator,
214239 class _Alloc,
215 class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
240 class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
216241 class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
217242 _LIBCPP_HIDE_FROM_ABI
218243 stack(_InputIterator __first, _InputIterator __last, const _Alloc& __alloc) : c(__first, __last, __alloc) {}
244
245 template <_ContainerCompatibleRange<_Tp> _Range,
246 class _Alloc,
247 class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
248 _LIBCPP_HIDE_FROM_ABI
249 stack(from_range_t, _Range&& __range, const _Alloc& __alloc)
250 : c(from_range, std::forward<_Range>(__range), __alloc) {}
251
219252#endif
220253
221254 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
......@@ -233,9 +266,23 @@ public:
233266 _LIBCPP_INLINE_VISIBILITY
234267 void push(value_type&& __v) {c.push_back(_VSTD::move(__v));}
235268
269#if _LIBCPP_STD_VER >= 23
270 template <_ContainerCompatibleRange<_Tp> _Range>
271 _LIBCPP_HIDE_FROM_ABI
272 void push_range(_Range&& __range) {
273 if constexpr (requires (container_type& __c) {
274 __c.append_range(std::forward<_Range>(__range));
275 }) {
276 c.append_range(std::forward<_Range>(__range));
277 } else {
278 ranges::copy(std::forward<_Range>(__range), std::back_inserter(c));
279 }
280 }
281#endif
282
236283 template <class... _Args>
237284 _LIBCPP_INLINE_VISIBILITY
238#if _LIBCPP_STD_VER > 14
285#if _LIBCPP_STD_VER >= 17
239286 decltype(auto) emplace(_Args&&... __args)
240287 { return c.emplace_back(_VSTD::forward<_Args>(__args)...);}
241288#else
......@@ -257,18 +304,18 @@ public:
257304
258305 _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
259306
260 template <class T1, class _C1>
307 template <class _T1, class _OtherContainer>
261308 friend
262309 bool
263 operator==(const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);
310 operator==(const stack<_T1, _OtherContainer>& __x, const stack<_T1, _OtherContainer>& __y);
264311
265 template <class T1, class _C1>
312 template <class _T1, class _OtherContainer>
266313 friend
267314 bool
268 operator< (const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);
315 operator< (const stack<_T1, _OtherContainer>& __x, const stack<_T1, _OtherContainer>& __y);
269316};
270317
271#if _LIBCPP_STD_VER > 14
318#if _LIBCPP_STD_VER >= 17
272319template<class _Container,
273320 class = enable_if_t<!__is_allocator<_Container>::value>
274321>
......@@ -284,18 +331,28 @@ stack(_Container, _Alloc)
284331 -> stack<typename _Container::value_type, _Container>;
285332#endif
286333
287#if _LIBCPP_STD_VER > 20
334#if _LIBCPP_STD_VER >= 23
288335template<class _InputIterator,
289 class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
336 class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>>
290337stack(_InputIterator, _InputIterator)
291338 -> stack<__iter_value_type<_InputIterator>>;
292339
340template <ranges::input_range _Range>
341stack(from_range_t, _Range&&) -> stack<ranges::range_value_t<_Range>>;
342
293343template<class _InputIterator,
294344 class _Alloc,
295 class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
345 class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
296346 class = __enable_if_t<__is_allocator<_Alloc>::value>>
297347stack(_InputIterator, _InputIterator, _Alloc)
298348 -> stack<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>;
349
350template <ranges::input_range _Range,
351 class _Alloc,
352 class = __enable_if_t<__is_allocator<_Alloc>::value>>
353stack(from_range_t, _Range&&, _Alloc)
354 -> stack<ranges::range_value_t<_Range>, deque<ranges::range_value_t<_Range>, _Alloc>>;
355
299356#endif
300357
301358template <class _Tp, class _Container>
......@@ -346,6 +403,17 @@ operator<=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
346403 return !(__y < __x);
347404}
348405
406#if _LIBCPP_STD_VER >= 20
407
408template <class _Tp, three_way_comparable _Container>
409_LIBCPP_HIDE_FROM_ABI compare_three_way_result_t<_Container>
410operator<=>(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) {
411 // clang 16 bug: declaring `friend operator<=>` causes "use of overloaded operator '*' is ambiguous" errors
412 return __x.__get_container() <=> __y.__get_container();
413}
414
415#endif
416
349417template <class _Tp, class _Container>
350418inline _LIBCPP_INLINE_VISIBILITY
351419__enable_if_t<__is_swappable<_Container>::value, void>
......@@ -366,6 +434,7 @@ _LIBCPP_END_NAMESPACE_STD
366434#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
367435# include <concepts>
368436# include <functional>
437# include <type_traits>
369438#endif
370439
371440#endif // _LIBCPP_STACK
lib/libcxx/include/stdatomic.h+2-2
......@@ -121,7 +121,7 @@ using std::atomic_signal_fence // see below
121121# pragma GCC system_header
122122#endif
123123
124#if defined(__cplusplus) && _LIBCPP_STD_VER > 20
124#if defined(__cplusplus) && _LIBCPP_STD_VER >= 23
125125
126126#include <atomic>
127127#include <version>
......@@ -230,6 +230,6 @@ using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS;
230230# include_next <stdatomic.h>
231231# endif
232232
233#endif // defined(__cplusplus) && _LIBCPP_STD_VER > 20
233#endif // defined(__cplusplus) && _LIBCPP_STD_VER >= 23
234234
235235#endif // _LIBCPP_STDATOMIC_H
lib/libcxx/include/stdexcept+41-44
......@@ -43,8 +43,8 @@ public:
4343
4444#include <__assert> // all public C++ headers provide the assertion handler
4545#include <__config>
46#include <cstdlib>
47#include <exception>
46#include <__exception/exception.h>
47#include <__verbose_abort>
4848#include <iosfwd> // for string forward decl
4949
5050#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -65,7 +65,7 @@ public:
6565 __libcpp_refstring& operator=(const __libcpp_refstring& __s) _NOEXCEPT;
6666 ~__libcpp_refstring();
6767
68 const char* c_str() const _NOEXCEPT {return __imp_;}
68 _LIBCPP_HIDE_FROM_ABI const char* c_str() const _NOEXCEPT {return __imp_;}
6969};
7070#endif // !_LIBCPP_ABI_VCRUNTIME
7171
......@@ -74,7 +74,7 @@ _LIBCPP_END_NAMESPACE_STD
7474namespace std // purposefully not using versioning namespace
7575{
7676
77class _LIBCPP_EXCEPTION_ABI logic_error
77class _LIBCPP_EXPORTED_FROM_ABI logic_error
7878 : public exception
7979{
8080#ifndef _LIBCPP_ABI_VCRUNTIME
......@@ -97,7 +97,7 @@ public:
9797#endif
9898};
9999
100class _LIBCPP_EXCEPTION_ABI runtime_error
100class _LIBCPP_EXPORTED_FROM_ABI runtime_error
101101 : public exception
102102{
103103#ifndef _LIBCPP_ABI_VCRUNTIME
......@@ -120,7 +120,7 @@ public:
120120#endif // _LIBCPP_ABI_VCRUNTIME
121121};
122122
123class _LIBCPP_EXCEPTION_ABI domain_error
123class _LIBCPP_EXPORTED_FROM_ABI domain_error
124124 : public logic_error
125125{
126126public:
......@@ -128,12 +128,12 @@ public:
128128 _LIBCPP_INLINE_VISIBILITY explicit domain_error(const char* __s) : logic_error(__s) {}
129129
130130#ifndef _LIBCPP_ABI_VCRUNTIME
131 domain_error(const domain_error&) _NOEXCEPT = default;
131 _LIBCPP_HIDE_FROM_ABI domain_error(const domain_error&) _NOEXCEPT = default;
132132 ~domain_error() _NOEXCEPT override;
133133#endif
134134};
135135
136class _LIBCPP_EXCEPTION_ABI invalid_argument
136class _LIBCPP_EXPORTED_FROM_ABI invalid_argument
137137 : public logic_error
138138{
139139public:
......@@ -141,24 +141,24 @@ public:
141141 _LIBCPP_INLINE_VISIBILITY explicit invalid_argument(const char* __s) : logic_error(__s) {}
142142
143143#ifndef _LIBCPP_ABI_VCRUNTIME
144 invalid_argument(const invalid_argument&) _NOEXCEPT = default;
144 _LIBCPP_HIDE_FROM_ABI invalid_argument(const invalid_argument&) _NOEXCEPT = default;
145145 ~invalid_argument() _NOEXCEPT override;
146146#endif
147147};
148148
149class _LIBCPP_EXCEPTION_ABI length_error
149class _LIBCPP_EXPORTED_FROM_ABI length_error
150150 : public logic_error
151151{
152152public:
153153 _LIBCPP_INLINE_VISIBILITY explicit length_error(const string& __s) : logic_error(__s) {}
154154 _LIBCPP_INLINE_VISIBILITY explicit length_error(const char* __s) : logic_error(__s) {}
155155#ifndef _LIBCPP_ABI_VCRUNTIME
156 length_error(const length_error&) _NOEXCEPT = default;
156 _LIBCPP_HIDE_FROM_ABI length_error(const length_error&) _NOEXCEPT = default;
157157 ~length_error() _NOEXCEPT override;
158158#endif
159159};
160160
161class _LIBCPP_EXCEPTION_ABI out_of_range
161class _LIBCPP_EXPORTED_FROM_ABI out_of_range
162162 : public logic_error
163163{
164164public:
......@@ -166,12 +166,12 @@ public:
166166 _LIBCPP_INLINE_VISIBILITY explicit out_of_range(const char* __s) : logic_error(__s) {}
167167
168168#ifndef _LIBCPP_ABI_VCRUNTIME
169 out_of_range(const out_of_range&) _NOEXCEPT = default;
169 _LIBCPP_HIDE_FROM_ABI out_of_range(const out_of_range&) _NOEXCEPT = default;
170170 ~out_of_range() _NOEXCEPT override;
171171#endif
172172};
173173
174class _LIBCPP_EXCEPTION_ABI range_error
174class _LIBCPP_EXPORTED_FROM_ABI range_error
175175 : public runtime_error
176176{
177177public:
......@@ -179,12 +179,12 @@ public:
179179 _LIBCPP_INLINE_VISIBILITY explicit range_error(const char* __s) : runtime_error(__s) {}
180180
181181#ifndef _LIBCPP_ABI_VCRUNTIME
182 range_error(const range_error&) _NOEXCEPT = default;
182 _LIBCPP_HIDE_FROM_ABI range_error(const range_error&) _NOEXCEPT = default;
183183 ~range_error() _NOEXCEPT override;
184184#endif
185185};
186186
187class _LIBCPP_EXCEPTION_ABI overflow_error
187class _LIBCPP_EXPORTED_FROM_ABI overflow_error
188188 : public runtime_error
189189{
190190public:
......@@ -192,12 +192,12 @@ public:
192192 _LIBCPP_INLINE_VISIBILITY explicit overflow_error(const char* __s) : runtime_error(__s) {}
193193
194194#ifndef _LIBCPP_ABI_VCRUNTIME
195 overflow_error(const overflow_error&) _NOEXCEPT = default;
195 _LIBCPP_HIDE_FROM_ABI overflow_error(const overflow_error&) _NOEXCEPT = default;
196196 ~overflow_error() _NOEXCEPT override;
197197#endif
198198};
199199
200class _LIBCPP_EXCEPTION_ABI underflow_error
200class _LIBCPP_EXPORTED_FROM_ABI underflow_error
201201 : public runtime_error
202202{
203203public:
......@@ -205,7 +205,7 @@ public:
205205 _LIBCPP_INLINE_VISIBILITY explicit underflow_error(const char* __s) : runtime_error(__s) {}
206206
207207#ifndef _LIBCPP_ABI_VCRUNTIME
208 underflow_error(const underflow_error&) _NOEXCEPT = default;
208 _LIBCPP_HIDE_FROM_ABI underflow_error(const underflow_error&) _NOEXCEPT = default;
209209 ~underflow_error() _NOEXCEPT override;
210210#endif
211211};
......@@ -215,96 +215,93 @@ public:
215215_LIBCPP_BEGIN_NAMESPACE_STD
216216
217217// in the dylib
218_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
218_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_runtime_error(const char*);
219219
220220_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
221221void __throw_logic_error(const char*__msg)
222222{
223#ifndef _LIBCPP_NO_EXCEPTIONS
223#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
224224 throw logic_error(__msg);
225225#else
226 ((void)__msg);
227 _VSTD::abort();
226 _LIBCPP_VERBOSE_ABORT("logic_error was thrown in -fno-exceptions mode with message \"%s\"", __msg);
228227#endif
229228}
230229
231230_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
232231void __throw_domain_error(const char*__msg)
233232{
234#ifndef _LIBCPP_NO_EXCEPTIONS
233#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
235234 throw domain_error(__msg);
236235#else
237 ((void)__msg);
238 _VSTD::abort();
236 _LIBCPP_VERBOSE_ABORT("domain_error was thrown in -fno-exceptions mode with message \"%s\"", __msg);
239237#endif
240238}
241239
242240_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
243241void __throw_invalid_argument(const char*__msg)
244242{
245#ifndef _LIBCPP_NO_EXCEPTIONS
243#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
246244 throw invalid_argument(__msg);
247245#else
248 ((void)__msg);
249 _VSTD::abort();
246 _LIBCPP_VERBOSE_ABORT("invalid_argument was thrown in -fno-exceptions mode with message \"%s\"", __msg);
250247#endif
251248}
252249
253250_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
254251void __throw_length_error(const char*__msg)
255252{
256#ifndef _LIBCPP_NO_EXCEPTIONS
253#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
257254 throw length_error(__msg);
258255#else
259 ((void)__msg);
260 _VSTD::abort();
256 _LIBCPP_VERBOSE_ABORT("length_error was thrown in -fno-exceptions mode with message \"%s\"", __msg);
261257#endif
262258}
263259
264260_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
265261void __throw_out_of_range(const char*__msg)
266262{
267#ifndef _LIBCPP_NO_EXCEPTIONS
263#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
268264 throw out_of_range(__msg);
269265#else
270 ((void)__msg);
271 _VSTD::abort();
266 _LIBCPP_VERBOSE_ABORT("out_of_range was thrown in -fno-exceptions mode with message \"%s\"", __msg);
272267#endif
273268}
274269
275270_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
276271void __throw_range_error(const char*__msg)
277272{
278#ifndef _LIBCPP_NO_EXCEPTIONS
273#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
279274 throw range_error(__msg);
280275#else
281 ((void)__msg);
282 _VSTD::abort();
276 _LIBCPP_VERBOSE_ABORT("range_error was thrown in -fno-exceptions mode with message \"%s\"", __msg);
283277#endif
284278}
285279
286280_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
287281void __throw_overflow_error(const char*__msg)
288282{
289#ifndef _LIBCPP_NO_EXCEPTIONS
283#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
290284 throw overflow_error(__msg);
291285#else
292 ((void)__msg);
293 _VSTD::abort();
286 _LIBCPP_VERBOSE_ABORT("overflow_error was thrown in -fno-exceptions mode with message \"%s\"", __msg);
294287#endif
295288}
296289
297290_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
298291void __throw_underflow_error(const char*__msg)
299292{
300#ifndef _LIBCPP_NO_EXCEPTIONS
293#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
301294 throw underflow_error(__msg);
302295#else
303 ((void)__msg);
304 _VSTD::abort();
296 _LIBCPP_VERBOSE_ABORT("underflow_error was thrown in -fno-exceptions mode with message \"%s\"", __msg);
305297#endif
306298}
307299
308300_LIBCPP_END_NAMESPACE_STD
309301
302#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
303# include <cstdlib>
304# include <exception>
305#endif
306
310307#endif // _LIBCPP_STDEXCEPT
lib/libcxx/include/stdlib.h+4-6
......@@ -109,16 +109,15 @@ extern "C++" {
109109#endif
110110
111111// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
112#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__)
112#if !defined(_LIBCPP_MSVCRT)
113113_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT {
114114 return __builtin_labs(__x);
115115}
116116_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {
117117 return __builtin_llabs(__x);
118118}
119#endif // !defined(_LIBCPP_MSVCRT) && !defined(__sun__)
119#endif // !defined(_LIBCPP_MSVCRT)
120120
121#if !defined(__sun__)
122121_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY float abs(float __lcpp_x) _NOEXCEPT {
123122 return __builtin_fabsf(__lcpp_x); // Use builtins to prevent needing math.h
124123}
......@@ -131,7 +130,6 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long double
131130abs(long double __lcpp_x) _NOEXCEPT {
132131 return __builtin_fabsl(__lcpp_x);
133132}
134#endif // !defined(__sun__)
135133
136134// div
137135
......@@ -146,7 +144,7 @@ abs(long double __lcpp_x) _NOEXCEPT {
146144#endif
147145
148146// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
149#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__)
147#if !defined(_LIBCPP_MSVCRT)
150148inline _LIBCPP_INLINE_VISIBILITY ldiv_t div(long __x, long __y) _NOEXCEPT {
151149 return ::ldiv(__x, __y);
152150}
......@@ -156,7 +154,7 @@ inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x,
156154 return ::lldiv(__x, __y);
157155}
158156#endif
159#endif // _LIBCPP_MSVCRT / __sun__
157#endif // _LIBCPP_MSVCRT
160158} // extern "C++"
161159#endif // __cplusplus
162160
lib/libcxx/include/stop_token created+49
......@@ -0,0 +1,49 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_STOP_TOKEN
11#define _LIBCPP_STOP_TOKEN
12
13/*
14
15namespace std {
16 // [stoptoken], class stop_token
17 class stop_token;
18
19 // [stopsource], class stop_source
20 class stop_source;
21
22 // no-shared-stop-state indicator
23 struct nostopstate_t {
24 explicit nostopstate_t() = default;
25 };
26 inline constexpr nostopstate_t nostopstate{};
27
28 // [stopcallback], class template stop_callback
29 template<class Callback>
30 class stop_callback;
31
32*/
33
34#include <__assert> // all public C++ headers provide the assertion handler
35#include <__config>
36#include <__stop_token/stop_callback.h>
37#include <__stop_token/stop_source.h>
38#include <__stop_token/stop_token.h>
39#include <version>
40
41#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
42# pragma GCC system_header
43#endif
44
45#ifdef _LIBCPP_HAS_NO_THREADS
46# error "<stop_token> is not supported since libc++ has been configured without support for threads."
47#endif
48
49#endif // _LIBCPP_STOP_TOKEN
lib/libcxx/include/streambuf+1-2
......@@ -109,6 +109,7 @@ protected:
109109
110110#include <__assert> // all public C++ headers provide the assertion handler
111111#include <__config>
112#include <__fwd/streambuf.h>
112113#include <cstdint>
113114#include <ios>
114115#include <iosfwd>
......@@ -489,11 +490,9 @@ basic_streambuf<_CharT, _Traits>::overflow(int_type)
489490}
490491
491492extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<char>;
492extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<char>;
493493
494494#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
495495extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>;
496extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<wchar_t>;
497496#endif
498497
499498_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/string+686-854
......@@ -119,11 +119,13 @@ public:
119119 explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17, constexpr since C++20
120120 basic_string(const value_type* s, const allocator_type& a = allocator_type()); // constexpr since C++20
121121 basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20
122 basic_string(nullptr_t) = delete; // C++2b
122 basic_string(nullptr_t) = delete; // C++23
123123 basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); // constexpr since C++20
124124 template<class InputIterator>
125125 basic_string(InputIterator begin, InputIterator end,
126126 const allocator_type& a = allocator_type()); // constexpr since C++20
127 template<container-compatible-range<charT> R>
128 constexpr basic_string(from_range_t, R&& rg, const Allocator& a = Allocator()); // since C++23
127129 basic_string(initializer_list<value_type>, const Allocator& = Allocator()); // constexpr since C++20
128130 basic_string(const basic_string&, const Allocator&); // constexpr since C++20
129131 basic_string(basic_string&&, const Allocator&); // constexpr since C++20
......@@ -140,7 +142,7 @@ public:
140142 allocator_type::propagate_on_container_move_assignment::value ||
141143 allocator_type::is_always_equal::value ); // C++17, constexpr since C++20
142144 basic_string& operator=(const value_type* s); // constexpr since C++20
143 basic_string& operator=(nullptr_t) = delete; // C++2b
145 basic_string& operator=(nullptr_t) = delete; // C++23
144146 basic_string& operator=(value_type c); // constexpr since C++20
145147 basic_string& operator=(initializer_list<value_type>); // constexpr since C++20
146148
......@@ -200,6 +202,8 @@ public:
200202 basic_string& append(size_type n, value_type c); // constexpr since C++20
201203 template<class InputIterator>
202204 basic_string& append(InputIterator first, InputIterator last); // constexpr since C++20
205 template<container-compatible-range<charT> R>
206 constexpr basic_string& append_range(R&& rg); // C++23
203207 basic_string& append(initializer_list<value_type>); // constexpr since C++20
204208
205209 void push_back(value_type c); // constexpr since C++20
......@@ -221,6 +225,8 @@ public:
221225 basic_string& assign(size_type n, value_type c); // constexpr since C++20
222226 template<class InputIterator>
223227 basic_string& assign(InputIterator first, InputIterator last); // constexpr since C++20
228 template<container-compatible-range<charT> R>
229 constexpr basic_string& assign_range(R&& rg); // C++23
224230 basic_string& assign(initializer_list<value_type>); // constexpr since C++20
225231
226232 basic_string& insert(size_type pos1, const basic_string& str); // constexpr since C++20
......@@ -237,6 +243,8 @@ public:
237243 iterator insert(const_iterator p, size_type n, value_type c); // constexpr since C++20
238244 template<class InputIterator>
239245 iterator insert(const_iterator p, InputIterator first, InputIterator last); // constexpr since C++20
246 template<container-compatible-range<charT> R>
247 constexpr iterator insert_range(const_iterator p, R&& rg); // C++23
240248 iterator insert(const_iterator p, initializer_list<value_type>); // constexpr since C++20
241249
242250 basic_string& erase(size_type pos = 0, size_type n = npos); // constexpr since C++20
......@@ -262,6 +270,8 @@ public:
262270 basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); // constexpr since C++20
263271 template<class InputIterator>
264272 basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20
273 template<container-compatible-range<charT> R>
274 constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2, R&& rg); // C++23
265275 basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>); // constexpr since C++20
266276
267277 size_type copy(value_type* s, size_type n, size_type pos = 0) const; // constexpr since C++20
......@@ -342,9 +352,9 @@ public:
342352 constexpr bool ends_with(charT c) const noexcept; // C++20
343353 constexpr bool ends_with(const charT* s) const; // C++20
344354
345 constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++2b
346 constexpr bool contains(charT c) const noexcept; // C++2b
347 constexpr bool contains(const charT* s) const; // C++2b
355 constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++23
356 constexpr bool contains(charT c) const noexcept; // C++23
357 constexpr bool contains(const charT* s) const; // C++23
348358};
349359
350360template<class InputIterator,
......@@ -354,6 +364,26 @@ basic_string(InputIterator, InputIterator, Allocator = Allocator())
354364 char_traits<typename iterator_traits<InputIterator>::value_type>,
355365 Allocator>; // C++17
356366
367template<ranges::input_range R,
368 class Allocator = allocator<ranges::range_value_t<R>>>
369 basic_string(from_range_t, R&&, Allocator = Allocator())
370 -> basic_string<ranges::range_value_t<R>, char_traits<ranges::range_value_t<R>>,
371 Allocator>; // C++23
372
373template<class charT,
374 class traits,
375 class Allocator = allocator<charT>>
376 explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
377 -> basic_string<charT, traits, Allocator>; // C++17
378
379template<class charT,
380 class traits,
381 class Allocator = allocator<charT>>
382 basic_string(basic_string_view<charT, traits>,
383 typename see below::size_type, typename see below::size_type,
384 const Allocator& = Allocator())
385 -> basic_string<charT, traits, Allocator>; // C++17
386
357387template<class charT, class traits, class Allocator>
358388basic_string<charT, traits, Allocator>
359389operator+(const basic_string<charT, traits, Allocator>& lhs,
......@@ -524,11 +554,11 @@ template <> struct hash<u16string>;
524554template <> struct hash<u32string>;
525555template <> struct hash<wstring>;
526556
527basic_string<char> operator "" s( const char *str, size_t len ); // C++14, constexpr since C++20
528basic_string<wchar_t> operator "" s( const wchar_t *str, size_t len ); // C++14, constexpr since C++20
529constexpr basic_string<char8_t> operator "" s( const char8_t *str, size_t len ); // C++20
530basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14, constexpr since C++20
531basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14, constexpr since C++20
557basic_string<char> operator""s( const char *str, size_t len ); // C++14, constexpr since C++20
558basic_string<wchar_t> operator""s( const wchar_t *str, size_t len ); // C++14, constexpr since C++20
559constexpr basic_string<char8_t> operator""s( const char8_t *str, size_t len ); // C++20
560basic_string<char16_t> operator""s( const char16_t *str, size_t len ); // C++14, constexpr since C++20
561basic_string<char32_t> operator""s( const char32_t *str, size_t len ); // C++14, constexpr since C++20
532562
533563} // std
534564
......@@ -540,7 +570,6 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len );
540570#include <__algorithm/remove_if.h>
541571#include <__assert> // all public C++ headers provide the assertion handler
542572#include <__config>
543#include <__debug>
544573#include <__format/enable_insertable.h>
545574#include <__functional/hash.h>
546575#include <__functional/unary_function.h>
......@@ -550,6 +579,7 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len );
550579#include <__iterator/iterator_traits.h>
551580#include <__iterator/reverse_iterator.h>
552581#include <__iterator/wrap_iter.h>
582#include <__memory/addressof.h>
553583#include <__memory/allocate_at_least.h>
554584#include <__memory/allocator.h>
555585#include <__memory/allocator_traits.h>
......@@ -558,23 +588,38 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len );
558588#include <__memory/pointer_traits.h>
559589#include <__memory/swap_allocator.h>
560590#include <__memory_resource/polymorphic_allocator.h>
591#include <__ranges/access.h>
592#include <__ranges/concepts.h>
593#include <__ranges/container_compatible_range.h>
594#include <__ranges/from_range.h>
595#include <__ranges/size.h>
561596#include <__string/char_traits.h>
562597#include <__string/extern_template_lists.h>
563598#include <__type_traits/is_allocator.h>
599#include <__type_traits/is_array.h>
600#include <__type_traits/is_convertible.h>
601#include <__type_traits/is_nothrow_default_constructible.h>
602#include <__type_traits/is_nothrow_move_assignable.h>
603#include <__type_traits/is_same.h>
604#include <__type_traits/is_standard_layout.h>
605#include <__type_traits/is_trivial.h>
564606#include <__type_traits/noexcept_move_assign_container.h>
607#include <__type_traits/remove_cvref.h>
608#include <__type_traits/void_t.h>
565609#include <__utility/auto_cast.h>
610#include <__utility/declval.h>
611#include <__utility/forward.h>
612#include <__utility/is_pointer_in_range.h>
566613#include <__utility/move.h>
567614#include <__utility/swap.h>
568615#include <__utility/unreachable.h>
569616#include <climits>
570617#include <cstdint>
571618#include <cstdio> // EOF
572#include <cstdlib>
573619#include <cstring>
574620#include <limits>
575621#include <stdexcept>
576622#include <string_view>
577#include <type_traits>
578623#include <version>
579624
580625#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
......@@ -632,7 +677,8 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
632677basic_string<_CharT, _Traits, _Allocator>
633678operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
634679
635extern template _LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
680extern template _LIBCPP_EXPORTED_FROM_ABI string operator+
681 <char, char_traits<char>, allocator<char> >(char const*, string const&);
636682
637683template <class _Iter>
638684struct __string_is_trivial_iterator : public false_type {};
......@@ -652,6 +698,7 @@ struct __can_be_converted_to_string_view : public _BoolConstant<
652698 > {};
653699
654700struct __uninitialized_size_tag {};
701struct __init_with_sentinel_tag {};
655702
656703template<class _CharT, class _Traits, class _Allocator>
657704class basic_string
......@@ -810,15 +857,21 @@ private:
810857 __set_long_pointer(__allocation);
811858 __set_long_size(__size);
812859 }
813 std::__debug_db_insert_c(this);
860 }
861
862 template <class _Iter, class _Sent>
863 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
864 basic_string(__init_with_sentinel_tag, _Iter __first, _Sent __last, const allocator_type& __a)
865 : __r_(__default_init_tag(), __a) {
866 __init_with_sentinel(std::move(__first), std::move(__last));
814867 }
815868
816869 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator __make_iterator(pointer __p) {
817 return iterator(this, __p);
870 return iterator(__p);
818871 }
819872
820873 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator __make_const_iterator(const_pointer __p) const {
821 return const_iterator(this, __p);
874 return const_iterator(__p);
822875 }
823876
824877public:
......@@ -827,7 +880,6 @@ public:
827880 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string()
828881 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
829882 : __r_(__default_init_tag(), __default_init_tag()) {
830 std::__debug_db_insert_c(this);
831883 __default_init();
832884 }
833885
......@@ -838,12 +890,24 @@ public:
838890 _NOEXCEPT
839891#endif
840892 : __r_(__default_init_tag(), __a) {
841 std::__debug_db_insert_c(this);
842893 __default_init();
843894 }
844895
845 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str);
846 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str, const allocator_type& __a);
896 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str)
897 : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) {
898 if (!__str.__is_long())
899 __r_.first() = __str.__r_.first();
900 else
901 __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
902 }
903
904 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str, const allocator_type& __a)
905 : __r_(__default_init_tag(), __a) {
906 if (!__str.__is_long())
907 __r_.first() = __str.__r_.first();
908 else
909 __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
910 }
847911
848912#ifndef _LIBCPP_CXX03_LANG
849913 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str)
......@@ -854,9 +918,6 @@ public:
854918# endif
855919 : __r_(std::move(__str.__r_)) {
856920 __str.__default_init();
857 std::__debug_db_insert_c(this);
858 if (__is_long())
859 std::__debug_db_swap(this, &__str);
860921 }
861922
862923 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str, const allocator_type& __a)
......@@ -869,49 +930,47 @@ public:
869930 __r_.first() = __str.__r_.first();
870931 __str.__default_init();
871932 }
872 std::__debug_db_insert_c(this);
873 if (__is_long())
874 std::__debug_db_swap(this, &__str);
875933 }
876934#endif // _LIBCPP_CXX03_LANG
877935
878 template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
936 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
879937 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s)
880938 : __r_(__default_init_tag(), __default_init_tag()) {
881 _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
939 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "basic_string(const char*) detected nullptr");
882940 __init(__s, traits_type::length(__s));
883 std::__debug_db_insert_c(this);
884941 }
885942
886 template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
887 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, const _Allocator& __a);
943 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
944 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, const _Allocator& __a)
945 : __r_(__default_init_tag(), __a) {
946 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
947 __init(__s, traits_type::length(__s));
948 }
888949
889#if _LIBCPP_STD_VER > 20
950#if _LIBCPP_STD_VER >= 23
890951 basic_string(nullptr_t) = delete;
891952#endif
892953
893954 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n)
894955 : __r_(__default_init_tag(), __default_init_tag()) {
895 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
956 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
896957 __init(__s, __n);
897 std::__debug_db_insert_c(this);
898958 }
899959
900960 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
901961 basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
902962 : __r_(__default_init_tag(), __a) {
903 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
963 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr,
964 "basic_string(const char*, n, allocator) detected nullptr");
904965 __init(__s, __n);
905 std::__debug_db_insert_c(this);
906966 }
907967
908968 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c)
909969 : __r_(__default_init_tag(), __default_init_tag()) {
910970 __init(__n, __c);
911 std::__debug_db_insert_c(this);
912971 }
913972
914#if _LIBCPP_STD_VER > 20
973#if _LIBCPP_STD_VER >= 23
915974 _LIBCPP_HIDE_FROM_ABI constexpr
916975 basic_string(basic_string&& __str, size_type __pos, const _Allocator& __alloc = _Allocator())
917976 : basic_string(std::move(__str), __pos, npos, __alloc) {}
......@@ -934,18 +993,23 @@ public:
934993 // Perform a copy because the allocators are not compatible.
935994 __init(__str.data() + __pos, __len);
936995 }
937
938 std::__debug_db_insert_c(this);
939 if (__is_long())
940 std::__debug_db_swap(this, &__str);
941996 }
942997#endif
943998
944 template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
945 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c, const _Allocator& __a);
999 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
1000 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c, const _Allocator& __a)
1001 : __r_(__default_init_tag(), __a) {
1002 __init(__n, __c);
1003 }
9461004
9471005 _LIBCPP_CONSTEXPR_SINCE_CXX20
948 basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator());
1006 basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator())
1007 : __r_(__default_init_tag(), __a) {
1008 size_type __str_sz = __str.size();
1009 if (__pos > __str_sz)
1010 __throw_out_of_range();
1011 __init(__str.data() + __pos, std::min(__n, __str_sz - __pos));
1012 }
9491013
9501014 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
9511015 basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator())
......@@ -954,65 +1018,91 @@ public:
9541018 if (__pos > __str_sz)
9551019 __throw_out_of_range();
9561020 __init(__str.data() + __pos, __str_sz - __pos);
957 std::__debug_db_insert_c(this);
9581021 }
9591022
9601023 template <class _Tp,
961 class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
962 !__is_same_uncvref<_Tp, basic_string>::value> >
1024 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1025 !__is_same_uncvref<_Tp, basic_string>::value,
1026 int> = 0>
9631027 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
964 basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type());
1028 basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type())
1029 : __r_(__default_init_tag(), __a) {
1030 __self_view __sv0 = __t;
1031 __self_view __sv = __sv0.substr(__pos, __n);
1032 __init(__sv.data(), __sv.size());
1033 }
9651034
9661035 template <class _Tp,
967 class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
968 !__is_same_uncvref<_Tp, basic_string>::value> >
969 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(
970 const _Tp& __t);
1036 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1037 !__is_same_uncvref<_Tp, basic_string>::value,
1038 int> = 0>
1039 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const _Tp& __t)
1040 : __r_(__default_init_tag(), __default_init_tag()) {
1041 __self_view __sv = __t;
1042 __init(__sv.data(), __sv.size());
1043 }
9711044
9721045 template <class _Tp,
973 class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
974 !__is_same_uncvref<_Tp, basic_string>::value> >
1046 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1047 !__is_same_uncvref<_Tp, basic_string>::value,
1048 int> = 0>
9751049 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(
976 const _Tp& __t, const allocator_type& __a);
1050 const _Tp& __t, const allocator_type& __a)
1051 : __r_(__default_init_tag(), __a) {
1052 __self_view __sv = __t;
1053 __init(__sv.data(), __sv.size());
1054 }
9771055
978 template <class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
1056 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
9791057 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(_InputIterator __first, _InputIterator __last)
9801058 : __r_(__default_init_tag(), __default_init_tag()) {
9811059 __init(__first, __last);
982 std::__debug_db_insert_c(this);
9831060 }
9841061
985 template <class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
1062 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
9861063 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
9871064 basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
9881065 : __r_(__default_init_tag(), __a) {
9891066 __init(__first, __last);
990 std::__debug_db_insert_c(this);
9911067 }
9921068
1069#if _LIBCPP_STD_VER >= 23
1070 template <_ContainerCompatibleRange<_CharT> _Range>
1071 _LIBCPP_HIDE_FROM_ABI constexpr
1072 basic_string(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type())
1073 : __r_(__default_init_tag(), __a) {
1074 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
1075 __init_with_size(ranges::begin(__range), ranges::end(__range), ranges::distance(__range));
1076 } else {
1077 __init_with_sentinel(ranges::begin(__range), ranges::end(__range));
1078 }
1079 }
1080#endif
1081
9931082#ifndef _LIBCPP_CXX03_LANG
9941083 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il)
9951084 : __r_(__default_init_tag(), __default_init_tag()) {
9961085 __init(__il.begin(), __il.end());
997 std::__debug_db_insert_c(this);
9981086 }
9991087
10001088 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il, const _Allocator& __a)
10011089 : __r_(__default_init_tag(), __a) {
10021090 __init(__il.begin(), __il.end());
1003 std::__debug_db_insert_c(this);
10041091 }
10051092#endif // _LIBCPP_CXX03_LANG
10061093
1007 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string();
1094 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() {
1095 if (__is_long())
1096 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
1097 }
10081098
10091099 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10101100 operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }
10111101
10121102 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const basic_string& __str);
10131103
1014 template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1015 !__is_same_uncvref<_Tp, basic_string>::value> >
1104 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1105 !__is_same_uncvref<_Tp, basic_string>::value, int> = 0>
10161106 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const _Tp& __t) {
10171107 __self_view __sv = __t;
10181108 return assign(__sv);
......@@ -1030,7 +1120,7 @@ public:
10301120#endif
10311121 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10321122 basic_string& operator=(const value_type* __s) {return assign(__s);}
1033#if _LIBCPP_STD_VER > 20
1123#if _LIBCPP_STD_VER >= 23
10341124 basic_string& operator=(nullptr_t) = delete;
10351125#endif
10361126 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(value_type __c);
......@@ -1097,7 +1187,7 @@ public:
10971187
10981188 _LIBCPP_CONSTEXPR_SINCE_CXX20 void reserve(size_type __requested_capacity);
10991189
1100#if _LIBCPP_STD_VER > 20
1190#if _LIBCPP_STD_VER >= 23
11011191 template <class _Op>
11021192 _LIBCPP_HIDE_FROM_ABI constexpr
11031193 void resize_and_overwrite(size_type __n, _Op __op) {
......@@ -1116,12 +1206,12 @@ public:
11161206 bool empty() const _NOEXCEPT {return size() == 0;}
11171207
11181208 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __pos) const _NOEXCEPT {
1119 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
1209 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
11201210 return *(data() + __pos);
11211211 }
11221212
11231213 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __pos) _NOEXCEPT {
1124 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
1214 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
11251215 return *(__get_pointer() + __pos);
11261216 }
11271217
......@@ -1132,14 +1222,11 @@ public:
11321222 return append(__str);
11331223 }
11341224
1135 template <class _Tp>
1136 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1137 __enable_if_t
1138 <
1139 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
1140 && !__is_same_uncvref<_Tp, basic_string >::value,
1141 basic_string&
1142 >
1225 template <class _Tp,
1226 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1227 !__is_same_uncvref<_Tp, basic_string >::value,
1228 int> = 0>
1229 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
11431230 operator+=(const _Tp& __t) {
11441231 __self_view __sv = __t; return append(__sv);
11451232 }
......@@ -1162,25 +1249,27 @@ public:
11621249 return append(__str.data(), __str.size());
11631250 }
11641251
1165 template <class _Tp>
1166 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1167 __enable_if_t<
1168 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
1169 && !__is_same_uncvref<_Tp, basic_string>::value,
1170 basic_string&
1171 >
1172 append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); }
1252 template <class _Tp,
1253 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1254 !__is_same_uncvref<_Tp, basic_string>::value,
1255 int> = 0>
1256 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1257 append(const _Tp& __t) {
1258 __self_view __sv = __t;
1259 return append(__sv.data(), __sv.size());
1260 }
1261
11731262 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
11741263
1175 template <class _Tp>
1264 template <class _Tp,
1265 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1266 !__is_same_uncvref<_Tp, basic_string>::value,
1267 int> = 0>
11761268 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1177 __enable_if_t
1178 <
1179 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
1180 && !__is_same_uncvref<_Tp, basic_string>::value,
1181 basic_string&
1182 >
1183 append(const _Tp& __t, size_type __pos, size_type __n=npos);
1269
1270 basic_string&
1271 append(const _Tp& __t, size_type __pos, size_type __n = npos);
1272
11841273 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n);
11851274 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s);
11861275 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(size_type __n, value_type __c);
......@@ -1188,29 +1277,27 @@ public:
11881277 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
11891278 void __append_default_init(size_type __n);
11901279
1191 template<class _InputIterator>
1192 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1193 __enable_if_t
1194 <
1195 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
1196 basic_string&
1197 >
1198 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1280 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
1281 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
11991282 append(_InputIterator __first, _InputIterator __last) {
1200 const basic_string __temp(__first, __last, __alloc());
1201 append(__temp.data(), __temp.size());
1202 return *this;
1283 const basic_string __temp(__first, __last, __alloc());
1284 append(__temp.data(), __temp.size());
1285 return *this;
12031286 }
1204 template<class _ForwardIterator>
1205 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1206 __enable_if_t
1207 <
1208 __is_cpp17_forward_iterator<_ForwardIterator>::value,
1209 basic_string&
1210 >
1211 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1287
1288 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
1289 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
12121290 append(_ForwardIterator __first, _ForwardIterator __last);
12131291
1292#if _LIBCPP_STD_VER >= 23
1293 template <_ContainerCompatibleRange<_CharT> _Range>
1294 _LIBCPP_HIDE_FROM_ABI
1295 constexpr basic_string& append_range(_Range&& __range) {
1296 insert_range(end(), std::forward<_Range>(__range));
1297 return *this;
1298 }
1299#endif
1300
12141301#ifndef _LIBCPP_CXX03_LANG
12151302 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
12161303 basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
......@@ -1220,33 +1307,32 @@ public:
12201307 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back();
12211308
12221309 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT {
1223 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
1310 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");
12241311 return *__get_pointer();
12251312 }
12261313
12271314 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT {
1228 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
1315 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");
12291316 return *data();
12301317 }
12311318
12321319 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT {
1233 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
1320 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");
12341321 return *(__get_pointer() + size() - 1);
12351322 }
12361323
12371324 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT {
1238 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
1325 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");
12391326 return *(data() + size() - 1);
12401327 }
12411328
1242 template <class _Tp>
1243 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1244 __enable_if_t
1245 <
1246 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1247 basic_string&
1248 >
1249 assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); }
1329 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1330 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1331 assign(const _Tp& __t) {
1332 __self_view __sv = __t;
1333 return assign(__sv.data(), __sv.size());
1334 }
1335
12501336 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
12511337 basic_string& assign(const basic_string& __str) { return *this = __str; }
12521338#ifndef _LIBCPP_CXX03_LANG
......@@ -1256,34 +1342,42 @@ public:
12561342 {*this = std::move(__str); return *this;}
12571343#endif
12581344 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
1259 template <class _Tp>
1260 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1261 __enable_if_t
1262 <
1263 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
1264 && !__is_same_uncvref<_Tp, basic_string>::value,
1265 basic_string&
1266 >
1267 assign(const _Tp & __t, size_type __pos, size_type __n=npos);
1345
1346 template <class _Tp,
1347 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1348 !__is_same_uncvref<_Tp, basic_string>::value,
1349 int> = 0>
1350 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1351 assign(const _Tp& __t, size_type __pos, size_type __n = npos);
1352
12681353 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n);
12691354 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s);
12701355 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(size_type __n, value_type __c);
1271 template<class _InputIterator>
1272 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1273 __enable_if_t
1274 <
1275 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
1276 basic_string&
1277 >
1278 assign(_InputIterator __first, _InputIterator __last);
1279 template<class _ForwardIterator>
1280 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1281 __enable_if_t
1282 <
1283 __is_cpp17_forward_iterator<_ForwardIterator>::value,
1284 basic_string&
1285 >
1286 assign(_ForwardIterator __first, _ForwardIterator __last);
1356 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
1357 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1358 assign(_InputIterator __first, _InputIterator __last);
1359
1360 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
1361 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1362 assign(_ForwardIterator __first, _ForwardIterator __last);
1363
1364#if _LIBCPP_STD_VER >= 23
1365 template <_ContainerCompatibleRange<_CharT> _Range>
1366 _LIBCPP_HIDE_FROM_ABI
1367 constexpr basic_string& assign_range(_Range&& __range) {
1368 if constexpr (__string_is_trivial_iterator<ranges::iterator_t<_Range>>::value &&
1369 (ranges::forward_range<_Range> || ranges::sized_range<_Range>)) {
1370 size_type __n = static_cast<size_type>(ranges::distance(__range));
1371 __assign_trivial(ranges::begin(__range), ranges::end(__range), __n);
1372
1373 } else {
1374 __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
1375 }
1376
1377 return *this;
1378 }
1379#endif
1380
12871381#ifndef _LIBCPP_CXX03_LANG
12881382 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
12891383 basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
......@@ -1294,56 +1388,57 @@ public:
12941388 return insert(__pos1, __str.data(), __str.size());
12951389 }
12961390
1297 template <class _Tp>
1298 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1299 __enable_if_t
1300 <
1301 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1302 basic_string&
1303 >
1304 insert(size_type __pos1, const _Tp& __t)
1305 { __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); }
1391 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1392 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1393 insert(size_type __pos1, const _Tp& __t) {
1394 __self_view __sv = __t;
1395 return insert(__pos1, __sv.data(), __sv.size());
1396 }
13061397
1307 template <class _Tp>
1308 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1309 __enable_if_t
1310 <
1311 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
1312 basic_string&
1313 >
1314 insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos);
1315 _LIBCPP_CONSTEXPR_SINCE_CXX20
1316 basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);
1317 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
1318 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s);
1319 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c);
1320 _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __pos, value_type __c);
1398 template <class _Tp,
1399 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1400 !__is_same_uncvref<_Tp, basic_string>::value,
1401 int> = 0>
1402 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1403 insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n = npos);
1404
1405 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1406 insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos);
1407 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
1408 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s);
1409 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c);
1410 _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __pos, value_type __c);
1411
1412#if _LIBCPP_STD_VER >= 23
1413 template <_ContainerCompatibleRange<_CharT> _Range>
1414 _LIBCPP_HIDE_FROM_ABI
1415 constexpr iterator insert_range(const_iterator __position, _Range&& __range) {
1416 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
1417 auto __n = static_cast<size_type>(ranges::distance(__range));
1418 return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n);
1419
1420 } else {
1421 basic_string __temp(from_range, std::forward<_Range>(__range), __alloc());
1422 return insert(__position, __temp.data(), __temp.data() + __temp.size());
1423 }
1424 }
1425#endif
13211426
13221427 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
13231428 insert(const_iterator __pos, size_type __n, value_type __c) {
1324 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
1325 "string::insert(iterator, n, value) called with an iterator not referring to this string");
13261429 difference_type __p = __pos - begin();
13271430 insert(static_cast<size_type>(__p), __n, __c);
13281431 return begin() + __p;
13291432 }
13301433
1331 template<class _InputIterator>
1332 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1333 __enable_if_t
1334 <
1335 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
1336 iterator
1337 >
1338 insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
1339 template<class _ForwardIterator>
1340 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1341 __enable_if_t
1342 <
1343 __is_cpp17_forward_iterator<_ForwardIterator>::value,
1344 iterator
1345 >
1346 insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
1434 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
1435 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
1436 insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
1437
1438 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
1439 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
1440 insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
1441
13471442#ifndef _LIBCPP_CXX03_LANG
13481443 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
13491444 iterator insert(const_iterator __pos, initializer_list<value_type> __il)
......@@ -1361,28 +1456,27 @@ public:
13611456 return replace(__pos1, __n1, __str.data(), __str.size());
13621457 }
13631458
1364 template <class _Tp>
1365 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1366 __enable_if_t
1367 <
1368 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1369 basic_string&
1370 >
1371 replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); }
1372 _LIBCPP_CONSTEXPR_SINCE_CXX20
1373 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
1374 template <class _Tp>
1375 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1376 __enable_if_t
1377 <
1378 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
1379 basic_string&
1380 >
1381 replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos);
1382 _LIBCPP_CONSTEXPR_SINCE_CXX20
1383 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
1384 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
1385 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
1459 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1460 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1461 replace(size_type __pos1, size_type __n1, const _Tp& __t) {
1462 __self_view __sv = __t;
1463 return replace(__pos1, __n1, __sv.data(), __sv.size());
1464 }
1465
1466 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1467 replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos);
1468
1469 template <class _Tp,
1470 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1471 !__is_same_uncvref<_Tp, basic_string>::value,
1472 int> = 0>
1473 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1474 replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos);
1475
1476 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1477 replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
1478 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
1479 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
13861480
13871481 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
13881482 replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) {
......@@ -1390,14 +1484,12 @@ public:
13901484 static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __str.data(), __str.size());
13911485 }
13921486
1393 template <class _Tp>
1394 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1395 __enable_if_t
1396 <
1397 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1398 basic_string&
1399 >
1400 replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); }
1487 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1488 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1489 replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) {
1490 __self_view __sv = __t;
1491 return replace(__i1 - begin(), __i2 - __i1, __sv);
1492 }
14011493
14021494 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
14031495 replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) {
......@@ -1414,14 +1506,19 @@ public:
14141506 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);
14151507 }
14161508
1417 template<class _InputIterator>
1418 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1419 __enable_if_t
1420 <
1421 __is_cpp17_input_iterator<_InputIterator>::value,
1422 basic_string&
1423 >
1424 replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
1509 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
1510 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1511 replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
1512
1513#if _LIBCPP_STD_VER >= 23
1514 template <_ContainerCompatibleRange<_CharT> _Range>
1515 _LIBCPP_HIDE_FROM_ABI
1516 constexpr basic_string& replace_with_range(const_iterator __i1, const_iterator __i2, _Range&& __range) {
1517 basic_string __temp(from_range, std::forward<_Range>(__range), __alloc());
1518 return replace(__i1, __i2, __temp);
1519 }
1520#endif
1521
14251522#ifndef _LIBCPP_CXX03_LANG
14261523 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
14271524 basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)
......@@ -1460,7 +1557,7 @@ public:
14601557 const value_type* c_str() const _NOEXCEPT {return data();}
14611558 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
14621559 const value_type* data() const _NOEXCEPT {return std::__to_address(__get_pointer());}
1463#if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY)
1560#if _LIBCPP_STD_VER >= 17
14641561 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
14651562 value_type* data() _NOEXCEPT {return std::__to_address(__get_pointer());}
14661563#endif
......@@ -1471,16 +1568,11 @@ public:
14711568 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
14721569 size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
14731570
1474 template <class _Tp>
1475 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1476 __enable_if_t
1477 <
1478 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1479 size_type
1480 >
1481 find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1482 _LIBCPP_CONSTEXPR_SINCE_CXX20
1483 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1571 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1572 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1573 find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1574
1575 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
14841576 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
14851577 size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
14861578 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
......@@ -1488,14 +1580,10 @@ public:
14881580 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
14891581 size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
14901582
1491 template <class _Tp>
1492 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1493 __enable_if_t
1494 <
1495 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1496 size_type
1497 >
1498 rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1583 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1584 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1585 rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1586
14991587 _LIBCPP_CONSTEXPR_SINCE_CXX20
15001588 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
15011589 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -1505,14 +1593,10 @@ public:
15051593 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15061594 size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
15071595
1508 template <class _Tp>
1509 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1510 __enable_if_t
1511 <
1512 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1513 size_type
1514 >
1515 find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1596 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1597 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1598 find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1599
15161600 _LIBCPP_CONSTEXPR_SINCE_CXX20
15171601 size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
15181602 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -1523,14 +1607,10 @@ public:
15231607 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15241608 size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
15251609
1526 template <class _Tp>
1527 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1528 __enable_if_t
1529 <
1530 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1531 size_type
1532 >
1533 find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1610 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1611 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1612 find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1613
15341614 _LIBCPP_CONSTEXPR_SINCE_CXX20
15351615 size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
15361616 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -1541,14 +1621,10 @@ public:
15411621 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15421622 size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
15431623
1544 template <class _Tp>
1545 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1546 __enable_if_t
1547 <
1548 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1549 size_type
1550 >
1551 find_first_not_of(const _Tp &__t, size_type __pos = 0) const _NOEXCEPT;
1624 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1625 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1626 find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1627
15521628 _LIBCPP_CONSTEXPR_SINCE_CXX20
15531629 size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
15541630 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -1559,14 +1635,10 @@ public:
15591635 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15601636 size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
15611637
1562 template <class _Tp>
1563 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1564 __enable_if_t
1565 <
1566 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1567 size_type
1568 >
1569 find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1638 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1639 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1640 find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1641
15701642 _LIBCPP_CONSTEXPR_SINCE_CXX20
15711643 size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
15721644 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -1577,23 +1649,13 @@ public:
15771649 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15781650 int compare(const basic_string& __str) const _NOEXCEPT;
15791651
1580 template <class _Tp>
1581 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1582 __enable_if_t
1583 <
1584 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1585 int
1586 >
1587 compare(const _Tp &__t) const _NOEXCEPT;
1652 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1653 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int
1654 compare(const _Tp& __t) const _NOEXCEPT;
15881655
1589 template <class _Tp>
1590 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1591 __enable_if_t
1592 <
1593 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1594 int
1595 >
1596 compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
1656 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1657 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int
1658 compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
15971659
15981660 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15991661 int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
......@@ -1601,20 +1663,19 @@ public:
16011663 int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2,
16021664 size_type __n2 = npos) const;
16031665
1604 template <class _Tp>
1605 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1606 __enable_if_t
1607 <
1608 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
1609 int
1610 >
1611 compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const;
1666 template <class _Tp,
1667 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1668 !__is_same_uncvref<_Tp, basic_string>::value,
1669 int> = 0>
1670 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
1671 compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos) const;
1672
16121673 _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const value_type* __s) const _NOEXCEPT;
16131674 _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
16141675 _LIBCPP_CONSTEXPR_SINCE_CXX20
16151676 int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
16161677
1617#if _LIBCPP_STD_VER > 17
1678#if _LIBCPP_STD_VER >= 20
16181679 constexpr _LIBCPP_HIDE_FROM_ABI
16191680 bool starts_with(__self_view __sv) const noexcept
16201681 { return __self_view(data(), size()).starts_with(__sv); }
......@@ -1640,7 +1701,7 @@ public:
16401701 { return ends_with(__self_view(__s)); }
16411702#endif
16421703
1643#if _LIBCPP_STD_VER > 20
1704#if _LIBCPP_STD_VER >= 23
16441705 constexpr _LIBCPP_HIDE_FROM_ABI
16451706 bool contains(__self_view __sv) const noexcept
16461707 { return __self_view(data(), size()).contains(__sv); }
......@@ -1658,15 +1719,6 @@ public:
16581719
16591720 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __clear_and_shrink() _NOEXCEPT;
16601721
1661#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1662
1663 bool __dereferenceable(const const_iterator* __i) const;
1664 bool __decrementable(const const_iterator* __i) const;
1665 bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
1666 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
1667
1668#endif // _LIBCPP_ENABLE_DEBUG_MODE
1669
16701722private:
16711723 template<class _Alloc>
16721724 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -1683,7 +1735,7 @@ private:
16831735 }
16841736
16851737 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __begin_lifetime(pointer __begin, size_type __n) {
1686#if _LIBCPP_STD_VER > 17
1738#if _LIBCPP_STD_VER >= 20
16871739 if (__libcpp_is_constant_evaluated()) {
16881740 for (size_type __i = 0; __i != __n; ++__i)
16891741 std::construct_at(std::addressof(__begin[__i]));
......@@ -1691,7 +1743,7 @@ private:
16911743#else
16921744 (void)__begin;
16931745 (void)__n;
1694#endif // _LIBCPP_STD_VER > 17
1746#endif // _LIBCPP_STD_VER >= 20
16951747 }
16961748
16971749 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __default_init() {
......@@ -1716,9 +1768,17 @@ private:
17161768 return !__libcpp_is_constant_evaluated() && (__sz < __min_cap);
17171769 }
17181770
1719 template <class _ForwardIterator>
1771 template <class _Iterator, class _Sentinel>
1772 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
1773 void __assign_trivial(_Iterator __first, _Sentinel __last, size_type __n);
1774
1775 template <class _Iterator, class _Sentinel>
1776 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
1777 void __assign_with_sentinel(_Iterator __first, _Sentinel __last);
1778
1779 template <class _ForwardIterator, class _Sentinel>
17201780 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1721 iterator __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _ForwardIterator __last) {
1781 iterator __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _Sentinel __last) {
17221782 size_type __sz = size();
17231783 size_type __cap = capacity();
17241784 value_type* __p;
......@@ -1731,7 +1791,7 @@ private:
17311791 }
17321792 else
17331793 {
1734 __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
1794 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
17351795 __p = std::__to_address(__get_long_pointer());
17361796 }
17371797 __sz += __n;
......@@ -1743,19 +1803,25 @@ private:
17431803 return begin() + __ip;
17441804 }
17451805
1806 template<class _Iterator, class _Sentinel>
1807 _LIBCPP_CONSTEXPR_SINCE_CXX20
1808 iterator __insert_with_size(const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n);
1809
17461810 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 allocator_type& __alloc() _NOEXCEPT { return __r_.second(); }
17471811 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); }
17481812
17491813 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
17501814 void __set_short_size(size_type __s) _NOEXCEPT {
1751 _LIBCPP_ASSERT(__s < __min_cap, "__s should never be greater than or equal to the short string capacity");
1815 _LIBCPP_ASSERT_INTERNAL(
1816 __s < __min_cap, "__s should never be greater than or equal to the short string capacity");
17521817 __r_.first().__s.__size_ = __s;
17531818 __r_.first().__s.__is_long_ = false;
17541819 }
17551820
17561821 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
17571822 size_type __get_short_size() const _NOEXCEPT {
1758 _LIBCPP_ASSERT(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size");
1823 _LIBCPP_ASSERT_INTERNAL(
1824 !__r_.first().__s.__is_long_, "String has to be short when trying to get the short size");
17591825 return __r_.first().__s.__size_;
17601826 }
17611827
......@@ -1839,25 +1905,29 @@ private:
18391905 // to only inline the fast path code directly in the ctor.
18401906 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init_copy_ctor_external(const value_type* __s, size_type __sz);
18411907
1842 template <class _InputIterator>
1843 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
1844 __enable_if_t
1845 <
1846 __is_exactly_cpp17_input_iterator<_InputIterator>::value
1847 >
1848 __init(_InputIterator __first, _InputIterator __last);
1908 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
1909 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_InputIterator __first, _InputIterator __last);
18491910
1850 template <class _ForwardIterator>
1851 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
1852 __enable_if_t
1853 <
1854 __is_cpp17_forward_iterator<_ForwardIterator>::value
1855 >
1856 __init(_ForwardIterator __first, _ForwardIterator __last);
1911 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
1912 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_ForwardIterator __first, _ForwardIterator __last);
1913
1914 template <class _InputIterator, class _Sentinel>
1915 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1916 void __init_with_sentinel(_InputIterator __first, _Sentinel __last);
1917 template <class _InputIterator, class _Sentinel>
1918 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1919 void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz);
18571920
18581921 _LIBCPP_CONSTEXPR_SINCE_CXX20
1922#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1
1923 _LIBCPP_HIDE_FROM_ABI
1924#endif
1925 _LIBCPP_DEPRECATED_("use __grow_by_without_replace")
18591926 void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
18601927 size_type __n_copy, size_type __n_del, size_type __n_add = 0);
1928 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
1929 void __grow_by_without_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1930 size_type __n_copy, size_type __n_del, size_type __n_add = 0);
18611931 _LIBCPP_CONSTEXPR_SINCE_CXX20
18621932 void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
18631933 size_type __n_copy, size_type __n_del,
......@@ -1918,7 +1988,7 @@ private:
19181988 _NOEXCEPT_(__alloc_traits::is_always_equal::value);
19191989 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
19201990 void __move_assign(basic_string& __str, true_type)
1921#if _LIBCPP_STD_VER > 14
1991#if _LIBCPP_STD_VER >= 17
19221992 _NOEXCEPT;
19231993#else
19241994 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
......@@ -1962,21 +2032,13 @@ private:
19622032 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
19632033 basic_string& __null_terminate_at(value_type* __p, size_type __newsz) {
19642034 __set_size(__newsz);
1965 __invalidate_iterators_past(__newsz);
19662035 traits_type::assign(__p[__newsz], value_type());
19672036 return *this;
19682037 }
19692038
1970 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __invalidate_iterators_past(size_type);
1971
1972 template<class _Tp>
1973 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1974 bool __addr_in_range(_Tp&& __t) const {
1975 // assume that the ranges overlap, because we can't check during constant evaluation
1976 if (__libcpp_is_constant_evaluated())
1977 return true;
1978 const volatile void *__p = std::addressof(__t);
1979 return data() <= __p && __p <= data() + size();
2039 template <class _Tp>
2040 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __addr_in_range(const _Tp& __v) const {
2041 return std::__is_pointer_in_range(data(), data() + size() + 1, std::addressof(__v));
19802042 }
19812043
19822044 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
......@@ -2017,7 +2079,7 @@ private:
20172079template<class _InputIterator,
20182080 class _CharT = __iter_value_type<_InputIterator>,
20192081 class _Allocator = allocator<_CharT>,
2020 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
2082 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
20212083 class = enable_if_t<__is_allocator<_Allocator>::value>
20222084 >
20232085basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
......@@ -2041,35 +2103,14 @@ basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _
20412103 -> basic_string<_CharT, _Traits, _Allocator>;
20422104#endif
20432105
2044template <class _CharT, class _Traits, class _Allocator>
2045inline _LIBCPP_CONSTEXPR_SINCE_CXX20
2046void
2047basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos)
2048{
2049#ifdef _LIBCPP_ENABLE_DEBUG_MODE
2050 if (!__libcpp_is_constant_evaluated()) {
2051 __c_node* __c = __get_db()->__find_c_and_lock(this);
2052 if (__c)
2053 {
2054 const_pointer __new_last = __get_pointer() + __pos;
2055 for (__i_node** __p = __c->end_; __p != __c->beg_; )
2056 {
2057 --__p;
2058 const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
2059 if (__i->base() > __new_last)
2060 {
2061 (*__p)->__c_ = nullptr;
2062 if (--__c->end_ != __p)
2063 std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
2064 }
2065 }
2066 __get_db()->unlock();
2067 }
2068 }
2069#else
2070 (void)__pos;
2071#endif // _LIBCPP_ENABLE_DEBUG_MODE
2072}
2106#if _LIBCPP_STD_VER >= 23
2107template <ranges::input_range _Range,
2108 class _Allocator = allocator<ranges::range_value_t<_Range>>,
2109 class = enable_if_t<__is_allocator<_Allocator>::value>
2110 >
2111basic_string(from_range_t, _Range&&, _Allocator = _Allocator())
2112 -> basic_string<ranges::range_value_t<_Range>, char_traits<ranges::range_value_t<_Range>>, _Allocator>;
2113#endif
20732114
20742115template <class _CharT, class _Traits, class _Allocator>
20752116_LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -2128,44 +2169,6 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
21282169 traits_type::assign(__p[__sz], value_type());
21292170}
21302171
2131template <class _CharT, class _Traits, class _Allocator>
2132template <class>
2133_LIBCPP_CONSTEXPR_SINCE_CXX20
2134basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a)
2135 : __r_(__default_init_tag(), __a)
2136{
2137 _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
2138 __init(__s, traits_type::length(__s));
2139 std::__debug_db_insert_c(this);
2140}
2141
2142template <class _CharT, class _Traits, class _Allocator>
2143_LIBCPP_CONSTEXPR_SINCE_CXX20
2144basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
2145 : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc()))
2146{
2147 if (!__str.__is_long())
2148 __r_.first() = __str.__r_.first();
2149 else
2150 __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()),
2151 __str.__get_long_size());
2152 std::__debug_db_insert_c(this);
2153}
2154
2155template <class _CharT, class _Traits, class _Allocator>
2156_LIBCPP_CONSTEXPR_SINCE_CXX20
2157basic_string<_CharT, _Traits, _Allocator>::basic_string(
2158 const basic_string& __str, const allocator_type& __a)
2159 : __r_(__default_init_tag(), __a)
2160{
2161 if (!__str.__is_long())
2162 __r_.first() = __str.__r_.first();
2163 else
2164 __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()),
2165 __str.__get_long_size());
2166 std::__debug_db_insert_c(this);
2167}
2168
21692172template <class _CharT, class _Traits, class _Allocator>
21702173_LIBCPP_CONSTEXPR_SINCE_CXX20
21712174void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(
......@@ -2220,81 +2223,26 @@ basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
22202223}
22212224
22222225template <class _CharT, class _Traits, class _Allocator>
2223template <class>
2224_LIBCPP_CONSTEXPR_SINCE_CXX20
2225basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a)
2226 : __r_(__default_init_tag(), __a)
2227{
2228 __init(__n, __c);
2229 std::__debug_db_insert_c(this);
2230}
2231
2232template <class _CharT, class _Traits, class _Allocator>
2233_LIBCPP_CONSTEXPR_SINCE_CXX20
2234basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str,
2235 size_type __pos, size_type __n,
2236 const _Allocator& __a)
2237 : __r_(__default_init_tag(), __a)
2238{
2239 size_type __str_sz = __str.size();
2240 if (__pos > __str_sz)
2241 __throw_out_of_range();
2242 __init(__str.data() + __pos, std::min(__n, __str_sz - __pos));
2243 std::__debug_db_insert_c(this);
2244}
2245
2246template <class _CharT, class _Traits, class _Allocator>
2247template <class _Tp, class>
2248_LIBCPP_CONSTEXPR_SINCE_CXX20
2249basic_string<_CharT, _Traits, _Allocator>::basic_string(
2250 const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a)
2251 : __r_(__default_init_tag(), __a)
2252{
2253 __self_view __sv0 = __t;
2254 __self_view __sv = __sv0.substr(__pos, __n);
2255 __init(__sv.data(), __sv.size());
2256 std::__debug_db_insert_c(this);
2257}
2258
2259template <class _CharT, class _Traits, class _Allocator>
2260template <class _Tp, class>
2261_LIBCPP_CONSTEXPR_SINCE_CXX20
2262basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t)
2263 : __r_(__default_init_tag(), __default_init_tag())
2264{
2265 __self_view __sv = __t;
2266 __init(__sv.data(), __sv.size());
2267 std::__debug_db_insert_c(this);
2268}
2269
2270template <class _CharT, class _Traits, class _Allocator>
2271template <class _Tp, class>
2226template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
22722227_LIBCPP_CONSTEXPR_SINCE_CXX20
2273basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a)
2274 : __r_(__default_init_tag(), __a)
2228void basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
22752229{
2276 __self_view __sv = __t;
2277 __init(__sv.data(), __sv.size());
2278 std::__debug_db_insert_c(this);
2230 __init_with_sentinel(std::move(__first), std::move(__last));
22792231}
22802232
22812233template <class _CharT, class _Traits, class _Allocator>
2282template <class _InputIterator>
2283_LIBCPP_CONSTEXPR_SINCE_CXX20
2284__enable_if_t
2285<
2286 __is_exactly_cpp17_input_iterator<_InputIterator>::value
2287>
2288basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
2289{
2234template <class _InputIterator, class _Sentinel>
2235_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
2236void basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator __first, _Sentinel __last) {
22902237 __default_init();
2291#ifndef _LIBCPP_NO_EXCEPTIONS
2238
2239#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
22922240 try
22932241 {
2294#endif // _LIBCPP_NO_EXCEPTIONS
2242#endif // _LIBCPP_HAS_NO_EXCEPTIONS
22952243 for (; __first != __last; ++__first)
22962244 push_back(*__first);
2297#ifndef _LIBCPP_NO_EXCEPTIONS
2245#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
22982246 }
22992247 catch (...)
23002248 {
......@@ -2302,28 +2250,35 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _Input
23022250 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
23032251 throw;
23042252 }
2305#endif // _LIBCPP_NO_EXCEPTIONS
2253#endif // _LIBCPP_HAS_NO_EXCEPTIONS
23062254}
23072255
23082256template <class _CharT, class _Traits, class _Allocator>
2309template <class _ForwardIterator>
2310_LIBCPP_CONSTEXPR_SINCE_CXX20
2311__enable_if_t
2312<
2313 __is_cpp17_forward_iterator<_ForwardIterator>::value
2314>
2257template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
2258_LIBCPP_CONSTEXPR_SINCE_CXX20 void
23152259basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
23162260{
2261 size_type __sz = static_cast<size_type>(std::distance(__first, __last));
2262 __init_with_size(__first, __last, __sz);
2263}
2264
2265template <class _CharT, class _Traits, class _Allocator>
2266template <class _InputIterator, class _Sentinel>
2267_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
2268void basic_string<_CharT, _Traits, _Allocator>::__init_with_size(
2269 _InputIterator __first, _Sentinel __last, size_type __sz) {
23172270 if (__libcpp_is_constant_evaluated())
23182271 __r_.first() = __rep();
2319 size_type __sz = static_cast<size_type>(std::distance(__first, __last));
2272
23202273 if (__sz > max_size())
23212274 __throw_length_error();
2275
23222276 pointer __p;
23232277 if (__fits_in_sso(__sz))
23242278 {
23252279 __set_short_size(__sz);
23262280 __p = __get_short_pointer();
2281
23272282 }
23282283 else
23292284 {
......@@ -2335,14 +2290,14 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For
23352290 __set_long_size(__sz);
23362291 }
23372292
2338#ifndef _LIBCPP_NO_EXCEPTIONS
2293#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
23392294 try
23402295 {
2341#endif // _LIBCPP_NO_EXCEPTIONS
2296#endif // _LIBCPP_HAS_NO_EXCEPTIONS
23422297 for (; __first != __last; ++__first, (void) ++__p)
23432298 traits_type::assign(*__p, *__first);
23442299 traits_type::assign(*__p, value_type());
2345#ifndef _LIBCPP_NO_EXCEPTIONS
2300#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
23462301 }
23472302 catch (...)
23482303 {
......@@ -2350,16 +2305,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For
23502305 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
23512306 throw;
23522307 }
2353#endif // _LIBCPP_NO_EXCEPTIONS
2354}
2355
2356template <class _CharT, class _Traits, class _Allocator>
2357_LIBCPP_CONSTEXPR_SINCE_CXX20
2358basic_string<_CharT, _Traits, _Allocator>::~basic_string()
2359{
2360 std::__debug_db_erase_c(this);
2361 if (__is_long())
2362 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
2308#endif // _LIBCPP_HAS_NO_EXCEPTIONS
23632309}
23642310
23652311template <class _CharT, class _Traits, class _Allocator>
......@@ -2379,7 +2325,6 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
23792325 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
23802326 pointer __p = __allocation.ptr;
23812327 __begin_lifetime(__p, __allocation.count);
2382 std::__debug_db_invalidate_all(this);
23832328 if (__n_copy != 0)
23842329 traits_type::copy(std::__to_address(__p),
23852330 std::__to_address(__old_p), __n_copy);
......@@ -2398,9 +2343,16 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
23982343 traits_type::assign(__p[__old_sz], value_type());
23992344}
24002345
2346// __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it
2347// may also not set the size at all when the string was short initially. This leads to unpredictable size value. It is
2348// not removed or changed to avoid breaking the ABI.
24012349template <class _CharT, class _Traits, class _Allocator>
24022350void
24032351_LIBCPP_CONSTEXPR_SINCE_CXX20
2352#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1
2353 _LIBCPP_HIDE_FROM_ABI
2354#endif
2355 _LIBCPP_DEPRECATED_("use __grow_by_without_replace")
24042356basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
24052357 size_type __n_copy, size_type __n_del, size_type __n_add)
24062358{
......@@ -2414,7 +2366,6 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t
24142366 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
24152367 pointer __p = __allocation.ptr;
24162368 __begin_lifetime(__p, __allocation.count);
2417 std::__debug_db_invalidate_all(this);
24182369 if (__n_copy != 0)
24192370 traits_type::copy(std::__to_address(__p),
24202371 std::__to_address(__old_p), __n_copy);
......@@ -2429,6 +2380,21 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t
24292380 __set_long_cap(__allocation.count);
24302381}
24312382
2383template <class _CharT, class _Traits, class _Allocator>
2384void _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
2385basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace(
2386 size_type __old_cap,
2387 size_type __delta_cap,
2388 size_type __old_sz,
2389 size_type __n_copy,
2390 size_type __n_del,
2391 size_type __n_add) {
2392 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
2393 __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add);
2394 _LIBCPP_SUPPRESS_DEPRECATED_POP
2395 __set_long_size(__old_sz - __n_del + __n_add);
2396}
2397
24322398// assign
24332399
24342400template <class _CharT, class _Traits, class _Allocator>
......@@ -2443,7 +2409,6 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
24432409 __is_short ? __set_short_size(__n) : __set_long_size(__n);
24442410 traits_type::copy(std::__to_address(__p), __s, __n);
24452411 traits_type::assign(__p[__n], value_type());
2446 __invalidate_iterators_past(__n);
24472412 } else {
24482413 size_type __sz = __is_short ? __get_short_size() : __get_long_size();
24492414 __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s);
......@@ -2473,7 +2438,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
24732438basic_string<_CharT, _Traits, _Allocator>&
24742439basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
24752440{
2476 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
2441 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::assign received nullptr");
24772442 return (__builtin_constant_p(__n) && __fits_in_sso(__n))
24782443 ? __assign_short(__s, __n)
24792444 : __assign_external(__s, __n);
......@@ -2488,7 +2453,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
24882453 if (__cap < __n)
24892454 {
24902455 size_type __sz = size();
2491 __grow_by(__cap, __n - __cap, __sz, 0, __sz);
2456 __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
24922457 }
24932458 value_type* __p = std::__to_address(__get_pointer());
24942459 traits_type::assign(__p, __n, __c);
......@@ -2513,7 +2478,6 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
25132478 }
25142479 traits_type::assign(*__p, __c);
25152480 traits_type::assign(*++__p, value_type());
2516 __invalidate_iterators_past(1);
25172481 return *this;
25182482}
25192483
......@@ -2522,7 +2486,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
25222486basic_string<_CharT, _Traits, _Allocator>&
25232487basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
25242488{
2525 if (this != &__str) {
2489 if (this != std::addressof(__str)) {
25262490 __copy_assign_alloc(__str);
25272491 if (!__is_long()) {
25282492 if (!__str.__is_long()) {
......@@ -2555,7 +2519,7 @@ template <class _CharT, class _Traits, class _Allocator>
25552519inline _LIBCPP_CONSTEXPR_SINCE_CXX20
25562520void
25572521basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
2558#if _LIBCPP_STD_VER > 14
2522#if _LIBCPP_STD_VER >= 17
25592523 _NOEXCEPT
25602524#else
25612525 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
......@@ -2584,55 +2548,62 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
25842548#endif
25852549
25862550template <class _CharT, class _Traits, class _Allocator>
2587template<class _InputIterator>
2588_LIBCPP_CONSTEXPR_SINCE_CXX20
2589__enable_if_t
2590<
2591 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
2592 basic_string<_CharT, _Traits, _Allocator>&
2593>
2551template<class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
2552_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
25942553basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
25952554{
2596 const basic_string __temp(__first, __last, __alloc());
2597 assign(__temp.data(), __temp.size());
2598 return *this;
2555 __assign_with_sentinel(__first, __last);
2556 return *this;
25992557}
26002558
26012559template <class _CharT, class _Traits, class _Allocator>
2602template<class _ForwardIterator>
2603_LIBCPP_CONSTEXPR_SINCE_CXX20
2604__enable_if_t
2605<
2606 __is_cpp17_forward_iterator<_ForwardIterator>::value,
2607 basic_string<_CharT, _Traits, _Allocator>&
2608>
2560template <class _InputIterator, class _Sentinel>
2561_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
2562void
2563basic_string<_CharT, _Traits, _Allocator>::__assign_with_sentinel(_InputIterator __first, _Sentinel __last) {
2564 const basic_string __temp(__init_with_sentinel_tag(), std::move(__first), std::move(__last), __alloc());
2565 assign(__temp.data(), __temp.size());
2566}
2567
2568template <class _CharT, class _Traits, class _Allocator>
2569template<class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
2570_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
26092571basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
26102572{
2611 size_type __cap = capacity();
2612 size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ?
2613 static_cast<size_type>(std::distance(__first, __last)) : 0;
2573 if (__string_is_trivial_iterator<_ForwardIterator>::value) {
2574 size_type __n = static_cast<size_type>(std::distance(__first, __last));
2575 __assign_trivial(__first, __last, __n);
2576 } else {
2577 __assign_with_sentinel(__first, __last);
2578 }
26142579
2615 if (__string_is_trivial_iterator<_ForwardIterator>::value &&
2616 (__cap >= __n || !__addr_in_range(*__first)))
2617 {
2618 if (__cap < __n)
2619 {
2620 size_type __sz = size();
2621 __grow_by(__cap, __n - __cap, __sz, 0, __sz);
2622 }
2623 pointer __p = __get_pointer();
2624 for (; __first != __last; ++__p, (void) ++__first)
2625 traits_type::assign(*__p, *__first);
2626 traits_type::assign(*__p, value_type());
2627 __set_size(__n);
2628 __invalidate_iterators_past(__n);
2629 }
2630 else
2631 {
2632 const basic_string __temp(__first, __last, __alloc());
2633 assign(__temp.data(), __temp.size());
2580 return *this;
2581}
2582
2583template <class _CharT, class _Traits, class _Allocator>
2584template <class _Iterator, class _Sentinel>
2585_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
2586void
2587basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n) {
2588 _LIBCPP_ASSERT_INTERNAL(
2589 __string_is_trivial_iterator<_Iterator>::value, "The iterator type given to `__assign_trivial` must be trivial");
2590
2591 size_type __cap = capacity();
2592 if (__cap < __n) {
2593 // Unlike `append` functions, if the input range points into the string itself, there is no case that the input
2594 // range could get invalidated by reallocation:
2595 // 1. If the input range is a subset of the string itself, its size cannot exceed the capacity of the string,
2596 // thus no reallocation would happen.
2597 // 2. In the exotic case where the input range is the byte representation of the string itself, the string
2598 // object itself stays valid even if reallocation happens.
2599 size_type __sz = size();
2600 __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
26342601 }
2635 return *this;
2602 pointer __p = __get_pointer();
2603 for (; __first != __last; ++__p, (void) ++__first)
2604 traits_type::assign(*__p, *__first);
2605 traits_type::assign(*__p, value_type());
2606 __set_size(__n);
26362607}
26372608
26382609template <class _CharT, class _Traits, class _Allocator>
......@@ -2647,16 +2618,12 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, siz
26472618}
26482619
26492620template <class _CharT, class _Traits, class _Allocator>
2650template <class _Tp>
2651_LIBCPP_CONSTEXPR_SINCE_CXX20
2652__enable_if_t
2653<
2654 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
2655 && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2656 basic_string<_CharT, _Traits, _Allocator>&
2657>
2658basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n)
2659{
2621template <class _Tp,
2622 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
2623 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2624 int> >
2625_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
2626basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp& __t, size_type __pos, size_type __n) {
26602627 __self_view __sv = __t;
26612628 size_type __sz = __sv.size();
26622629 if (__pos > __sz)
......@@ -2664,7 +2631,6 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __p
26642631 return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
26652632}
26662633
2667
26682634template <class _CharT, class _Traits, class _Allocator>
26692635_LIBCPP_CONSTEXPR_SINCE_CXX20
26702636basic_string<_CharT, _Traits, _Allocator>&
......@@ -2677,7 +2643,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
26772643basic_string<_CharT, _Traits, _Allocator>&
26782644basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
26792645{
2680 _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
2646 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::assign received nullptr");
26812647 return __builtin_constant_p(*__s)
26822648 ? (__fits_in_sso(traits_type::length(__s))
26832649 ? __assign_short(__s, traits_type::length(__s))
......@@ -2691,7 +2657,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
26912657basic_string<_CharT, _Traits, _Allocator>&
26922658basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
26932659{
2694 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr");
2660 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::append received nullptr");
26952661 size_type __cap = capacity();
26962662 size_type __sz = size();
26972663 if (__cap - __sz >= __n)
......@@ -2720,7 +2686,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
27202686 size_type __cap = capacity();
27212687 size_type __sz = size();
27222688 if (__cap - __sz < __n)
2723 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
2689 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
27242690 pointer __p = __get_pointer();
27252691 traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
27262692 __sz += __n;
......@@ -2739,7 +2705,7 @@ basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
27392705 size_type __cap = capacity();
27402706 size_type __sz = size();
27412707 if (__cap - __sz < __n)
2742 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
2708 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
27432709 pointer __p = __get_pointer();
27442710 __sz += __n;
27452711 __set_size(__sz);
......@@ -2767,7 +2733,7 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
27672733 }
27682734 if (__sz == __cap)
27692735 {
2770 __grow_by(__cap, 1, __sz, __sz, 0);
2736 __grow_by_without_replace(__cap, 1, __sz, __sz, 0);
27712737 __is_short = false; // the string is always long after __grow_by
27722738 }
27732739 pointer __p = __get_pointer();
......@@ -2786,13 +2752,8 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
27862752}
27872753
27882754template <class _CharT, class _Traits, class _Allocator>
2789template<class _ForwardIterator>
2790_LIBCPP_CONSTEXPR_SINCE_CXX20
2791__enable_if_t
2792<
2793 __is_cpp17_forward_iterator<_ForwardIterator>::value,
2794 basic_string<_CharT, _Traits, _Allocator>&
2795>
2755template<class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
2756_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
27962757basic_string<_CharT, _Traits, _Allocator>::append(
27972758 _ForwardIterator __first, _ForwardIterator __last)
27982759{
......@@ -2805,7 +2766,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(
28052766 !__addr_in_range(*__first))
28062767 {
28072768 if (__cap - __sz < __n)
2808 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
2769 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
28092770 pointer __p = __get_pointer() + __sz;
28102771 for (; __first != __last; ++__p, (void) ++__first)
28112772 traits_type::assign(*__p, *__first);
......@@ -2833,15 +2794,12 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, siz
28332794}
28342795
28352796template <class _CharT, class _Traits, class _Allocator>
2836template <class _Tp>
2837_LIBCPP_CONSTEXPR_SINCE_CXX20
2838 __enable_if_t
2839 <
2840 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2841 basic_string<_CharT, _Traits, _Allocator>&
2842 >
2843basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n)
2844{
2797template <class _Tp,
2798 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
2799 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2800 int> >
2801_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
2802basic_string<_CharT, _Traits, _Allocator>::append(const _Tp& __t, size_type __pos, size_type __n) {
28452803 __self_view __sv = __t;
28462804 size_type __sz = __sv.size();
28472805 if (__pos > __sz)
......@@ -2854,7 +2812,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
28542812basic_string<_CharT, _Traits, _Allocator>&
28552813basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
28562814{
2857 _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr");
2815 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::append received nullptr");
28582816 return append(__s, traits_type::length(__s));
28592817}
28602818
......@@ -2865,7 +2823,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
28652823basic_string<_CharT, _Traits, _Allocator>&
28662824basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
28672825{
2868 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr");
2826 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::insert received nullptr");
28692827 size_type __sz = size();
28702828 if (__pos > __sz)
28712829 __throw_out_of_range();
......@@ -2921,7 +2879,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
29212879 }
29222880 else
29232881 {
2924 __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
2882 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
29252883 __p = std::__to_address(__get_long_pointer());
29262884 }
29272885 traits_type::assign(__p + __pos, __n, __c);
......@@ -2933,47 +2891,40 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
29332891}
29342892
29352893template <class _CharT, class _Traits, class _Allocator>
2936template<class _InputIterator>
2937_LIBCPP_CONSTEXPR_SINCE_CXX20
2938__enable_if_t
2939<
2940 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
2941 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2942>
2894template<class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
2895_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator
29432896basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
29442897{
2945 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
2946 "string::insert(iterator, range) called with an iterator not"
2947 " referring to this string");
29482898 const basic_string __temp(__first, __last, __alloc());
29492899 return insert(__pos, __temp.data(), __temp.data() + __temp.size());
29502900}
29512901
29522902template <class _CharT, class _Traits, class _Allocator>
2953template<class _ForwardIterator>
2954_LIBCPP_CONSTEXPR_SINCE_CXX20
2955__enable_if_t
2956<
2957 __is_cpp17_forward_iterator<_ForwardIterator>::value,
2958 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2959>
2903template<class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
2904_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator
29602905basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
29612906{
2962 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
2963 "string::insert(iterator, range) called with an iterator not referring to this string");
2907 auto __n = static_cast<size_type>(std::distance(__first, __last));
2908 return __insert_with_size(__pos, __first, __last, __n);
2909}
29642910
2911template <class _CharT, class _Traits, class _Allocator>
2912template<class _Iterator, class _Sentinel>
2913_LIBCPP_CONSTEXPR_SINCE_CXX20
2914typename basic_string<_CharT, _Traits, _Allocator>::iterator
2915basic_string<_CharT, _Traits, _Allocator>::__insert_with_size(
2916 const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n) {
29652917 size_type __ip = static_cast<size_type>(__pos - begin());
2966 size_type __n = static_cast<size_type>(std::distance(__first, __last));
29672918 if (__n == 0)
29682919 return begin() + __ip;
29692920
2970 if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first))
2921 if (__string_is_trivial_iterator<_Iterator>::value && !__addr_in_range(*__first))
29712922 {
29722923 return __insert_from_safe_copy(__n, __ip, __first, __last);
29732924 }
29742925 else
29752926 {
2976 const basic_string __temp(__first, __last, __alloc());
2927 const basic_string __temp(__init_with_sentinel_tag(), __first, __last, __alloc());
29772928 return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end());
29782929 }
29792930}
......@@ -2991,16 +2942,12 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_
29912942}
29922943
29932944template <class _CharT, class _Traits, class _Allocator>
2994template <class _Tp>
2995_LIBCPP_CONSTEXPR_SINCE_CXX20
2996__enable_if_t
2997<
2998 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2999 basic_string<_CharT, _Traits, _Allocator>&
3000>
3001basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t,
3002 size_type __pos2, size_type __n)
3003{
2945template <class _Tp,
2946 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
2947 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2948 int> >
2949_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
2950basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n) {
30042951 __self_view __sv = __t;
30052952 size_type __str_sz = __sv.size();
30062953 if (__pos2 > __str_sz)
......@@ -3013,7 +2960,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
30132960basic_string<_CharT, _Traits, _Allocator>&
30142961basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
30152962{
3016 _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr");
2963 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::insert received nullptr");
30172964 return insert(__pos, __s, traits_type::length(__s));
30182965}
30192966
......@@ -3022,17 +2969,13 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
30222969typename basic_string<_CharT, _Traits, _Allocator>::iterator
30232970basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
30242971{
3025 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
3026 "string::insert(iterator, character) called with an iterator not"
3027 " referring to this string");
3028
30292972 size_type __ip = static_cast<size_type>(__pos - begin());
30302973 size_type __sz = size();
30312974 size_type __cap = capacity();
30322975 value_type* __p;
30332976 if (__cap == __sz)
30342977 {
3035 __grow_by(__cap, 1, __sz, __ip, 0, 1);
2978 __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1);
30362979 __p = std::__to_address(__get_long_pointer());
30372980 }
30382981 else
......@@ -3056,7 +2999,7 @@ basic_string<_CharT, _Traits, _Allocator>&
30562999basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
30573000 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
30583001{
3059 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
3002 _LIBCPP_ASSERT_UNCATEGORIZED(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
30603003 size_type __sz = size();
30613004 if (__pos > __sz)
30623005 __throw_out_of_range();
......@@ -3064,10 +3007,6 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
30643007 size_type __cap = capacity();
30653008 if (__cap - __sz + __n1 >= __n2)
30663009 {
3067 if (__libcpp_is_constant_evaluated()) {
3068 __grow_by_and_replace(__cap, 0, __sz, __pos, __n1, __n2, __s);
3069 return *this;
3070 }
30713010 value_type* __p = std::__to_address(__get_pointer());
30723011 if (__n1 != __n2)
30733012 {
......@@ -3080,7 +3019,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
30803019 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
30813020 return __null_terminate_at(__p, __sz + (__n2 - __n1));
30823021 }
3083 if (__p + __pos < __s && __s < __p + __sz)
3022 if (std::__is_pointer_in_range(__p + __pos + 1, __p + __sz, __s))
30843023 {
30853024 if (__p + __pos + __n1 <= __s)
30863025 __s += __n2 - __n1;
......@@ -3127,7 +3066,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
31273066 }
31283067 else
31293068 {
3130 __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
3069 __grow_by_without_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
31313070 __p = std::__to_address(__get_long_pointer());
31323071 }
31333072 traits_type::assign(__p + __pos, __n2, __c);
......@@ -3135,13 +3074,8 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
31353074}
31363075
31373076template <class _CharT, class _Traits, class _Allocator>
3138template<class _InputIterator>
3139_LIBCPP_CONSTEXPR_SINCE_CXX20
3140__enable_if_t
3141<
3142 __is_cpp17_input_iterator<_InputIterator>::value,
3143 basic_string<_CharT, _Traits, _Allocator>&
3144>
3077template<class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
3078_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
31453079basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
31463080 _InputIterator __j1, _InputIterator __j2)
31473081{
......@@ -3162,16 +3096,13 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _
31623096}
31633097
31643098template <class _CharT, class _Traits, class _Allocator>
3165template <class _Tp>
3166_LIBCPP_CONSTEXPR_SINCE_CXX20
3167__enable_if_t
3168<
3169 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
3170 basic_string<_CharT, _Traits, _Allocator>&
3171>
3172basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t,
3173 size_type __pos2, size_type __n2)
3174{
3099template <class _Tp,
3100 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
3101 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
3102 int> >
3103_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
3104basic_string<_CharT, _Traits, _Allocator>::replace(
3105 size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) {
31753106 __self_view __sv = __t;
31763107 size_type __str_sz = __sv.size();
31773108 if (__pos2 > __str_sz)
......@@ -3184,7 +3115,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
31843115basic_string<_CharT, _Traits, _Allocator>&
31853116basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
31863117{
3187 _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr");
3118 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::replace received nullptr");
31883119 return replace(__pos, __n1, __s, traits_type::length(__s));
31893120}
31903121
......@@ -3230,11 +3161,8 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20
32303161typename basic_string<_CharT, _Traits, _Allocator>::iterator
32313162basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
32323163{
3233 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
3234 "string::erase(iterator) called with an iterator not"
3235 " referring to this string");
3236
3237 _LIBCPP_ASSERT(__pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator");
3164 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
3165 __pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator");
32383166 iterator __b = begin();
32393167 size_type __r = static_cast<size_type>(__pos - __b);
32403168 erase(__r, 1);
......@@ -3246,11 +3174,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20
32463174typename basic_string<_CharT, _Traits, _Allocator>::iterator
32473175basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
32483176{
3249 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
3250 "string::erase(iterator, iterator) called with an iterator not"
3251 " referring to this string");
3252
3253 _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range");
3177 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "string::erase(first, last) called with invalid range");
32543178 iterator __b = begin();
32553179 size_type __r = static_cast<size_type>(__first - __b);
32563180 erase(__r, static_cast<size_type>(__last - __first));
......@@ -3262,7 +3186,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20
32623186void
32633187basic_string<_CharT, _Traits, _Allocator>::pop_back()
32643188{
3265 _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty");
3189 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::pop_back(): string is already empty");
32663190 __erase_to_end(size() - 1);
32673191}
32683192
......@@ -3271,7 +3195,6 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20
32713195void
32723196basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
32733197{
3274 std::__debug_db_invalidate_all(this);
32753198 if (__is_long())
32763199 {
32773200 traits_type::assign(*__get_long_pointer(), value_type());
......@@ -3365,23 +3288,23 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target
33653288 }
33663289 else
33673290 {
3368 #ifndef _LIBCPP_NO_EXCEPTIONS
3291 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
33693292 try
33703293 {
3371 #endif // _LIBCPP_NO_EXCEPTIONS
3294 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
33723295 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
33733296 __new_data = __allocation.ptr;
33743297 __target_capacity = __allocation.count - 1;
3375 #ifndef _LIBCPP_NO_EXCEPTIONS
3298 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
33763299 }
33773300 catch (...)
33783301 {
33793302 return;
33803303 }
3381 #else // _LIBCPP_NO_EXCEPTIONS
3304 #else // _LIBCPP_HAS_NO_EXCEPTIONS
33823305 if (__new_data == nullptr)
33833306 return;
3384 #endif // _LIBCPP_NO_EXCEPTIONS
3307 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
33853308 }
33863309 __begin_lifetime(__new_data, __target_capacity + 1);
33873310 __now_long = true;
......@@ -3400,7 +3323,6 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target
34003323 }
34013324 else
34023325 __set_short_size(__sz);
3403 std::__debug_db_invalidate_all(this);
34043326}
34053327
34063328template <class _CharT, class _Traits, class _Allocator>
......@@ -3447,13 +3369,7 @@ basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
34473369 __is_nothrow_swappable<allocator_type>::value)
34483370#endif
34493371{
3450 if (!__is_long())
3451 std::__debug_db_invalidate_all(this);
3452 if (!__str.__is_long())
3453 std::__debug_db_invalidate_all(&__str);
3454 std::__debug_db_swap(this, &__str);
3455
3456 _LIBCPP_ASSERT(
3372 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
34573373 __alloc_traits::propagate_on_container_swap::value ||
34583374 __alloc_traits::is_always_equal::value ||
34593375 __alloc() == __str.__alloc(), "swapping non-equal allocators");
......@@ -3479,7 +3395,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
34793395 size_type __pos,
34803396 size_type __n) const _NOEXCEPT
34813397{
3482 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr");
3398 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find(): received nullptr");
34833399 return std::__str_find<value_type, size_type, traits_type, npos>
34843400 (data(), size(), __s, __pos, __n);
34853401}
......@@ -3495,13 +3411,8 @@ basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
34953411}
34963412
34973413template<class _CharT, class _Traits, class _Allocator>
3498template <class _Tp>
3499_LIBCPP_CONSTEXPR_SINCE_CXX20
3500__enable_if_t
3501<
3502 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3503 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3504>
3414template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3415_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
35053416basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,
35063417 size_type __pos) const _NOEXCEPT
35073418{
......@@ -3516,7 +3427,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
35163427basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
35173428 size_type __pos) const _NOEXCEPT
35183429{
3519 _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr");
3430 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find(): received nullptr");
35203431 return std::__str_find<value_type, size_type, traits_type, npos>
35213432 (data(), size(), __s, __pos, traits_type::length(__s));
35223433}
......@@ -3540,7 +3451,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
35403451 size_type __pos,
35413452 size_type __n) const _NOEXCEPT
35423453{
3543 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
3454 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
35443455 return std::__str_rfind<value_type, size_type, traits_type, npos>
35453456 (data(), size(), __s, __pos, __n);
35463457}
......@@ -3556,13 +3467,8 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
35563467}
35573468
35583469template<class _CharT, class _Traits, class _Allocator>
3559template <class _Tp>
3560_LIBCPP_CONSTEXPR_SINCE_CXX20
3561__enable_if_t
3562<
3563 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3564 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3565>
3470template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3471_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
35663472basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,
35673473 size_type __pos) const _NOEXCEPT
35683474{
......@@ -3577,7 +3483,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
35773483basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
35783484 size_type __pos) const _NOEXCEPT
35793485{
3580 _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr");
3486 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::rfind(): received nullptr");
35813487 return std::__str_rfind<value_type, size_type, traits_type, npos>
35823488 (data(), size(), __s, __pos, traits_type::length(__s));
35833489}
......@@ -3601,7 +3507,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
36013507 size_type __pos,
36023508 size_type __n) const _NOEXCEPT
36033509{
3604 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
3510 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
36053511 return std::__str_find_first_of<value_type, size_type, traits_type, npos>
36063512 (data(), size(), __s, __pos, __n);
36073513}
......@@ -3617,13 +3523,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __s
36173523}
36183524
36193525template<class _CharT, class _Traits, class _Allocator>
3620template <class _Tp>
3621_LIBCPP_CONSTEXPR_SINCE_CXX20
3622__enable_if_t
3623<
3624 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3625 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3626>
3526template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3527_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
36273528basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,
36283529 size_type __pos) const _NOEXCEPT
36293530{
......@@ -3638,7 +3539,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
36383539basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
36393540 size_type __pos) const _NOEXCEPT
36403541{
3641 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr");
3542 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_first_of(): received nullptr");
36423543 return std::__str_find_first_of<value_type, size_type, traits_type, npos>
36433544 (data(), size(), __s, __pos, traits_type::length(__s));
36443545}
......@@ -3661,7 +3562,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
36613562 size_type __pos,
36623563 size_type __n) const _NOEXCEPT
36633564{
3664 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
3565 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
36653566 return std::__str_find_last_of<value_type, size_type, traits_type, npos>
36663567 (data(), size(), __s, __pos, __n);
36673568}
......@@ -3677,13 +3578,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __st
36773578}
36783579
36793580template<class _CharT, class _Traits, class _Allocator>
3680template <class _Tp>
3681_LIBCPP_CONSTEXPR_SINCE_CXX20
3682__enable_if_t
3683<
3684 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3685 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3686>
3581template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3582_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
36873583basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,
36883584 size_type __pos) const _NOEXCEPT
36893585{
......@@ -3698,7 +3594,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
36983594basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
36993595 size_type __pos) const _NOEXCEPT
37003596{
3701 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr");
3597 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_last_of(): received nullptr");
37023598 return std::__str_find_last_of<value_type, size_type, traits_type, npos>
37033599 (data(), size(), __s, __pos, traits_type::length(__s));
37043600}
......@@ -3721,7 +3617,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _
37213617 size_type __pos,
37223618 size_type __n) const _NOEXCEPT
37233619{
3724 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
3620 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
37253621 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
37263622 (data(), size(), __s, __pos, __n);
37273623}
......@@ -3737,13 +3633,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string&
37373633}
37383634
37393635template<class _CharT, class _Traits, class _Allocator>
3740template <class _Tp>
3741_LIBCPP_CONSTEXPR_SINCE_CXX20
3742__enable_if_t
3743<
3744 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3745 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3746>
3636template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3637_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
37473638basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,
37483639 size_type __pos) const _NOEXCEPT
37493640{
......@@ -3758,7 +3649,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
37583649basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
37593650 size_type __pos) const _NOEXCEPT
37603651{
3761 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr");
3652 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_first_not_of(): received nullptr");
37623653 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
37633654 (data(), size(), __s, __pos, traits_type::length(__s));
37643655}
......@@ -3782,7 +3673,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __
37823673 size_type __pos,
37833674 size_type __n) const _NOEXCEPT
37843675{
3785 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
3676 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
37863677 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
37873678 (data(), size(), __s, __pos, __n);
37883679}
......@@ -3798,13 +3689,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string&
37983689}
37993690
38003691template<class _CharT, class _Traits, class _Allocator>
3801template <class _Tp>
3802_LIBCPP_CONSTEXPR_SINCE_CXX20
3803__enable_if_t
3804<
3805 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3806 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3807>
3692template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3693_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
38083694basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,
38093695 size_type __pos) const _NOEXCEPT
38103696{
......@@ -3819,7 +3705,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
38193705basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
38203706 size_type __pos) const _NOEXCEPT
38213707{
3822 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr");
3708 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_last_not_of(): received nullptr");
38233709 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
38243710 (data(), size(), __s, __pos, traits_type::length(__s));
38253711}
......@@ -3837,13 +3723,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
38373723// compare
38383724
38393725template <class _CharT, class _Traits, class _Allocator>
3840template <class _Tp>
3841_LIBCPP_CONSTEXPR_SINCE_CXX20
3842__enable_if_t
3843<
3844 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3845 int
3846>
3726template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3727_LIBCPP_CONSTEXPR_SINCE_CXX20 int
38473728basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT
38483729{
38493730 __self_view __sv = __t;
......@@ -3876,7 +3757,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
38763757 const value_type* __s,
38773758 size_type __n2) const
38783759{
3879 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
3760 _LIBCPP_ASSERT_UNCATEGORIZED(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
38803761 size_type __sz = size();
38813762 if (__pos1 > __sz || __n2 == npos)
38823763 __throw_out_of_range();
......@@ -3893,13 +3774,8 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
38933774}
38943775
38953776template <class _CharT, class _Traits, class _Allocator>
3896template <class _Tp>
3897_LIBCPP_CONSTEXPR_SINCE_CXX20
3898__enable_if_t
3899<
3900 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3901 int
3902>
3777template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3778_LIBCPP_CONSTEXPR_SINCE_CXX20 int
39033779basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
39043780 size_type __n1,
39053781 const _Tp& __t) const
......@@ -3919,20 +3795,12 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
39193795}
39203796
39213797template <class _CharT, class _Traits, class _Allocator>
3922template <class _Tp>
3923_LIBCPP_CONSTEXPR_SINCE_CXX20
3924__enable_if_t
3925<
3926 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
3927 && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
3928 int
3929>
3930basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3931 size_type __n1,
3932 const _Tp& __t,
3933 size_type __pos2,
3934 size_type __n2) const
3935{
3798template <class _Tp,
3799 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
3800 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
3801 int> >
3802_LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare(
3803 size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) const {
39363804 __self_view __sv = __t;
39373805 return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
39383806}
......@@ -3954,7 +3822,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
39543822int
39553823basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
39563824{
3957 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
3825 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::compare(): received nullptr");
39583826 return compare(0, npos, __s, traits_type::length(__s));
39593827}
39603828
......@@ -3965,7 +3833,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
39653833 size_type __n1,
39663834 const value_type* __s) const
39673835{
3968 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
3836 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::compare(): received nullptr");
39693837 return compare(__pos1, __n1, __s, traits_type::length(__s));
39703838}
39713839
......@@ -3982,7 +3850,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invariants() const
39823850 return false;
39833851 if (data() == nullptr)
39843852 return false;
3985 if (data()[size()] != value_type())
3853 if (!_Traits::eq(data()[size()], value_type()))
39863854 return false;
39873855 return true;
39883856}
......@@ -4010,7 +3878,7 @@ bool
40103878operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
40113879 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
40123880{
4013#if _LIBCPP_STD_VER > 17
3881#if _LIBCPP_STD_VER >= 20
40143882 return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs);
40153883#else
40163884 size_t __lhs_sz = __lhs.size();
......@@ -4047,7 +3915,7 @@ operator==(const _CharT* __lhs,
40473915 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
40483916{
40493917 typedef basic_string<_CharT, _Traits, _Allocator> _String;
4050 _LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");
3918 _LIBCPP_ASSERT_UNCATEGORIZED(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");
40513919 size_t __lhs_len = _Traits::length(__lhs);
40523920 if (__lhs_len != __rhs.size()) return false;
40533921 return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0;
......@@ -4060,18 +3928,18 @@ bool
40603928operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
40613929 const _CharT* __rhs) _NOEXCEPT
40623930{
4063#if _LIBCPP_STD_VER > 17
3931#if _LIBCPP_STD_VER >= 20
40643932 return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs);
40653933#else
40663934 typedef basic_string<_CharT, _Traits, _Allocator> _String;
4067 _LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
3935 _LIBCPP_ASSERT_UNCATEGORIZED(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
40683936 size_t __rhs_len = _Traits::length(__rhs);
40693937 if (__rhs_len != __lhs.size()) return false;
40703938 return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0;
40713939#endif
40723940}
40733941
4074#if _LIBCPP_STD_VER > 17
3942#if _LIBCPP_STD_VER >= 20
40753943
40763944template <class _CharT, class _Traits, class _Allocator>
40773945_LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(
......@@ -4086,7 +3954,7 @@ operator<=>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT
40863954 return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs);
40873955}
40883956
4089#else // _LIBCPP_STD_VER > 17
3957#else // _LIBCPP_STD_VER >= 20
40903958
40913959template<class _CharT, class _Traits, class _Allocator>
40923960inline _LIBCPP_HIDE_FROM_ABI
......@@ -4230,7 +4098,7 @@ operator>=(const _CharT* __lhs,
42304098{
42314099 return !(__lhs < __rhs);
42324100}
4233#endif // _LIBCPP_STD_VER > 17
4101#endif // _LIBCPP_STD_VER >= 20
42344102
42354103// operator +
42364104
......@@ -4397,46 +4265,46 @@ swap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
43974265 __lhs.swap(__rhs);
43984266}
43994267
4400_LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = nullptr, int __base = 10);
4401_LIBCPP_FUNC_VIS long stol (const string& __str, size_t* __idx = nullptr, int __base = 10);
4402_LIBCPP_FUNC_VIS unsigned long stoul (const string& __str, size_t* __idx = nullptr, int __base = 10);
4403_LIBCPP_FUNC_VIS long long stoll (const string& __str, size_t* __idx = nullptr, int __base = 10);
4404_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
4268_LIBCPP_EXPORTED_FROM_ABI int stoi (const string& __str, size_t* __idx = nullptr, int __base = 10);
4269_LIBCPP_EXPORTED_FROM_ABI long stol (const string& __str, size_t* __idx = nullptr, int __base = 10);
4270_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul (const string& __str, size_t* __idx = nullptr, int __base = 10);
4271_LIBCPP_EXPORTED_FROM_ABI long long stoll (const string& __str, size_t* __idx = nullptr, int __base = 10);
4272_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
44054273
4406_LIBCPP_FUNC_VIS float stof (const string& __str, size_t* __idx = nullptr);
4407_LIBCPP_FUNC_VIS double stod (const string& __str, size_t* __idx = nullptr);
4408_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = nullptr);
4274_LIBCPP_EXPORTED_FROM_ABI float stof (const string& __str, size_t* __idx = nullptr);
4275_LIBCPP_EXPORTED_FROM_ABI double stod (const string& __str, size_t* __idx = nullptr);
4276_LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr);
44094277
4410_LIBCPP_FUNC_VIS string to_string(int __val);
4411_LIBCPP_FUNC_VIS string to_string(unsigned __val);
4412_LIBCPP_FUNC_VIS string to_string(long __val);
4413_LIBCPP_FUNC_VIS string to_string(unsigned long __val);
4414_LIBCPP_FUNC_VIS string to_string(long long __val);
4415_LIBCPP_FUNC_VIS string to_string(unsigned long long __val);
4416_LIBCPP_FUNC_VIS string to_string(float __val);
4417_LIBCPP_FUNC_VIS string to_string(double __val);
4418_LIBCPP_FUNC_VIS string to_string(long double __val);
4278_LIBCPP_EXPORTED_FROM_ABI string to_string(int __val);
4279_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val);
4280_LIBCPP_EXPORTED_FROM_ABI string to_string(long __val);
4281_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val);
4282_LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val);
4283_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val);
4284_LIBCPP_EXPORTED_FROM_ABI string to_string(float __val);
4285_LIBCPP_EXPORTED_FROM_ABI string to_string(double __val);
4286_LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val);
44194287
44204288#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4421_LIBCPP_FUNC_VIS int stoi (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4422_LIBCPP_FUNC_VIS long stol (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4423_LIBCPP_FUNC_VIS unsigned long stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4424_LIBCPP_FUNC_VIS long long stoll (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4425_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4426
4427_LIBCPP_FUNC_VIS float stof (const wstring& __str, size_t* __idx = nullptr);
4428_LIBCPP_FUNC_VIS double stod (const wstring& __str, size_t* __idx = nullptr);
4429_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = nullptr);
4430
4431_LIBCPP_FUNC_VIS wstring to_wstring(int __val);
4432_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val);
4433_LIBCPP_FUNC_VIS wstring to_wstring(long __val);
4434_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val);
4435_LIBCPP_FUNC_VIS wstring to_wstring(long long __val);
4436_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val);
4437_LIBCPP_FUNC_VIS wstring to_wstring(float __val);
4438_LIBCPP_FUNC_VIS wstring to_wstring(double __val);
4439_LIBCPP_FUNC_VIS wstring to_wstring(long double __val);
4289_LIBCPP_EXPORTED_FROM_ABI int stoi (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4290_LIBCPP_EXPORTED_FROM_ABI long stol (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4291_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4292_LIBCPP_EXPORTED_FROM_ABI long long stoll (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4293_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4294
4295_LIBCPP_EXPORTED_FROM_ABI float stof (const wstring& __str, size_t* __idx = nullptr);
4296_LIBCPP_EXPORTED_FROM_ABI double stod (const wstring& __str, size_t* __idx = nullptr);
4297_LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
4298
4299_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
4300_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
4301_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
4302_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
4303_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
4304_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
4305_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
4306_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
4307_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
44404308#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
44414309
44424310template<class _CharT, class _Traits, class _Allocator>
......@@ -4445,11 +4313,11 @@ const typename basic_string<_CharT, _Traits, _Allocator>::size_type
44454313 basic_string<_CharT, _Traits, _Allocator>::npos;
44464314
44474315template <class _CharT, class _Allocator>
4448struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t>
4449{
4450 size_t
4451 operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT
4452 { return std::__do_string_hash(__val.data(), __val.data() + __val.size()); }
4316struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> {
4317 _LIBCPP_HIDE_FROM_ABI size_t
4318 operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT {
4319 return std::__do_string_hash(__val.data(), __val.data() + __val.size());
4320 }
44534321};
44544322
44554323template <class _Allocator>
......@@ -4504,7 +4372,7 @@ basic_istream<_CharT, _Traits>&
45044372getline(basic_istream<_CharT, _Traits>&& __is,
45054373 basic_string<_CharT, _Traits, _Allocator>& __str);
45064374
4507#if _LIBCPP_STD_VER > 17
4375#if _LIBCPP_STD_VER >= 20
45084376template <class _CharT, class _Traits, class _Allocator, class _Up>
45094377inline _LIBCPP_HIDE_FROM_ABI
45104378 typename basic_string<_CharT, _Traits, _Allocator>::size_type
......@@ -4526,57 +4394,21 @@ inline _LIBCPP_HIDE_FROM_ABI
45264394}
45274395#endif
45284396
4529#ifdef _LIBCPP_ENABLE_DEBUG_MODE
4530
4531template<class _CharT, class _Traits, class _Allocator>
4532bool
4533basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const
4534{
4535 return data() <= std::__to_address(__i->base()) &&
4536 std::__to_address(__i->base()) < data() + size();
4537}
4538
4539template<class _CharT, class _Traits, class _Allocator>
4540bool
4541basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const
4542{
4543 return data() < std::__to_address(__i->base()) &&
4544 std::__to_address(__i->base()) <= data() + size();
4545}
4546
4547template<class _CharT, class _Traits, class _Allocator>
4548bool
4549basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
4550{
4551 const value_type* __p = std::__to_address(__i->base()) + __n;
4552 return data() <= __p && __p <= data() + size();
4553}
4554
4555template<class _CharT, class _Traits, class _Allocator>
4556bool
4557basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
4558{
4559 const value_type* __p = std::__to_address(__i->base()) + __n;
4560 return data() <= __p && __p < data() + size();
4561}
4562
4563#endif // _LIBCPP_ENABLE_DEBUG_MODE
4564
4565#if _LIBCPP_STD_VER > 11
4397#if _LIBCPP_STD_VER >= 14
45664398// Literal suffixes for basic_string [basic.string.literals]
45674399inline namespace literals
45684400{
45694401 inline namespace string_literals
45704402 {
45714403 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4572 basic_string<char> operator "" s( const char *__str, size_t __len )
4404 basic_string<char> operator""s( const char *__str, size_t __len )
45734405 {
45744406 return basic_string<char> (__str, __len);
45754407 }
45764408
45774409#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
45784410 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4579 basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
4411 basic_string<wchar_t> operator""s( const wchar_t *__str, size_t __len )
45804412 {
45814413 return basic_string<wchar_t> (__str, __len);
45824414 }
......@@ -4584,27 +4416,27 @@ inline namespace literals
45844416
45854417#ifndef _LIBCPP_HAS_NO_CHAR8_T
45864418 inline _LIBCPP_HIDE_FROM_ABI constexpr
4587 basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len)
4419 basic_string<char8_t> operator""s(const char8_t *__str, size_t __len)
45884420 {
45894421 return basic_string<char8_t> (__str, __len);
45904422 }
45914423#endif
45924424
45934425 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4594 basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
4426 basic_string<char16_t> operator""s( const char16_t *__str, size_t __len )
45954427 {
45964428 return basic_string<char16_t> (__str, __len);
45974429 }
45984430
45994431 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4600 basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
4432 basic_string<char32_t> operator""s( const char32_t *__str, size_t __len )
46014433 {
46024434 return basic_string<char32_t> (__str, __len);
46034435 }
46044436 } // namespace string_literals
46054437} // namespace literals
46064438
4607#if _LIBCPP_STD_VER > 17
4439#if _LIBCPP_STD_VER >= 20
46084440template <>
46094441inline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true;
46104442#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
......@@ -4622,12 +4454,12 @@ _LIBCPP_POP_MACROS
46224454#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
46234455# include <algorithm>
46244456# include <concepts>
4625# include <functional>
4457# include <cstdlib>
46264458# include <iterator>
46274459# include <new>
4460# include <type_traits>
46284461# include <typeinfo>
46294462# include <utility>
4630# include <vector>
46314463#endif
46324464
46334465#endif // _LIBCPP_STRING
lib/libcxx/include/string.h+1-2
......@@ -64,8 +64,7 @@ size_t strlen(const char* s);
6464// MSVCRT, GNU libc and its derivates may already have the correct prototype in
6565// <string.h>. This macro can be defined by users if their C library provides
6666// the right signature.
67#if defined(__CORRECT_ISO_CPP_STRING_H_PROTO) || defined(_LIBCPP_MSVCRT) || \
68 defined(__sun__) || defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_)
67#if defined(__CORRECT_ISO_CPP_STRING_H_PROTO) || defined(_LIBCPP_MSVCRT) || defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_)
6968#define _LIBCPP_STRING_H_HAS_CONST_OVERLOADS
7069#endif
7170
lib/libcxx/include/string_view+102-67
......@@ -90,7 +90,7 @@ namespace std {
9090 basic_string_view& operator=(const basic_string_view&) noexcept = default;
9191 template<class Allocator>
9292 constexpr basic_string_view(const charT* str);
93 basic_string_view(nullptr_t) = delete; // C++2b
93 basic_string_view(nullptr_t) = delete; // C++23
9494 constexpr basic_string_view(const charT* str, size_type len);
9595 template <class It, class End>
9696 constexpr basic_string_view(It begin, End end); // C++20
......@@ -168,9 +168,9 @@ namespace std {
168168 constexpr bool ends_with(charT c) const noexcept; // C++20
169169 constexpr bool ends_with(const charT* s) const; // C++20
170170
171 constexpr bool contains(basic_string_view s) const noexcept; // C++2b
172 constexpr bool contains(charT c) const noexcept; // C++2b
173 constexpr bool contains(const charT* s) const; // C++2b
171 constexpr bool contains(basic_string_view s) const noexcept; // C++23
172 constexpr bool contains(charT c) const noexcept; // C++23
173 constexpr bool contains(const charT* s) const; // C++23
174174
175175 private:
176176 const_pointer data_; // exposition only
......@@ -191,11 +191,11 @@ namespace std {
191191 template <> struct hash<u32string_view>;
192192 template <> struct hash<wstring_view>;
193193
194 constexpr basic_string_view<char> operator "" sv(const char *str, size_t len) noexcept;
195 constexpr basic_string_view<wchar_t> operator "" sv(const wchar_t *str, size_t len) noexcept;
196 constexpr basic_string_view<char8_t> operator "" sv(const char8_t *str, size_t len) noexcept; // C++20
197 constexpr basic_string_view<char16_t> operator "" sv(const char16_t *str, size_t len) noexcept;
198 constexpr basic_string_view<char32_t> operator "" sv(const char32_t *str, size_t len) noexcept;
194 constexpr basic_string_view<char> operator""sv(const char *str, size_t len) noexcept;
195 constexpr basic_string_view<wchar_t> operator""sv(const wchar_t *str, size_t len) noexcept;
196 constexpr basic_string_view<char8_t> operator""sv(const char8_t *str, size_t len) noexcept; // C++20
197 constexpr basic_string_view<char16_t> operator""sv(const char16_t *str, size_t len) noexcept;
198 constexpr basic_string_view<char32_t> operator""sv(const char32_t *str, size_t len) noexcept;
199199
200200} // namespace std
201201
......@@ -208,8 +208,9 @@ namespace std {
208208#include <__functional/hash.h>
209209#include <__functional/unary_function.h>
210210#include <__fwd/string_view.h>
211#include <__iterator/bounded_iter.h>
211212#include <__iterator/concepts.h>
212#include <__iterator/readable_traits.h>
213#include <__iterator/iterator_traits.h>
213214#include <__iterator/reverse_iterator.h>
214215#include <__memory/pointer_traits.h>
215216#include <__ranges/concepts.h>
......@@ -218,10 +219,18 @@ namespace std {
218219#include <__ranges/enable_view.h>
219220#include <__ranges/size.h>
220221#include <__string/char_traits.h>
222#include <__type_traits/is_array.h>
223#include <__type_traits/is_convertible.h>
224#include <__type_traits/is_same.h>
225#include <__type_traits/is_standard_layout.h>
226#include <__type_traits/is_trivial.h>
227#include <__type_traits/remove_cvref.h>
228#include <__type_traits/remove_reference.h>
229#include <__type_traits/type_identity.h>
230#include <cstddef>
221231#include <iosfwd>
222232#include <limits>
223233#include <stdexcept>
224#include <type_traits>
225234#include <version>
226235
227236// standard-mandated includes
......@@ -252,7 +261,9 @@ template <class _Traits>
252261_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
253262inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {
254263 // This needs to be a single statement for C++11 constexpr
255 return _LIBCPP_ASSERT(__s != nullptr, "null pointer passed to non-null argument of char_traits<...>::length"), _Traits::length(__s);
264 return _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr,
265 "null pointer passed to non-null argument of char_traits<...>::length"),
266 _Traits::length(__s);
256267}
257268
258269template<class _CharT, class _Traits>
......@@ -265,7 +276,11 @@ public:
265276 using const_pointer = const _CharT*;
266277 using reference = _CharT&;
267278 using const_reference = const _CharT&;
279#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
280 using const_iterator = __bounded_iter<const_pointer>;
281#else
268282 using const_iterator = const_pointer; // See [string.view.iterators]
283#endif
269284 using iterator = const_iterator;
270285 using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>;
271286 using reverse_iterator = const_reverse_iterator;
......@@ -293,22 +308,27 @@ public:
293308 basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
294309 : __data_(__s), __size_(__len)
295310 {
296#if _LIBCPP_STD_VER > 11
297 _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr");
311#if _LIBCPP_STD_VER >= 14
312 _LIBCPP_ASSERT_UNCATEGORIZED(
313 __len <= static_cast<size_type>(numeric_limits<difference_type>::max()),
314 "string_view::string_view(_CharT *, size_t): length does not fit in difference_type");
315 _LIBCPP_ASSERT_UNCATEGORIZED(__len == 0 || __s != nullptr,
316 "string_view::string_view(_CharT *, size_t): received nullptr");
298317#endif
299318 }
300319
301#if _LIBCPP_STD_VER > 17
320#if _LIBCPP_STD_VER >= 20
302321 template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
303322 requires (is_same_v<iter_value_t<_It>, _CharT> && !is_convertible_v<_End, size_type>)
304323 constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end)
305324 : __data_(_VSTD::to_address(__begin)), __size_(__end - __begin)
306325 {
307 _LIBCPP_ASSERT((__end - __begin) >= 0, "std::string_view::string_view(iterator, sentinel) received invalid range");
326 _LIBCPP_ASSERT_VALID_INPUT_RANGE((__end - __begin) >= 0,
327 "std::string_view::string_view(iterator, sentinel) received invalid range");
308328 }
309#endif // _LIBCPP_STD_VER > 17
329#endif // _LIBCPP_STD_VER >= 20
310330
311#if _LIBCPP_STD_VER > 20
331#if _LIBCPP_STD_VER >= 23
312332 template <class _Range>
313333 requires (
314334 !is_same_v<remove_cvref_t<_Range>, basic_string_view> &&
......@@ -318,20 +338,17 @@ public:
318338 !is_convertible_v<_Range, const _CharT*> &&
319339 (!requires(remove_cvref_t<_Range>& __d) {
320340 __d.operator _VSTD::basic_string_view<_CharT, _Traits>();
321 }) &&
322 (!requires {
323 typename remove_reference_t<_Range>::traits_type;
324 } || is_same_v<typename remove_reference_t<_Range>::traits_type, _Traits>)
341 })
325342 )
326343 constexpr explicit _LIBCPP_HIDE_FROM_ABI
327344 basic_string_view(_Range&& __r) : __data_(ranges::data(__r)), __size_(ranges::size(__r)) {}
328#endif // _LIBCPP_STD_VER > 20
345#endif // _LIBCPP_STD_VER >= 23
329346
330347 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
331348 basic_string_view(const _CharT* __s)
332349 : __data_(__s), __size_(_VSTD::__char_traits_length_checked<_Traits>(__s)) {}
333350
334#if _LIBCPP_STD_VER > 20
351#if _LIBCPP_STD_VER >= 23
335352 basic_string_view(nullptr_t) = delete;
336353#endif
337354
......@@ -343,10 +360,22 @@ public:
343360 const_iterator end() const _NOEXCEPT { return cend(); }
344361
345362 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
346 const_iterator cbegin() const _NOEXCEPT { return __data_; }
363 const_iterator cbegin() const _NOEXCEPT {
364#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
365 return std::__make_bounded_iter(data(), data(), data() + size());
366#else
367 return __data_;
368#endif
369 }
347370
348371 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
349 const_iterator cend() const _NOEXCEPT { return __data_ + __size_; }
372 const_iterator cend() const _NOEXCEPT {
373#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
374 return std::__make_bounded_iter(data() + size(), data(), data() + size());
375#else
376 return __data_ + __size_;
377#endif
378 }
350379
351380 _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_INLINE_VISIBILITY
352381 const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); }
......@@ -376,7 +405,7 @@ public:
376405 // [string.view.access], element access
377406 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
378407 const_reference operator[](size_type __pos) const _NOEXCEPT {
379 return _LIBCPP_ASSERT(__pos < size(), "string_view[] index out of bounds"), __data_[__pos];
408 return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos < size(), "string_view[] index out of bounds"), __data_[__pos];
380409 }
381410
382411 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
......@@ -390,13 +419,14 @@ public:
390419 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
391420 const_reference front() const _NOEXCEPT
392421 {
393 return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data_[0];
422 return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::front(): string is empty"), __data_[0];
394423 }
395424
396425 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
397426 const_reference back() const _NOEXCEPT
398427 {
399 return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data_[__size_-1];
428 return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::back(): string is empty"),
429 __data_[__size_ - 1];
400430 }
401431
402432 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
......@@ -406,7 +436,7 @@ public:
406436 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
407437 void remove_prefix(size_type __n) _NOEXCEPT
408438 {
409 _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()");
439 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_prefix() can't remove more than size()");
410440 __data_ += __n;
411441 __size_ -= __n;
412442 }
......@@ -414,7 +444,7 @@ public:
414444 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
415445 void remove_suffix(size_type __n) _NOEXCEPT
416446 {
417 _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()");
447 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_suffix() can't remove more than size()");
418448 __size_ -= __n;
419449 }
420450
......@@ -492,7 +522,7 @@ public:
492522 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
493523 size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
494524 {
495 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
525 _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
496526 return std::__str_find<value_type, size_type, traits_type, npos>
497527 (data(), size(), __s.data(), __pos, __s.size());
498528 }
......@@ -507,7 +537,7 @@ public:
507537 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
508538 size_type find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
509539 {
510 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
540 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
511541 return std::__str_find<value_type, size_type, traits_type, npos>
512542 (data(), size(), __s, __pos, __n);
513543 }
......@@ -515,7 +545,7 @@ public:
515545 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
516546 size_type find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT
517547 {
518 _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr");
548 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find(): received nullptr");
519549 return std::__str_find<value_type, size_type, traits_type, npos>
520550 (data(), size(), __s, __pos, traits_type::length(__s));
521551 }
......@@ -524,7 +554,7 @@ public:
524554 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
525555 size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
526556 {
527 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
557 _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
528558 return std::__str_rfind<value_type, size_type, traits_type, npos>
529559 (data(), size(), __s.data(), __pos, __s.size());
530560 }
......@@ -539,7 +569,7 @@ public:
539569 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
540570 size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
541571 {
542 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
572 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
543573 return std::__str_rfind<value_type, size_type, traits_type, npos>
544574 (data(), size(), __s, __pos, __n);
545575 }
......@@ -547,7 +577,7 @@ public:
547577 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
548578 size_type rfind(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
549579 {
550 _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr");
580 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::rfind(): received nullptr");
551581 return std::__str_rfind<value_type, size_type, traits_type, npos>
552582 (data(), size(), __s, __pos, traits_type::length(__s));
553583 }
......@@ -556,7 +586,8 @@ public:
556586 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
557587 size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
558588 {
559 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
589 _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr,
590 "string_view::find_first_of(): received nullptr");
560591 return std::__str_find_first_of<value_type, size_type, traits_type, npos>
561592 (data(), size(), __s.data(), __pos, __s.size());
562593 }
......@@ -568,7 +599,7 @@ public:
568599 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
569600 size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
570601 {
571 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
602 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
572603 return std::__str_find_first_of<value_type, size_type, traits_type, npos>
573604 (data(), size(), __s, __pos, __n);
574605 }
......@@ -576,7 +607,7 @@ public:
576607 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
577608 size_type find_first_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
578609 {
579 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr");
610 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find_first_of(): received nullptr");
580611 return std::__str_find_first_of<value_type, size_type, traits_type, npos>
581612 (data(), size(), __s, __pos, traits_type::length(__s));
582613 }
......@@ -585,7 +616,8 @@ public:
585616 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
586617 size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
587618 {
588 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
619 _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr,
620 "string_view::find_last_of(): received nullptr");
589621 return std::__str_find_last_of<value_type, size_type, traits_type, npos>
590622 (data(), size(), __s.data(), __pos, __s.size());
591623 }
......@@ -597,7 +629,7 @@ public:
597629 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
598630 size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
599631 {
600 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
632 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
601633 return std::__str_find_last_of<value_type, size_type, traits_type, npos>
602634 (data(), size(), __s, __pos, __n);
603635 }
......@@ -605,7 +637,7 @@ public:
605637 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
606638 size_type find_last_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
607639 {
608 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr");
640 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find_last_of(): received nullptr");
609641 return std::__str_find_last_of<value_type, size_type, traits_type, npos>
610642 (data(), size(), __s, __pos, traits_type::length(__s));
611643 }
......@@ -614,7 +646,8 @@ public:
614646 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
615647 size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
616648 {
617 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
649 _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr,
650 "string_view::find_first_not_of(): received nullptr");
618651 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
619652 (data(), size(), __s.data(), __pos, __s.size());
620653 }
......@@ -629,7 +662,7 @@ public:
629662 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
630663 size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
631664 {
632 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
665 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
633666 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
634667 (data(), size(), __s, __pos, __n);
635668 }
......@@ -637,7 +670,7 @@ public:
637670 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
638671 size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
639672 {
640 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
673 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
641674 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
642675 (data(), size(), __s, __pos, traits_type::length(__s));
643676 }
......@@ -646,7 +679,8 @@ public:
646679 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
647680 size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
648681 {
649 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
682 _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr,
683 "string_view::find_last_not_of(): received nullptr");
650684 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
651685 (data(), size(), __s.data(), __pos, __s.size());
652686 }
......@@ -661,7 +695,7 @@ public:
661695 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
662696 size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
663697 {
664 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
698 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
665699 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
666700 (data(), size(), __s, __pos, __n);
667701 }
......@@ -669,12 +703,12 @@ public:
669703 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
670704 size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
671705 {
672 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
706 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
673707 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
674708 (data(), size(), __s, __pos, traits_type::length(__s));
675709 }
676710
677#if _LIBCPP_STD_VER > 17
711#if _LIBCPP_STD_VER >= 20
678712 constexpr _LIBCPP_INLINE_VISIBILITY
679713 bool starts_with(basic_string_view __s) const noexcept
680714 { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; }
......@@ -700,7 +734,7 @@ public:
700734 { return ends_with(basic_string_view(__s)); }
701735#endif
702736
703#if _LIBCPP_STD_VER > 20
737#if _LIBCPP_STD_VER >= 23
704738 constexpr _LIBCPP_INLINE_VISIBILITY
705739 bool contains(basic_string_view __sv) const noexcept
706740 { return find(__sv) != npos; }
......@@ -720,23 +754,23 @@ private:
720754};
721755_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_string_view);
722756
723#if _LIBCPP_STD_VER > 17
757#if _LIBCPP_STD_VER >= 20
724758template <class _CharT, class _Traits>
725759inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true;
726760
727761template <class _CharT, class _Traits>
728762inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;
729#endif // _LIBCPP_STD_VER > 17
763#endif // _LIBCPP_STD_VER >= 20
730764
731765// [string.view.deduct]
732766
733#if _LIBCPP_STD_VER > 17
767#if _LIBCPP_STD_VER >= 20
734768template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
735769 basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
736#endif // _LIBCPP_STD_VER > 17
770#endif // _LIBCPP_STD_VER >= 20
737771
738772
739#if _LIBCPP_STD_VER > 20
773#if _LIBCPP_STD_VER >= 23
740774template <ranges::contiguous_range _Range>
741775 basic_string_view(_Range) -> basic_string_view<ranges::range_value_t<_Range>>;
742776#endif
......@@ -773,11 +807,11 @@ bool operator==(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
773807 if (__lhs.size() != __rhs.size()) return false;
774808 return __lhs.compare(__rhs) == 0;
775809}
776#endif // _LIBCPP_STD_VER > 17
810#endif // _LIBCPP_STD_VER >= 20
777811
778812// operator <=>
779813
780#if _LIBCPP_STD_VER > 17
814#if _LIBCPP_STD_VER >= 20
781815
782816template <class _CharT, class _Traits>
783817_LIBCPP_HIDE_FROM_ABI constexpr auto
......@@ -807,7 +841,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(
807841 }
808842}
809843
810#else // _LIBCPP_STD_VER > 17
844#else // _LIBCPP_STD_VER >= 20
811845
812846// operator !=
813847template<class _CharT, class _Traits>
......@@ -940,7 +974,7 @@ bool operator>=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
940974 return __lhs.compare(__rhs) >= 0;
941975}
942976
943#endif // _LIBCPP_STD_VER > 17
977#endif // _LIBCPP_STD_VER >= 20
944978
945979template<class _CharT, class _Traits>
946980_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
......@@ -976,20 +1010,20 @@ template <>
9761010struct hash<basic_string_view<wchar_t, char_traits<wchar_t> > > : __string_view_hash<wchar_t> {};
9771011#endif
9781012
979#if _LIBCPP_STD_VER > 11
1013#if _LIBCPP_STD_VER >= 14
9801014inline namespace literals
9811015{
9821016 inline namespace string_view_literals
9831017 {
9841018 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
985 basic_string_view<char> operator "" sv(const char *__str, size_t __len) _NOEXCEPT
1019 basic_string_view<char> operator""sv(const char *__str, size_t __len) _NOEXCEPT
9861020 {
9871021 return basic_string_view<char> (__str, __len);
9881022 }
9891023
9901024#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
9911025 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
992 basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT
1026 basic_string_view<wchar_t> operator""sv(const wchar_t *__str, size_t __len) _NOEXCEPT
9931027 {
9941028 return basic_string_view<wchar_t> (__str, __len);
9951029 }
......@@ -997,20 +1031,20 @@ inline namespace literals
9971031
9981032#ifndef _LIBCPP_HAS_NO_CHAR8_T
9991033 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1000 basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT
1034 basic_string_view<char8_t> operator""sv(const char8_t *__str, size_t __len) _NOEXCEPT
10011035 {
10021036 return basic_string_view<char8_t> (__str, __len);
10031037 }
10041038#endif
10051039
10061040 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1007 basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT
1041 basic_string_view<char16_t> operator""sv(const char16_t *__str, size_t __len) _NOEXCEPT
10081042 {
10091043 return basic_string_view<char16_t> (__str, __len);
10101044 }
10111045
10121046 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1013 basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len) _NOEXCEPT
1047 basic_string_view<char32_t> operator""sv(const char32_t *__str, size_t __len) _NOEXCEPT
10141048 {
10151049 return basic_string_view<char32_t> (__str, __len);
10161050 }
......@@ -1024,8 +1058,9 @@ _LIBCPP_POP_MACROS
10241058#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
10251059# include <algorithm>
10261060# include <concepts>
1027# include <functional>
1061# include <cstdlib>
10281062# include <iterator>
1063# include <type_traits>
10291064#endif
10301065
10311066#endif // _LIBCPP_STRING_VIEW
lib/libcxx/include/strstream+11-11
......@@ -141,12 +141,12 @@ private:
141141
142142_LIBCPP_BEGIN_NAMESPACE_STD
143143
144class _LIBCPP_TYPE_VIS strstreambuf
144class _LIBCPP_DEPRECATED _LIBCPP_EXPORTED_FROM_ABI strstreambuf
145145 : public streambuf
146146{
147147public:
148148#ifndef _LIBCPP_CXX03_LANG
149 strstreambuf() : strstreambuf(0) {}
149 _LIBCPP_HIDE_FROM_ABI strstreambuf() : strstreambuf(0) {}
150150 explicit strstreambuf(streamsize __alsize);
151151#else
152152 explicit strstreambuf(streamsize __alsize = 0);
......@@ -237,7 +237,7 @@ strstreambuf::operator=(strstreambuf&& __rhs)
237237
238238#endif // _LIBCPP_CXX03_LANG
239239
240class _LIBCPP_TYPE_VIS istrstream
240class _LIBCPP_DEPRECATED _LIBCPP_EXPORTED_FROM_ABI istrstream
241241 : public istream
242242{
243243public:
......@@ -256,8 +256,8 @@ public:
256256
257257#ifndef _LIBCPP_CXX03_LANG
258258 _LIBCPP_INLINE_VISIBILITY
259 istrstream(istrstream&& __rhs)
260 : istream(_VSTD::move(__rhs)),
259 istrstream(istrstream&& __rhs) // extension
260 : istream(_VSTD::move(static_cast<istream&>(__rhs))),
261261 __sb_(_VSTD::move(__rhs.__sb_))
262262 {
263263 istream::set_rdbuf(&__sb_);
......@@ -290,7 +290,7 @@ private:
290290 strstreambuf __sb_;
291291};
292292
293class _LIBCPP_TYPE_VIS ostrstream
293class _LIBCPP_DEPRECATED _LIBCPP_EXPORTED_FROM_ABI ostrstream
294294 : public ostream
295295{
296296public:
......@@ -305,8 +305,8 @@ public:
305305
306306#ifndef _LIBCPP_CXX03_LANG
307307 _LIBCPP_INLINE_VISIBILITY
308 ostrstream(ostrstream&& __rhs)
309 : ostream(_VSTD::move(__rhs)),
308 ostrstream(ostrstream&& __rhs) // extension
309 : ostream(_VSTD::move(static_cast<ostream&>(__rhs))),
310310 __sb_(_VSTD::move(__rhs.__sb_))
311311 {
312312 ostream::set_rdbuf(&__sb_);
......@@ -343,7 +343,7 @@ private:
343343 strstreambuf __sb_; // exposition only
344344};
345345
346class _LIBCPP_TYPE_VIS strstream
346class _LIBCPP_DEPRECATED _LIBCPP_EXPORTED_FROM_ABI strstream
347347 : public iostream
348348{
349349public:
......@@ -365,8 +365,8 @@ public:
365365
366366#ifndef _LIBCPP_CXX03_LANG
367367 _LIBCPP_INLINE_VISIBILITY
368 strstream(strstream&& __rhs)
369 : iostream(_VSTD::move(__rhs)),
368 strstream(strstream&& __rhs) // extension
369 : iostream(_VSTD::move(static_cast<iostream&>(__rhs))),
370370 __sb_(_VSTD::move(__rhs.__sb_))
371371 {
372372 iostream::set_rdbuf(&__sb_);
lib/libcxx/include/system_error+10-386
......@@ -146,13 +146,11 @@ template <> struct hash<std::error_condition>;
146146
147147#include <__assert> // all public C++ headers provide the assertion handler
148148#include <__config>
149#include <__errc>
150#include <__functional/hash.h>
151#include <__functional/unary_function.h>
152#include <__memory/addressof.h>
153#include <stdexcept>
154#include <string>
155#include <type_traits>
149#include <__system_error/errc.h>
150#include <__system_error/error_category.h>
151#include <__system_error/error_code.h>
152#include <__system_error/error_condition.h>
153#include <__system_error/system_error.h>
156154#include <version>
157155
158156// standard-mandated includes
......@@ -164,385 +162,11 @@ template <> struct hash<std::error_condition>;
164162# pragma GCC system_header
165163#endif
166164
167_LIBCPP_BEGIN_NAMESPACE_STD
168
169// is_error_code_enum
170
171template <class _Tp>
172struct _LIBCPP_TEMPLATE_VIS is_error_code_enum
173 : public false_type {};
174
175#if _LIBCPP_STD_VER > 14
176template <class _Tp>
177inline constexpr bool is_error_code_enum_v = is_error_code_enum<_Tp>::value;
178#endif
179
180// is_error_condition_enum
181
182template <class _Tp>
183struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum
184 : public false_type {};
185
186#if _LIBCPP_STD_VER > 14
187template <class _Tp>
188inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<_Tp>::value;
189#endif
190
191template <>
192struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc>
193 : true_type { };
194
195#ifdef _LIBCPP_CXX03_LANG
196template <>
197struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx>
198 : true_type { };
199#endif
200
201class _LIBCPP_TYPE_VIS error_condition;
202class _LIBCPP_TYPE_VIS error_code;
203
204// class error_category
205
206class _LIBCPP_HIDDEN __do_message;
207
208class _LIBCPP_TYPE_VIS error_category
209{
210public:
211 virtual ~error_category() _NOEXCEPT;
212
213#if defined(_LIBCPP_ERROR_CATEGORY_DEFINE_LEGACY_INLINE_FUNCTIONS)
214 error_category() noexcept;
215#else
216 _LIBCPP_INLINE_VISIBILITY
217 _LIBCPP_CONSTEXPR_SINCE_CXX14 error_category() _NOEXCEPT = default;
165#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
166# include <cstdint>
167# include <cstring>
168# include <limits>
169# include <type_traits>
218170#endif
219 error_category(const error_category&) = delete;
220 error_category& operator=(const error_category&) = delete;
221
222 virtual const char* name() const _NOEXCEPT = 0;
223 virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;
224 virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;
225 virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;
226 virtual string message(int __ev) const = 0;
227
228 _LIBCPP_INLINE_VISIBILITY
229 bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;}
230
231#if _LIBCPP_STD_VER > 17
232
233 _LIBCPP_HIDE_FROM_ABI
234 strong_ordering operator<=>(const error_category& __rhs) const noexcept {return compare_three_way()(this, std::addressof(__rhs));}
235
236#else // _LIBCPP_STD_VER > 17
237
238 _LIBCPP_INLINE_VISIBILITY
239 bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);}
240
241 _LIBCPP_INLINE_VISIBILITY
242 bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;}
243
244#endif // _LIBCPP_STD_VER > 17
245
246 friend class _LIBCPP_HIDDEN __do_message;
247};
248
249class _LIBCPP_HIDDEN __do_message
250 : public error_category
251{
252public:
253 string message(int __ev) const override;
254};
255
256_LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT;
257_LIBCPP_FUNC_VIS const error_category& system_category() _NOEXCEPT;
258
259namespace __adl_only {
260 // Those cause ADL to trigger but they are not viable candidates,
261 // so they are never actually selected.
262 void make_error_condition() = delete;
263 void make_error_code() = delete;
264} // namespace __adl_only
265
266class _LIBCPP_TYPE_VIS error_condition
267{
268 int __val_;
269 const error_category* __cat_;
270public:
271 _LIBCPP_INLINE_VISIBILITY
272 error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {}
273
274 _LIBCPP_INLINE_VISIBILITY
275 error_condition(int __val, const error_category& __cat) _NOEXCEPT
276 : __val_(__val), __cat_(&__cat) {}
277
278 template <class _Ep>
279 _LIBCPP_INLINE_VISIBILITY
280 error_condition(_Ep __e,
281 typename enable_if<is_error_condition_enum<_Ep>::value>::type* = nullptr
282 ) _NOEXCEPT
283 {
284 using __adl_only::make_error_condition;
285 *this = make_error_condition(__e);
286 }
287
288 _LIBCPP_INLINE_VISIBILITY
289 void assign(int __val, const error_category& __cat) _NOEXCEPT
290 {
291 __val_ = __val;
292 __cat_ = &__cat;
293 }
294
295 template <class _Ep>
296 _LIBCPP_INLINE_VISIBILITY
297 typename enable_if
298 <
299 is_error_condition_enum<_Ep>::value,
300 error_condition&
301 >::type
302 operator=(_Ep __e) _NOEXCEPT
303 {
304 using __adl_only::make_error_condition;
305 *this = make_error_condition(__e);
306 return *this;
307 }
308
309 _LIBCPP_INLINE_VISIBILITY
310 void clear() _NOEXCEPT
311 {
312 __val_ = 0;
313 __cat_ = &generic_category();
314 }
315
316 _LIBCPP_INLINE_VISIBILITY
317 int value() const _NOEXCEPT {return __val_;}
318
319 _LIBCPP_INLINE_VISIBILITY
320 const error_category& category() const _NOEXCEPT {return *__cat_;}
321 string message() const;
322
323 _LIBCPP_INLINE_VISIBILITY
324 explicit operator bool() const _NOEXCEPT {return __val_ != 0;}
325};
326
327inline _LIBCPP_INLINE_VISIBILITY
328error_condition
329make_error_condition(errc __e) _NOEXCEPT
330{
331 return error_condition(static_cast<int>(__e), generic_category());
332}
333
334// error_code
335
336class _LIBCPP_TYPE_VIS error_code
337{
338 int __val_;
339 const error_category* __cat_;
340public:
341 _LIBCPP_INLINE_VISIBILITY
342 error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {}
343
344 _LIBCPP_INLINE_VISIBILITY
345 error_code(int __val, const error_category& __cat) _NOEXCEPT
346 : __val_(__val), __cat_(&__cat) {}
347
348 template <class _Ep>
349 _LIBCPP_INLINE_VISIBILITY
350 error_code(_Ep __e,
351 typename enable_if<is_error_code_enum<_Ep>::value>::type* = nullptr
352 ) _NOEXCEPT
353 {
354 using __adl_only::make_error_code;
355 *this = make_error_code(__e);
356 }
357
358 _LIBCPP_INLINE_VISIBILITY
359 void assign(int __val, const error_category& __cat) _NOEXCEPT
360 {
361 __val_ = __val;
362 __cat_ = &__cat;
363 }
364
365 template <class _Ep>
366 _LIBCPP_INLINE_VISIBILITY
367 typename enable_if
368 <
369 is_error_code_enum<_Ep>::value,
370 error_code&
371 >::type
372 operator=(_Ep __e) _NOEXCEPT
373 {
374 using __adl_only::make_error_code;
375 *this = make_error_code(__e);
376 return *this;
377 }
378
379 _LIBCPP_INLINE_VISIBILITY
380 void clear() _NOEXCEPT
381 {
382 __val_ = 0;
383 __cat_ = &system_category();
384 }
385
386 _LIBCPP_INLINE_VISIBILITY
387 int value() const _NOEXCEPT {return __val_;}
388
389 _LIBCPP_INLINE_VISIBILITY
390 const error_category& category() const _NOEXCEPT {return *__cat_;}
391
392 _LIBCPP_INLINE_VISIBILITY
393 error_condition default_error_condition() const _NOEXCEPT
394 {return __cat_->default_error_condition(__val_);}
395
396 string message() const;
397
398 _LIBCPP_INLINE_VISIBILITY
399 explicit operator bool() const _NOEXCEPT {return __val_ != 0;}
400};
401
402inline _LIBCPP_INLINE_VISIBILITY
403error_code
404make_error_code(errc __e) _NOEXCEPT
405{
406 return error_code(static_cast<int>(__e), generic_category());
407}
408
409inline _LIBCPP_INLINE_VISIBILITY
410bool
411operator==(const error_code& __x, const error_code& __y) _NOEXCEPT
412{
413 return __x.category() == __y.category() && __x.value() == __y.value();
414}
415
416inline _LIBCPP_INLINE_VISIBILITY
417bool
418operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT
419{
420 return __x.category().equivalent(__x.value(), __y)
421 || __y.category().equivalent(__x, __y.value());
422}
423
424#if _LIBCPP_STD_VER <= 17
425inline _LIBCPP_INLINE_VISIBILITY
426bool
427operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT
428{
429 return __y == __x;
430}
431#endif
432
433inline _LIBCPP_INLINE_VISIBILITY
434bool
435operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT
436{
437 return __x.category() == __y.category() && __x.value() == __y.value();
438}
439
440#if _LIBCPP_STD_VER <= 17
441
442inline _LIBCPP_INLINE_VISIBILITY
443bool
444operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT
445{return !(__x == __y);}
446
447inline _LIBCPP_INLINE_VISIBILITY
448bool
449operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT
450{return !(__x == __y);}
451
452inline _LIBCPP_INLINE_VISIBILITY
453bool
454operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT
455{return !(__x == __y);}
456
457inline _LIBCPP_INLINE_VISIBILITY
458bool
459operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT
460{return !(__x == __y);}
461
462inline _LIBCPP_INLINE_VISIBILITY
463bool
464operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT
465{
466 return __x.category() < __y.category()
467 || (__x.category() == __y.category() && __x.value() < __y.value());
468}
469
470inline _LIBCPP_INLINE_VISIBILITY
471bool
472operator<(const error_code& __x, const error_code& __y) _NOEXCEPT
473{
474 return __x.category() < __y.category()
475 || (__x.category() == __y.category() && __x.value() < __y.value());
476}
477
478#else // _LIBCPP_STD_VER <= 17
479
480inline _LIBCPP_HIDE_FROM_ABI strong_ordering
481operator<=>(const error_code& __x, const error_code& __y) noexcept
482{
483 if (auto __c = __x.category() <=> __y.category(); __c != 0)
484 return __c;
485 return __x.value() <=> __y.value();
486}
487
488inline _LIBCPP_HIDE_FROM_ABI strong_ordering
489operator<=>(const error_condition& __x, const error_condition& __y) noexcept
490{
491 if (auto __c = __x.category() <=> __y.category(); __c != 0)
492 return __c;
493 return __x.value() <=> __y.value();
494}
495
496#endif // _LIBCPP_STD_VER <= 17
497
498template <>
499struct _LIBCPP_TEMPLATE_VIS hash<error_code>
500 : public __unary_function<error_code, size_t>
501{
502 _LIBCPP_INLINE_VISIBILITY
503 size_t operator()(const error_code& __ec) const _NOEXCEPT
504 {
505 return static_cast<size_t>(__ec.value());
506 }
507};
508
509template <>
510struct _LIBCPP_TEMPLATE_VIS hash<error_condition>
511 : public __unary_function<error_condition, size_t>
512{
513 _LIBCPP_INLINE_VISIBILITY
514 size_t operator()(const error_condition& __ec) const _NOEXCEPT
515 {
516 return static_cast<size_t>(__ec.value());
517 }
518};
519
520// system_error
521
522class _LIBCPP_TYPE_VIS system_error
523 : public runtime_error
524{
525 error_code __ec_;
526public:
527 system_error(error_code __ec, const string& __what_arg);
528 system_error(error_code __ec, const char* __what_arg);
529 system_error(error_code __ec);
530 system_error(int __ev, const error_category& __ecat, const string& __what_arg);
531 system_error(int __ev, const error_category& __ecat, const char* __what_arg);
532 system_error(int __ev, const error_category& __ecat);
533 system_error(const system_error&) _NOEXCEPT = default;
534 ~system_error() _NOEXCEPT override;
535
536 _LIBCPP_INLINE_VISIBILITY
537 const error_code& code() const _NOEXCEPT {return __ec_;}
538
539private:
540 static string __init(const error_code&, string);
541};
542
543_LIBCPP_NORETURN _LIBCPP_FUNC_VIS
544void __throw_system_error(int __ev, const char* __what_arg);
545
546_LIBCPP_END_NAMESPACE_STD
547171
548172#endif // _LIBCPP_SYSTEM_ERROR
lib/libcxx/include/thread+16-307
......@@ -64,6 +64,9 @@ template<class charT, class traits>
6464basic_ostream<charT, traits>&
6565operator<<(basic_ostream<charT, traits>& out, thread::id id);
6666
67template<class charT>
68struct formatter<thread::id, charT>;
69
6770namespace this_thread
6871{
6972
......@@ -84,19 +87,12 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
8487*/
8588
8689#include <__assert> // all public C++ headers provide the assertion handler
90#include <__availability>
8791#include <__config>
88#include <__functional/hash.h>
89#include <__memory/unique_ptr.h>
90#include <__mutex_base>
91#include <__thread/poll_with_backoff.h>
92#include <__thread/timed_backoff_policy.h>
92#include <__thread/formatter.h>
93#include <__thread/this_thread.h>
94#include <__thread/thread.h>
9395#include <__threading_support>
94#include <__utility/forward.h>
95#include <cstddef>
96#include <iosfwd>
97#include <system_error>
98#include <tuple>
99#include <type_traits>
10096#include <version>
10197
10298// standard-mandated includes
......@@ -108,314 +104,27 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
108104# pragma GCC system_header
109105#endif
110106
111_LIBCPP_PUSH_MACROS
112#include <__undef_macros>
113
114107#ifdef _LIBCPP_HAS_NO_THREADS
115108# error "<thread> is not supported since libc++ has been configured without support for threads."
116109#endif
117110
118_LIBCPP_BEGIN_NAMESPACE_STD
119
120template <class _Tp> class __thread_specific_ptr;
121class _LIBCPP_TYPE_VIS __thread_struct;
122class _LIBCPP_HIDDEN __thread_struct_imp;
123class __assoc_sub_state;
124
125_LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
126
127class _LIBCPP_TYPE_VIS __thread_struct
128{
129 __thread_struct_imp* __p_;
130
131 __thread_struct(const __thread_struct&);
132 __thread_struct& operator=(const __thread_struct&);
133public:
134 __thread_struct();
135 ~__thread_struct();
136
137 void notify_all_at_thread_exit(condition_variable*, mutex*);
138 void __make_ready_at_thread_exit(__assoc_sub_state*);
139};
140
141template <class _Tp>
142class __thread_specific_ptr
143{
144 __libcpp_tls_key __key_;
145
146 // Only __thread_local_data() may construct a __thread_specific_ptr
147 // and only with _Tp == __thread_struct.
148 static_assert((is_same<_Tp, __thread_struct>::value), "");
149 __thread_specific_ptr();
150 friend _LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
151
152 __thread_specific_ptr(const __thread_specific_ptr&);
153 __thread_specific_ptr& operator=(const __thread_specific_ptr&);
154
155 _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
156
157public:
158 typedef _Tp* pointer;
159
160 ~__thread_specific_ptr();
161
162 _LIBCPP_INLINE_VISIBILITY
163 pointer get() const {return static_cast<_Tp*>(__libcpp_tls_get(__key_));}
164 _LIBCPP_INLINE_VISIBILITY
165 pointer operator*() const {return *get();}
166 _LIBCPP_INLINE_VISIBILITY
167 pointer operator->() const {return get();}
168 void set_pointer(pointer __p);
169};
170
171template <class _Tp>
172void _LIBCPP_TLS_DESTRUCTOR_CC
173__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
174{
175 delete static_cast<pointer>(__p);
176}
177
178template <class _Tp>
179__thread_specific_ptr<_Tp>::__thread_specific_ptr()
180{
181 int __ec =
182 __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
183 if (__ec)
184 __throw_system_error(__ec, "__thread_specific_ptr construction failed");
185}
186
187template <class _Tp>
188__thread_specific_ptr<_Tp>::~__thread_specific_ptr()
189{
190 // __thread_specific_ptr is only created with a static storage duration
191 // so this destructor is only invoked during program termination. Invoking
192 // pthread_key_delete(__key_) may prevent other threads from deleting their
193 // thread local data. For this reason we leak the key.
194}
195
196template <class _Tp>
197void
198__thread_specific_ptr<_Tp>::set_pointer(pointer __p)
199{
200 _LIBCPP_ASSERT(get() == nullptr,
201 "Attempting to overwrite thread local data");
202 std::__libcpp_tls_set(__key_, __p);
203}
204
205template<>
206struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>
207 : public __unary_function<__thread_id, size_t>
208{
209 _LIBCPP_INLINE_VISIBILITY
210 size_t operator()(__thread_id __v) const _NOEXCEPT
211 {
212 return hash<__libcpp_thread_id>()(__v.__id_);
213 }
214};
215
216template<class _CharT, class _Traits>
217_LIBCPP_INLINE_VISIBILITY
218basic_ostream<_CharT, _Traits>&
219operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)
220{return __os << __id.__id_;}
221
222class _LIBCPP_TYPE_VIS thread
223{
224 __libcpp_thread_t __t_;
225
226 thread(const thread&);
227 thread& operator=(const thread&);
228public:
229 typedef __thread_id id;
230 typedef __libcpp_thread_t native_handle_type;
231
232 _LIBCPP_INLINE_VISIBILITY
233 thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
234#ifndef _LIBCPP_CXX03_LANG
235 template <class _Fp, class ..._Args,
236 class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value> >
237 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
238 explicit thread(_Fp&& __f, _Args&&... __args);
239#else // _LIBCPP_CXX03_LANG
240 template <class _Fp>
241 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
242 explicit thread(_Fp __f);
111#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES)
112# include <cstddef>
113# include <ctime>
114# include <iosfwd>
115# include <ratio>
243116#endif
244 ~thread();
245
246 _LIBCPP_INLINE_VISIBILITY
247 thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {
248 __t.__t_ = _LIBCPP_NULL_THREAD;
249 }
250
251 _LIBCPP_INLINE_VISIBILITY
252 thread& operator=(thread&& __t) _NOEXCEPT {
253 if (!__libcpp_thread_isnull(&__t_))
254 terminate();
255 __t_ = __t.__t_;
256 __t.__t_ = _LIBCPP_NULL_THREAD;
257 return *this;
258 }
259
260 _LIBCPP_INLINE_VISIBILITY
261 void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);}
262
263 _LIBCPP_INLINE_VISIBILITY
264 bool joinable() const _NOEXCEPT {return !__libcpp_thread_isnull(&__t_);}
265 void join();
266 void detach();
267 _LIBCPP_INLINE_VISIBILITY
268 id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);}
269 _LIBCPP_INLINE_VISIBILITY
270 native_handle_type native_handle() _NOEXCEPT {return __t_;}
271
272 static unsigned hardware_concurrency() _NOEXCEPT;
273};
274
275#ifndef _LIBCPP_CXX03_LANG
276
277template <class _TSp, class _Fp, class ..._Args, size_t ..._Indices>
278inline _LIBCPP_INLINE_VISIBILITY
279void
280__thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>)
281{
282 _VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
283}
284
285template <class _Fp>
286_LIBCPP_INLINE_VISIBILITY
287void* __thread_proxy(void* __vp)
288{
289 // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...>
290 unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
291 __thread_local_data().set_pointer(_VSTD::get<0>(*__p.get()).release());
292 typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index;
293 _VSTD::__thread_execute(*__p.get(), _Index());
294 return nullptr;
295}
296
297template <class _Fp, class ..._Args,
298 class
299 >
300thread::thread(_Fp&& __f, _Args&&... __args)
301{
302 typedef unique_ptr<__thread_struct> _TSPtr;
303 _TSPtr __tsp(new __thread_struct);
304 typedef tuple<_TSPtr, typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp;
305 unique_ptr<_Gp> __p(
306 new _Gp(_VSTD::move(__tsp),
307 _VSTD::forward<_Fp>(__f),
308 _VSTD::forward<_Args>(__args)...));
309 int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
310 if (__ec == 0)
311 __p.release();
312 else
313 __throw_system_error(__ec, "thread constructor failed");
314}
315
316#else // _LIBCPP_CXX03_LANG
317
318template <class _Fp>
319struct __thread_invoke_pair {
320 // This type is used to pass memory for thread local storage and a functor
321 // to a newly created thread because std::pair doesn't work with
322 // std::unique_ptr in C++03.
323 __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {}
324 unique_ptr<__thread_struct> __tsp_;
325 _Fp __fn_;
326};
327
328template <class _Fp>
329_LIBCPP_HIDE_FROM_ABI void* __thread_proxy_cxx03(void* __vp)
330{
331 unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
332 __thread_local_data().set_pointer(__p->__tsp_.release());
333 (__p->__fn_)();
334 return nullptr;
335}
336
337template <class _Fp>
338thread::thread(_Fp __f)
339{
340
341 typedef __thread_invoke_pair<_Fp> _InvokePair;
342 typedef unique_ptr<_InvokePair> _PairPtr;
343 _PairPtr __pp(new _InvokePair(__f));
344 int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
345 if (__ec == 0)
346 __pp.release();
347 else
348 __throw_system_error(__ec, "thread constructor failed");
349}
350
351#endif // _LIBCPP_CXX03_LANG
352
353inline _LIBCPP_INLINE_VISIBILITY
354void swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);}
355
356namespace this_thread
357{
358
359_LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& __ns);
360
361template <class _Rep, class _Period>
362_LIBCPP_HIDE_FROM_ABI void
363sleep_for(const chrono::duration<_Rep, _Period>& __d)
364{
365 if (__d > chrono::duration<_Rep, _Period>::zero())
366 {
367 // The standard guarantees a 64bit signed integer resolution for nanoseconds,
368 // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits>
369 // and issues with long double folding on PowerPC with GCC.
370 _LIBCPP_CONSTEXPR chrono::duration<long double> _Max =
371 chrono::duration<long double>(9223372036.0L);
372 chrono::nanoseconds __ns;
373 if (__d < _Max)
374 {
375 __ns = chrono::duration_cast<chrono::nanoseconds>(__d);
376 if (__ns < __d)
377 ++__ns;
378 }
379 else
380 __ns = chrono::nanoseconds::max();
381 this_thread::sleep_for(__ns);
382 }
383}
384
385template <class _Clock, class _Duration>
386_LIBCPP_HIDE_FROM_ABI void
387sleep_until(const chrono::time_point<_Clock, _Duration>& __t)
388{
389 mutex __mut;
390 condition_variable __cv;
391 unique_lock<mutex> __lk(__mut);
392 while (_Clock::now() < __t)
393 __cv.wait_until(__lk, __t);
394}
395
396template <class _Duration>
397inline _LIBCPP_INLINE_VISIBILITY
398void
399sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)
400{
401 this_thread::sleep_for(__t - chrono::steady_clock::now());
402}
403
404inline _LIBCPP_INLINE_VISIBILITY
405void yield() _NOEXCEPT {__libcpp_thread_yield();}
406
407} // namespace this_thread
408
409_LIBCPP_END_NAMESPACE_STD
410
411_LIBCPP_POP_MACROS
412117
413118#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
414119# include <chrono>
415120#endif
416121
417122#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
123# include <cstring>
418124# include <functional>
125# include <new>
126# include <system_error>
127# include <type_traits>
419128#endif
420129
421130#endif // _LIBCPP_THREAD
lib/libcxx/include/tuple+65-54
......@@ -206,10 +206,18 @@ template <class... Types>
206206#include <__compare/synth_three_way.h>
207207#include <__config>
208208#include <__functional/invoke.h>
209#include <__functional/unwrap_ref.h>
210209#include <__fwd/array.h>
210#include <__fwd/get.h>
211#include <__fwd/tuple.h>
211212#include <__memory/allocator_arg_t.h>
212213#include <__memory/uses_allocator.h>
214#include <__tuple/make_tuple_types.h>
215#include <__tuple/sfinae_helpers.h>
216#include <__tuple/tuple_element.h>
217#include <__tuple/tuple_indices.h>
218#include <__tuple/tuple_like_ext.h>
219#include <__tuple/tuple_size.h>
220#include <__tuple/tuple_types.h>
213221#include <__type_traits/apply_cv.h>
214222#include <__type_traits/common_reference.h>
215223#include <__type_traits/common_type.h>
......@@ -244,6 +252,7 @@ template <class... Types>
244252#include <__type_traits/negation.h>
245253#include <__type_traits/remove_cvref.h>
246254#include <__type_traits/remove_reference.h>
255#include <__type_traits/unwrap_ref.h>
247256#include <__utility/forward.h>
248257#include <__utility/integer_sequence.h>
249258#include <__utility/move.h>
......@@ -262,6 +271,9 @@ template <class... Types>
262271# pragma GCC system_header
263272#endif
264273
274_LIBCPP_PUSH_MACROS
275#include <__undef_macros>
276
265277_LIBCPP_BEGIN_NAMESPACE_STD
266278
267279#ifndef _LIBCPP_CXX03_LANG
......@@ -295,7 +307,7 @@ class __tuple_leaf
295307 _Hp __value_;
296308
297309 template <class _Tp>
298 static constexpr bool __can_bind_reference() {
310 static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
299311#if __has_keyword(__reference_binds_to_temporary)
300312 return !__reference_binds_to_temporary(_Hp, _Tp);
301313#else
......@@ -367,8 +379,8 @@ public:
367379 {static_assert(!is_reference<_Hp>::value,
368380 "Attempted to uses-allocator construct a reference element in a tuple");}
369381
370 __tuple_leaf(const __tuple_leaf& __t) = default;
371 __tuple_leaf(__tuple_leaf&& __t) = default;
382 _LIBCPP_HIDE_FROM_ABI __tuple_leaf(const __tuple_leaf& __t) = default;
383 _LIBCPP_HIDE_FROM_ABI __tuple_leaf(__tuple_leaf&& __t) = default;
372384
373385 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
374386 int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
......@@ -865,7 +877,7 @@ public:
865877 : __base_(allocator_arg_t(), __a, __t)
866878 { }
867879
868#if _LIBCPP_STD_VER > 20
880#if _LIBCPP_STD_VER >= 23
869881 // tuple(tuple<U...>&) constructors (including allocator_arg_t variants)
870882
871883 template <class... _Up, enable_if_t<
......@@ -879,7 +891,7 @@ public:
879891 _LIBCPP_HIDE_FROM_ABI constexpr
880892 explicit(!(is_convertible_v<_Up&, _Tp> && ...))
881893 tuple(allocator_arg_t, const _Alloc& __alloc, tuple<_Up...>& __t) : __base_(allocator_arg_t(), __alloc, __t) {}
882#endif // _LIBCPP_STD_VER > 20
894#endif // _LIBCPP_STD_VER >= 23
883895
884896 // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
885897
......@@ -929,7 +941,7 @@ public:
929941 : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
930942 { }
931943
932#if _LIBCPP_STD_VER > 20
944#if _LIBCPP_STD_VER >= 23
933945 // tuple(const tuple<U...>&&) constructors (including allocator_arg_t variants)
934946
935947 template <class... _Up, enable_if_t<
......@@ -944,17 +956,17 @@ public:
944956 explicit(!(is_convertible_v<const _Up&&, _Tp> && ...))
945957 tuple(allocator_arg_t, const _Alloc& __alloc, const tuple<_Up...>&& __t)
946958 : __base_(allocator_arg_t(), __alloc, std::move(__t)) {}
947#endif // _LIBCPP_STD_VER > 20
959#endif // _LIBCPP_STD_VER >= 23
948960
949961 // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
950962
951 template <template <class...> class Pred, class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
963 template <template <class...> class _Pred, class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
952964 struct _CtorPredicateFromPair : false_type{};
953965
954 template <template <class...> class Pred, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
955 struct _CtorPredicateFromPair<Pred, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
956 Pred<_Tp1, __copy_cvref_t<_Pair, _Up1> >,
957 Pred<_Tp2, __copy_cvref_t<_Pair, _Up2> >
966 template <template <class...> class _Pred, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
967 struct _CtorPredicateFromPair<_Pred, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
968 _Pred<_Tp1, __copy_cvref_t<_Pair, _Up1> >,
969 _Pred<_Tp2, __copy_cvref_t<_Pair, _Up2> >
958970 > {};
959971
960972 template <class _Pair>
......@@ -1018,7 +1030,7 @@ public:
10181030 : __base_(allocator_arg_t(), __a, __p)
10191031 { }
10201032
1021#if _LIBCPP_STD_VER > 20
1033#if _LIBCPP_STD_VER >= 23
10221034 // tuple(pair<U1, U2>&) constructors (including allocator_arg_t variants)
10231035
10241036 template <class _U1, class _U2, enable_if_t<
......@@ -1082,7 +1094,7 @@ public:
10821094 : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
10831095 { }
10841096
1085#if _LIBCPP_STD_VER > 20
1097#if _LIBCPP_STD_VER >= 23
10861098 // tuple(const pair<U1, U2>&&) constructors (including allocator_arg_t variants)
10871099
10881100 template <class _U1, class _U2, enable_if_t<
......@@ -1097,7 +1109,7 @@ public:
10971109 explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
10981110 tuple(allocator_arg_t, const _Alloc& __alloc, const pair<_U1, _U2>&& __p)
10991111 : __base_(allocator_arg_t(), __alloc, std::move(__p)) {}
1100#endif // _LIBCPP_STD_VER > 20
1112#endif // _LIBCPP_STD_VER >= 23
11011113
11021114 // [tuple.assign]
11031115 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -1109,7 +1121,7 @@ public:
11091121 return *this;
11101122 }
11111123
1112#if _LIBCPP_STD_VER > 20
1124#if _LIBCPP_STD_VER >= 23
11131125 _LIBCPP_HIDE_FROM_ABI constexpr
11141126 const tuple& operator=(tuple const& __tuple) const
11151127 requires (_And<is_copy_assignable<const _Tp>...>::value) {
......@@ -1126,7 +1138,7 @@ public:
11261138 typename __make_tuple_indices<sizeof...(_Tp)>::type());
11271139 return *this;
11281140 }
1129#endif // _LIBCPP_STD_VER > 20
1141#endif // _LIBCPP_STD_VER >= 23
11301142
11311143 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
11321144 tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
......@@ -1170,7 +1182,7 @@ public:
11701182 }
11711183
11721184
1173#if _LIBCPP_STD_VER > 20
1185#if _LIBCPP_STD_VER >= 23
11741186 template <class... _UTypes, enable_if_t<
11751187 _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
11761188 is_assignable<const _Tp&, const _UTypes&>...>::value>* = nullptr>
......@@ -1193,17 +1205,17 @@ public:
11931205 typename __make_tuple_indices<sizeof...(_Tp)>::type());
11941206 return *this;
11951207 }
1196#endif // _LIBCPP_STD_VER > 20
1208#endif // _LIBCPP_STD_VER >= 23
11971209
1198 template <template<class...> class Pred, bool _Const,
1210 template <template<class...> class _Pred, bool _Const,
11991211 class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
12001212 struct _AssignPredicateFromPair : false_type {};
12011213
1202 template <template<class...> class Pred, bool _Const,
1214 template <template<class...> class _Pred, bool _Const,
12031215 class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
1204 struct _AssignPredicateFromPair<Pred, _Const, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > :
1205 _And<Pred<__maybe_const<_Const, _Tp1>&, __copy_cvref_t<_Pair, _Up1> >,
1206 Pred<__maybe_const<_Const, _Tp2>&, __copy_cvref_t<_Pair, _Up2> >
1216 struct _AssignPredicateFromPair<_Pred, _Const, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > :
1217 _And<_Pred<__maybe_const<_Const, _Tp1>&, __copy_cvref_t<_Pair, _Up1> >,
1218 _Pred<__maybe_const<_Const, _Tp2>&, __copy_cvref_t<_Pair, _Up2> >
12071219 > {};
12081220
12091221 template <bool _Const, class _Pair>
......@@ -1212,7 +1224,7 @@ public:
12121224 template <bool _Const, class _Pair>
12131225 struct _NothrowAssignFromPair : _AssignPredicateFromPair<is_nothrow_assignable, _Const, _Pair> {};
12141226
1215#if _LIBCPP_STD_VER > 20
1227#if _LIBCPP_STD_VER >= 23
12161228 template <class _U1, class _U2, enable_if_t<
12171229 _EnableAssignFromPair<true, const pair<_U1, _U2>&>::value>* = nullptr>
12181230 _LIBCPP_HIDE_FROM_ABI constexpr
......@@ -1232,7 +1244,7 @@ public:
12321244 std::get<1>(*this) = std::move(__pair.second);
12331245 return *this;
12341246 }
1235#endif // _LIBCPP_STD_VER > 20
1247#endif // _LIBCPP_STD_VER >= 23
12361248
12371249 template<class _Up1, class _Up2, __enable_if_t<
12381250 _EnableAssignFromPair<false, pair<_Up1, _Up2> const&>::value
......@@ -1296,20 +1308,19 @@ public:
12961308 void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
12971309 {__base_.swap(__t.__base_);}
12981310
1299#if _LIBCPP_STD_VER > 20
1311#if _LIBCPP_STD_VER >= 23
13001312 _LIBCPP_HIDE_FROM_ABI constexpr
13011313 void swap(const tuple& __t) const noexcept(__all<is_nothrow_swappable_v<const _Tp&>...>::value) {
13021314 __base_.swap(__t.__base_);
13031315 }
1304#endif // _LIBCPP_STD_VER > 20
1316#endif // _LIBCPP_STD_VER >= 23
13051317};
13061318
13071319template <>
13081320class _LIBCPP_TEMPLATE_VIS tuple<>
13091321{
13101322public:
1311 _LIBCPP_INLINE_VISIBILITY constexpr
1312 tuple() _NOEXCEPT = default;
1323 constexpr tuple() _NOEXCEPT = default;
13131324 template <class _Alloc>
13141325 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13151326 tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
......@@ -1324,12 +1335,12 @@ public:
13241335 tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
13251336 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13261337 void swap(tuple&) _NOEXCEPT {}
1327#if _LIBCPP_STD_VER > 20
1338#if _LIBCPP_STD_VER >= 23
13281339 _LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple&) const noexcept {}
13291340#endif
13301341};
13311342
1332#if _LIBCPP_STD_VER > 20
1343#if _LIBCPP_STD_VER >= 23
13331344template <class... _TTypes, class... _UTypes, template<class> class _TQual, template<class> class _UQual>
13341345 requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; }
13351346struct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> {
......@@ -1341,9 +1352,9 @@ template <class... _TTypes, class... _UTypes>
13411352struct common_type<tuple<_TTypes...>, tuple<_UTypes...>> {
13421353 using type = tuple<common_type_t<_TTypes, _UTypes>...>;
13431354};
1344#endif // _LIBCPP_STD_VER > 20
1355#endif // _LIBCPP_STD_VER >= 23
13451356
1346#if _LIBCPP_STD_VER > 14
1357#if _LIBCPP_STD_VER >= 17
13471358template <class ..._Tp>
13481359tuple(_Tp...) -> tuple<_Tp...>;
13491360template <class _Tp1, class _Tp2>
......@@ -1363,7 +1374,7 @@ swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
13631374 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
13641375 {__t.swap(__u);}
13651376
1366#if _LIBCPP_STD_VER > 20
1377#if _LIBCPP_STD_VER >= 23
13671378template <class... _Tp>
13681379_LIBCPP_HIDE_FROM_ABI constexpr
13691380enable_if_t<__all<is_swappable_v<const _Tp>...>::value, void>
......@@ -1413,7 +1424,7 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT
14131424 static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
14141425}
14151426
1416#if _LIBCPP_STD_VER > 11
1427#if _LIBCPP_STD_VER >= 14
14171428
14181429namespace __find_detail {
14191430
......@@ -1501,9 +1512,13 @@ struct __ignore_t
15011512 const __ignore_t& operator=(_Tp&&) const {return *this;}
15021513};
15031514
1515# if _LIBCPP_STD_VER >= 17
1516inline constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
1517# else
15041518namespace {
15051519 constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
15061520} // namespace
1521# endif
15071522
15081523template <class... _Tp>
15091524inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
......@@ -1552,7 +1567,7 @@ operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
15521567 return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
15531568}
15541569
1555#if _LIBCPP_STD_VER > 17
1570#if _LIBCPP_STD_VER >= 20
15561571
15571572// operator<=>
15581573
......@@ -1574,7 +1589,7 @@ operator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
15741589 return _VSTD::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{});
15751590}
15761591
1577#else // _LIBCPP_STD_VER > 17
1592#else // _LIBCPP_STD_VER >= 20
15781593
15791594template <class ..._Tp, class ..._Up>
15801595inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
......@@ -1644,7 +1659,7 @@ operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
16441659 return !(__y < __x);
16451660}
16461661
1647#endif // _LIBCPP_STD_VER > 17
1662#endif // _LIBCPP_STD_VER >= 20
16481663
16491664// tuple_cat
16501665
......@@ -1712,17 +1727,15 @@ template <class ..._Types, size_t ..._I0, class _Tuple0>
17121727struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
17131728{
17141729 typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0;
1715 typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1716 typename tuple_element<_I0, _T0>::type>::type&&...> type;
1730 typedef tuple<_Types..., __apply_cv_t<_Tuple0, typename tuple_element<_I0, _T0>::type>&&...> type;
17171731};
17181732
17191733template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
17201734struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
17211735 _Tuple0, _Tuple1, _Tuples...>
17221736 : public __tuple_cat_return_ref_imp<
1723 tuple<_Types..., typename __apply_cv<_Tuple0,
1724 typename tuple_element<_I0,
1725 __libcpp_remove_reference_t<_Tuple0> >::type>::type&&...>,
1737 tuple<_Types..., __apply_cv_t<_Tuple0,
1738 typename tuple_element<_I0, __libcpp_remove_reference_t<_Tuple0>>::type>&&...>,
17261739 typename __make_tuple_indices<tuple_size<__libcpp_remove_reference_t<_Tuple1> >::value>::type,
17271740 _Tuple1, _Tuples...>
17281741{
......@@ -1762,13 +1775,9 @@ struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J
17621775 (void)__t; // avoid unused parameter warning on GCC when _I0 is empty
17631776 typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0;
17641777 typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple1> _T1;
1765 return __tuple_cat<
1766 tuple<_Types...,
1767 typename __apply_cv<_Tuple0, typename tuple_element<
1768 _J0, _T0>::type>::type&&...>,
1769 typename __make_tuple_indices<sizeof...(_Types) +
1770 tuple_size<_T0>::value>::type,
1771 typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1778 return __tuple_cat<tuple<_Types..., __apply_cv_t<_Tuple0, typename tuple_element<_J0, _T0>::type>&&...>,
1779 typename __make_tuple_indices<sizeof...(_Types) + tuple_size<_T0>::value>::type,
1780 typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
17721781 _VSTD::forward_as_tuple(
17731782 _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
17741783 _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...),
......@@ -1803,7 +1812,7 @@ pair<_T1, _T2>::pair(piecewise_construct_t,
18031812{
18041813}
18051814
1806#if _LIBCPP_STD_VER > 14
1815#if _LIBCPP_STD_VER >= 17
18071816template <class _Tp>
18081817inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
18091818
......@@ -1845,12 +1854,14 @@ _LIBCPP_NOEXCEPT_RETURN(
18451854
18461855#undef _LIBCPP_NOEXCEPT_RETURN
18471856
1848#endif // _LIBCPP_STD_VER > 14
1857#endif // _LIBCPP_STD_VER >= 17
18491858
18501859#endif // !defined(_LIBCPP_CXX03_LANG)
18511860
18521861_LIBCPP_END_NAMESPACE_STD
18531862
1863_LIBCPP_POP_MACROS
1864
18541865#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
18551866# include <exception>
18561867# include <iosfwd>
lib/libcxx/include/type_traits+4-3
......@@ -51,7 +51,7 @@ namespace std
5151 template <class T> struct is_arithmetic;
5252 template <class T> struct is_fundamental;
5353 template <class T> struct is_member_pointer;
54 template <class T> struct is_scoped_enum; // C++2b
54 template <class T> struct is_scoped_enum; // C++23
5555 template <class T> struct is_scalar;
5656 template <class T> struct is_object;
5757 template <class T> struct is_compound;
......@@ -286,7 +286,7 @@ namespace std
286286 template <class T> inline constexpr bool is_member_pointer_v
287287 = is_member_pointer<T>::value; // C++17
288288 template <class T> inline constexpr bool is_scoped_enum_v
289 = is_scoped_enum<T>::value; // C++2b
289 = is_scoped_enum<T>::value; // C++23
290290
291291 // See C++14 20.10.4.3, type properties
292292 template <class T> inline constexpr bool is_const_v
......@@ -418,7 +418,6 @@ namespace std
418418*/
419419#include <__assert> // all public C++ headers provide the assertion handler
420420#include <__config>
421#include <__functional/invoke.h>
422421#include <__fwd/hash.h> // This is https://llvm.org/PR56938
423422#include <__type_traits/add_const.h>
424423#include <__type_traits/add_cv.h>
......@@ -443,6 +442,7 @@ namespace std
443442#include <__type_traits/has_unique_object_representation.h>
444443#include <__type_traits/has_virtual_destructor.h>
445444#include <__type_traits/integral_constant.h>
445#include <__type_traits/invoke.h>
446446#include <__type_traits/is_abstract.h>
447447#include <__type_traits/is_aggregate.h>
448448#include <__type_traits/is_arithmetic.h>
......@@ -532,6 +532,7 @@ namespace std
532532#include <__type_traits/result_of.h>
533533#include <__type_traits/type_identity.h>
534534#include <__type_traits/underlying_type.h>
535#include <__type_traits/unwrap_ref.h>
535536#include <__type_traits/void_t.h>
536537#include <__utility/declval.h>
537538#include <cstddef>
lib/libcxx/include/typeindex+1-1
......@@ -87,7 +87,7 @@ public:
8787 _LIBCPP_INLINE_VISIBILITY
8888 bool operator>=(const type_index& __y) const _NOEXCEPT
8989 {return !__t_->before(*__y.__t_);}
90#if _LIBCPP_STD_VER > 17
90#if _LIBCPP_STD_VER >= 20
9191 _LIBCPP_HIDE_FROM_ABI
9292 strong_ordering operator<=>(const type_index& __y) const noexcept {
9393 if (*__t_ == *__y.__t_)
lib/libcxx/include/typeinfo+32-16
......@@ -7,8 +7,8 @@
77//
88//===----------------------------------------------------------------------===//
99
10#ifndef __LIBCPP_TYPEINFO
11#define __LIBCPP_TYPEINFO
10#ifndef _LIBCPP_TYPEINFO
11#define _LIBCPP_TYPEINFO
1212
1313/*
1414
......@@ -21,7 +21,7 @@ class type_info
2121public:
2222 virtual ~type_info();
2323
24 bool operator==(const type_info& rhs) const noexcept;
24 bool operator==(const type_info& rhs) const noexcept; // constexpr since C++23
2525 bool operator!=(const type_info& rhs) const noexcept; // removed in C++20
2626
2727 bool before(const type_info& rhs) const noexcept;
......@@ -59,11 +59,11 @@ public:
5959#include <__assert> // all public C++ headers provide the assertion handler
6060#include <__availability>
6161#include <__config>
62#include <__exception/exception.h>
63#include <__type_traits/is_constant_evaluated.h>
64#include <__verbose_abort>
6265#include <cstddef>
6366#include <cstdint>
64#include <cstdlib>
65#include <exception>
66#include <type_traits>
6767
6868#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
6969# pragma GCC system_header
......@@ -79,7 +79,7 @@ namespace std // purposefully not using versioning namespace
7979
8080#if defined(_LIBCPP_ABI_MICROSOFT)
8181
82class _LIBCPP_EXCEPTION_ABI type_info
82class _LIBCPP_EXPORTED_FROM_ABI type_info
8383{
8484 type_info& operator=(const type_info&);
8585 type_info(const type_info&);
......@@ -104,8 +104,13 @@ public:
104104
105105 size_t hash_code() const _NOEXCEPT;
106106
107 _LIBCPP_INLINE_VISIBILITY
107 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
108108 bool operator==(const type_info& __arg) const _NOEXCEPT {
109 // When evaluated in a constant expression, both type infos simply can't come
110 // from different translation units, so it is sufficient to compare their addresses.
111 if (__libcpp_is_constant_evaluated()) {
112 return this == &__arg;
113 }
109114 return __compare(__arg) == 0;
110115 }
111116
......@@ -294,7 +299,7 @@ struct __type_info_implementations {
294299 __impl;
295300};
296301
297class _LIBCPP_EXCEPTION_ABI type_info
302class _LIBCPP_EXPORTED_FROM_ABI type_info
298303{
299304 type_info& operator=(const type_info&);
300305 type_info(const type_info&);
......@@ -330,9 +335,14 @@ public:
330335 return __impl::__hash(__type_name);
331336 }
332337
333 _LIBCPP_INLINE_VISIBILITY
338 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
334339 bool operator==(const type_info& __arg) const _NOEXCEPT
335340 {
341 // When evaluated in a constant expression, both type infos simply can't come
342 // from different translation units, so it is sufficient to compare their addresses.
343 if (__libcpp_is_constant_evaluated()) {
344 return this == &__arg;
345 }
336346 return __impl::__eq(__type_name, __arg.__type_name);
337347 }
338348
......@@ -344,17 +354,17 @@ public:
344354};
345355#endif // defined(_LIBCPP_ABI_MICROSOFT)
346356
347class _LIBCPP_EXCEPTION_ABI bad_cast
357class _LIBCPP_EXPORTED_FROM_ABI bad_cast
348358 : public exception
349359{
350360 public:
351361 bad_cast() _NOEXCEPT;
352 bad_cast(const bad_cast&) _NOEXCEPT = default;
362 _LIBCPP_HIDE_FROM_ABI bad_cast(const bad_cast&) _NOEXCEPT = default;
353363 ~bad_cast() _NOEXCEPT override;
354364 const char* what() const _NOEXCEPT override;
355365};
356366
357class _LIBCPP_EXCEPTION_ABI bad_typeid
367class _LIBCPP_EXPORTED_FROM_ABI bad_typeid
358368 : public exception
359369{
360370 public:
......@@ -395,12 +405,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
395405_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
396406void __throw_bad_cast()
397407{
398#ifndef _LIBCPP_NO_EXCEPTIONS
408#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
399409 throw bad_cast();
400410#else
401 _VSTD::abort();
411 _LIBCPP_VERBOSE_ABORT("bad_cast was thrown in -fno-exceptions mode");
402412#endif
403413}
404414_LIBCPP_END_NAMESPACE_STD
405415
406#endif // __LIBCPP_TYPEINFO
416#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
417# include <cstdlib>
418# include <exception>
419# include <type_traits>
420#endif
421
422#endif // _LIBCPP_TYPEINFO
lib/libcxx/include/uchar.h+3-1
......@@ -42,10 +42,12 @@ size_t c32rtomb(char* s, char32_t c32, mbstate_t* ps);
4242
4343// Some platforms don't implement <uchar.h> and we don't want to give a hard
4444// error on those platforms. When the platform doesn't provide <uchar.h>, at
45// least include <stddef.h> so we get the declaration for size_t.
45// least include <stddef.h> so we get the declaration for size_t, and try to
46// get the declaration of mbstate_t too.
4647#if __has_include_next(<uchar.h>)
4748# include_next <uchar.h>
4849#else
50# include <__mbstate_t.h>
4951# include <stddef.h>
5052#endif
5153
lib/libcxx/include/unordered_map+343-191
......@@ -59,6 +59,11 @@ public:
5959 size_type n = 0, const hasher& hf = hasher(),
6060 const key_equal& eql = key_equal(),
6161 const allocator_type& a = allocator_type());
62 template<container-compatible-range<value_type> R>
63 unordered_map(from_range_t, R&& rg, size_type n = see below,
64 const hasher& hf = hasher(), const key_equal& eql = key_equal(),
65 const allocator_type& a = allocator_type()); // C++23
66
6267 explicit unordered_map(const allocator_type&);
6368 unordered_map(const unordered_map&);
6469 unordered_map(const unordered_map&, const Allocator&);
......@@ -82,6 +87,12 @@ public:
8287 unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf,
8388 const allocator_type& a)
8489 : unordered_map(f, l, n, hf, key_equal(), a) {} // C++14
90 template<container-compatible-range<value_type> R>
91 unordered_map(from_range_t, R&& rg, size_type n, const allocator_type& a)
92 : unordered_map(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23
93 template<container-compatible-range<value_type> R>
94 unordered_map(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a)
95 : unordered_map(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } // C++23
8596 unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
8697 : unordered_map(il, n, hasher(), key_equal(), a) {} // C++14
8798 unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf,
......@@ -122,6 +133,8 @@ public:
122133 iterator insert(const_iterator hint, P&& obj);
123134 template <class InputIterator>
124135 void insert(InputIterator first, InputIterator last);
136 template<container-compatible-range<value_type> R>
137 void insert_range(R&& rg); // C++23
125138 void insert(initializer_list<value_type>);
126139
127140 node_type extract(const_iterator position); // C++17
......@@ -224,6 +237,13 @@ unordered_map(InputIterator, InputIterator, typename see below::size_type = see
224237 -> unordered_map<iter_key_t<InputIterator>, iter_value_t<InputIterator>, Hash, Pred,
225238 Allocator>; // C++17
226239
240template<ranges::input_range R, class Hash = hash<range-key-type<R>>,
241 class Pred = equal_to<range-key-type<R>>,
242 class Allocator = allocator<range-to-alloc-type<R>>>
243 unordered_map(from_range_t, R&&, typename see below::size_type = see below,
244 Hash = Hash(), Pred = Pred(), Allocator = Allocator())
245 -> unordered_map<range-key-type<R>, range-mapped-type<R>, Hash, Pred, Allocator>; // C++23
246
227247template<class Key, class T, class Hash = hash<Key>,
228248 class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
229249unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type = see below,
......@@ -245,6 +265,21 @@ unordered_map(InputIterator, InputIterator, typename see below::size_type, Hash,
245265 -> unordered_map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Hash,
246266 equal_to<iter_key_t<InputIterator>>, Allocator>; // C++17
247267
268template<ranges::input_range R, class Allocator>
269 unordered_map(from_range_t, R&&, typename see below::size_type, Allocator)
270 -> unordered_map<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>,
271 equal_to<range-key-type<R>>, Allocator>; // C++23
272
273template<ranges::input_range R, class Allocator>
274 unordered_map(from_range_t, R&&, Allocator)
275 -> unordered_map<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>,
276 equal_to<range-key-type<R>>, Allocator>; // C++23
277
278template<ranges::input_range R, class Hash, class Allocator>
279 unordered_map(from_range_t, R&&, typename see below::size_type, Hash, Allocator)
280 -> unordered_map<range-key-type<R>, range-mapped-type<R>, Hash,
281 equal_to<range-key-type<R>>, Allocator>; // C++23
282
248283template<class Key, class T, typename Allocator>
249284unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type, Allocator)
250285 -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>; // C++17
......@@ -270,7 +305,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
270305template <class Key, class T, class Hash, class Pred, class Alloc>
271306 bool
272307 operator!=(const unordered_map<Key, T, Hash, Pred, Alloc>& x,
273 const unordered_map<Key, T, Hash, Pred, Alloc>& y);
308 const unordered_map<Key, T, Hash, Pred, Alloc>& y); // Removed in C++20
274309
275310template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
276311 class Alloc = allocator<pair<const Key, T>>>
......@@ -311,6 +346,10 @@ public:
311346 size_type n = 0, const hasher& hf = hasher(),
312347 const key_equal& eql = key_equal(),
313348 const allocator_type& a = allocator_type());
349 template<container-compatible-range<value_type> R>
350 unordered_multimap(from_range_t, R&& rg, size_type n = see below,
351 const hasher& hf = hasher(), const key_equal& eql = key_equal(),
352 const allocator_type& a = allocator_type()); // C++23
314353 explicit unordered_multimap(const allocator_type&);
315354 unordered_multimap(const unordered_multimap&);
316355 unordered_multimap(const unordered_multimap&, const Allocator&);
......@@ -334,6 +373,12 @@ public:
334373 unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf,
335374 const allocator_type& a)
336375 : unordered_multimap(f, l, n, hf, key_equal(), a) {} // C++14
376 template<container-compatible-range<value_type> R>
377 unordered_multimap(from_range_t, R&& rg, size_type n, const allocator_type& a)
378 : unordered_multimap(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23
379 template<container-compatible-range<value_type> R>
380 unordered_multimap(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a)
381 : unordered_multimap(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } // C++23
337382 unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
338383 : unordered_multimap(il, n, hasher(), key_equal(), a) {} // C++14
339384 unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf,
......@@ -374,6 +419,8 @@ public:
374419 iterator insert(const_iterator hint, P&& obj);
375420 template <class InputIterator>
376421 void insert(InputIterator first, InputIterator last);
422 template<container-compatible-range<value_type> R>
423 void insert_range(R&& rg); // C++23
377424 void insert(initializer_list<value_type>);
378425
379426 node_type extract(const_iterator position); // C++17
......@@ -453,6 +500,13 @@ unordered_multimap(InputIterator, InputIterator, typename see below::size_type =
453500 -> unordered_multimap<iter_key_t<InputIterator>, iter_value_t<InputIterator>, Hash, Pred,
454501 Allocator>; // C++17
455502
503template<ranges::input_range R, class Hash = hash<range-key-type<R>>,
504 class Pred = equal_to<range-key-type<R>>,
505 class Allocator = allocator<range-to-alloc-type<R>>>
506 unordered_multimap(from_range_t, R&&, typename see below::size_type = see below,
507 Hash = Hash(), Pred = Pred(), Allocator = Allocator())
508 -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, Hash, Pred, Allocator>; // C++23
509
456510template<class Key, class T, class Hash = hash<Key>,
457511 class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
458512unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type = see below,
......@@ -474,6 +528,21 @@ unordered_multimap(InputIterator, InputIterator, typename see below::size_type,
474528 -> unordered_multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Hash,
475529 equal_to<iter_key_t<InputIterator>>, Allocator>; // C++17
476530
531template<ranges::input_range R, class Allocator>
532 unordered_multimap(from_range_t, R&&, typename see below::size_type, Allocator)
533 -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>,
534 equal_to<range-key-type<R>>, Allocator>; // C++23
535
536template<ranges::input_range R, class Allocator>
537 unordered_multimap(from_range_t, R&&, Allocator)
538 -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>,
539 equal_to<range-key-type<R>>, Allocator>; // C++23
540
541template<ranges::input_range R, class Hash, class Allocator>
542 unordered_multimap(from_range_t, R&&, typename see below::size_type, Hash, Allocator)
543 -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, Hash,
544 equal_to<range-key-type<R>>, Allocator>; // C++23
545
477546template<class Key, class T, typename Allocator>
478547unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type, Allocator)
479548 -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>; // C++17
......@@ -508,7 +577,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
508577template <class Key, class T, class Hash, class Pred, class Alloc>
509578 bool
510579 operator!=(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
511 const unordered_multimap<Key, T, Hash, Pred, Alloc>& y);
580 const unordered_multimap<Key, T, Hash, Pred, Alloc>& y); // Removed in C++20
512581
513582} // std
514583
......@@ -516,19 +585,24 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
516585
517586#include <__algorithm/is_permutation.h>
518587#include <__assert> // all public C++ headers provide the assertion handler
588#include <__availability>
519589#include <__config>
520#include <__debug>
521590#include <__functional/is_transparent.h>
522591#include <__functional/operations.h>
523592#include <__hash_table>
524593#include <__iterator/distance.h>
525594#include <__iterator/erase_if_container.h>
526595#include <__iterator/iterator_traits.h>
596#include <__iterator/ranges_iterator_traits.h>
527597#include <__memory/addressof.h>
528598#include <__memory/allocator.h>
529599#include <__memory_resource/polymorphic_allocator.h>
530600#include <__node_handle>
601#include <__ranges/concepts.h>
602#include <__ranges/container_compatible_range.h>
603#include <__ranges/from_range.h>
531604#include <__type_traits/is_allocator.h>
605#include <__type_traits/type_identity.h>
532606#include <__utility/forward.h>
533607#include <stdexcept>
534608#include <tuple>
......@@ -575,7 +649,7 @@ public:
575649 _LIBCPP_INLINE_VISIBILITY
576650 size_t operator()(const _Key& __x) const
577651 {return static_cast<const _Hash&>(*this)(__x);}
578#if _LIBCPP_STD_VER > 17
652#if _LIBCPP_STD_VER >= 20
579653 template <typename _K2>
580654 _LIBCPP_INLINE_VISIBILITY
581655 size_t operator()(const _K2& __x) const
......@@ -611,7 +685,7 @@ public:
611685 _LIBCPP_INLINE_VISIBILITY
612686 size_t operator()(const _Key& __x) const
613687 {return __hash_(__x);}
614#if _LIBCPP_STD_VER > 17
688#if _LIBCPP_STD_VER >= 20
615689 template <typename _K2>
616690 _LIBCPP_INLINE_VISIBILITY
617691 size_t operator()(const _K2& __x) const
......@@ -661,7 +735,7 @@ public:
661735 _LIBCPP_INLINE_VISIBILITY
662736 bool operator()(const _Key& __x, const _Cp& __y) const
663737 {return static_cast<const _Pred&>(*this)(__x, __y.__get_value().first);}
664#if _LIBCPP_STD_VER > 17
738#if _LIBCPP_STD_VER >= 20
665739 template <typename _K2>
666740 _LIBCPP_INLINE_VISIBILITY
667741 bool operator()(const _Cp& __x, const _K2& __y) const
......@@ -712,7 +786,7 @@ public:
712786 _LIBCPP_INLINE_VISIBILITY
713787 bool operator()(const _Key& __x, const _Cp& __y) const
714788 {return __pred_(__x, __y.__get_value().first);}
715#if _LIBCPP_STD_VER > 17
789#if _LIBCPP_STD_VER >= 20
716790 template <typename _K2>
717791 _LIBCPP_INLINE_VISIBILITY
718792 bool operator()(const _Cp& __x, const _K2& __y) const
......@@ -825,7 +899,7 @@ public:
825899 _LIBCPP_INLINE_VISIBILITY
826900 value_type& __get_value()
827901 {
828#if _LIBCPP_STD_VER > 14
902#if _LIBCPP_STD_VER >= 17
829903 return *_VSTD::launder(_VSTD::addressof(__cc_));
830904#else
831905 return __cc_;
......@@ -835,7 +909,7 @@ public:
835909 _LIBCPP_INLINE_VISIBILITY
836910 const value_type& __get_value() const
837911 {
838#if _LIBCPP_STD_VER > 14
912#if _LIBCPP_STD_VER >= 17
839913 return *_VSTD::launder(_VSTD::addressof(__cc_));
840914#else
841915 return __cc_;
......@@ -953,9 +1027,11 @@ public:
9531027 friend _LIBCPP_INLINE_VISIBILITY
9541028 bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
9551029 {return __x.__i_ == __y.__i_;}
1030#if _LIBCPP_STD_VER <= 17
9561031 friend _LIBCPP_INLINE_VISIBILITY
9571032 bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
9581033 {return __x.__i_ != __y.__i_;}
1034#endif
9591035
9601036 template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
9611037 template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
......@@ -1007,9 +1083,11 @@ public:
10071083 friend _LIBCPP_INLINE_VISIBILITY
10081084 bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
10091085 {return __x.__i_ == __y.__i_;}
1086#if _LIBCPP_STD_VER <= 17
10101087 friend _LIBCPP_INLINE_VISIBILITY
10111088 bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
10121089 {return __x.__i_ != __y.__i_;}
1090#endif
10131091
10141092 template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
10151093 template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
......@@ -1035,7 +1113,7 @@ public:
10351113 typedef value_type& reference;
10361114 typedef const value_type& const_reference;
10371115 static_assert((is_same<value_type, typename allocator_type::value_type>::value),
1038 "Invalid allocator::value_type");
1116 "Allocator::value_type must be same type as value_type");
10391117
10401118private:
10411119 typedef __hash_value_type<key_type, mapped_type> __value_type;
......@@ -1075,7 +1153,7 @@ public:
10751153 typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;
10761154 typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;
10771155
1078#if _LIBCPP_STD_VER > 14
1156#if _LIBCPP_STD_VER >= 17
10791157 typedef __map_node_handle<__node, allocator_type> node_type;
10801158 typedef __insert_return_type<iterator, node_type> insert_return_type;
10811159#endif
......@@ -1089,41 +1167,55 @@ public:
10891167 unordered_map()
10901168 _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
10911169 {
1092 _VSTD::__debug_db_insert_c(this);
10931170 }
1094 explicit unordered_map(size_type __n, const hasher& __hf = hasher(),
1171 explicit _LIBCPP_HIDE_FROM_ABI unordered_map(size_type __n, const hasher& __hf = hasher(),
10951172 const key_equal& __eql = key_equal());
1096 unordered_map(size_type __n, const hasher& __hf,
1173 _LIBCPP_HIDE_FROM_ABI unordered_map(size_type __n, const hasher& __hf,
10971174 const key_equal& __eql,
10981175 const allocator_type& __a);
10991176 template <class _InputIterator>
1100 unordered_map(_InputIterator __first, _InputIterator __last);
1177 _LIBCPP_HIDE_FROM_ABI unordered_map(_InputIterator __first, _InputIterator __last);
11011178 template <class _InputIterator>
1102 unordered_map(_InputIterator __first, _InputIterator __last,
1179 _LIBCPP_HIDE_FROM_ABI unordered_map(_InputIterator __first, _InputIterator __last,
11031180 size_type __n, const hasher& __hf = hasher(),
11041181 const key_equal& __eql = key_equal());
11051182 template <class _InputIterator>
1106 unordered_map(_InputIterator __first, _InputIterator __last,
1183 _LIBCPP_HIDE_FROM_ABI unordered_map(_InputIterator __first, _InputIterator __last,
11071184 size_type __n, const hasher& __hf,
11081185 const key_equal& __eql,
11091186 const allocator_type& __a);
1187
1188#if _LIBCPP_STD_VER >= 23
1189 template <_ContainerCompatibleRange<value_type> _Range>
1190 _LIBCPP_HIDE_FROM_ABI
1191 unordered_map(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0,
1192 const hasher& __hf = hasher(), const key_equal& __eql = key_equal(),
1193 const allocator_type& __a = allocator_type())
1194 : __table_(__hf, __eql, typename __table::allocator_type(__a)) {
1195 if (__n > 0) {
1196 __table_.__rehash_unique(__n);
1197 }
1198 insert_range(std::forward<_Range>(__range));
1199 }
1200#endif
1201
11101202 _LIBCPP_INLINE_VISIBILITY
11111203 explicit unordered_map(const allocator_type& __a);
1112 unordered_map(const unordered_map& __u);
1113 unordered_map(const unordered_map& __u, const allocator_type& __a);
1204 _LIBCPP_HIDE_FROM_ABI unordered_map(const unordered_map& __u);
1205 _LIBCPP_HIDE_FROM_ABI unordered_map(const unordered_map& __u, const allocator_type& __a);
11141206#ifndef _LIBCPP_CXX03_LANG
11151207 _LIBCPP_INLINE_VISIBILITY
11161208 unordered_map(unordered_map&& __u)
11171209 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
1118 unordered_map(unordered_map&& __u, const allocator_type& __a);
1119 unordered_map(initializer_list<value_type> __il);
1120 unordered_map(initializer_list<value_type> __il, size_type __n,
1210 _LIBCPP_HIDE_FROM_ABI unordered_map(unordered_map&& __u, const allocator_type& __a);
1211 _LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list<value_type> __il);
1212 _LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list<value_type> __il, size_type __n,
11211213 const hasher& __hf = hasher(), const key_equal& __eql = key_equal());
1122 unordered_map(initializer_list<value_type> __il, size_type __n,
1214 _LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list<value_type> __il, size_type __n,
11231215 const hasher& __hf, const key_equal& __eql,
11241216 const allocator_type& __a);
11251217#endif // _LIBCPP_CXX03_LANG
1126#if _LIBCPP_STD_VER > 11
1218#if _LIBCPP_STD_VER >= 14
11271219 _LIBCPP_INLINE_VISIBILITY
11281220 unordered_map(size_type __n, const allocator_type& __a)
11291221 : unordered_map(__n, hasher(), key_equal(), __a) {}
......@@ -1139,6 +1231,19 @@ public:
11391231 unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf,
11401232 const allocator_type& __a)
11411233 : unordered_map(__first, __last, __n, __hf, key_equal(), __a) {}
1234
1235#if _LIBCPP_STD_VER >= 23
1236 template <_ContainerCompatibleRange<value_type> _Range>
1237 _LIBCPP_HIDE_FROM_ABI
1238 unordered_map(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a)
1239 : unordered_map(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {}
1240
1241 template <_ContainerCompatibleRange<value_type> _Range>
1242 _LIBCPP_HIDE_FROM_ABI
1243 unordered_map(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a)
1244 : unordered_map(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {}
1245#endif
1246
11421247 _LIBCPP_INLINE_VISIBILITY
11431248 unordered_map(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
11441249 : unordered_map(__il, __n, hasher(), key_equal(), __a) {}
......@@ -1205,11 +1310,7 @@ public:
12051310 pair<iterator, bool> insert(const value_type& __x)
12061311 {return __table_.__insert_unique(__x);}
12071312
1208 iterator insert(const_iterator __p, const value_type& __x) {
1209 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1210 "unordered_map::insert(const_iterator, const value_type&) called with an iterator not "
1211 "referring to this unordered_map");
1212 ((void)__p);
1313 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, const value_type& __x) {
12131314 return insert(__x).first;
12141315 }
12151316
......@@ -1217,6 +1318,16 @@ public:
12171318 _LIBCPP_INLINE_VISIBILITY
12181319 void insert(_InputIterator __first, _InputIterator __last);
12191320
1321#if _LIBCPP_STD_VER >= 23
1322 template <_ContainerCompatibleRange<value_type> _Range>
1323 _LIBCPP_HIDE_FROM_ABI
1324 void insert_range(_Range&& __range) {
1325 for (auto&& __element : __range) {
1326 __table_.__insert_unique(std::forward<decltype(__element)>(__element));
1327 }
1328 }
1329#endif
1330
12201331#ifndef _LIBCPP_CXX03_LANG
12211332 _LIBCPP_INLINE_VISIBILITY
12221333 void insert(initializer_list<value_type> __il)
......@@ -1226,11 +1337,7 @@ public:
12261337 pair<iterator, bool> insert(value_type&& __x)
12271338 {return __table_.__insert_unique(_VSTD::move(__x));}
12281339
1229 iterator insert(const_iterator __p, value_type&& __x) {
1230 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1231 "unordered_map::insert(const_iterator, const value_type&) called with an iterator not"
1232 " referring to this unordered_map");
1233 ((void)__p);
1340 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, value_type&& __x) {
12341341 return __table_.__insert_unique(_VSTD::move(__x)).first;
12351342 }
12361343
......@@ -1243,12 +1350,8 @@ public:
12431350 template <class _Pp,
12441351 class = __enable_if_t<is_constructible<value_type, _Pp>::value> >
12451352 _LIBCPP_INLINE_VISIBILITY
1246 iterator insert(const_iterator __p, _Pp&& __x)
1353 iterator insert(const_iterator, _Pp&& __x)
12471354 {
1248 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1249 "unordered_map::insert(const_iterator, value_type&&) called with an iterator not"
1250 " referring to this unordered_map");
1251 ((void)__p);
12521355 return insert(_VSTD::forward<_Pp>(__x)).first;
12531356 }
12541357
......@@ -1260,17 +1363,13 @@ public:
12601363
12611364 template <class... _Args>
12621365 _LIBCPP_INLINE_VISIBILITY
1263 iterator emplace_hint(const_iterator __p, _Args&&... __args) {
1264 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
1265 "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not"
1266 " referring to this unordered_map");
1267 ((void)__p);
1366 iterator emplace_hint(const_iterator, _Args&&... __args) {
12681367 return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
12691368 }
12701369
12711370#endif // _LIBCPP_CXX03_LANG
12721371
1273#if _LIBCPP_STD_VER > 14
1372#if _LIBCPP_STD_VER >= 17
12741373 template <class... _Args>
12751374 _LIBCPP_INLINE_VISIBILITY
12761375 pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args)
......@@ -1291,23 +1390,15 @@ public:
12911390
12921391 template <class... _Args>
12931392 _LIBCPP_INLINE_VISIBILITY
1294 iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args)
1393 iterator try_emplace(const_iterator, const key_type& __k, _Args&&... __args)
12951394 {
1296 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this,
1297 "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not"
1298 " referring to this unordered_map");
1299 ((void)__h);
13001395 return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first;
13011396 }
13021397
13031398 template <class... _Args>
13041399 _LIBCPP_INLINE_VISIBILITY
1305 iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args)
1400 iterator try_emplace(const_iterator, key_type&& __k, _Args&&... __args)
13061401 {
1307 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this,
1308 "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not"
1309 " referring to this unordered_map");
1310 ((void)__h);
13111402 return try_emplace(_VSTD::move(__k), _VSTD::forward<_Args>(__args)...).first;
13121403 }
13131404
......@@ -1339,7 +1430,6 @@ public:
13391430 _LIBCPP_INLINE_VISIBILITY
13401431 iterator insert_or_assign(const_iterator, const key_type& __k, _Vp&& __v)
13411432 {
1342 // FIXME: Add debug mode checking for the iterator input
13431433 return insert_or_assign(__k, _VSTD::forward<_Vp>(__v)).first;
13441434 }
13451435
......@@ -1347,10 +1437,9 @@ public:
13471437 _LIBCPP_INLINE_VISIBILITY
13481438 iterator insert_or_assign(const_iterator, key_type&& __k, _Vp&& __v)
13491439 {
1350 // FIXME: Add debug mode checking for the iterator input
13511440 return insert_or_assign(_VSTD::move(__k), _VSTD::forward<_Vp>(__v)).first;
13521441 }
1353#endif // _LIBCPP_STD_VER > 14
1442#endif // _LIBCPP_STD_VER >= 17
13541443
13551444 _LIBCPP_INLINE_VISIBILITY
13561445 iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);}
......@@ -1364,11 +1453,11 @@ public:
13641453 _LIBCPP_INLINE_VISIBILITY
13651454 void clear() _NOEXCEPT {__table_.clear();}
13661455
1367#if _LIBCPP_STD_VER > 14
1456#if _LIBCPP_STD_VER >= 17
13681457 _LIBCPP_INLINE_VISIBILITY
13691458 insert_return_type insert(node_type&& __nh)
13701459 {
1371 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1460 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
13721461 "node_type with incompatible allocator passed to unordered_map::insert()");
13731462 return __table_.template __node_handle_insert_unique<
13741463 node_type, insert_return_type>(_VSTD::move(__nh));
......@@ -1376,7 +1465,7 @@ public:
13761465 _LIBCPP_INLINE_VISIBILITY
13771466 iterator insert(const_iterator __hint, node_type&& __nh)
13781467 {
1379 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1468 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
13801469 "node_type with incompatible allocator passed to unordered_map::insert()");
13811470 return __table_.template __node_handle_insert_unique<node_type>(
13821471 __hint.__i_, _VSTD::move(__nh));
......@@ -1397,32 +1486,32 @@ public:
13971486 _LIBCPP_INLINE_VISIBILITY
13981487 void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
13991488 {
1400 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1401 "merging container with incompatible allocator");
1489 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1490 "merging container with incompatible allocator");
14021491 return __table_.__node_handle_merge_unique(__source.__table_);
14031492 }
14041493 template <class _H2, class _P2>
14051494 _LIBCPP_INLINE_VISIBILITY
14061495 void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
14071496 {
1408 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1409 "merging container with incompatible allocator");
1497 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1498 "merging container with incompatible allocator");
14101499 return __table_.__node_handle_merge_unique(__source.__table_);
14111500 }
14121501 template <class _H2, class _P2>
14131502 _LIBCPP_INLINE_VISIBILITY
14141503 void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
14151504 {
1416 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1417 "merging container with incompatible allocator");
1505 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1506 "merging container with incompatible allocator");
14181507 return __table_.__node_handle_merge_unique(__source.__table_);
14191508 }
14201509 template <class _H2, class _P2>
14211510 _LIBCPP_INLINE_VISIBILITY
14221511 void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
14231512 {
1424 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1425 "merging container with incompatible allocator");
1513 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1514 "merging container with incompatible allocator");
14261515 return __table_.__node_handle_merge_unique(__source.__table_);
14271516 }
14281517#endif
......@@ -1443,31 +1532,31 @@ public:
14431532 iterator find(const key_type& __k) {return __table_.find(__k);}
14441533 _LIBCPP_INLINE_VISIBILITY
14451534 const_iterator find(const key_type& __k) const {return __table_.find(__k);}
1446#if _LIBCPP_STD_VER > 17
1535#if _LIBCPP_STD_VER >= 20
14471536 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
14481537 _LIBCPP_INLINE_VISIBILITY
14491538 iterator find(const _K2& __k) {return __table_.find(__k);}
14501539 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
14511540 _LIBCPP_INLINE_VISIBILITY
14521541 const_iterator find(const _K2& __k) const {return __table_.find(__k);}
1453#endif // _LIBCPP_STD_VER > 17
1542#endif // _LIBCPP_STD_VER >= 20
14541543
14551544 _LIBCPP_INLINE_VISIBILITY
14561545 size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
1457#if _LIBCPP_STD_VER > 17
1546#if _LIBCPP_STD_VER >= 20
14581547 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
14591548 _LIBCPP_INLINE_VISIBILITY
14601549 size_type count(const _K2& __k) const {return __table_.__count_unique(__k);}
1461#endif // _LIBCPP_STD_VER > 17
1550#endif // _LIBCPP_STD_VER >= 20
14621551
1463#if _LIBCPP_STD_VER > 17
1552#if _LIBCPP_STD_VER >= 20
14641553 _LIBCPP_INLINE_VISIBILITY
14651554 bool contains(const key_type& __k) const {return find(__k) != end();}
14661555
14671556 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
14681557 _LIBCPP_INLINE_VISIBILITY
14691558 bool contains(const _K2& __k) const {return find(__k) != end();}
1470#endif // _LIBCPP_STD_VER > 17
1559#endif // _LIBCPP_STD_VER >= 20
14711560
14721561 _LIBCPP_INLINE_VISIBILITY
14731562 pair<iterator, iterator> equal_range(const key_type& __k)
......@@ -1475,7 +1564,7 @@ public:
14751564 _LIBCPP_INLINE_VISIBILITY
14761565 pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
14771566 {return __table_.__equal_range_unique(__k);}
1478#if _LIBCPP_STD_VER > 17
1567#if _LIBCPP_STD_VER >= 20
14791568 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
14801569 _LIBCPP_INLINE_VISIBILITY
14811570 pair<iterator, iterator> equal_range(const _K2& __k)
......@@ -1484,15 +1573,15 @@ public:
14841573 _LIBCPP_INLINE_VISIBILITY
14851574 pair<const_iterator, const_iterator> equal_range(const _K2& __k) const
14861575 {return __table_.__equal_range_unique(__k);}
1487#endif // _LIBCPP_STD_VER > 17
1576#endif // _LIBCPP_STD_VER >= 20
14881577
1489 mapped_type& operator[](const key_type& __k);
1578 _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
14901579#ifndef _LIBCPP_CXX03_LANG
1491 mapped_type& operator[](key_type&& __k);
1580 _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k);
14921581#endif
14931582
1494 mapped_type& at(const key_type& __k);
1495 const mapped_type& at(const key_type& __k) const;
1583 _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k);
1584 _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;
14961585
14971586 _LIBCPP_INLINE_VISIBILITY
14981587 size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
......@@ -1529,23 +1618,10 @@ public:
15291618 _LIBCPP_INLINE_VISIBILITY
15301619 void reserve(size_type __n) {__table_.__reserve_unique(__n);}
15311620
1532#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1533
1534 bool __dereferenceable(const const_iterator* __i) const
1535 {return __table_.__dereferenceable(_VSTD::addressof(__i->__i_));}
1536 bool __decrementable(const const_iterator* __i) const
1537 {return __table_.__decrementable(_VSTD::addressof(__i->__i_));}
1538 bool __addable(const const_iterator* __i, ptrdiff_t __n) const
1539 {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);}
1540 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
1541 {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);}
1542
1543#endif // _LIBCPP_ENABLE_DEBUG_MODE
1544
15451621private:
15461622
15471623#ifdef _LIBCPP_CXX03_LANG
1548 __node_holder __construct_node_with_key(const key_type& __k);
1624 _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_with_key(const key_type& __k);
15491625#endif
15501626};
15511627
......@@ -1554,7 +1630,7 @@ template<class _InputIterator,
15541630 class _Hash = hash<__iter_key_type<_InputIterator>>,
15551631 class _Pred = equal_to<__iter_key_type<_InputIterator>>,
15561632 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
1557 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1633 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
15581634 class = enable_if_t<!__is_allocator<_Hash>::value>,
15591635 class = enable_if_t<!is_integral<_Hash>::value>,
15601636 class = enable_if_t<!__is_allocator<_Pred>::value>,
......@@ -1563,6 +1639,20 @@ unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocat
15631639 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
15641640 -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Hash, _Pred, _Allocator>;
15651641
1642#if _LIBCPP_STD_VER >= 23
1643template <ranges::input_range _Range,
1644 class _Hash = hash<__range_key_type<_Range>>,
1645 class _Pred = equal_to<__range_key_type<_Range>>,
1646 class _Allocator = allocator<__range_to_alloc_type<_Range>>,
1647 class = enable_if_t<!__is_allocator<_Hash>::value>,
1648 class = enable_if_t<!is_integral<_Hash>::value>,
1649 class = enable_if_t<!__is_allocator<_Pred>::value>,
1650 class = enable_if_t<__is_allocator<_Allocator>::value>>
1651unordered_map(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0,
1652 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1653 -> unordered_map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Hash, _Pred, _Allocator>; // C++23
1654#endif
1655
15661656template<class _Key, class _Tp, class _Hash = hash<remove_const_t<_Key>>,
15671657 class _Pred = equal_to<remove_const_t<_Key>>,
15681658 class _Allocator = allocator<pair<const _Key, _Tp>>,
......@@ -1575,21 +1665,21 @@ unordered_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allo
15751665 -> unordered_map<remove_const_t<_Key>, _Tp, _Hash, _Pred, _Allocator>;
15761666
15771667template<class _InputIterator, class _Allocator,
1578 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1668 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
15791669 class = enable_if_t<__is_allocator<_Allocator>::value>>
15801670unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator)
15811671 -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
15821672 hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>;
15831673
15841674template<class _InputIterator, class _Allocator,
1585 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1675 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
15861676 class = enable_if_t<__is_allocator<_Allocator>::value>>
15871677unordered_map(_InputIterator, _InputIterator, _Allocator)
15881678 -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
15891679 hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>;
15901680
15911681template<class _InputIterator, class _Hash, class _Allocator,
1592 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1682 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
15931683 class = enable_if_t<!__is_allocator<_Hash>::value>,
15941684 class = enable_if_t<!is_integral<_Hash>::value>,
15951685 class = enable_if_t<__is_allocator<_Allocator>::value>>
......@@ -1597,6 +1687,30 @@ unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocat
15971687 -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
15981688 _Hash, equal_to<__iter_key_type<_InputIterator>>, _Allocator>;
15991689
1690#if _LIBCPP_STD_VER >= 23
1691
1692template <ranges::input_range _Range, class _Allocator,
1693 class = enable_if_t<__is_allocator<_Allocator>::value>>
1694unordered_map(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator)
1695 -> unordered_map<__range_key_type<_Range>, __range_mapped_type<_Range>, hash<__range_key_type<_Range>>,
1696 equal_to<__range_key_type<_Range>>, _Allocator>;
1697
1698template <ranges::input_range _Range, class _Allocator,
1699 class = enable_if_t<__is_allocator<_Allocator>::value>>
1700unordered_map(from_range_t, _Range&&, _Allocator)
1701 -> unordered_map<__range_key_type<_Range>, __range_mapped_type<_Range>, hash<__range_key_type<_Range>>,
1702 equal_to<__range_key_type<_Range>>, _Allocator>;
1703
1704template <ranges::input_range _Range, class _Hash, class _Allocator,
1705 class = enable_if_t<!__is_allocator<_Hash>::value>,
1706 class = enable_if_t<!is_integral<_Hash>::value>,
1707 class = enable_if_t<__is_allocator<_Allocator>::value>>
1708unordered_map(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
1709 -> unordered_map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Hash,
1710 equal_to<__range_key_type<_Range>>, _Allocator>;
1711
1712#endif
1713
16001714template<class _Key, class _Tp, class _Allocator,
16011715 class = enable_if_t<__is_allocator<_Allocator>::value>>
16021716unordered_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Allocator)
......@@ -1625,7 +1739,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
16251739 size_type __n, const hasher& __hf, const key_equal& __eql)
16261740 : __table_(__hf, __eql)
16271741{
1628 _VSTD::__debug_db_insert_c(this);
16291742 __table_.__rehash_unique(__n);
16301743}
16311744
......@@ -1635,7 +1748,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
16351748 const allocator_type& __a)
16361749 : __table_(__hf, __eql, typename __table::allocator_type(__a))
16371750{
1638 _VSTD::__debug_db_insert_c(this);
16391751 __table_.__rehash_unique(__n);
16401752}
16411753
......@@ -1645,7 +1757,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
16451757 const allocator_type& __a)
16461758 : __table_(typename __table::allocator_type(__a))
16471759{
1648 _VSTD::__debug_db_insert_c(this);
16491760}
16501761
16511762template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
......@@ -1653,7 +1764,6 @@ template <class _InputIterator>
16531764unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
16541765 _InputIterator __first, _InputIterator __last)
16551766{
1656 _VSTD::__debug_db_insert_c(this);
16571767 insert(__first, __last);
16581768}
16591769
......@@ -1664,7 +1774,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
16641774 const hasher& __hf, const key_equal& __eql)
16651775 : __table_(__hf, __eql)
16661776{
1667 _VSTD::__debug_db_insert_c(this);
16681777 __table_.__rehash_unique(__n);
16691778 insert(__first, __last);
16701779}
......@@ -1676,7 +1785,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
16761785 const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
16771786 : __table_(__hf, __eql, typename __table::allocator_type(__a))
16781787{
1679 _VSTD::__debug_db_insert_c(this);
16801788 __table_.__rehash_unique(__n);
16811789 insert(__first, __last);
16821790}
......@@ -1686,7 +1794,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
16861794 const unordered_map& __u)
16871795 : __table_(__u.__table_)
16881796{
1689 _VSTD::__debug_db_insert_c(this);
16901797 __table_.__rehash_unique(__u.bucket_count());
16911798 insert(__u.begin(), __u.end());
16921799}
......@@ -1696,7 +1803,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
16961803 const unordered_map& __u, const allocator_type& __a)
16971804 : __table_(__u.__table_, typename __table::allocator_type(__a))
16981805{
1699 _VSTD::__debug_db_insert_c(this);
17001806 __table_.__rehash_unique(__u.bucket_count());
17011807 insert(__u.begin(), __u.end());
17021808}
......@@ -1710,8 +1816,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
17101816 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
17111817 : __table_(_VSTD::move(__u.__table_))
17121818{
1713 _VSTD::__debug_db_insert_c(this);
1714 std::__debug_db_swap(this, std::addressof(__u));
17151819}
17161820
17171821template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
......@@ -1719,7 +1823,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
17191823 unordered_map&& __u, const allocator_type& __a)
17201824 : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a))
17211825{
1722 _VSTD::__debug_db_insert_c(this);
17231826 if (__a != __u.get_allocator())
17241827 {
17251828 iterator __i = __u.begin();
......@@ -1728,15 +1831,12 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
17281831 __u.__table_.remove((__i++).__i_)->__value_.__move());
17291832 }
17301833 }
1731 else
1732 std::__debug_db_swap(this, std::addressof(__u));
17331834}
17341835
17351836template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
17361837unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
17371838 initializer_list<value_type> __il)
17381839{
1739 _VSTD::__debug_db_insert_c(this);
17401840 insert(__il.begin(), __il.end());
17411841}
17421842
......@@ -1746,7 +1846,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
17461846 const key_equal& __eql)
17471847 : __table_(__hf, __eql)
17481848{
1749 _VSTD::__debug_db_insert_c(this);
17501849 __table_.__rehash_unique(__n);
17511850 insert(__il.begin(), __il.end());
17521851}
......@@ -1757,7 +1856,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
17571856 const key_equal& __eql, const allocator_type& __a)
17581857 : __table_(__hf, __eql, typename __table::allocator_type(__a))
17591858{
1760 _VSTD::__debug_db_insert_c(this);
17611859 __table_.__rehash_unique(__n);
17621860 insert(__il.begin(), __il.end());
17631861}
......@@ -1874,7 +1972,7 @@ swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
18741972 __x.swap(__y);
18751973}
18761974
1877#if _LIBCPP_STD_VER > 17
1975#if _LIBCPP_STD_VER >= 20
18781976template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
18791977 class _Predicate>
18801978inline _LIBCPP_INLINE_VISIBILITY
......@@ -1904,6 +2002,8 @@ operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
19042002 return true;
19052003}
19062004
2005#if _LIBCPP_STD_VER <= 17
2006
19072007template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
19082008inline _LIBCPP_INLINE_VISIBILITY
19092009bool
......@@ -1913,6 +2013,8 @@ operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
19132013 return !(__x == __y);
19142014}
19152015
2016#endif
2017
19162018template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
19172019 class _Alloc = allocator<pair<const _Key, _Tp> > >
19182020class _LIBCPP_TEMPLATE_VIS unordered_multimap
......@@ -1928,7 +2030,7 @@ public:
19282030 typedef value_type& reference;
19292031 typedef const value_type& const_reference;
19302032 static_assert((is_same<value_type, typename allocator_type::value_type>::value),
1931 "Invalid allocator::value_type");
2033 "Allocator::value_type must be same type as value_type");
19322034
19332035private:
19342036 typedef __hash_value_type<key_type, mapped_type> __value_type;
......@@ -1967,7 +2069,7 @@ private:
19672069 typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;
19682070 typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;
19692071
1970#if _LIBCPP_STD_VER > 14
2072#if _LIBCPP_STD_VER >= 17
19712073 typedef __map_node_handle<__node, allocator_type> node_type;
19722074#endif
19732075
......@@ -1980,42 +2082,56 @@ private:
19802082 unordered_multimap()
19812083 _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
19822084 {
1983 _VSTD::__debug_db_insert_c(this);
19842085 }
1985 explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(),
2086 explicit _LIBCPP_HIDE_FROM_ABI unordered_multimap(size_type __n, const hasher& __hf = hasher(),
19862087 const key_equal& __eql = key_equal());
1987 unordered_multimap(size_type __n, const hasher& __hf,
2088 _LIBCPP_HIDE_FROM_ABI unordered_multimap(size_type __n, const hasher& __hf,
19882089 const key_equal& __eql,
19892090 const allocator_type& __a);
19902091 template <class _InputIterator>
1991 unordered_multimap(_InputIterator __first, _InputIterator __last);
2092 _LIBCPP_HIDE_FROM_ABI unordered_multimap(_InputIterator __first, _InputIterator __last);
19922093 template <class _InputIterator>
1993 unordered_multimap(_InputIterator __first, _InputIterator __last,
2094 _LIBCPP_HIDE_FROM_ABI unordered_multimap(_InputIterator __first, _InputIterator __last,
19942095 size_type __n, const hasher& __hf = hasher(),
19952096 const key_equal& __eql = key_equal());
19962097 template <class _InputIterator>
1997 unordered_multimap(_InputIterator __first, _InputIterator __last,
2098 _LIBCPP_HIDE_FROM_ABI unordered_multimap(_InputIterator __first, _InputIterator __last,
19982099 size_type __n, const hasher& __hf,
19992100 const key_equal& __eql,
20002101 const allocator_type& __a);
2102
2103#if _LIBCPP_STD_VER >= 23
2104 template <_ContainerCompatibleRange<value_type> _Range>
2105 _LIBCPP_HIDE_FROM_ABI
2106 unordered_multimap(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0,
2107 const hasher& __hf = hasher(), const key_equal& __eql = key_equal(),
2108 const allocator_type& __a = allocator_type())
2109 : __table_(__hf, __eql, typename __table::allocator_type(__a)) {
2110 if (__n > 0) {
2111 __table_.__rehash_multi(__n);
2112 }
2113 insert_range(std::forward<_Range>(__range));
2114 }
2115#endif
2116
20012117 _LIBCPP_INLINE_VISIBILITY
20022118 explicit unordered_multimap(const allocator_type& __a);
2003 unordered_multimap(const unordered_multimap& __u);
2004 unordered_multimap(const unordered_multimap& __u, const allocator_type& __a);
2119 _LIBCPP_HIDE_FROM_ABI unordered_multimap(const unordered_multimap& __u);
2120 _LIBCPP_HIDE_FROM_ABI unordered_multimap(const unordered_multimap& __u, const allocator_type& __a);
20052121#ifndef _LIBCPP_CXX03_LANG
20062122 _LIBCPP_INLINE_VISIBILITY
20072123 unordered_multimap(unordered_multimap&& __u)
20082124 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
2009 unordered_multimap(unordered_multimap&& __u, const allocator_type& __a);
2010 unordered_multimap(initializer_list<value_type> __il);
2011 unordered_multimap(initializer_list<value_type> __il, size_type __n,
2125 _LIBCPP_HIDE_FROM_ABI unordered_multimap(unordered_multimap&& __u, const allocator_type& __a);
2126 _LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list<value_type> __il);
2127 _LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list<value_type> __il, size_type __n,
20122128 const hasher& __hf = hasher(),
20132129 const key_equal& __eql = key_equal());
2014 unordered_multimap(initializer_list<value_type> __il, size_type __n,
2130 _LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list<value_type> __il, size_type __n,
20152131 const hasher& __hf, const key_equal& __eql,
20162132 const allocator_type& __a);
20172133#endif // _LIBCPP_CXX03_LANG
2018#if _LIBCPP_STD_VER > 11
2134#if _LIBCPP_STD_VER >= 14
20192135 _LIBCPP_INLINE_VISIBILITY
20202136 unordered_multimap(size_type __n, const allocator_type& __a)
20212137 : unordered_multimap(__n, hasher(), key_equal(), __a) {}
......@@ -2031,6 +2147,19 @@ private:
20312147 unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf,
20322148 const allocator_type& __a)
20332149 : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) {}
2150
2151#if _LIBCPP_STD_VER >= 23
2152 template <_ContainerCompatibleRange<value_type> _Range>
2153 _LIBCPP_HIDE_FROM_ABI
2154 unordered_multimap(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a)
2155 : unordered_multimap(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {}
2156
2157 template <_ContainerCompatibleRange<value_type> _Range>
2158 _LIBCPP_HIDE_FROM_ABI
2159 unordered_multimap(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a)
2160 : unordered_multimap(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {}
2161#endif
2162
20342163 _LIBCPP_INLINE_VISIBILITY
20352164 unordered_multimap(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
20362165 : unordered_multimap(__il, __n, hasher(), key_equal(), __a) {}
......@@ -2104,6 +2233,16 @@ private:
21042233 _LIBCPP_INLINE_VISIBILITY
21052234 void insert(_InputIterator __first, _InputIterator __last);
21062235
2236#if _LIBCPP_STD_VER >= 23
2237 template <_ContainerCompatibleRange<value_type> _Range>
2238 _LIBCPP_HIDE_FROM_ABI
2239 void insert_range(_Range&& __range) {
2240 for (auto&& __element : __range) {
2241 __table_.__insert_multi(std::forward<decltype(__element)>(__element));
2242 }
2243 }
2244#endif
2245
21072246#ifndef _LIBCPP_CXX03_LANG
21082247 _LIBCPP_INLINE_VISIBILITY
21092248 void insert(initializer_list<value_type> __il)
......@@ -2128,12 +2267,12 @@ private:
21282267 {return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));}
21292268
21302269 template <class... _Args>
2131 iterator emplace(_Args&&... __args) {
2270 _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) {
21322271 return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...);
21332272 }
21342273
21352274 template <class... _Args>
2136 iterator emplace_hint(const_iterator __p, _Args&&... __args) {
2275 _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {
21372276 return __table_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...);
21382277 }
21392278#endif // _LIBCPP_CXX03_LANG
......@@ -2151,11 +2290,11 @@ private:
21512290 _LIBCPP_INLINE_VISIBILITY
21522291 void clear() _NOEXCEPT {__table_.clear();}
21532292
2154#if _LIBCPP_STD_VER > 14
2293#if _LIBCPP_STD_VER >= 17
21552294 _LIBCPP_INLINE_VISIBILITY
21562295 iterator insert(node_type&& __nh)
21572296 {
2158 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
2297 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
21592298 "node_type with incompatible allocator passed to unordered_multimap::insert()");
21602299 return __table_.template __node_handle_insert_multi<node_type>(
21612300 _VSTD::move(__nh));
......@@ -2163,7 +2302,7 @@ private:
21632302 _LIBCPP_INLINE_VISIBILITY
21642303 iterator insert(const_iterator __hint, node_type&& __nh)
21652304 {
2166 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
2305 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
21672306 "node_type with incompatible allocator passed to unordered_multimap::insert()");
21682307 return __table_.template __node_handle_insert_multi<node_type>(
21692308 __hint.__i_, _VSTD::move(__nh));
......@@ -2184,32 +2323,32 @@ private:
21842323 _LIBCPP_INLINE_VISIBILITY
21852324 void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
21862325 {
2187 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
2188 "merging container with incompatible allocator");
2326 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
2327 "merging container with incompatible allocator");
21892328 return __table_.__node_handle_merge_multi(__source.__table_);
21902329 }
21912330 template <class _H2, class _P2>
21922331 _LIBCPP_INLINE_VISIBILITY
21932332 void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
21942333 {
2195 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
2196 "merging container with incompatible allocator");
2334 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
2335 "merging container with incompatible allocator");
21972336 return __table_.__node_handle_merge_multi(__source.__table_);
21982337 }
21992338 template <class _H2, class _P2>
22002339 _LIBCPP_INLINE_VISIBILITY
22012340 void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
22022341 {
2203 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
2204 "merging container with incompatible allocator");
2342 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
2343 "merging container with incompatible allocator");
22052344 return __table_.__node_handle_merge_multi(__source.__table_);
22062345 }
22072346 template <class _H2, class _P2>
22082347 _LIBCPP_INLINE_VISIBILITY
22092348 void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
22102349 {
2211 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
2212 "merging container with incompatible allocator");
2350 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
2351 "merging container with incompatible allocator");
22132352 return __table_.__node_handle_merge_multi(__source.__table_);
22142353 }
22152354#endif
......@@ -2230,31 +2369,31 @@ private:
22302369 iterator find(const key_type& __k) {return __table_.find(__k);}
22312370 _LIBCPP_INLINE_VISIBILITY
22322371 const_iterator find(const key_type& __k) const {return __table_.find(__k);}
2233#if _LIBCPP_STD_VER > 17
2372#if _LIBCPP_STD_VER >= 20
22342373 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
22352374 _LIBCPP_INLINE_VISIBILITY
22362375 iterator find(const _K2& __k) {return __table_.find(__k);}
22372376 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
22382377 _LIBCPP_INLINE_VISIBILITY
22392378 const_iterator find(const _K2& __k) const {return __table_.find(__k);}
2240#endif // _LIBCPP_STD_VER > 17
2379#endif // _LIBCPP_STD_VER >= 20
22412380
22422381 _LIBCPP_INLINE_VISIBILITY
22432382 size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
2244#if _LIBCPP_STD_VER > 17
2383#if _LIBCPP_STD_VER >= 20
22452384 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
22462385 _LIBCPP_INLINE_VISIBILITY
22472386 size_type count(const _K2& __k) const {return __table_.__count_multi(__k);}
2248#endif // _LIBCPP_STD_VER > 17
2387#endif // _LIBCPP_STD_VER >= 20
22492388
2250#if _LIBCPP_STD_VER > 17
2389#if _LIBCPP_STD_VER >= 20
22512390 _LIBCPP_INLINE_VISIBILITY
22522391 bool contains(const key_type& __k) const {return find(__k) != end();}
22532392
22542393 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
22552394 _LIBCPP_INLINE_VISIBILITY
22562395 bool contains(const _K2& __k) const {return find(__k) != end();}
2257#endif // _LIBCPP_STD_VER > 17
2396#endif // _LIBCPP_STD_VER >= 20
22582397
22592398 _LIBCPP_INLINE_VISIBILITY
22602399 pair<iterator, iterator> equal_range(const key_type& __k)
......@@ -2262,7 +2401,7 @@ private:
22622401 _LIBCPP_INLINE_VISIBILITY
22632402 pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
22642403 {return __table_.__equal_range_multi(__k);}
2265#if _LIBCPP_STD_VER > 17
2404#if _LIBCPP_STD_VER >= 20
22662405 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
22672406 _LIBCPP_INLINE_VISIBILITY
22682407 pair<iterator, iterator> equal_range(const _K2& __k)
......@@ -2271,7 +2410,7 @@ private:
22712410 _LIBCPP_INLINE_VISIBILITY
22722411 pair<const_iterator, const_iterator> equal_range(const _K2& __k) const
22732412 {return __table_.__equal_range_multi(__k);}
2274#endif // _LIBCPP_STD_VER > 17
2413#endif // _LIBCPP_STD_VER >= 20
22752414
22762415 _LIBCPP_INLINE_VISIBILITY
22772416 size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
......@@ -2308,21 +2447,6 @@ private:
23082447 void rehash(size_type __n) {__table_.__rehash_multi(__n);}
23092448 _LIBCPP_INLINE_VISIBILITY
23102449 void reserve(size_type __n) {__table_.__reserve_multi(__n);}
2311
2312#ifdef _LIBCPP_ENABLE_DEBUG_MODE
2313
2314 bool __dereferenceable(const const_iterator* __i) const
2315 {return __table_.__dereferenceable(_VSTD::addressof(__i->__i_));}
2316 bool __decrementable(const const_iterator* __i) const
2317 {return __table_.__decrementable(_VSTD::addressof(__i->__i_));}
2318 bool __addable(const const_iterator* __i, ptrdiff_t __n) const
2319 {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);}
2320 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
2321 {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);}
2322
2323#endif // _LIBCPP_ENABLE_DEBUG_MODE
2324
2325
23262450};
23272451
23282452#if _LIBCPP_STD_VER >= 17
......@@ -2330,7 +2454,7 @@ template<class _InputIterator,
23302454 class _Hash = hash<__iter_key_type<_InputIterator>>,
23312455 class _Pred = equal_to<__iter_key_type<_InputIterator>>,
23322456 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
2333 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
2457 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
23342458 class = enable_if_t<!__is_allocator<_Hash>::value>,
23352459 class = enable_if_t<!is_integral<_Hash>::value>,
23362460 class = enable_if_t<!__is_allocator<_Pred>::value>,
......@@ -2339,6 +2463,20 @@ unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Al
23392463 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
23402464 -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Hash, _Pred, _Allocator>;
23412465
2466#if _LIBCPP_STD_VER >= 23
2467template <ranges::input_range _Range,
2468 class _Hash = hash<__range_key_type<_Range>>,
2469 class _Pred = equal_to<__range_key_type<_Range>>,
2470 class _Allocator = allocator<__range_to_alloc_type<_Range>>,
2471 class = enable_if_t<!__is_allocator<_Hash>::value>,
2472 class = enable_if_t<!is_integral<_Hash>::value>,
2473 class = enable_if_t<!__is_allocator<_Pred>::value>,
2474 class = enable_if_t<__is_allocator<_Allocator>::value>>
2475unordered_multimap(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0,
2476 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
2477 -> unordered_multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Hash, _Pred, _Allocator>;
2478#endif
2479
23422480template<class _Key, class _Tp, class _Hash = hash<remove_const_t<_Key>>,
23432481 class _Pred = equal_to<remove_const_t<_Key>>,
23442482 class _Allocator = allocator<pair<const _Key, _Tp>>,
......@@ -2351,21 +2489,21 @@ unordered_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<
23512489 -> unordered_multimap<remove_const_t<_Key>, _Tp, _Hash, _Pred, _Allocator>;
23522490
23532491template<class _InputIterator, class _Allocator,
2354 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
2492 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
23552493 class = enable_if_t<__is_allocator<_Allocator>::value>>
23562494unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator)
23572495 -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
23582496 hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>;
23592497
23602498template<class _InputIterator, class _Allocator,
2361 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
2499 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
23622500 class = enable_if_t<__is_allocator<_Allocator>::value>>
23632501unordered_multimap(_InputIterator, _InputIterator, _Allocator)
23642502 -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
23652503 hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>;
23662504
23672505template<class _InputIterator, class _Hash, class _Allocator,
2368 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
2506 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
23692507 class = enable_if_t<!__is_allocator<_Hash>::value>,
23702508 class = enable_if_t<!is_integral<_Hash>::value>,
23712509 class = enable_if_t<__is_allocator<_Allocator>::value>>
......@@ -2373,6 +2511,30 @@ unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Al
23732511 -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
23742512 _Hash, equal_to<__iter_key_type<_InputIterator>>, _Allocator>;
23752513
2514#if _LIBCPP_STD_VER >= 23
2515
2516template <ranges::input_range _Range, class _Allocator,
2517 class = enable_if_t<__is_allocator<_Allocator>::value>>
2518unordered_multimap(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator)
2519 -> unordered_multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, hash<__range_key_type<_Range>>,
2520 equal_to<__range_key_type<_Range>>, _Allocator>;
2521
2522template <ranges::input_range _Range, class _Allocator,
2523 class = enable_if_t<__is_allocator<_Allocator>::value>>
2524unordered_multimap(from_range_t, _Range&&, _Allocator)
2525 -> unordered_multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, hash<__range_key_type<_Range>>,
2526 equal_to<__range_key_type<_Range>>, _Allocator>;
2527
2528template <ranges::input_range _Range, class _Hash, class _Allocator,
2529 class = enable_if_t<!__is_allocator<_Hash>::value>,
2530 class = enable_if_t<!is_integral<_Hash>::value>,
2531 class = enable_if_t<__is_allocator<_Allocator>::value>>
2532unordered_multimap(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
2533 -> unordered_multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Hash,
2534 equal_to<__range_key_type<_Range>>, _Allocator>;
2535
2536#endif
2537
23762538template<class _Key, class _Tp, class _Allocator,
23772539 class = enable_if_t<__is_allocator<_Allocator>::value>>
23782540unordered_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Allocator)
......@@ -2401,7 +2563,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
24012563 size_type __n, const hasher& __hf, const key_equal& __eql)
24022564 : __table_(__hf, __eql)
24032565{
2404 _VSTD::__debug_db_insert_c(this);
24052566 __table_.__rehash_multi(__n);
24062567}
24072568
......@@ -2411,7 +2572,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
24112572 const allocator_type& __a)
24122573 : __table_(__hf, __eql, typename __table::allocator_type(__a))
24132574{
2414 _VSTD::__debug_db_insert_c(this);
24152575 __table_.__rehash_multi(__n);
24162576}
24172577
......@@ -2420,7 +2580,6 @@ template <class _InputIterator>
24202580unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
24212581 _InputIterator __first, _InputIterator __last)
24222582{
2423 _VSTD::__debug_db_insert_c(this);
24242583 insert(__first, __last);
24252584}
24262585
......@@ -2431,7 +2590,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
24312590 const hasher& __hf, const key_equal& __eql)
24322591 : __table_(__hf, __eql)
24332592{
2434 _VSTD::__debug_db_insert_c(this);
24352593 __table_.__rehash_multi(__n);
24362594 insert(__first, __last);
24372595}
......@@ -2443,7 +2601,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
24432601 const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
24442602 : __table_(__hf, __eql, typename __table::allocator_type(__a))
24452603{
2446 _VSTD::__debug_db_insert_c(this);
24472604 __table_.__rehash_multi(__n);
24482605 insert(__first, __last);
24492606}
......@@ -2454,7 +2611,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
24542611 const allocator_type& __a)
24552612 : __table_(typename __table::allocator_type(__a))
24562613{
2457 _VSTD::__debug_db_insert_c(this);
24582614}
24592615
24602616template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
......@@ -2462,7 +2618,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
24622618 const unordered_multimap& __u)
24632619 : __table_(__u.__table_)
24642620{
2465 _VSTD::__debug_db_insert_c(this);
24662621 __table_.__rehash_multi(__u.bucket_count());
24672622 insert(__u.begin(), __u.end());
24682623}
......@@ -2472,7 +2627,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
24722627 const unordered_multimap& __u, const allocator_type& __a)
24732628 : __table_(__u.__table_, typename __table::allocator_type(__a))
24742629{
2475 _VSTD::__debug_db_insert_c(this);
24762630 __table_.__rehash_multi(__u.bucket_count());
24772631 insert(__u.begin(), __u.end());
24782632}
......@@ -2486,8 +2640,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
24862640 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
24872641 : __table_(_VSTD::move(__u.__table_))
24882642{
2489 _VSTD::__debug_db_insert_c(this);
2490 std::__debug_db_swap(this, std::addressof(__u));
24912643}
24922644
24932645template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
......@@ -2495,7 +2647,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
24952647 unordered_multimap&& __u, const allocator_type& __a)
24962648 : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a))
24972649{
2498 _VSTD::__debug_db_insert_c(this);
24992650 if (__a != __u.get_allocator())
25002651 {
25012652 iterator __i = __u.begin();
......@@ -2505,15 +2656,12 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
25052656 __u.__table_.remove((__i++).__i_)->__value_.__move());
25062657 }
25072658 }
2508 else
2509 std::__debug_db_swap(this, std::addressof(__u));
25102659}
25112660
25122661template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
25132662unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
25142663 initializer_list<value_type> __il)
25152664{
2516 _VSTD::__debug_db_insert_c(this);
25172665 insert(__il.begin(), __il.end());
25182666}
25192667
......@@ -2523,7 +2671,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
25232671 const key_equal& __eql)
25242672 : __table_(__hf, __eql)
25252673{
2526 _VSTD::__debug_db_insert_c(this);
25272674 __table_.__rehash_multi(__n);
25282675 insert(__il.begin(), __il.end());
25292676}
......@@ -2534,7 +2681,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
25342681 const key_equal& __eql, const allocator_type& __a)
25352682 : __table_(__hf, __eql, typename __table::allocator_type(__a))
25362683{
2537 _VSTD::__debug_db_insert_c(this);
25382684 __table_.__rehash_multi(__n);
25392685 insert(__il.begin(), __il.end());
25402686}
......@@ -2584,7 +2730,7 @@ swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
25842730 __x.swap(__y);
25852731}
25862732
2587#if _LIBCPP_STD_VER > 17
2733#if _LIBCPP_STD_VER >= 20
25882734template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
25892735 class _Predicate>
25902736inline _LIBCPP_INLINE_VISIBILITY
......@@ -2618,6 +2764,8 @@ operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
26182764 return true;
26192765}
26202766
2767#if _LIBCPP_STD_VER <= 17
2768
26212769template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
26222770inline _LIBCPP_INLINE_VISIBILITY
26232771bool
......@@ -2627,17 +2775,19 @@ operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
26272775 return !(__x == __y);
26282776}
26292777
2778#endif
2779
26302780_LIBCPP_END_NAMESPACE_STD
26312781
2632#if _LIBCPP_STD_VER > 14
2782#if _LIBCPP_STD_VER >= 17
26332783_LIBCPP_BEGIN_NAMESPACE_STD
26342784namespace pmr {
26352785template <class _KeyT, class _ValueT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>>
2636using unordered_map =
2786using unordered_map _LIBCPP_AVAILABILITY_PMR =
26372787 std::unordered_map<_KeyT, _ValueT, _HashT, _PredT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
26382788
26392789template <class _KeyT, class _ValueT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>>
2640using unordered_multimap =
2790using unordered_multimap _LIBCPP_AVAILABILITY_PMR =
26412791 std::unordered_multimap<_KeyT, _ValueT, _HashT, _PredT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
26422792} // namespace pmr
26432793_LIBCPP_END_NAMESPACE_STD
......@@ -2647,7 +2797,9 @@ _LIBCPP_END_NAMESPACE_STD
26472797# include <algorithm>
26482798# include <bit>
26492799# include <concepts>
2800# include <cstdlib>
26502801# include <iterator>
2802# include <type_traits>
26512803#endif
26522804
26532805#endif // _LIBCPP_UNORDERED_MAP
lib/libcxx/include/unordered_set+321-163
......@@ -58,6 +58,10 @@ public:
5858 size_type n = 0, const hasher& hf = hasher(),
5959 const key_equal& eql = key_equal(),
6060 const allocator_type& a = allocator_type());
61 template<container-compatible-range<value_type> R>
62 unordered_set(from_range_t, R&& rg, size_type n = see below,
63 const hasher& hf = hasher(), const key_equal& eql = key_equal(),
64 const allocator_type& a = allocator_type()); // C++23
6165 explicit unordered_set(const allocator_type&);
6266 unordered_set(const unordered_set&);
6367 unordered_set(const unordered_set&, const Allocator&);
......@@ -77,6 +81,12 @@ public:
7781 template <class InputIterator>
7882 unordered_set(InputIterator f, InputIterator l, size_type n,
7983 const hasher& hf, const allocator_type& a); // C++14
84 template<container-compatible-range<value_type> R>
85 unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a)
86 : unordered_set(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23
87 template<container-compatible-range<value_type> R>
88 unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a)
89 : unordered_set(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } // C++23
8090 unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14
8191 unordered_set(initializer_list<value_type> il, size_type n,
8292 const hasher& hf, const allocator_type& a); // C++14
......@@ -113,6 +123,8 @@ public:
113123 iterator insert(const_iterator hint, value_type&& obj);
114124 template <class InputIterator>
115125 void insert(InputIterator first, InputIterator last);
126 template<container-compatible-range<value_type> R>
127 void insert_range(R&& rg); // C++23
116128 void insert(initializer_list<value_type>);
117129
118130 node_type extract(const_iterator position); // C++17
......@@ -191,6 +203,13 @@ unordered_set(InputIterator, InputIterator, typename see below::size_type = see
191203 -> unordered_set<typename iterator_traits<InputIterator>::value_type,
192204 Hash, Pred, Allocator>; // C++17
193205
206template<ranges::input_range R,
207 class Hash = hash<ranges::range_value_t<R>>,
208 class Pred = equal_to<ranges::range_value_t<R>>,
209 class Allocator = allocator<ranges::range_value_t<R>>>
210 unordered_set(from_range_t, R&&, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator())
211 -> unordered_set<ranges::range_value_t<R>, Hash, Pred, Allocator>; // C++23
212
194213template<class T, class Hash = hash<T>,
195214 class Pred = equal_to<T>, class Allocator = allocator<T>>
196215unordered_set(initializer_list<T>, typename see below::size_type = see below,
......@@ -211,6 +230,21 @@ unordered_set(InputIterator, InputIterator, typename see below::size_type,
211230 equal_to<typename iterator_traits<InputIterator>::value_type>,
212231 Allocator>; // C++17
213232
233template<ranges::input_range R, class Allocator>
234 unordered_set(from_range_t, R&&, typename see below::size_type, Allocator)
235 -> unordered_set<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
236 equal_to<ranges::range_value_t<R>>, Allocator>; // C++23
237
238template<ranges::input_range R, class Allocator>
239 unordered_set(from_range_t, R&&, Allocator)
240 -> unordered_set<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
241 equal_to<ranges::range_value_t<R>>, Allocator>; // C++23
242
243template<ranges::input_range R, class Hash, class Allocator>
244 unordered_set(from_range_t, R&&, typename see below::size_type, Hash, Allocator)
245 -> unordered_set<ranges::range_value_t<R>, Hash,
246 equal_to<ranges::range_value_t<R>>, Allocator>; // C++23
247
214248template<class T, class Allocator>
215249unordered_set(initializer_list<T>, typename see below::size_type, Allocator)
216250 -> unordered_set<T, hash<T>, equal_to<T>, Allocator>; // C++17
......@@ -232,7 +266,7 @@ template <class Value, class Hash, class Pred, class Alloc>
232266template <class Value, class Hash, class Pred, class Alloc>
233267 bool
234268 operator!=(const unordered_set<Value, Hash, Pred, Alloc>& x,
235 const unordered_set<Value, Hash, Pred, Alloc>& y);
269 const unordered_set<Value, Hash, Pred, Alloc>& y); // removed in C++20
236270
237271template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
238272 class Alloc = allocator<Value>>
......@@ -272,6 +306,10 @@ public:
272306 size_type n = 0, const hasher& hf = hasher(),
273307 const key_equal& eql = key_equal(),
274308 const allocator_type& a = allocator_type());
309 template<container-compatible-range<value_type> R>
310 unordered_multiset(from_range_t, R&& rg, size_type n = see below,
311 const hasher& hf = hasher(), const key_equal& eql = key_equal(),
312 const allocator_type& a = allocator_type()); // C++23
275313 explicit unordered_multiset(const allocator_type&);
276314 unordered_multiset(const unordered_multiset&);
277315 unordered_multiset(const unordered_multiset&, const Allocator&);
......@@ -291,6 +329,12 @@ public:
291329 template <class InputIterator>
292330 unordered_multiset(InputIterator f, InputIterator l, size_type n,
293331 const hasher& hf, const allocator_type& a); // C++14
332 template<container-compatible-range<value_type> R>
333 unordered_multiset(from_range_t, R&& rg, size_type n, const allocator_type& a)
334 : unordered_multiset(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23
335 template<container-compatible-range<value_type> R>
336 unordered_multiset(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a)
337 : unordered_multiset(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } // C++23
294338 unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14
295339 unordered_multiset(initializer_list<value_type> il, size_type n,
296340 const hasher& hf, const allocator_type& a); // C++14
......@@ -327,6 +371,8 @@ public:
327371 iterator insert(const_iterator hint, value_type&& obj);
328372 template <class InputIterator>
329373 void insert(InputIterator first, InputIterator last);
374 template<container-compatible-range<value_type> R>
375 void insert_range(R&& rg); // C++23
330376 void insert(initializer_list<value_type>);
331377
332378 node_type extract(const_iterator position); // C++17
......@@ -405,6 +451,13 @@ unordered_multiset(InputIterator, InputIterator, see below::size_type = see belo
405451 -> unordered_multiset<typename iterator_traits<InputIterator>::value_type,
406452 Hash, Pred, Allocator>; // C++17
407453
454template<ranges::input_range R,
455 class Hash = hash<ranges::range_value_t<R>>,
456 class Pred = equal_to<ranges::range_value_t<R>>,
457 class Allocator = allocator<ranges::range_value_t<R>>>
458 unordered_multiset(from_range_t, R&&, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator())
459 -> unordered_multiset<ranges::range_value_t<R>, Hash, Pred, Allocator>; // C++23
460
408461template<class T, class Hash = hash<T>,
409462 class Pred = equal_to<T>, class Allocator = allocator<T>>
410463unordered_multiset(initializer_list<T>, typename see below::size_type = see below,
......@@ -424,6 +477,21 @@ unordered_multiset(InputIterator, InputIterator, typename see below::size_type,
424477 -> unordered_multiset<typename iterator_traits<InputIterator>::value_type, Hash,
425478 equal_to<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17
426479
480template<ranges::input_range R, class Allocator>
481 unordered_multiset(from_range_t, R&&, typename see below::size_type, Allocator)
482 -> unordered_multiset<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
483 equal_to<ranges::range_value_t<R>>, Allocator>; // C++23
484
485template<ranges::input_range R, class Allocator>
486 unordered_multiset(from_range_t, R&&, Allocator)
487 -> unordered_multiset<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
488 equal_to<ranges::range_value_t<R>>, Allocator>; // C++23
489
490template<ranges::input_range R, class Hash, class Allocator>
491 unordered_multiset(from_range_t, R&&, typename see below::size_type, Hash, Allocator)
492 -> unordered_multiset<ranges::range_value_t<R>, Hash,
493 equal_to<ranges::range_value_t<R>>, Allocator>; // C++23
494
427495template<class T, class Allocator>
428496unordered_multiset(initializer_list<T>, typename see below::size_type, Allocator)
429497 -> unordered_multiset<T, hash<T>, equal_to<T>, Allocator>; // C++17
......@@ -454,25 +522,29 @@ template <class Value, class Hash, class Pred, class Alloc>
454522template <class Value, class Hash, class Pred, class Alloc>
455523 bool
456524 operator!=(const unordered_multiset<Value, Hash, Pred, Alloc>& x,
457 const unordered_multiset<Value, Hash, Pred, Alloc>& y);
525 const unordered_multiset<Value, Hash, Pred, Alloc>& y); // removed in C++20
458526} // std
459527
460528*/
461529
462530#include <__algorithm/is_permutation.h>
463531#include <__assert> // all public C++ headers provide the assertion handler
532#include <__availability>
464533#include <__config>
465#include <__debug>
466534#include <__functional/is_transparent.h>
467535#include <__functional/operations.h>
468536#include <__hash_table>
469537#include <__iterator/distance.h>
470538#include <__iterator/erase_if_container.h>
471539#include <__iterator/iterator_traits.h>
540#include <__iterator/ranges_iterator_traits.h>
472541#include <__memory/addressof.h>
473542#include <__memory/allocator.h>
474543#include <__memory_resource/polymorphic_allocator.h>
475544#include <__node_handle>
545#include <__ranges/concepts.h>
546#include <__ranges/container_compatible_range.h>
547#include <__ranges/from_range.h>
476548#include <__type_traits/is_allocator.h>
477549#include <__utility/forward.h>
478550#include <version>
......@@ -513,7 +585,7 @@ public:
513585 typedef value_type& reference;
514586 typedef const value_type& const_reference;
515587 static_assert((is_same<value_type, typename allocator_type::value_type>::value),
516 "Invalid allocator::value_type");
588 "Allocator::value_type must be same type as value_type");
517589
518590 static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value,
519591 "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
......@@ -535,7 +607,7 @@ public:
535607 typedef typename __table::const_local_iterator local_iterator;
536608 typedef typename __table::const_local_iterator const_local_iterator;
537609
538#if _LIBCPP_STD_VER > 14
610#if _LIBCPP_STD_VER >= 17
539611 typedef __set_node_handle<typename __table::__node, allocator_type> node_type;
540612 typedef __insert_return_type<iterator, node_type> insert_return_type;
541613#endif
......@@ -549,11 +621,10 @@ public:
549621 unordered_set()
550622 _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
551623 {
552 _VSTD::__debug_db_insert_c(this);
553624 }
554 explicit unordered_set(size_type __n, const hasher& __hf = hasher(),
625 explicit _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf = hasher(),
555626 const key_equal& __eql = key_equal());
556#if _LIBCPP_STD_VER > 11
627#if _LIBCPP_STD_VER >= 14
557628 inline _LIBCPP_INLINE_VISIBILITY
558629 unordered_set(size_type __n, const allocator_type& __a)
559630 : unordered_set(__n, hasher(), key_equal(), __a) {}
......@@ -561,46 +632,74 @@ public:
561632 unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a)
562633 : unordered_set(__n, __hf, key_equal(), __a) {}
563634#endif
564 unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql,
635 _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql,
565636 const allocator_type& __a);
566637 template <class _InputIterator>
567 unordered_set(_InputIterator __first, _InputIterator __last);
638 _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last);
568639 template <class _InputIterator>
569 unordered_set(_InputIterator __first, _InputIterator __last,
640 _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last,
570641 size_type __n, const hasher& __hf = hasher(),
571642 const key_equal& __eql = key_equal());
572643 template <class _InputIterator>
573 unordered_set(_InputIterator __first, _InputIterator __last,
644 _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last,
574645 size_type __n, const hasher& __hf, const key_equal& __eql,
575646 const allocator_type& __a);
576#if _LIBCPP_STD_VER > 11
647
648#if _LIBCPP_STD_VER >= 23
649 template <_ContainerCompatibleRange<value_type> _Range>
650 _LIBCPP_HIDE_FROM_ABI
651 unordered_set(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0,
652 const hasher& __hf = hasher(), const key_equal& __eql = key_equal(),
653 const allocator_type& __a = allocator_type())
654 : __table_(__hf, __eql, __a) {
655 if (__n > 0) {
656 __table_.__rehash_unique(__n);
657 }
658 insert_range(std::forward<_Range>(__range));
659 }
660#endif
661
662#if _LIBCPP_STD_VER >= 14
577663 template <class _InputIterator>
578664 inline _LIBCPP_INLINE_VISIBILITY
579665 unordered_set(_InputIterator __first, _InputIterator __last,
580666 size_type __n, const allocator_type& __a)
581667 : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) {}
582668 template <class _InputIterator>
583 unordered_set(_InputIterator __first, _InputIterator __last,
669 _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last,
584670 size_type __n, const hasher& __hf, const allocator_type& __a)
585671 : unordered_set(__first, __last, __n, __hf, key_equal(), __a) {}
586672#endif
673
674#if _LIBCPP_STD_VER >= 23
675 template <_ContainerCompatibleRange<value_type> _Range>
676 _LIBCPP_HIDE_FROM_ABI
677 unordered_set(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a)
678 : unordered_set(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {}
679
680 template <_ContainerCompatibleRange<value_type> _Range>
681 _LIBCPP_HIDE_FROM_ABI
682 unordered_set(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a)
683 : unordered_set(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {}
684#endif
685
587686 _LIBCPP_INLINE_VISIBILITY
588687 explicit unordered_set(const allocator_type& __a);
589 unordered_set(const unordered_set& __u);
590 unordered_set(const unordered_set& __u, const allocator_type& __a);
688 _LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u);
689 _LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u, const allocator_type& __a);
591690#ifndef _LIBCPP_CXX03_LANG
592691 _LIBCPP_INLINE_VISIBILITY
593692 unordered_set(unordered_set&& __u)
594693 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
595 unordered_set(unordered_set&& __u, const allocator_type& __a);
596 unordered_set(initializer_list<value_type> __il);
597 unordered_set(initializer_list<value_type> __il, size_type __n,
694 _LIBCPP_HIDE_FROM_ABI unordered_set(unordered_set&& __u, const allocator_type& __a);
695 _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il);
696 _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il, size_type __n,
598697 const hasher& __hf = hasher(),
599698 const key_equal& __eql = key_equal());
600 unordered_set(initializer_list<value_type> __il, size_type __n,
699 _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il, size_type __n,
601700 const hasher& __hf, const key_equal& __eql,
602701 const allocator_type& __a);
603#if _LIBCPP_STD_VER > 11
702#if _LIBCPP_STD_VER >= 14
604703 inline _LIBCPP_INLINE_VISIBILITY
605704 unordered_set(initializer_list<value_type> __il, size_type __n,
606705 const allocator_type& __a)
......@@ -661,11 +760,7 @@ public:
661760 {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...);}
662761 template <class... _Args>
663762 _LIBCPP_INLINE_VISIBILITY
664 iterator emplace_hint(const_iterator __p, _Args&&... __args) {
665 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this,
666 "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not"
667 " referring to this unordered_set");
668 (void)__p;
763 iterator emplace_hint(const_iterator, _Args&&... __args) {
669764 return __table_.__emplace_unique(std::forward<_Args>(__args)...).first;
670765 }
671766
......@@ -673,11 +768,7 @@ public:
673768 pair<iterator, bool> insert(value_type&& __x)
674769 {return __table_.__insert_unique(_VSTD::move(__x));}
675770 _LIBCPP_INLINE_VISIBILITY
676 iterator insert(const_iterator __p, value_type&& __x) {
677 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this,
678 "unordered_set::insert(const_iterator, value_type&&) called with an iterator not"
679 " referring to this unordered_set");
680 (void)__p;
771 iterator insert(const_iterator, value_type&& __x) {
681772 return insert(std::move(__x)).first;
682773 }
683774
......@@ -690,17 +781,23 @@ public:
690781 {return __table_.__insert_unique(__x);}
691782
692783 _LIBCPP_INLINE_VISIBILITY
693 iterator insert(const_iterator __p, const value_type& __x) {
694 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this,
695 "unordered_set::insert(const_iterator, const value_type&) called with an iterator not"
696 " referring to this unordered_set");
697 (void)__p;
784 iterator insert(const_iterator, const value_type& __x) {
698785 return insert(__x).first;
699786 }
700787 template <class _InputIterator>
701788 _LIBCPP_INLINE_VISIBILITY
702789 void insert(_InputIterator __first, _InputIterator __last);
703790
791#if _LIBCPP_STD_VER >= 23
792 template <_ContainerCompatibleRange<value_type> _Range>
793 _LIBCPP_HIDE_FROM_ABI
794 void insert_range(_Range&& __range) {
795 for (auto&& __element : __range) {
796 __table_.__insert_unique(std::forward<decltype(__element)>(__element));
797 }
798 }
799#endif
800
704801 _LIBCPP_INLINE_VISIBILITY
705802 iterator erase(const_iterator __p) {return __table_.erase(__p);}
706803 _LIBCPP_INLINE_VISIBILITY
......@@ -711,11 +808,11 @@ public:
711808 _LIBCPP_INLINE_VISIBILITY
712809 void clear() _NOEXCEPT {__table_.clear();}
713810
714#if _LIBCPP_STD_VER > 14
811#if _LIBCPP_STD_VER >= 17
715812 _LIBCPP_INLINE_VISIBILITY
716813 insert_return_type insert(node_type&& __nh)
717814 {
718 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
815 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
719816 "node_type with incompatible allocator passed to unordered_set::insert()");
720817 return __table_.template __node_handle_insert_unique<
721818 node_type, insert_return_type>(_VSTD::move(__nh));
......@@ -723,7 +820,7 @@ public:
723820 _LIBCPP_INLINE_VISIBILITY
724821 iterator insert(const_iterator __h, node_type&& __nh)
725822 {
726 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
823 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
727824 "node_type with incompatible allocator passed to unordered_set::insert()");
728825 return __table_.template __node_handle_insert_unique<node_type>(
729826 __h, _VSTD::move(__nh));
......@@ -743,32 +840,32 @@ public:
743840 _LIBCPP_INLINE_VISIBILITY
744841 void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source)
745842 {
746 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
747 "merging container with incompatible allocator");
843 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
844 "merging container with incompatible allocator");
748845 __table_.__node_handle_merge_unique(__source.__table_);
749846 }
750847 template<class _H2, class _P2>
751848 _LIBCPP_INLINE_VISIBILITY
752849 void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source)
753850 {
754 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
755 "merging container with incompatible allocator");
851 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
852 "merging container with incompatible allocator");
756853 __table_.__node_handle_merge_unique(__source.__table_);
757854 }
758855 template<class _H2, class _P2>
759856 _LIBCPP_INLINE_VISIBILITY
760857 void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source)
761858 {
762 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
763 "merging container with incompatible allocator");
859 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
860 "merging container with incompatible allocator");
764861 __table_.__node_handle_merge_unique(__source.__table_);
765862 }
766863 template<class _H2, class _P2>
767864 _LIBCPP_INLINE_VISIBILITY
768865 void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source)
769866 {
770 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
771 "merging container with incompatible allocator");
867 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
868 "merging container with incompatible allocator");
772869 __table_.__node_handle_merge_unique(__source.__table_);
773870 }
774871#endif
......@@ -787,31 +884,31 @@ public:
787884 iterator find(const key_type& __k) {return __table_.find(__k);}
788885 _LIBCPP_INLINE_VISIBILITY
789886 const_iterator find(const key_type& __k) const {return __table_.find(__k);}
790#if _LIBCPP_STD_VER > 17
887#if _LIBCPP_STD_VER >= 20
791888 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
792889 _LIBCPP_INLINE_VISIBILITY
793890 iterator find(const _K2& __k) {return __table_.find(__k);}
794891 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
795892 _LIBCPP_INLINE_VISIBILITY
796893 const_iterator find(const _K2& __k) const {return __table_.find(__k);}
797#endif // _LIBCPP_STD_VER > 17
894#endif // _LIBCPP_STD_VER >= 20
798895
799896 _LIBCPP_INLINE_VISIBILITY
800897 size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
801#if _LIBCPP_STD_VER > 17
898#if _LIBCPP_STD_VER >= 20
802899 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
803900 _LIBCPP_INLINE_VISIBILITY
804901 size_type count(const _K2& __k) const {return __table_.__count_unique(__k);}
805#endif // _LIBCPP_STD_VER > 17
902#endif // _LIBCPP_STD_VER >= 20
806903
807#if _LIBCPP_STD_VER > 17
904#if _LIBCPP_STD_VER >= 20
808905 _LIBCPP_INLINE_VISIBILITY
809906 bool contains(const key_type& __k) const {return find(__k) != end();}
810907
811908 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
812909 _LIBCPP_INLINE_VISIBILITY
813910 bool contains(const _K2& __k) const {return find(__k) != end();}
814#endif // _LIBCPP_STD_VER > 17
911#endif // _LIBCPP_STD_VER >= 20
815912
816913 _LIBCPP_INLINE_VISIBILITY
817914 pair<iterator, iterator> equal_range(const key_type& __k)
......@@ -819,7 +916,7 @@ public:
819916 _LIBCPP_INLINE_VISIBILITY
820917 pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
821918 {return __table_.__equal_range_unique(__k);}
822#if _LIBCPP_STD_VER > 17
919#if _LIBCPP_STD_VER >= 20
823920 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
824921 _LIBCPP_INLINE_VISIBILITY
825922 pair<iterator, iterator> equal_range(const _K2& __k)
......@@ -828,7 +925,7 @@ public:
828925 _LIBCPP_INLINE_VISIBILITY
829926 pair<const_iterator, const_iterator> equal_range(const _K2& __k) const
830927 {return __table_.__equal_range_unique(__k);}
831#endif // _LIBCPP_STD_VER > 17
928#endif // _LIBCPP_STD_VER >= 20
832929
833930 _LIBCPP_INLINE_VISIBILITY
834931 size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
......@@ -863,20 +960,6 @@ public:
863960 void rehash(size_type __n) {__table_.__rehash_unique(__n);}
864961 _LIBCPP_INLINE_VISIBILITY
865962 void reserve(size_type __n) {__table_.__reserve_unique(__n);}
866
867#ifdef _LIBCPP_ENABLE_DEBUG_MODE
868
869 bool __dereferenceable(const const_iterator* __i) const
870 {return __table_.__dereferenceable(__i);}
871 bool __decrementable(const const_iterator* __i) const
872 {return __table_.__decrementable(__i);}
873 bool __addable(const const_iterator* __i, ptrdiff_t __n) const
874 {return __table_.__addable(__i, __n);}
875 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
876 {return __table_.__addable(__i, __n);}
877
878#endif // _LIBCPP_ENABLE_DEBUG_MODE
879
880963};
881964
882965#if _LIBCPP_STD_VER >= 17
......@@ -884,7 +967,7 @@ template<class _InputIterator,
884967 class _Hash = hash<__iter_value_type<_InputIterator>>,
885968 class _Pred = equal_to<__iter_value_type<_InputIterator>>,
886969 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
887 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
970 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
888971 class = enable_if_t<!__is_allocator<_Hash>::value>,
889972 class = enable_if_t<!is_integral<_Hash>::value>,
890973 class = enable_if_t<!__is_allocator<_Pred>::value>,
......@@ -893,6 +976,20 @@ unordered_set(_InputIterator, _InputIterator, typename allocator_traits<_Allocat
893976 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
894977 -> unordered_set<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>;
895978
979#if _LIBCPP_STD_VER >= 23
980template <ranges::input_range _Range,
981 class _Hash = hash<ranges::range_value_t<_Range>>,
982 class _Pred = equal_to<ranges::range_value_t<_Range>>,
983 class _Allocator = allocator<ranges::range_value_t<_Range>>,
984 class = enable_if_t<!__is_allocator<_Hash>::value>,
985 class = enable_if_t<!is_integral<_Hash>::value>,
986 class = enable_if_t<!__is_allocator<_Pred>::value>,
987 class = enable_if_t<__is_allocator<_Allocator>::value>>
988unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0,
989 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
990 -> unordered_set<ranges::range_value_t<_Range>, _Hash, _Pred, _Allocator>; // C++23
991#endif
992
896993template<class _Tp, class _Hash = hash<_Tp>,
897994 class _Pred = equal_to<_Tp>,
898995 class _Allocator = allocator<_Tp>,
......@@ -905,7 +1002,7 @@ unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size
9051002 -> unordered_set<_Tp, _Hash, _Pred, _Allocator>;
9061003
9071004template<class _InputIterator, class _Allocator,
908 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1005 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
9091006 class = enable_if_t<__is_allocator<_Allocator>::value>>
9101007unordered_set(_InputIterator, _InputIterator,
9111008 typename allocator_traits<_Allocator>::size_type, _Allocator)
......@@ -915,7 +1012,7 @@ unordered_set(_InputIterator, _InputIterator,
9151012 _Allocator>;
9161013
9171014template<class _InputIterator, class _Hash, class _Allocator,
918 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1015 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
9191016 class = enable_if_t<!__is_allocator<_Hash>::value>,
9201017 class = enable_if_t<!is_integral<_Hash>::value>,
9211018 class = enable_if_t<__is_allocator<_Allocator>::value>>
......@@ -925,6 +1022,29 @@ unordered_set(_InputIterator, _InputIterator,
9251022 equal_to<__iter_value_type<_InputIterator>>,
9261023 _Allocator>;
9271024
1025#if _LIBCPP_STD_VER >= 23
1026
1027template <ranges::input_range _Range, class _Allocator,
1028 class = enable_if_t<__is_allocator<_Allocator>::value>>
1029unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator)
1030 -> unordered_set<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>,
1031 equal_to<ranges::range_value_t<_Range>>, _Allocator>;
1032
1033template <ranges::input_range _Range, class _Allocator,
1034 class = enable_if_t<__is_allocator<_Allocator>::value>>
1035unordered_set(from_range_t, _Range&&, _Allocator)
1036 -> unordered_set<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>,
1037 equal_to<ranges::range_value_t<_Range>>, _Allocator>;
1038
1039template <ranges::input_range _Range, class _Hash, class _Allocator,
1040 class = enable_if_t<!__is_allocator<_Hash>::value>,
1041 class = enable_if_t<!is_integral<_Hash>::value>,
1042 class = enable_if_t<__is_allocator<_Allocator>::value>>
1043unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
1044 -> unordered_set<ranges::range_value_t<_Range>, _Hash, equal_to<ranges::range_value_t<_Range>>, _Allocator>;
1045
1046#endif
1047
9281048template<class _Tp, class _Allocator,
9291049 class = enable_if_t<__is_allocator<_Allocator>::value>>
9301050unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator)
......@@ -943,7 +1063,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,
9431063 const hasher& __hf, const key_equal& __eql)
9441064 : __table_(__hf, __eql)
9451065{
946 _VSTD::__debug_db_insert_c(this);
9471066 __table_.__rehash_unique(__n);
9481067}
9491068
......@@ -952,7 +1071,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,
9521071 const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
9531072 : __table_(__hf, __eql, __a)
9541073{
955 _VSTD::__debug_db_insert_c(this);
9561074 __table_.__rehash_unique(__n);
9571075}
9581076
......@@ -961,7 +1079,6 @@ template <class _InputIterator>
9611079unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
9621080 _InputIterator __first, _InputIterator __last)
9631081{
964 _VSTD::__debug_db_insert_c(this);
9651082 insert(__first, __last);
9661083}
9671084
......@@ -972,7 +1089,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
9721089 const hasher& __hf, const key_equal& __eql)
9731090 : __table_(__hf, __eql)
9741091{
975 _VSTD::__debug_db_insert_c(this);
9761092 __table_.__rehash_unique(__n);
9771093 insert(__first, __last);
9781094}
......@@ -984,7 +1100,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
9841100 const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
9851101 : __table_(__hf, __eql, __a)
9861102{
987 _VSTD::__debug_db_insert_c(this);
9881103 __table_.__rehash_unique(__n);
9891104 insert(__first, __last);
9901105}
......@@ -995,7 +1110,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
9951110 const allocator_type& __a)
9961111 : __table_(__a)
9971112{
998 _VSTD::__debug_db_insert_c(this);
9991113}
10001114
10011115template <class _Value, class _Hash, class _Pred, class _Alloc>
......@@ -1003,7 +1117,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
10031117 const unordered_set& __u)
10041118 : __table_(__u.__table_)
10051119{
1006 _VSTD::__debug_db_insert_c(this);
10071120 __table_.__rehash_unique(__u.bucket_count());
10081121 insert(__u.begin(), __u.end());
10091122}
......@@ -1013,7 +1126,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
10131126 const unordered_set& __u, const allocator_type& __a)
10141127 : __table_(__u.__table_, __a)
10151128{
1016 _VSTD::__debug_db_insert_c(this);
10171129 __table_.__rehash_unique(__u.bucket_count());
10181130 insert(__u.begin(), __u.end());
10191131}
......@@ -1027,8 +1139,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
10271139 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
10281140 : __table_(_VSTD::move(__u.__table_))
10291141{
1030 _VSTD::__debug_db_insert_c(this);
1031 std::__debug_db_swap(this, std::addressof(__u));
10321142}
10331143
10341144template <class _Value, class _Hash, class _Pred, class _Alloc>
......@@ -1036,22 +1146,18 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
10361146 unordered_set&& __u, const allocator_type& __a)
10371147 : __table_(_VSTD::move(__u.__table_), __a)
10381148{
1039 _VSTD::__debug_db_insert_c(this);
10401149 if (__a != __u.get_allocator())
10411150 {
10421151 iterator __i = __u.begin();
10431152 while (__u.size() != 0)
10441153 __table_.__insert_unique(_VSTD::move(__u.__table_.remove(__i++)->__value_));
10451154 }
1046 else
1047 std::__debug_db_swap(this, std::addressof(__u));
10481155}
10491156
10501157template <class _Value, class _Hash, class _Pred, class _Alloc>
10511158unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
10521159 initializer_list<value_type> __il)
10531160{
1054 _VSTD::__debug_db_insert_c(this);
10551161 insert(__il.begin(), __il.end());
10561162}
10571163
......@@ -1061,7 +1167,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
10611167 const key_equal& __eql)
10621168 : __table_(__hf, __eql)
10631169{
1064 _VSTD::__debug_db_insert_c(this);
10651170 __table_.__rehash_unique(__n);
10661171 insert(__il.begin(), __il.end());
10671172}
......@@ -1072,7 +1177,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
10721177 const key_equal& __eql, const allocator_type& __a)
10731178 : __table_(__hf, __eql, __a)
10741179{
1075 _VSTD::__debug_db_insert_c(this);
10761180 __table_.__rehash_unique(__n);
10771181 insert(__il.begin(), __il.end());
10781182}
......@@ -1120,7 +1224,7 @@ swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
11201224 __x.swap(__y);
11211225}
11221226
1123#if _LIBCPP_STD_VER > 17
1227#if _LIBCPP_STD_VER >= 20
11241228template <class _Value, class _Hash, class _Pred, class _Alloc,
11251229 class _Predicate>
11261230inline _LIBCPP_INLINE_VISIBILITY
......@@ -1150,6 +1254,8 @@ operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
11501254 return true;
11511255}
11521256
1257#if _LIBCPP_STD_VER <= 17
1258
11531259template <class _Value, class _Hash, class _Pred, class _Alloc>
11541260inline _LIBCPP_INLINE_VISIBILITY
11551261bool
......@@ -1159,6 +1265,8 @@ operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
11591265 return !(__x == __y);
11601266}
11611267
1268#endif
1269
11621270template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
11631271 class _Alloc = allocator<_Value> >
11641272class _LIBCPP_TEMPLATE_VIS unordered_multiset
......@@ -1173,7 +1281,7 @@ public:
11731281 typedef value_type& reference;
11741282 typedef const value_type& const_reference;
11751283 static_assert((is_same<value_type, typename allocator_type::value_type>::value),
1176 "Invalid allocator::value_type");
1284 "Allocator::value_type must be same type as value_type");
11771285
11781286private:
11791287 typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
......@@ -1191,7 +1299,7 @@ public:
11911299 typedef typename __table::const_local_iterator local_iterator;
11921300 typedef typename __table::const_local_iterator const_local_iterator;
11931301
1194#if _LIBCPP_STD_VER > 14
1302#if _LIBCPP_STD_VER >= 17
11951303 typedef __set_node_handle<typename __table::__node, allocator_type> node_type;
11961304#endif
11971305
......@@ -1204,13 +1312,12 @@ public:
12041312 unordered_multiset()
12051313 _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
12061314 {
1207 _VSTD::__debug_db_insert_c(this);
12081315 }
1209 explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(),
1316 explicit _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const hasher& __hf = hasher(),
12101317 const key_equal& __eql = key_equal());
1211 unordered_multiset(size_type __n, const hasher& __hf,
1318 _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const hasher& __hf,
12121319 const key_equal& __eql, const allocator_type& __a);
1213#if _LIBCPP_STD_VER > 11
1320#if _LIBCPP_STD_VER >= 14
12141321 inline _LIBCPP_INLINE_VISIBILITY
12151322 unordered_multiset(size_type __n, const allocator_type& __a)
12161323 : unordered_multiset(__n, hasher(), key_equal(), __a) {}
......@@ -1219,16 +1326,31 @@ public:
12191326 : unordered_multiset(__n, __hf, key_equal(), __a) {}
12201327#endif
12211328 template <class _InputIterator>
1222 unordered_multiset(_InputIterator __first, _InputIterator __last);
1329 _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last);
12231330 template <class _InputIterator>
1224 unordered_multiset(_InputIterator __first, _InputIterator __last,
1331 _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last,
12251332 size_type __n, const hasher& __hf = hasher(),
12261333 const key_equal& __eql = key_equal());
12271334 template <class _InputIterator>
1228 unordered_multiset(_InputIterator __first, _InputIterator __last,
1335 _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last,
12291336 size_type __n , const hasher& __hf,
12301337 const key_equal& __eql, const allocator_type& __a);
1231#if _LIBCPP_STD_VER > 11
1338
1339#if _LIBCPP_STD_VER >= 23
1340 template <_ContainerCompatibleRange<value_type> _Range>
1341 _LIBCPP_HIDE_FROM_ABI
1342 unordered_multiset(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0,
1343 const hasher& __hf = hasher(), const key_equal& __eql = key_equal(),
1344 const allocator_type& __a = allocator_type())
1345 : __table_(__hf, __eql, __a) {
1346 if (__n > 0) {
1347 __table_.__rehash_multi(__n);
1348 }
1349 insert_range(std::forward<_Range>(__range));
1350 }
1351#endif
1352
1353#if _LIBCPP_STD_VER >= 14
12321354 template <class _InputIterator>
12331355 inline _LIBCPP_INLINE_VISIBILITY
12341356 unordered_multiset(_InputIterator __first, _InputIterator __last,
......@@ -1240,23 +1362,36 @@ public:
12401362 size_type __n, const hasher& __hf, const allocator_type& __a)
12411363 : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {}
12421364#endif
1365
1366#if _LIBCPP_STD_VER >= 23
1367 template <_ContainerCompatibleRange<value_type> _Range>
1368 _LIBCPP_HIDE_FROM_ABI
1369 unordered_multiset(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a)
1370 : unordered_multiset(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {}
1371
1372 template <_ContainerCompatibleRange<value_type> _Range>
1373 _LIBCPP_HIDE_FROM_ABI
1374 unordered_multiset(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a)
1375 : unordered_multiset(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {}
1376#endif
1377
12431378 _LIBCPP_INLINE_VISIBILITY
12441379 explicit unordered_multiset(const allocator_type& __a);
1245 unordered_multiset(const unordered_multiset& __u);
1246 unordered_multiset(const unordered_multiset& __u, const allocator_type& __a);
1380 _LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u);
1381 _LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u, const allocator_type& __a);
12471382#ifndef _LIBCPP_CXX03_LANG
12481383 _LIBCPP_INLINE_VISIBILITY
12491384 unordered_multiset(unordered_multiset&& __u)
12501385 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
1251 unordered_multiset(unordered_multiset&& __u, const allocator_type& __a);
1252 unordered_multiset(initializer_list<value_type> __il);
1253 unordered_multiset(initializer_list<value_type> __il, size_type __n,
1386 _LIBCPP_HIDE_FROM_ABI unordered_multiset(unordered_multiset&& __u, const allocator_type& __a);
1387 _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il);
1388 _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il, size_type __n,
12541389 const hasher& __hf = hasher(),
12551390 const key_equal& __eql = key_equal());
1256 unordered_multiset(initializer_list<value_type> __il, size_type __n,
1391 _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il, size_type __n,
12571392 const hasher& __hf, const key_equal& __eql,
12581393 const allocator_type& __a);
1259#if _LIBCPP_STD_VER > 11
1394#if _LIBCPP_STD_VER >= 14
12601395 inline _LIBCPP_INLINE_VISIBILITY
12611396 unordered_multiset(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
12621397 : unordered_multiset(__il, __n, hasher(), key_equal(), __a) {}
......@@ -1280,7 +1415,7 @@ public:
12801415 _LIBCPP_INLINE_VISIBILITY
12811416 unordered_multiset& operator=(unordered_multiset&& __u)
12821417 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
1283 unordered_multiset& operator=(initializer_list<value_type> __il);
1418 _LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(initializer_list<value_type> __il);
12841419#endif // _LIBCPP_CXX03_LANG
12851420
12861421 _LIBCPP_INLINE_VISIBILITY
......@@ -1338,11 +1473,21 @@ public:
13381473 _LIBCPP_INLINE_VISIBILITY
13391474 void insert(_InputIterator __first, _InputIterator __last);
13401475
1341#if _LIBCPP_STD_VER > 14
1476#if _LIBCPP_STD_VER >= 23
1477 template <_ContainerCompatibleRange<value_type> _Range>
1478 _LIBCPP_HIDE_FROM_ABI
1479 void insert_range(_Range&& __range) {
1480 for (auto&& __element : __range) {
1481 __table_.__insert_multi(std::forward<decltype(__element)>(__element));
1482 }
1483 }
1484#endif
1485
1486#if _LIBCPP_STD_VER >= 17
13421487 _LIBCPP_INLINE_VISIBILITY
13431488 iterator insert(node_type&& __nh)
13441489 {
1345 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1490 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
13461491 "node_type with incompatible allocator passed to unordered_multiset::insert()");
13471492 return __table_.template __node_handle_insert_multi<node_type>(
13481493 _VSTD::move(__nh));
......@@ -1350,7 +1495,7 @@ public:
13501495 _LIBCPP_INLINE_VISIBILITY
13511496 iterator insert(const_iterator __hint, node_type&& __nh)
13521497 {
1353 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1498 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
13541499 "node_type with incompatible allocator passed to unordered_multiset::insert()");
13551500 return __table_.template __node_handle_insert_multi<node_type>(
13561501 __hint, _VSTD::move(__nh));
......@@ -1371,32 +1516,32 @@ public:
13711516 _LIBCPP_INLINE_VISIBILITY
13721517 void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source)
13731518 {
1374 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1375 "merging container with incompatible allocator");
1519 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1520 "merging container with incompatible allocator");
13761521 return __table_.__node_handle_merge_multi(__source.__table_);
13771522 }
13781523 template <class _H2, class _P2>
13791524 _LIBCPP_INLINE_VISIBILITY
13801525 void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source)
13811526 {
1382 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1383 "merging container with incompatible allocator");
1527 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1528 "merging container with incompatible allocator");
13841529 return __table_.__node_handle_merge_multi(__source.__table_);
13851530 }
13861531 template <class _H2, class _P2>
13871532 _LIBCPP_INLINE_VISIBILITY
13881533 void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source)
13891534 {
1390 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1391 "merging container with incompatible allocator");
1535 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1536 "merging container with incompatible allocator");
13921537 return __table_.__node_handle_merge_multi(__source.__table_);
13931538 }
13941539 template <class _H2, class _P2>
13951540 _LIBCPP_INLINE_VISIBILITY
13961541 void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source)
13971542 {
1398 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1399 "merging container with incompatible allocator");
1543 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1544 "merging container with incompatible allocator");
14001545 return __table_.__node_handle_merge_multi(__source.__table_);
14011546 }
14021547#endif
......@@ -1425,31 +1570,31 @@ public:
14251570 iterator find(const key_type& __k) {return __table_.find(__k);}
14261571 _LIBCPP_INLINE_VISIBILITY
14271572 const_iterator find(const key_type& __k) const {return __table_.find(__k);}
1428#if _LIBCPP_STD_VER > 17
1573#if _LIBCPP_STD_VER >= 20
14291574 template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
14301575 _LIBCPP_INLINE_VISIBILITY
14311576 iterator find(const _K2& __k) {return __table_.find(__k);}
14321577 template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
14331578 _LIBCPP_INLINE_VISIBILITY
14341579 const_iterator find(const _K2& __k) const {return __table_.find(__k);}
1435#endif // _LIBCPP_STD_VER > 17
1580#endif // _LIBCPP_STD_VER >= 20
14361581
14371582 _LIBCPP_INLINE_VISIBILITY
14381583 size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
1439#if _LIBCPP_STD_VER > 17
1584#if _LIBCPP_STD_VER >= 20
14401585 template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
14411586 _LIBCPP_INLINE_VISIBILITY
14421587 size_type count(const _K2& __k) const {return __table_.__count_multi(__k);}
1443#endif // _LIBCPP_STD_VER > 17
1588#endif // _LIBCPP_STD_VER >= 20
14441589
1445#if _LIBCPP_STD_VER > 17
1590#if _LIBCPP_STD_VER >= 20
14461591 _LIBCPP_INLINE_VISIBILITY
14471592 bool contains(const key_type& __k) const {return find(__k) != end();}
14481593
14491594 template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
14501595 _LIBCPP_INLINE_VISIBILITY
14511596 bool contains(const _K2& __k) const {return find(__k) != end();}
1452#endif // _LIBCPP_STD_VER > 17
1597#endif // _LIBCPP_STD_VER >= 20
14531598
14541599 _LIBCPP_INLINE_VISIBILITY
14551600 pair<iterator, iterator> equal_range(const key_type& __k)
......@@ -1457,7 +1602,7 @@ public:
14571602 _LIBCPP_INLINE_VISIBILITY
14581603 pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
14591604 {return __table_.__equal_range_multi(__k);}
1460#if _LIBCPP_STD_VER > 17
1605#if _LIBCPP_STD_VER >= 20
14611606 template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
14621607 _LIBCPP_INLINE_VISIBILITY
14631608 pair<iterator, iterator> equal_range(const _K2& __k)
......@@ -1466,7 +1611,7 @@ public:
14661611 _LIBCPP_INLINE_VISIBILITY
14671612 pair<const_iterator, const_iterator> equal_range(const _K2& __k) const
14681613 {return __table_.__equal_range_multi(__k);}
1469#endif // _LIBCPP_STD_VER > 17
1614#endif // _LIBCPP_STD_VER >= 20
14701615
14711616 _LIBCPP_INLINE_VISIBILITY
14721617 size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
......@@ -1501,20 +1646,6 @@ public:
15011646 void rehash(size_type __n) {__table_.__rehash_multi(__n);}
15021647 _LIBCPP_INLINE_VISIBILITY
15031648 void reserve(size_type __n) {__table_.__reserve_multi(__n);}
1504
1505#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1506
1507 bool __dereferenceable(const const_iterator* __i) const
1508 {return __table_.__dereferenceable(__i);}
1509 bool __decrementable(const const_iterator* __i) const
1510 {return __table_.__decrementable(__i);}
1511 bool __addable(const const_iterator* __i, ptrdiff_t __n) const
1512 {return __table_.__addable(__i, __n);}
1513 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
1514 {return __table_.__addable(__i, __n);}
1515
1516#endif // _LIBCPP_ENABLE_DEBUG_MODE
1517
15181649};
15191650
15201651#if _LIBCPP_STD_VER >= 17
......@@ -1522,7 +1653,7 @@ template<class _InputIterator,
15221653 class _Hash = hash<__iter_value_type<_InputIterator>>,
15231654 class _Pred = equal_to<__iter_value_type<_InputIterator>>,
15241655 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
1525 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1656 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
15261657 class = enable_if_t<!__is_allocator<_Hash>::value>,
15271658 class = enable_if_t<!is_integral<_Hash>::value>,
15281659 class = enable_if_t<!__is_allocator<_Pred>::value>,
......@@ -1531,6 +1662,20 @@ unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Al
15311662 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
15321663 -> unordered_multiset<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>;
15331664
1665#if _LIBCPP_STD_VER >= 23
1666template <ranges::input_range _Range,
1667 class _Hash = hash<ranges::range_value_t<_Range>>,
1668 class _Pred = equal_to<ranges::range_value_t<_Range>>,
1669 class _Allocator = allocator<ranges::range_value_t<_Range>>,
1670 class = enable_if_t<!__is_allocator<_Hash>::value>,
1671 class = enable_if_t<!is_integral<_Hash>::value>,
1672 class = enable_if_t<!__is_allocator<_Pred>::value>,
1673 class = enable_if_t<__is_allocator<_Allocator>::value>>
1674unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0,
1675 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1676 -> unordered_multiset<ranges::range_value_t<_Range>, _Hash, _Pred, _Allocator>; // C++23
1677#endif
1678
15341679template<class _Tp, class _Hash = hash<_Tp>,
15351680 class _Pred = equal_to<_Tp>, class _Allocator = allocator<_Tp>,
15361681 class = enable_if_t<!__is_allocator<_Hash>::value>,
......@@ -1542,7 +1687,7 @@ unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>:
15421687 -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>;
15431688
15441689template<class _InputIterator, class _Allocator,
1545 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1690 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
15461691 class = enable_if_t<__is_allocator<_Allocator>::value>>
15471692unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator)
15481693 -> unordered_multiset<__iter_value_type<_InputIterator>,
......@@ -1551,7 +1696,7 @@ unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Al
15511696 _Allocator>;
15521697
15531698template<class _InputIterator, class _Hash, class _Allocator,
1554 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1699 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
15551700 class = enable_if_t<!__is_allocator<_Hash>::value>,
15561701 class = enable_if_t<!is_integral<_Hash>::value>,
15571702 class = enable_if_t<__is_allocator<_Allocator>::value>>
......@@ -1561,6 +1706,29 @@ unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Al
15611706 equal_to<__iter_value_type<_InputIterator>>,
15621707 _Allocator>;
15631708
1709#if _LIBCPP_STD_VER >= 23
1710
1711template <ranges::input_range _Range, class _Allocator,
1712 class = enable_if_t<__is_allocator<_Allocator>::value>>
1713unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator)
1714 -> unordered_multiset<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>,
1715 equal_to<ranges::range_value_t<_Range>>, _Allocator>;
1716
1717template <ranges::input_range _Range, class _Allocator,
1718 class = enable_if_t<__is_allocator<_Allocator>::value>>
1719unordered_multiset(from_range_t, _Range&&, _Allocator)
1720 -> unordered_multiset<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>,
1721 equal_to<ranges::range_value_t<_Range>>, _Allocator>;
1722
1723template <ranges::input_range _Range, class _Hash, class _Allocator,
1724 class = enable_if_t<!__is_allocator<_Hash>::value>,
1725 class = enable_if_t<!is_integral<_Hash>::value>,
1726 class = enable_if_t<__is_allocator<_Allocator>::value>>
1727unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
1728 -> unordered_multiset<ranges::range_value_t<_Range>, _Hash, equal_to<ranges::range_value_t<_Range>>, _Allocator>;
1729
1730#endif
1731
15641732template<class _Tp, class _Allocator,
15651733 class = enable_if_t<__is_allocator<_Allocator>::value>>
15661734unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator)
......@@ -1579,7 +1747,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
15791747 size_type __n, const hasher& __hf, const key_equal& __eql)
15801748 : __table_(__hf, __eql)
15811749{
1582 _VSTD::__debug_db_insert_c(this);
15831750 __table_.__rehash_multi(__n);
15841751}
15851752
......@@ -1589,7 +1756,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
15891756 const allocator_type& __a)
15901757 : __table_(__hf, __eql, __a)
15911758{
1592 _VSTD::__debug_db_insert_c(this);
15931759 __table_.__rehash_multi(__n);
15941760}
15951761
......@@ -1598,7 +1764,6 @@ template <class _InputIterator>
15981764unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
15991765 _InputIterator __first, _InputIterator __last)
16001766{
1601 _VSTD::__debug_db_insert_c(this);
16021767 insert(__first, __last);
16031768}
16041769
......@@ -1609,7 +1774,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
16091774 const hasher& __hf, const key_equal& __eql)
16101775 : __table_(__hf, __eql)
16111776{
1612 _VSTD::__debug_db_insert_c(this);
16131777 __table_.__rehash_multi(__n);
16141778 insert(__first, __last);
16151779}
......@@ -1621,7 +1785,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
16211785 const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
16221786 : __table_(__hf, __eql, __a)
16231787{
1624 _VSTD::__debug_db_insert_c(this);
16251788 __table_.__rehash_multi(__n);
16261789 insert(__first, __last);
16271790}
......@@ -1632,7 +1795,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
16321795 const allocator_type& __a)
16331796 : __table_(__a)
16341797{
1635 _VSTD::__debug_db_insert_c(this);
16361798}
16371799
16381800template <class _Value, class _Hash, class _Pred, class _Alloc>
......@@ -1640,7 +1802,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
16401802 const unordered_multiset& __u)
16411803 : __table_(__u.__table_)
16421804{
1643 _VSTD::__debug_db_insert_c(this);
16441805 __table_.__rehash_multi(__u.bucket_count());
16451806 insert(__u.begin(), __u.end());
16461807}
......@@ -1650,7 +1811,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
16501811 const unordered_multiset& __u, const allocator_type& __a)
16511812 : __table_(__u.__table_, __a)
16521813{
1653 _VSTD::__debug_db_insert_c(this);
16541814 __table_.__rehash_multi(__u.bucket_count());
16551815 insert(__u.begin(), __u.end());
16561816}
......@@ -1664,8 +1824,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
16641824 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
16651825 : __table_(_VSTD::move(__u.__table_))
16661826{
1667 _VSTD::__debug_db_insert_c(this);
1668 std::__debug_db_swap(this, std::addressof(__u));
16691827}
16701828
16711829template <class _Value, class _Hash, class _Pred, class _Alloc>
......@@ -1673,22 +1831,18 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
16731831 unordered_multiset&& __u, const allocator_type& __a)
16741832 : __table_(_VSTD::move(__u.__table_), __a)
16751833{
1676 _VSTD::__debug_db_insert_c(this);
16771834 if (__a != __u.get_allocator())
16781835 {
16791836 iterator __i = __u.begin();
16801837 while (__u.size() != 0)
16811838 __table_.__insert_multi(_VSTD::move(__u.__table_.remove(__i++)->__value_));
16821839 }
1683 else
1684 std::__debug_db_swap(this, std::addressof(__u));
16851840}
16861841
16871842template <class _Value, class _Hash, class _Pred, class _Alloc>
16881843unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
16891844 initializer_list<value_type> __il)
16901845{
1691 _VSTD::__debug_db_insert_c(this);
16921846 insert(__il.begin(), __il.end());
16931847}
16941848
......@@ -1698,7 +1852,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
16981852 const key_equal& __eql)
16991853 : __table_(__hf, __eql)
17001854{
1701 _VSTD::__debug_db_insert_c(this);
17021855 __table_.__rehash_multi(__n);
17031856 insert(__il.begin(), __il.end());
17041857}
......@@ -1709,7 +1862,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
17091862 const key_equal& __eql, const allocator_type& __a)
17101863 : __table_(__hf, __eql, __a)
17111864{
1712 _VSTD::__debug_db_insert_c(this);
17131865 __table_.__rehash_multi(__n);
17141866 insert(__il.begin(), __il.end());
17151867}
......@@ -1758,7 +1910,7 @@ swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
17581910 __x.swap(__y);
17591911}
17601912
1761#if _LIBCPP_STD_VER > 17
1913#if _LIBCPP_STD_VER >= 20
17621914template <class _Value, class _Hash, class _Pred, class _Alloc,
17631915 class _Predicate>
17641916inline _LIBCPP_INLINE_VISIBILITY
......@@ -1792,6 +1944,8 @@ operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
17921944 return true;
17931945}
17941946
1947#if _LIBCPP_STD_VER <= 17
1948
17951949template <class _Value, class _Hash, class _Pred, class _Alloc>
17961950inline _LIBCPP_INLINE_VISIBILITY
17971951bool
......@@ -1801,24 +1955,28 @@ operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
18011955 return !(__x == __y);
18021956}
18031957
1958#endif
1959
18041960_LIBCPP_END_NAMESPACE_STD
18051961
1806#if _LIBCPP_STD_VER > 14
1962#if _LIBCPP_STD_VER >= 17
18071963_LIBCPP_BEGIN_NAMESPACE_STD
18081964namespace pmr {
18091965template <class _KeyT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>>
1810using unordered_set = std::unordered_set<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>;
1966using unordered_set _LIBCPP_AVAILABILITY_PMR = std::unordered_set<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>;
18111967
18121968template <class _KeyT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>>
1813using unordered_multiset = std::unordered_multiset<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>;
1969using unordered_multiset _LIBCPP_AVAILABILITY_PMR = std::unordered_multiset<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>;
18141970} // namespace pmr
18151971_LIBCPP_END_NAMESPACE_STD
18161972#endif
18171973
18181974#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
18191975# include <concepts>
1976# include <cstdlib>
18201977# include <functional>
18211978# include <iterator>
1979# include <type_traits>
18221980#endif
18231981
18241982#endif // _LIBCPP_UNORDERED_SET
lib/libcxx/include/utility+30-21
......@@ -84,14 +84,15 @@ struct pair
8484 explicit(see-below) constexpr pair();
8585 explicit(see-below) pair(const T1& x, const T2& y); // constexpr in C++14
8686 template <class U = T1, class V = T2> explicit(see-below) pair(U&&, V&&); // constexpr in C++14
87 template <class U, class V> constexpr explicit(see below) pair(pair<U, V>&); // since C++23
87 template <class U, class V> constexpr explicit(see-below) pair(pair<U, V>&); // since C++23
8888 template <class U, class V> explicit(see-below) pair(const pair<U, V>& p); // constexpr in C++14
8989 template <class U, class V> explicit(see-below) pair(pair<U, V>&& p); // constexpr in C++14
9090 template <class U, class V>
91 constexpr explicit(see below) pair(const pair<U, V>&&); // since C++23
91 constexpr explicit(see-below) pair(const pair<U, V>&&); // since C++23
92 template <pair-like P> constexpr explicit(see-below) pair(P&&); // since C++23
9293 template <class... Args1, class... Args2>
93 pair(piecewise_construct_t, tuple<Args1...> first_args,
94 tuple<Args2...> second_args); // constexpr in C++20
94 pair(piecewise_construct_t, tuple<Args1...> first_args, // constexpr in C++20
95 tuple<Args2...> second_args);
9596
9697 constexpr const pair& operator=(const pair& p) const; // since C++23
9798 template <class U, class V> pair& operator=(const pair<U, V>& p); // constexpr in C++20
......@@ -103,6 +104,8 @@ struct pair
103104 template <class U, class V> pair& operator=(pair<U, V>&& p); // constexpr in C++20
104105 template <class U, class V>
105106 constexpr const pair& operator=(pair<U, V>&& p) const; // since C++23
107 template <pair-like P> constexpr pair& operator=(P&&); // since C++23
108 template <pair-like P> constexpr const pair& operator=(P&&) const; // since C++23
106109
107110 void swap(pair& p) noexcept(is_nothrow_swappable_v<T1> &&
108111 is_nothrow_swappable_v<T2>); // constexpr in C++20
......@@ -117,24 +120,30 @@ struct common_type<pair<T1, T2>, pair<U1, U2>>;
117120
118121template<class T1, class T2> pair(T1, T2) -> pair<T1, T2>;
119122
120template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
121template <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20
122template <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20
123template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20
124template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20
125template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20
126template <class T1, class T2>
127 constexpr common_comparison_type_t<synth-three-way-result<T1>,
128 synth-three-way-result<T2>>
129 operator<=>(const pair<T1,T2>&, const pair<T1,T2>&); // C++20
123template <class T1, class T2, class U1, class U2>
124bool operator==(const pair<T1,T2>&, const pair<U1,U2>&); // constexpr in C++14
125template <class T1, class T2, class U1, class U2>
126bool operator!=(const pair<T1,T2>&, const pair<U1,U2>&); // constexpr in C++14, removed in C++20
127template <class T1, class T2, class U1, class U2>
128bool operator< (const pair<T1,T2>&, const pair<U1,U2>&); // constexpr in C++14, removed in C++20
129template <class T1, class T2, class U1, class U2>
130bool operator> (const pair<T1,T2>&, const pair<U1,U2>&); // constexpr in C++14, removed in C++20
131template <class T1, class T2, class U1, class U2>
132bool operator>=(const pair<T1,T2>&, const pair<U1,U2>&); // constexpr in C++14, removed in C++20
133template <class T1, class T2, class U1, class U2>
134bool operator<=(const pair<T1,T2>&, const pair<U1,U2>&); // constexpr in C++14, removed in C++20
135template <class T1, class T2, class U1, class U2>
136 constexpr common_comparison_type_t<synth-three-way-result<T1,U1>,
137 synth-three-way-result<T2,U2>>
138 operator<=>(const pair<T1,T2>&, const pair<U1,U2>&); // C++20
130139
131140template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&); // constexpr in C++14
132141template <class T1, class T2>
133142void
134143swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20
135144
136template<class T1, class T2>
137constexpr void swap(const pair<T1, T2>& x, const pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); // since C++23
145template<class T1, class T2> // since C++23
146constexpr void swap(const pair<T1, T2>& x, const pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
138147
139148struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
140149inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
......@@ -208,8 +217,8 @@ template<class... T>
208217 using index_sequence_for = make_index_sequence<sizeof...(T)>;
209218
210219template<class T, class U=T>
211 constexpr T exchange(T& obj, U&& new_value)
212 noexcept(is_nothrow_move_constructible<T>::value && is_nothrow_assignable<T&, U>::value); // constexpr in C++17, noexcept in C++23
220 constexpr T exchange(T& obj, U&& new_value) // constexpr in C++17, noexcept in C++23
221 noexcept(is_nothrow_move_constructible<T>::value && is_nothrow_assignable<T&, U>::value);
213222
214223// 20.2.7, in-place construction // C++17
215224struct in_place_t {
......@@ -231,7 +240,7 @@ template <size_t I>
231240
232241// [utility.underlying], to_underlying
233242template <class T>
234 constexpr underlying_type_t<T> to_underlying( T value ) noexcept; // C++2b
243 constexpr underlying_type_t<T> to_underlying( T value ) noexcept; // C++23
235244
236245} // std
237246
......@@ -266,8 +275,8 @@ template <class T>
266275#include <initializer_list>
267276
268277// [tuple.helper]
269#include <__tuple_dir/tuple_element.h>
270#include <__tuple_dir/tuple_size.h>
278#include <__tuple/tuple_element.h>
279#include <__tuple/tuple_size.h>
271280
272281#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
273282# pragma GCC system_header
lib/libcxx/include/valarray+61-47
......@@ -116,6 +116,8 @@ public:
116116 size_t start() const;
117117 size_t size() const;
118118 size_t stride() const;
119
120 friend bool operator==(const slice& x, const slice& y); // since C++20
119121};
120122
121123template <class T>
......@@ -351,8 +353,10 @@ template <class T> unspecified2 end(const valarray<T>& v);
351353#include <__assert> // all public C++ headers provide the assertion handler
352354#include <__config>
353355#include <__functional/operations.h>
356#include <__memory/addressof.h>
354357#include <__memory/allocator.h>
355358#include <__memory/uninitialized_algorithms.h>
359#include <__type_traits/decay.h>
356360#include <__type_traits/remove_reference.h>
357361#include <__utility/move.h>
358362#include <__utility/swap.h>
......@@ -400,10 +404,18 @@ public:
400404 _LIBCPP_INLINE_VISIBILITY size_t start() const {return __start_;}
401405 _LIBCPP_INLINE_VISIBILITY size_t size() const {return __size_;}
402406 _LIBCPP_INLINE_VISIBILITY size_t stride() const {return __stride_;}
407
408#if _LIBCPP_STD_VER >= 20
409
410 _LIBCPP_HIDE_FROM_ABI friend bool operator==(const slice& __x, const slice& __y) {
411 return __x.start() == __y.start() && __x.size() == __y.size() && __x.stride() == __y.stride();
412 }
413
414#endif
403415};
404416
405417template <class _Tp> class _LIBCPP_TEMPLATE_VIS slice_array;
406class _LIBCPP_TYPE_VIS gslice;
418class _LIBCPP_EXPORTED_FROM_ABI gslice;
407419template <class _Tp> class _LIBCPP_TEMPLATE_VIS gslice_array;
408420template <class _Tp> class _LIBCPP_TEMPLATE_VIS mask_array;
409421template <class _Tp> class _LIBCPP_TEMPLATE_VIS indirect_array;
......@@ -432,7 +444,7 @@ template <class _Op, class _A0>
432444struct _UnaryOp
433445{
434446 typedef typename _Op::__result_type __result_type;
435 typedef typename decay<__result_type>::type value_type;
447 using value_type = __decay_t<__result_type>;
436448
437449 _Op __op_;
438450 _A0 __a0_;
......@@ -451,7 +463,7 @@ template <class _Op, class _A0, class _A1>
451463struct _BinaryOp
452464{
453465 typedef typename _Op::__result_type __result_type;
454 typedef typename decay<__result_type>::type value_type;
466 using value_type = __decay_t<__result_type>;
455467
456468 _Op __op_;
457469 _A0 __a0_;
......@@ -1104,18 +1116,18 @@ private:
11041116 valarray& __assign_range(const value_type* __f, const value_type* __l);
11051117};
11061118
1107#if _LIBCPP_STD_VER > 14
1119#if _LIBCPP_STD_VER >= 17
11081120template<class _Tp, size_t _Size>
11091121valarray(const _Tp(&)[_Size], size_t) -> valarray<_Tp>;
11101122#endif
11111123
1112extern template _LIBCPP_FUNC_VIS void valarray<size_t>::resize(size_t, size_t);
1124extern template _LIBCPP_EXPORTED_FROM_ABI void valarray<size_t>::resize(size_t, size_t);
11131125
11141126template <class _Op, class _Tp>
11151127struct _UnaryOp<_Op, valarray<_Tp> >
11161128{
11171129 typedef typename _Op::__result_type __result_type;
1118 typedef typename decay<__result_type>::type value_type;
1130 using value_type = __decay_t<__result_type>;
11191131
11201132 _Op __op_;
11211133 const valarray<_Tp>& __a0_;
......@@ -1134,7 +1146,7 @@ template <class _Op, class _Tp, class _A1>
11341146struct _BinaryOp<_Op, valarray<_Tp>, _A1>
11351147{
11361148 typedef typename _Op::__result_type __result_type;
1137 typedef typename decay<__result_type>::type value_type;
1149 using value_type = __decay_t<__result_type>;
11381150
11391151 _Op __op_;
11401152 const valarray<_Tp>& __a0_;
......@@ -1155,7 +1167,7 @@ template <class _Op, class _A0, class _Tp>
11551167struct _BinaryOp<_Op, _A0, valarray<_Tp> >
11561168{
11571169 typedef typename _Op::__result_type __result_type;
1158 typedef typename decay<__result_type>::type value_type;
1170 using value_type = __decay_t<__result_type>;
11591171
11601172 _Op __op_;
11611173 _A0 __a0_;
......@@ -1176,7 +1188,7 @@ template <class _Op, class _Tp>
11761188struct _BinaryOp<_Op, valarray<_Tp>, valarray<_Tp> >
11771189{
11781190 typedef typename _Op::__result_type __result_type;
1179 typedef typename decay<__result_type>::type value_type;
1191 using value_type = __decay_t<__result_type>;
11801192
11811193 _Op __op_;
11821194 const valarray<_Tp>& __a0_;
......@@ -1326,7 +1338,6 @@ private:
13261338 {}
13271339
13281340 template <class> friend class valarray;
1329 template <class> friend class sliceExpr;
13301341};
13311342
13321343template <class _Tp>
......@@ -1527,7 +1538,7 @@ slice_array<_Tp>::operator=(const value_type& __x) const
15271538
15281539// gslice
15291540
1530class _LIBCPP_TYPE_VIS gslice
1541class _LIBCPP_EXPORTED_FROM_ABI gslice
15311542{
15321543 valarray<size_t> __size_;
15331544 valarray<size_t> __stride_;
......@@ -2818,20 +2829,20 @@ valarray<_Tp>::valarray(size_t __n)
28182829 if (__n)
28192830 {
28202831 __begin_ = __end_ = allocator<value_type>().allocate(__n);
2821#ifndef _LIBCPP_NO_EXCEPTIONS
2832#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
28222833 try
28232834 {
2824#endif // _LIBCPP_NO_EXCEPTIONS
2835#endif // _LIBCPP_HAS_NO_EXCEPTIONS
28252836 for (size_t __n_left = __n; __n_left; --__n_left, ++__end_)
28262837 ::new ((void*)__end_) value_type();
2827#ifndef _LIBCPP_NO_EXCEPTIONS
2838#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
28282839 }
28292840 catch (...)
28302841 {
28312842 __clear(__n);
28322843 throw;
28332844 }
2834#endif // _LIBCPP_NO_EXCEPTIONS
2845#endif // _LIBCPP_HAS_NO_EXCEPTIONS
28352846 }
28362847}
28372848
......@@ -2852,20 +2863,20 @@ valarray<_Tp>::valarray(const value_type* __p, size_t __n)
28522863 if (__n)
28532864 {
28542865 __begin_ = __end_ = allocator<value_type>().allocate(__n);
2855#ifndef _LIBCPP_NO_EXCEPTIONS
2866#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
28562867 try
28572868 {
2858#endif // _LIBCPP_NO_EXCEPTIONS
2869#endif // _LIBCPP_HAS_NO_EXCEPTIONS
28592870 for (size_t __n_left = __n; __n_left; ++__end_, ++__p, --__n_left)
28602871 ::new ((void*)__end_) value_type(*__p);
2861#ifndef _LIBCPP_NO_EXCEPTIONS
2872#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
28622873 }
28632874 catch (...)
28642875 {
28652876 __clear(__n);
28662877 throw;
28672878 }
2868#endif // _LIBCPP_NO_EXCEPTIONS
2879#endif // _LIBCPP_HAS_NO_EXCEPTIONS
28692880 }
28702881}
28712882
......@@ -2877,20 +2888,20 @@ valarray<_Tp>::valarray(const valarray& __v)
28772888 if (__v.size())
28782889 {
28792890 __begin_ = __end_ = allocator<value_type>().allocate(__v.size());
2880#ifndef _LIBCPP_NO_EXCEPTIONS
2891#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
28812892 try
28822893 {
2883#endif // _LIBCPP_NO_EXCEPTIONS
2894#endif // _LIBCPP_HAS_NO_EXCEPTIONS
28842895 for (value_type* __p = __v.__begin_; __p != __v.__end_; ++__end_, ++__p)
28852896 ::new ((void*)__end_) value_type(*__p);
2886#ifndef _LIBCPP_NO_EXCEPTIONS
2897#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
28872898 }
28882899 catch (...)
28892900 {
28902901 __clear(__v.size());
28912902 throw;
28922903 }
2893#endif // _LIBCPP_NO_EXCEPTIONS
2904#endif // _LIBCPP_HAS_NO_EXCEPTIONS
28942905 }
28952906}
28962907
......@@ -2914,21 +2925,21 @@ valarray<_Tp>::valarray(initializer_list<value_type> __il)
29142925 if (__n)
29152926 {
29162927 __begin_ = __end_ = allocator<value_type>().allocate(__n);
2917#ifndef _LIBCPP_NO_EXCEPTIONS
2928#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
29182929 try
29192930 {
2920#endif // _LIBCPP_NO_EXCEPTIONS
2931#endif // _LIBCPP_HAS_NO_EXCEPTIONS
29212932 size_t __n_left = __n;
29222933 for (const value_type* __p = __il.begin(); __n_left; ++__end_, ++__p, --__n_left)
29232934 ::new ((void*)__end_) value_type(*__p);
2924#ifndef _LIBCPP_NO_EXCEPTIONS
2935#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
29252936 }
29262937 catch (...)
29272938 {
29282939 __clear(__n);
29292940 throw;
29302941 }
2931#endif // _LIBCPP_NO_EXCEPTIONS
2942#endif // _LIBCPP_HAS_NO_EXCEPTIONS
29322943 }
29332944}
29342945
......@@ -2943,21 +2954,21 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa)
29432954 if (__n)
29442955 {
29452956 __begin_ = __end_ = allocator<value_type>().allocate(__n);
2946#ifndef _LIBCPP_NO_EXCEPTIONS
2957#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
29472958 try
29482959 {
2949#endif // _LIBCPP_NO_EXCEPTIONS
2960#endif // _LIBCPP_HAS_NO_EXCEPTIONS
29502961 size_t __n_left = __n;
29512962 for (const value_type* __p = __sa.__vp_; __n_left; ++__end_, __p += __sa.__stride_, --__n_left)
29522963 ::new ((void*)__end_) value_type(*__p);
2953#ifndef _LIBCPP_NO_EXCEPTIONS
2964#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
29542965 }
29552966 catch (...)
29562967 {
29572968 __clear(__n);
29582969 throw;
29592970 }
2960#endif // _LIBCPP_NO_EXCEPTIONS
2971#endif // _LIBCPP_HAS_NO_EXCEPTIONS
29612972 }
29622973}
29632974
......@@ -2970,23 +2981,23 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga)
29702981 if (__n)
29712982 {
29722983 __begin_ = __end_ = allocator<value_type>().allocate(__n);
2973#ifndef _LIBCPP_NO_EXCEPTIONS
2984#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
29742985 try
29752986 {
2976#endif // _LIBCPP_NO_EXCEPTIONS
2987#endif // _LIBCPP_HAS_NO_EXCEPTIONS
29772988 typedef const size_t* _Ip;
29782989 const value_type* __s = __ga.__vp_;
29792990 for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_;
29802991 __i != __e; ++__i, ++__end_)
29812992 ::new ((void*)__end_) value_type(__s[*__i]);
2982#ifndef _LIBCPP_NO_EXCEPTIONS
2993#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
29832994 }
29842995 catch (...)
29852996 {
29862997 __clear(__n);
29872998 throw;
29882999 }
2989#endif // _LIBCPP_NO_EXCEPTIONS
3000#endif // _LIBCPP_HAS_NO_EXCEPTIONS
29903001 }
29913002}
29923003
......@@ -2999,23 +3010,23 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma)
29993010 if (__n)
30003011 {
30013012 __begin_ = __end_ = allocator<value_type>().allocate(__n);
3002#ifndef _LIBCPP_NO_EXCEPTIONS
3013#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
30033014 try
30043015 {
3005#endif // _LIBCPP_NO_EXCEPTIONS
3016#endif // _LIBCPP_HAS_NO_EXCEPTIONS
30063017 typedef const size_t* _Ip;
30073018 const value_type* __s = __ma.__vp_;
30083019 for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_;
30093020 __i != __e; ++__i, ++__end_)
30103021 ::new ((void*)__end_) value_type(__s[*__i]);
3011#ifndef _LIBCPP_NO_EXCEPTIONS
3022#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
30123023 }
30133024 catch (...)
30143025 {
30153026 __clear(__n);
30163027 throw;
30173028 }
3018#endif // _LIBCPP_NO_EXCEPTIONS
3029#endif // _LIBCPP_HAS_NO_EXCEPTIONS
30193030 }
30203031}
30213032
......@@ -3028,23 +3039,23 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia)
30283039 if (__n)
30293040 {
30303041 __begin_ = __end_ = allocator<value_type>().allocate(__n);
3031#ifndef _LIBCPP_NO_EXCEPTIONS
3042#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
30323043 try
30333044 {
3034#endif // _LIBCPP_NO_EXCEPTIONS
3045#endif // _LIBCPP_HAS_NO_EXCEPTIONS
30353046 typedef const size_t* _Ip;
30363047 const value_type* __s = __ia.__vp_;
30373048 for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_;
30383049 __i != __e; ++__i, ++__end_)
30393050 ::new ((void*)__end_) value_type(__s[*__i]);
3040#ifndef _LIBCPP_NO_EXCEPTIONS
3051#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
30413052 }
30423053 catch (...)
30433054 {
30443055 __clear(__n);
30453056 throw;
30463057 }
3047#endif // _LIBCPP_NO_EXCEPTIONS
3058#endif // _LIBCPP_HAS_NO_EXCEPTIONS
30483059 }
30493060}
30503061
......@@ -3753,20 +3764,20 @@ valarray<_Tp>::resize(size_t __n, value_type __x)
37533764 if (__n)
37543765 {
37553766 __begin_ = __end_ = allocator<value_type>().allocate(__n);
3756#ifndef _LIBCPP_NO_EXCEPTIONS
3767#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
37573768 try
37583769 {
3759#endif // _LIBCPP_NO_EXCEPTIONS
3770#endif // _LIBCPP_HAS_NO_EXCEPTIONS
37603771 for (size_t __n_left = __n; __n_left; --__n_left, ++__end_)
37613772 ::new ((void*)__end_) value_type(__x);
3762#ifndef _LIBCPP_NO_EXCEPTIONS
3773#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
37633774 }
37643775 catch (...)
37653776 {
37663777 __clear(__n);
37673778 throw;
37683779 }
3769#endif // _LIBCPP_NO_EXCEPTIONS
3780#endif // _LIBCPP_HAS_NO_EXCEPTIONS
37703781 }
37713782}
37723783
......@@ -4933,8 +4944,11 @@ _LIBCPP_POP_MACROS
49334944#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
49344945# include <algorithm>
49354946# include <concepts>
4947# include <cstdlib>
49364948# include <cstring>
49374949# include <functional>
4950# include <stdexcept>
4951# include <type_traits>
49384952#endif
49394953
49404954#endif // _LIBCPP_VALARRAY
lib/libcxx/include/variant+35-31
......@@ -210,10 +210,12 @@ namespace std {
210210#include <__compare/compare_three_way_result.h>
211211#include <__compare/three_way_comparable.h>
212212#include <__config>
213#include <__exception/exception.h>
213214#include <__functional/hash.h>
214215#include <__functional/invoke.h>
215216#include <__functional/operations.h>
216217#include <__functional/unary_function.h>
218#include <__memory/addressof.h>
217219#include <__type_traits/add_const.h>
218220#include <__type_traits/add_cv.h>
219221#include <__type_traits/add_pointer.h>
......@@ -231,12 +233,13 @@ namespace std {
231233#include <__type_traits/remove_const.h>
232234#include <__type_traits/type_identity.h>
233235#include <__type_traits/void_t.h>
236#include <__utility/declval.h>
234237#include <__utility/forward.h>
235238#include <__utility/in_place.h>
236239#include <__utility/move.h>
237240#include <__utility/swap.h>
238241#include <__variant/monostate.h>
239#include <exception>
242#include <__verbose_abort>
240243#include <initializer_list>
241244#include <limits>
242245#include <new>
......@@ -257,7 +260,7 @@ _LIBCPP_PUSH_MACROS
257260
258261namespace std { // explicitly not using versioning namespace
259262
260class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception {
263class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception {
261264public:
262265 const char* what() const _NOEXCEPT override;
263266};
......@@ -266,7 +269,7 @@ public:
266269
267270_LIBCPP_BEGIN_NAMESPACE_STD
268271
269#if _LIBCPP_STD_VER > 14
272#if _LIBCPP_STD_VER >= 17
270273
271274// Light N-dimensional array of function pointers. Used in place of std::array to avoid
272275// adding a dependency.
......@@ -285,10 +288,10 @@ _LIBCPP_NORETURN
285288inline _LIBCPP_HIDE_FROM_ABI
286289_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
287290void __throw_bad_variant_access() {
288#ifndef _LIBCPP_NO_EXCEPTIONS
291#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
289292 throw bad_variant_access();
290293#else
291 _VSTD::abort();
294 _LIBCPP_VERBOSE_ABORT("bad_variant_access was thrown in -fno-exceptions mode");
292295#endif
293296}
294297
......@@ -547,7 +550,7 @@ private:
547550 }
548551
549552 template <class _Fp, class... _Fs>
550 static constexpr void __std_visit_visitor_return_type_check() {
553 static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_visitor_return_type_check() {
551554 static_assert(
552555 __all<is_same_v<_Fp, _Fs>...>::value,
553556 "`std::visit` requires the visitor to have a single return type.");
......@@ -594,9 +597,9 @@ private:
594597 template <class _Fp, class _Vp, class... _Vs>
595598 _LIBCPP_HIDE_FROM_ABI
596599 static constexpr auto __make_fdiagonal() {
597 constexpr size_t _Np = __remove_cvref_t<_Vp>::__size();
598 static_assert(__all<(_Np == __remove_cvref_t<_Vs>::__size())...>::value);
599 return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{});
600 constexpr size_t __np = __remove_cvref_t<_Vp>::__size();
601 static_assert(__all<(__np == __remove_cvref_t<_Vs>::__size())...>::value);
602 return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<__np>{});
600603 }
601604
602605 template <class _Fp, class... _Vs, size_t... _Is>
......@@ -660,7 +663,7 @@ struct __variant {
660663 _VSTD::forward<_Vs>(__vs)...);
661664 }
662665
663#if _LIBCPP_STD_VER > 17
666#if _LIBCPP_STD_VER >= 20
664667 template <class _Rp, class _Visitor, class... _Vs>
665668 _LIBCPP_HIDE_FROM_ABI
666669 static constexpr _Rp __visit_value(_Visitor&& __visitor,
......@@ -673,7 +676,7 @@ struct __variant {
673676
674677private:
675678 template <class _Visitor, class... _Values>
676 static constexpr void __std_visit_exhaustive_visitor_check() {
679 static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_exhaustive_visitor_check() {
677680 static_assert(is_invocable_v<_Visitor, _Values...>,
678681 "`std::visit` requires the visitor to be exhaustive.");
679682 }
......@@ -692,7 +695,7 @@ private:
692695 _Visitor&& __visitor;
693696 };
694697
695#if _LIBCPP_STD_VER > 17
698#if _LIBCPP_STD_VER >= 20
696699 template <class _Rp, class _Visitor>
697700 struct __value_visitor_return_type {
698701 template <class... _Alts>
......@@ -721,7 +724,7 @@ private:
721724 return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)};
722725 }
723726
724#if _LIBCPP_STD_VER > 17
727#if _LIBCPP_STD_VER >= 20
725728 template <class _Rp, class _Visitor>
726729 _LIBCPP_HIDE_FROM_ABI
727730 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
......@@ -1034,10 +1037,10 @@ protected:
10341037 __a.__value = _VSTD::forward<_Arg>(__arg);
10351038 } else {
10361039 struct {
1037 void operator()(true_type) const {
1040 _LIBCPP_HIDE_FROM_ABI void operator()(true_type) const {
10381041 __this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg));
10391042 }
1040 void operator()(false_type) const {
1043 _LIBCPP_HIDE_FROM_ABI void operator()(false_type) const {
10411044 __this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg)));
10421045 }
10431046 __assignment* __this;
......@@ -1155,10 +1158,10 @@ class _LIBCPP_TEMPLATE_VIS __impl
11551158
11561159public:
11571160 using __base_type::__base_type; // get in_place_index_t constructor & friends
1158 __impl(__impl const&) = default;
1159 __impl(__impl&&) = default;
1160 __impl& operator=(__impl const&) = default;
1161 __impl& operator=(__impl&&) = default;
1161 _LIBCPP_HIDE_FROM_ABI __impl(__impl const&) = default;
1162 _LIBCPP_HIDE_FROM_ABI __impl(__impl&&) = default;
1163 _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl const&) = default;
1164 _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl&&) = default;
11621165
11631166 template <size_t _Ip, class _Arg>
11641167 _LIBCPP_HIDE_FROM_ABI
......@@ -1187,7 +1190,7 @@ public:
11871190 _VSTD::swap(__lhs, __rhs);
11881191 }
11891192 __impl __tmp(_VSTD::move(*__rhs));
1190#ifndef _LIBCPP_NO_EXCEPTIONS
1193#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
11911194 if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) {
11921195 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
11931196 } else {
......@@ -1271,7 +1274,7 @@ struct __all_overloads : _Bases... {
12711274 using _Bases::operator()...;
12721275};
12731276
1274template <class IdxSeq>
1277template <class _IdxSeq>
12751278struct __make_overloads_imp;
12761279
12771280template <size_t ..._Idx>
......@@ -1291,7 +1294,7 @@ using __best_match_t =
12911294} // namespace __variant_detail
12921295
12931296template <class... _Types>
1294class _LIBCPP_TEMPLATE_VIS variant
1297class _LIBCPP_TEMPLATE_VIS _LIBCPP_DECLSPEC_EMPTY_BASES variant
12951298 : private __sfinae_ctor_base<
12961299 __all<is_copy_constructible_v<_Types>...>::value,
12971300 __all<is_move_constructible_v<_Types>...>::value>,
......@@ -1323,8 +1326,8 @@ public:
13231326 constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
13241327 : __impl_(in_place_index<0>) {}
13251328
1326 constexpr variant(const variant&) = default;
1327 constexpr variant(variant&&) = default;
1329 _LIBCPP_HIDE_FROM_ABI constexpr variant(const variant&) = default;
1330 _LIBCPP_HIDE_FROM_ABI constexpr variant(variant&&) = default;
13281331
13291332 template <
13301333 class _Arg,
......@@ -1393,10 +1396,10 @@ public:
13931396 is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>)
13941397 : __impl_(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
13951398
1396 ~variant() = default;
1399 _LIBCPP_HIDE_FROM_ABI ~variant() = default;
13971400
1398 constexpr variant& operator=(const variant&) = default;
1399 constexpr variant& operator=(variant&&) = default;
1401 _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(const variant&) = default;
1402 _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(variant&&) = default;
14001403
14011404 template <
14021405 class _Arg,
......@@ -1652,7 +1655,7 @@ constexpr bool operator==(const variant<_Types...>& __lhs,
16521655 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
16531656}
16541657
1655# if _LIBCPP_STD_VER > 17
1658# if _LIBCPP_STD_VER >= 20
16561659
16571660template <class... _Types> requires (three_way_comparable<_Types> && ...)
16581661_LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t<compare_three_way_result_t<_Types>...>
......@@ -1671,7 +1674,7 @@ operator<=>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
16711674 return __variant::__visit_value_at(__lhs.index(), __three_way, __lhs, __rhs);
16721675}
16731676
1674# endif // _LIBCPP_STD_VER > 17
1677# endif // _LIBCPP_STD_VER >= 20
16751678
16761679template <class... _Types>
16771680_LIBCPP_HIDE_FROM_ABI
......@@ -1757,7 +1760,7 @@ constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
17571760 _VSTD::forward<_Vs>(__vs)...);
17581761}
17591762
1760#if _LIBCPP_STD_VER > 17
1763#if _LIBCPP_STD_VER >= 20
17611764template <
17621765 class _Rp, class _Visitor, class... _Vs,
17631766 typename = void_t<decltype(_VSTD::__as_variant(std::declval<_Vs>()))...> >
......@@ -1824,13 +1827,14 @@ constexpr auto&& __unchecked_get(variant<_Types...>& __v) noexcept {
18241827 return std::__unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
18251828}
18261829
1827#endif // _LIBCPP_STD_VER > 14
1830#endif // _LIBCPP_STD_VER >= 17
18281831
18291832_LIBCPP_END_NAMESPACE_STD
18301833
18311834_LIBCPP_POP_MACROS
18321835
18331836#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1837# include <exception>
18341838# include <type_traits>
18351839# include <typeinfo>
18361840# include <utility>
lib/libcxx/include/vector+474-375
......@@ -41,6 +41,8 @@ public:
4141 vector(size_type n, const value_type& value, const allocator_type& = allocator_type());
4242 template <class InputIterator>
4343 vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type());
44 template<container-compatible-range<T> R>
45 constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
4446 vector(const vector& x);
4547 vector(vector&& x)
4648 noexcept(is_nothrow_move_constructible<allocator_type>::value);
......@@ -55,6 +57,8 @@ public:
5557 vector& operator=(initializer_list<value_type> il);
5658 template <class InputIterator>
5759 void assign(InputIterator first, InputIterator last);
60 template<container-compatible-range<T> R>
61 constexpr void assign_range(R&& rg); // C++23
5862 void assign(size_type n, const value_type& u);
5963 void assign(initializer_list<value_type> il);
6064
......@@ -99,6 +103,8 @@ public:
99103 void push_back(value_type&& x);
100104 template <class... Args>
101105 reference emplace_back(Args&&... args); // reference in C++17
106 template<container-compatible-range<T> R>
107 constexpr void append_range(R&& rg); // C++23
102108 void pop_back();
103109
104110 template <class... Args> iterator emplace(const_iterator position, Args&&... args);
......@@ -107,6 +113,8 @@ public:
107113 iterator insert(const_iterator position, size_type n, const value_type& x);
108114 template <class InputIterator>
109115 iterator insert(const_iterator position, InputIterator first, InputIterator last);
116 template<container-compatible-range<T> R>
117 constexpr iterator insert_range(const_iterator position, R&& rg); // C++23
110118 iterator insert(const_iterator position, initializer_list<value_type> il);
111119
112120 iterator erase(const_iterator position);
......@@ -165,6 +173,8 @@ public:
165173 vector(size_type n, const value_type& value, const allocator_type& = allocator_type());
166174 template <class InputIterator>
167175 vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type());
176 template<container-compatible-range<bool> R>
177 constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator());
168178 vector(const vector& x);
169179 vector(vector&& x)
170180 noexcept(is_nothrow_move_constructible<allocator_type>::value);
......@@ -179,6 +189,8 @@ public:
179189 vector& operator=(initializer_list<value_type> il);
180190 template <class InputIterator>
181191 void assign(InputIterator first, InputIterator last);
192 template<container-compatible-range<T> R>
193 constexpr void assign_range(R&& rg); // C++23
182194 void assign(size_type n, const value_type& u);
183195 void assign(initializer_list<value_type> il);
184196
......@@ -218,6 +230,8 @@ public:
218230
219231 void push_back(const value_type& x);
220232 template <class... Args> reference emplace_back(Args&&... args); // C++14; reference in C++17
233 template<container-compatible-range<T> R>
234 constexpr void append_range(R&& rg); // C++23
221235 void pop_back();
222236
223237 template <class... Args> iterator emplace(const_iterator position, Args&&... args); // C++14
......@@ -225,6 +239,8 @@ public:
225239 iterator insert(const_iterator position, size_type n, const value_type& x);
226240 template <class InputIterator>
227241 iterator insert(const_iterator position, InputIterator first, InputIterator last);
242 template<container-compatible-range<T> R>
243 constexpr iterator insert_range(const_iterator position, R&& rg); // C++23
228244 iterator insert(const_iterator position, initializer_list<value_type> il);
229245
230246 iterator erase(const_iterator position);
......@@ -247,14 +263,21 @@ template <class InputIterator, class Allocator = allocator<typename iterator_tra
247263 vector(InputIterator, InputIterator, Allocator = Allocator())
248264 -> vector<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
249265
266template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
267 vector(from_range_t, R&&, Allocator = Allocator())
268 -> vector<ranges::range_value_t<R>, Allocator>; // C++23
269
250270template <class Allocator> struct hash<std::vector<bool, Allocator>>;
251271
252template <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
253template <class T, class Allocator> bool operator< (const vector<T,Allocator>& x, const vector<T,Allocator>& y);
254template <class T, class Allocator> bool operator!=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
255template <class T, class Allocator> bool operator> (const vector<T,Allocator>& x, const vector<T,Allocator>& y);
256template <class T, class Allocator> bool operator>=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
257template <class T, class Allocator> bool operator<=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
272template <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y); // constexpr since C++20
273template <class T, class Allocator> bool operator!=(const vector<T,Allocator>& x, const vector<T,Allocator>& y); // removed in C++20
274template <class T, class Allocator> bool operator< (const vector<T,Allocator>& x, const vector<T,Allocator>& y); // removed in C++20
275template <class T, class Allocator> bool operator> (const vector<T,Allocator>& x, const vector<T,Allocator>& y); // removed in C++20
276template <class T, class Allocator> bool operator>=(const vector<T,Allocator>& x, const vector<T,Allocator>& y); // removed in C++20
277template <class T, class Allocator> bool operator<=(const vector<T,Allocator>& x, const vector<T,Allocator>& y); // removed in C++20
278template <class T, class Allocator> constexpr
279 constexpr synth-three-way-result<T> operator<=>(const vector<T, Allocator>& x,
280 const vector<T, Allocator>& y); // since C++20
258281
259282template <class T, class Allocator>
260283void swap(vector<T,Allocator>& x, vector<T,Allocator>& y)
......@@ -262,10 +285,10 @@ void swap(vector<T,Allocator>& x, vector<T,Allocator>& y)
262285
263286template <class T, class Allocator, class U>
264287typename vector<T, Allocator>::size_type
265erase(vector<T, Allocator>& c, const U& value); // C++20
288erase(vector<T, Allocator>& c, const U& value); // since C++20
266289template <class T, class Allocator, class Predicate>
267290typename vector<T, Allocator>::size_type
268erase_if(vector<T, Allocator>& c, Predicate pred); // C++20
291erase_if(vector<T, Allocator>& c, Predicate pred); // since C++20
269292
270293
271294template<class T>
......@@ -281,44 +304,57 @@ template<class T, class charT> requires is-vector-bool-reference<T> // Since C++
281304#include <__algorithm/copy.h>
282305#include <__algorithm/equal.h>
283306#include <__algorithm/fill_n.h>
307#include <__algorithm/iterator_operations.h>
284308#include <__algorithm/lexicographical_compare.h>
309#include <__algorithm/lexicographical_compare_three_way.h>
285310#include <__algorithm/remove.h>
286311#include <__algorithm/remove_if.h>
287312#include <__algorithm/rotate.h>
288313#include <__algorithm/unwrap_iter.h>
289314#include <__assert> // all public C++ headers provide the assertion handler
315#include <__availability>
290316#include <__bit_reference>
291317#include <__concepts/same_as.h>
292318#include <__config>
293#include <__debug>
294319#include <__format/enable_insertable.h>
295320#include <__format/formatter.h>
321#include <__format/formatter_bool.h>
296322#include <__functional/hash.h>
297323#include <__functional/unary_function.h>
298324#include <__iterator/advance.h>
325#include <__iterator/distance.h>
299326#include <__iterator/iterator_traits.h>
300327#include <__iterator/reverse_iterator.h>
301328#include <__iterator/wrap_iter.h>
329#include <__memory/addressof.h>
302330#include <__memory/allocate_at_least.h>
331#include <__memory/allocator_traits.h>
303332#include <__memory/pointer_traits.h>
304333#include <__memory/swap_allocator.h>
305334#include <__memory/temp_value.h>
306335#include <__memory/uninitialized_algorithms.h>
307336#include <__memory_resource/polymorphic_allocator.h>
337#include <__ranges/access.h>
338#include <__ranges/concepts.h>
339#include <__ranges/container_compatible_range.h>
340#include <__ranges/from_range.h>
341#include <__ranges/size.h>
308342#include <__split_buffer>
309343#include <__type_traits/is_allocator.h>
344#include <__type_traits/is_constructible.h>
345#include <__type_traits/is_nothrow_move_assignable.h>
310346#include <__type_traits/noexcept_move_assign_container.h>
347#include <__type_traits/type_identity.h>
311348#include <__utility/exception_guard.h>
312349#include <__utility/forward.h>
313350#include <__utility/move.h>
351#include <__utility/pair.h>
314352#include <__utility/swap.h>
315353#include <climits>
316#include <cstdlib>
317354#include <cstring>
318355#include <iosfwd> // for forward declaration of vector
319356#include <limits>
320357#include <stdexcept>
321#include <type_traits>
322358#include <version>
323359
324360// standard-mandated includes
......@@ -341,7 +377,6 @@ template<class T, class charT> requires is-vector-bool-reference<T> // Since C++
341377_LIBCPP_PUSH_MACROS
342378#include <__undef_macros>
343379
344
345380_LIBCPP_BEGIN_NAMESPACE_STD
346381
347382template <class _Tp, class _Allocator /* = allocator<_Tp> */>
......@@ -376,7 +411,6 @@ public:
376411 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
377412 vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
378413 {
379 std::__debug_db_insert_c(this);
380414 }
381415 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(const allocator_type& __a)
382416#if _LIBCPP_STD_VER <= 14
......@@ -386,10 +420,9 @@ public:
386420#endif
387421 : __end_cap_(nullptr, __a)
388422 {
389 std::__debug_db_insert_c(this);
390423 }
391424 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n);
392#if _LIBCPP_STD_VER > 11
425#if _LIBCPP_STD_VER >= 14
393426 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n, const allocator_type& __a);
394427#endif
395428 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(size_type __n, const value_type& __x);
......@@ -399,7 +432,6 @@ public:
399432 vector(size_type __n, const value_type& __x, const allocator_type& __a)
400433 : __end_cap_(nullptr, __a)
401434 {
402 std::__debug_db_insert_c(this);
403435 if (__n > 0)
404436 {
405437 __vallocate(__n);
......@@ -408,12 +440,12 @@ public:
408440 }
409441
410442 template <class _InputIterator,
411 __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
443 __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
412444 is_constructible<value_type, typename iterator_traits<_InputIterator>::reference>::value,
413445 int> = 0>
414446 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(_InputIterator __first, _InputIterator __last);
415447 template <class _InputIterator,
416 __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
448 __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
417449 is_constructible<value_type, typename iterator_traits<_InputIterator>::reference>::value,
418450 int> = 0>
419451 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
......@@ -421,29 +453,41 @@ public:
421453
422454 template <
423455 class _ForwardIterator,
424 __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
456 __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
425457 is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
426458 int> = 0>
427459 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(_ForwardIterator __first, _ForwardIterator __last);
428460
429461 template <class _ForwardIterator,
430 __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
462 __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
431463 is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
432464 int> = 0>
433465 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
434466 vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a);
435467
468#if _LIBCPP_STD_VER >= 23
469 template <_ContainerCompatibleRange<_Tp> _Range>
470 _LIBCPP_HIDE_FROM_ABI constexpr vector(from_range_t, _Range&& __range,
471 const allocator_type& __alloc = allocator_type()) : __end_cap_(nullptr, __alloc) {
472 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
473 auto __n = static_cast<size_type>(ranges::distance(__range));
474 __init_with_size(ranges::begin(__range), ranges::end(__range), __n);
475
476 } else {
477 __init_with_sentinel(ranges::begin(__range), ranges::end(__range));
478 }
479 }
480#endif
481
436482private:
437483 class __destroy_vector {
438484 public:
439 _LIBCPP_CONSTEXPR __destroy_vector(vector& __vec) : __vec_(__vec) {}
485 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __destroy_vector(vector& __vec) : __vec_(__vec) {}
440486
441487 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator()() {
442 __vec_.__annotate_delete();
443 std::__debug_db_erase_c(std::addressof(__vec_));
444
445488 if (__vec_.__begin_ != nullptr) {
446489 __vec_.__clear();
490 __vec_.__annotate_delete();
447491 __alloc_traits::deallocate(__vec_.__alloc(), __vec_.__begin_, __vec_.capacity());
448492 }
449493 }
......@@ -474,7 +518,7 @@ public:
474518
475519 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
476520 vector(vector&& __x)
477#if _LIBCPP_STD_VER > 14
521#if _LIBCPP_STD_VER >= 17
478522 noexcept;
479523#else
480524 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
......@@ -487,17 +531,31 @@ public:
487531 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
488532
489533 template <class _InputIterator,
490 __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
534 __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
491535 is_constructible<value_type, typename iterator_traits<_InputIterator>::reference>::value,
492536 int> = 0>
493537 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(_InputIterator __first, _InputIterator __last);
494538 template <
495539 class _ForwardIterator,
496 __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
540 __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
497541 is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
498542 int> = 0>
499543 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(_ForwardIterator __first, _ForwardIterator __last);
500544
545#if _LIBCPP_STD_VER >= 23
546 template <_ContainerCompatibleRange<_Tp> _Range>
547 _LIBCPP_HIDE_FROM_ABI
548 constexpr void assign_range(_Range&& __range) {
549 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
550 auto __n = static_cast<size_type>(ranges::distance(__range));
551 __assign_with_size(ranges::begin(__range), ranges::end(__range), __n);
552
553 } else {
554 __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
555 }
556 }
557#endif
558
501559 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const_reference __u);
502560
503561#ifndef _LIBCPP_CXX03_LANG
......@@ -561,22 +619,22 @@ public:
561619
562620 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT
563621 {
564 _LIBCPP_ASSERT(!empty(), "front() called on an empty vector");
622 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
565623 return *this->__begin_;
566624 }
567625 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT
568626 {
569 _LIBCPP_ASSERT(!empty(), "front() called on an empty vector");
627 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
570628 return *this->__begin_;
571629 }
572630 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT
573631 {
574 _LIBCPP_ASSERT(!empty(), "back() called on an empty vector");
632 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
575633 return *(this->__end_ - 1);
576634 }
577635 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT
578636 {
579 _LIBCPP_ASSERT(!empty(), "back() called on an empty vector");
637 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
580638 return *(this->__end_ - 1);
581639 }
582640
......@@ -594,12 +652,20 @@ public:
594652
595653 template <class... _Args>
596654 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
597#if _LIBCPP_STD_VER > 14
655#if _LIBCPP_STD_VER >= 17
598656 reference emplace_back(_Args&&... __args);
599657#else
600658 void emplace_back(_Args&&... __args);
601659#endif
602660
661#if _LIBCPP_STD_VER >= 23
662 template <_ContainerCompatibleRange<_Tp> _Range>
663 _LIBCPP_HIDE_FROM_ABI
664 constexpr void append_range(_Range&& __range) {
665 insert_range(end(), std::forward<_Range>(__range));
666 }
667#endif
668
603669 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
604670 void pop_back();
605671
......@@ -613,15 +679,29 @@ public:
613679 iterator insert(const_iterator __position, size_type __n, const_reference __x);
614680
615681 template <class _InputIterator,
616 __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
682 __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
617683 is_constructible< value_type, typename iterator_traits<_InputIterator>::reference>::value,
618684 int> = 0>
619685 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
620686 insert(const_iterator __position, _InputIterator __first, _InputIterator __last);
621687
688#if _LIBCPP_STD_VER >= 23
689 template <_ContainerCompatibleRange<_Tp> _Range>
690 _LIBCPP_HIDE_FROM_ABI
691 constexpr iterator insert_range(const_iterator __position, _Range&& __range) {
692 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
693 auto __n = static_cast<size_type>(ranges::distance(__range));
694 return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n);
695
696 } else {
697 return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
698 }
699 }
700#endif
701
622702 template <
623703 class _ForwardIterator,
624 __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
704 __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
625705 is_constructible< value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
626706 int> = 0>
627707 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
......@@ -642,7 +722,6 @@ public:
642722 size_type __old_size = size();
643723 __clear();
644724 __annotate_shrink(__old_size);
645 std::__debug_db_invalidate_all(this);
646725 }
647726
648727 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz);
......@@ -658,23 +737,12 @@ public:
658737
659738 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
660739
661#ifdef _LIBCPP_ENABLE_DEBUG_MODE
662
663 bool __dereferenceable(const const_iterator* __i) const;
664 bool __decrementable(const const_iterator* __i) const;
665 bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
666 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
667
668#endif // _LIBCPP_ENABLE_DEBUG_MODE
669
670740private:
671741 pointer __begin_ = nullptr;
672742 pointer __end_ = nullptr;
673743 __compressed_pair<pointer, allocator_type> __end_cap_ =
674744 __compressed_pair<pointer, allocator_type>(nullptr, __default_init_tag());
675745
676 _LIBCPP_HIDE_FROM_ABI void __invalidate_iterators_past(pointer __new_last);
677
678746 // Allocate space for __n objects
679747 // throws length_error if __n > max_size()
680748 // throws (probably bad_alloc) if memory run out
......@@ -698,16 +766,56 @@ private:
698766 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
699767 void __construct_at_end(size_type __n, const_reference __x);
700768
701 template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value, int> = 0>
702 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
703 __construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n);
769 template <class _InputIterator, class _Sentinel>
770 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
771 void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __n) {
772 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
773
774 if (__n > 0) {
775 __vallocate(__n);
776 __construct_at_end(__first, __last, __n);
777 }
778
779 __guard.__complete();
780 }
781
782 template <class _InputIterator, class _Sentinel>
783 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
784 void __init_with_sentinel(_InputIterator __first, _Sentinel __last) {
785 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
786
787 for (; __first != __last; ++__first)
788 emplace_back(*__first);
789
790 __guard.__complete();
791 }
792
793 template <class _Iterator, class _Sentinel>
794 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
795 void __assign_with_sentinel(_Iterator __first, _Sentinel __last);
796
797 template <class _ForwardIterator, class _Sentinel>
798 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
799 void __assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n);
800
801 template <class _InputIterator, class _Sentinel>
802 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
803 iterator __insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last);
804
805 template <class _Iterator, class _Sentinel>
806 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
807 iterator __insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n);
808
809 template <class _InputIterator, class _Sentinel>
810 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
811 void __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n);
704812
705813 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);
706814 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x);
707815 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
708 iterator __make_iter(pointer __p) _NOEXCEPT { return iterator(this, __p); }
816 iterator __make_iter(pointer __p) _NOEXCEPT { return iterator(__p); }
709817 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
710 const_iterator __make_iter(const_pointer __p) const _NOEXCEPT { return const_iterator(this, __p); }
818 const_iterator __make_iter(const_pointer __p) const _NOEXCEPT { return const_iterator(__p); }
711819 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v);
712820 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p);
713821 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_range(pointer __from_s, pointer __from_e, pointer __to);
......@@ -718,8 +826,6 @@ private:
718826 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
719827 void __destruct_at_end(pointer __new_last) _NOEXCEPT
720828 {
721 if (!__libcpp_is_constant_evaluated())
722 __invalidate_iterators_past(__new_last);
723829 size_type __old_size = size();
724830 __base_destruct_at_end(__new_last);
725831 __annotate_shrink(__old_size);
......@@ -734,17 +840,19 @@ private:
734840 inline void __emplace_back_slow_path(_Args&&... __args);
735841
736842 // The following functions are no-ops outside of AddressSanitizer mode.
737 // We call annotatations only for the default Allocator because other allocators
738 // may not meet the AddressSanitizer alignment constraints.
739 // See the documentation for __sanitizer_annotate_contiguous_container for more details.
843 // We call annotations for every allocator, unless explicitly disabled.
844 //
845 // To disable annotations for a particular allocator, change value of
846 // __asan_annotate_container_with_allocator to false.
847 // For more details, see the "Using libc++" documentation page or
848 // the documentation for __sanitizer_annotate_contiguous_container.
740849#ifndef _LIBCPP_HAS_NO_ASAN
741850 _LIBCPP_CONSTEXPR_SINCE_CXX20
742851 void __annotate_contiguous_container(const void *__beg, const void *__end,
743852 const void *__old_mid,
744853 const void *__new_mid) const
745854 {
746
747 if (!__libcpp_is_constant_evaluated() && __beg && is_same<allocator_type, __default_allocator_type>::value)
855 if (!__libcpp_is_constant_evaluated() && __beg != nullptr && __asan_annotate_container_with_allocator<_Allocator>::value)
748856 __sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid);
749857 }
750858#else
......@@ -866,6 +974,7 @@ private:
866974 if (__alloc() != __c.__alloc())
867975 {
868976 __clear();
977 __annotate_delete();
869978 __alloc_traits::deallocate(__alloc(), this->__begin_, capacity());
870979 this->__begin_ = this->__end_ = __end_cap() = nullptr;
871980 }
......@@ -892,7 +1001,7 @@ private:
8921001#if _LIBCPP_STD_VER >= 17
8931002template<class _InputIterator,
8941003 class _Alloc = allocator<__iter_value_type<_InputIterator>>,
895 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1004 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
8961005 class = enable_if_t<__is_allocator<_Alloc>::value>
8971006 >
8981007vector(_InputIterator, _InputIterator)
......@@ -900,13 +1009,22 @@ vector(_InputIterator, _InputIterator)
9001009
9011010template<class _InputIterator,
9021011 class _Alloc,
903 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1012 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
9041013 class = enable_if_t<__is_allocator<_Alloc>::value>
9051014 >
9061015vector(_InputIterator, _InputIterator, _Alloc)
9071016 -> vector<__iter_value_type<_InputIterator>, _Alloc>;
9081017#endif
9091018
1019#if _LIBCPP_STD_VER >= 23
1020template <ranges::input_range _Range,
1021 class _Alloc = allocator<ranges::range_value_t<_Range>>,
1022 class = enable_if_t<__is_allocator<_Alloc>::value>
1023 >
1024vector(from_range_t, _Range&&, _Alloc = _Alloc())
1025 -> vector<ranges::range_value_t<_Range>, _Alloc>;
1026#endif
1027
9101028template <class _Tp, class _Allocator>
9111029_LIBCPP_CONSTEXPR_SINCE_CXX20
9121030void
......@@ -922,7 +1040,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
9221040 std::swap(this->__end_cap(), __v.__end_cap());
9231041 __v.__first_ = __v.__begin_;
9241042 __annotate_new(size());
925 std::__debug_db_invalidate_all(this);
9261043}
9271044
9281045template <class _Tp, class _Allocator>
......@@ -942,7 +1059,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
9421059 std::swap(this->__end_cap(), __v.__end_cap());
9431060 __v.__first_ = __v.__begin_;
9441061 __annotate_new(size());
945 std::__debug_db_invalidate_all(this);
9461062 return __r;
9471063}
9481064
......@@ -954,6 +1070,7 @@ vector<_Tp, _Allocator>::__vdeallocate() _NOEXCEPT
9541070 if (this->__begin_ != nullptr)
9551071 {
9561072 clear();
1073 __annotate_delete();
9571074 __alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity());
9581075 this->__begin_ = this->__end_ = this->__end_cap() = nullptr;
9591076 }
......@@ -1021,10 +1138,9 @@ vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
10211138}
10221139
10231140template <class _Tp, class _Allocator>
1024template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value, int> >
1141template <class _InputIterator, class _Sentinel>
10251142_LIBCPP_CONSTEXPR_SINCE_CXX20 void
1026vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n)
1027{
1143vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
10281144 _ConstructTransaction __tx(*this, __n);
10291145 __tx.__pos_ = std::__uninitialized_allocator_copy(__alloc(), __first, __last, __tx.__pos_);
10301146}
......@@ -1074,7 +1190,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
10741190vector<_Tp, _Allocator>::vector(size_type __n)
10751191{
10761192 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
1077 std::__debug_db_insert_c(this);
10781193 if (__n > 0)
10791194 {
10801195 __vallocate(__n);
......@@ -1083,14 +1198,13 @@ vector<_Tp, _Allocator>::vector(size_type __n)
10831198 __guard.__complete();
10841199}
10851200
1086#if _LIBCPP_STD_VER > 11
1201#if _LIBCPP_STD_VER >= 14
10871202template <class _Tp, class _Allocator>
10881203_LIBCPP_CONSTEXPR_SINCE_CXX20
10891204vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a)
10901205 : __end_cap_(nullptr, __a)
10911206{
10921207 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
1093 std::__debug_db_insert_c(this);
10941208 if (__n > 0)
10951209 {
10961210 __vallocate(__n);
......@@ -1105,7 +1219,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
11051219vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x)
11061220{
11071221 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
1108 std::__debug_db_insert_c(this);
11091222 if (__n > 0)
11101223 {
11111224 __vallocate(__n);
......@@ -1115,69 +1228,47 @@ vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x)
11151228}
11161229
11171230template <class _Tp, class _Allocator>
1118template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
1231template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
11191232 is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value,
11201233 int> >
11211234_LIBCPP_CONSTEXPR_SINCE_CXX20
11221235vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last)
11231236{
1124 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
1125 std::__debug_db_insert_c(this);
1126 for (; __first != __last; ++__first)
1127 emplace_back(*__first);
1128 __guard.__complete();
1237 __init_with_sentinel(__first, __last);
11291238}
11301239
11311240template <class _Tp, class _Allocator>
1132template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
1241template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
11331242 is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value,
11341243 int> >
11351244_LIBCPP_CONSTEXPR_SINCE_CXX20
11361245vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
11371246 : __end_cap_(nullptr, __a)
11381247{
1139 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
1140 std::__debug_db_insert_c(this);
1141 for (; __first != __last; ++__first)
1142 emplace_back(*__first);
1143 __guard.__complete();
1248 __init_with_sentinel(__first, __last);
11441249}
11451250
11461251template <class _Tp, class _Allocator>
1147template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
1252template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
11481253 is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value,
11491254 int> >
11501255_LIBCPP_CONSTEXPR_SINCE_CXX20
11511256vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last)
11521257{
1153 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
1154 std::__debug_db_insert_c(this);
1155 size_type __n = static_cast<size_type>(std::distance(__first, __last));
1156 if (__n > 0)
1157 {
1158 __vallocate(__n);
1159 __construct_at_end(__first, __last, __n);
1160 }
1161 __guard.__complete();
1258 size_type __n = static_cast<size_type>(std::distance(__first, __last));
1259 __init_with_size(__first, __last, __n);
11621260}
11631261
11641262template <class _Tp, class _Allocator>
1165template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
1263template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
11661264 is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value,
11671265 int> >
11681266_LIBCPP_CONSTEXPR_SINCE_CXX20
11691267vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a)
11701268 : __end_cap_(nullptr, __a)
11711269{
1172 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
1173 std::__debug_db_insert_c(this);
1174 size_type __n = static_cast<size_type>(std::distance(__first, __last));
1175 if (__n > 0)
1176 {
1177 __vallocate(__n);
1178 __construct_at_end(__first, __last, __n);
1179 }
1180 __guard.__complete();
1270 size_type __n = static_cast<size_type>(std::distance(__first, __last));
1271 __init_with_size(__first, __last, __n);
11811272}
11821273
11831274template <class _Tp, class _Allocator>
......@@ -1185,15 +1276,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
11851276vector<_Tp, _Allocator>::vector(const vector& __x)
11861277 : __end_cap_(nullptr, __alloc_traits::select_on_container_copy_construction(__x.__alloc()))
11871278{
1188 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
1189 std::__debug_db_insert_c(this);
1190 size_type __n = __x.size();
1191 if (__n > 0)
1192 {
1193 __vallocate(__n);
1194 __construct_at_end(__x.__begin_, __x.__end_, __n);
1195 }
1196 __guard.__complete();
1279 __init_with_size(__x.__begin_, __x.__end_, __x.size());
11971280}
11981281
11991282template <class _Tp, class _Allocator>
......@@ -1201,30 +1284,20 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
12011284vector<_Tp, _Allocator>::vector(const vector& __x, const __type_identity_t<allocator_type>& __a)
12021285 : __end_cap_(nullptr, __a)
12031286{
1204 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
1205 std::__debug_db_insert_c(this);
1206 size_type __n = __x.size();
1207 if (__n > 0)
1208 {
1209 __vallocate(__n);
1210 __construct_at_end(__x.__begin_, __x.__end_, __n);
1211 }
1212 __guard.__complete();
1287 __init_with_size(__x.__begin_, __x.__end_, __x.size());
12131288}
12141289
12151290template <class _Tp, class _Allocator>
12161291_LIBCPP_CONSTEXPR_SINCE_CXX20
12171292inline _LIBCPP_HIDE_FROM_ABI
12181293vector<_Tp, _Allocator>::vector(vector&& __x)
1219#if _LIBCPP_STD_VER > 14
1294#if _LIBCPP_STD_VER >= 17
12201295 noexcept
12211296#else
12221297 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
12231298#endif
12241299 : __end_cap_(nullptr, std::move(__x.__alloc()))
12251300{
1226 std::__debug_db_insert_c(this);
1227 std::__debug_db_swap(this, std::addressof(__x));
12281301 this->__begin_ = __x.__begin_;
12291302 this->__end_ = __x.__end_;
12301303 this->__end_cap() = __x.__end_cap();
......@@ -1237,14 +1310,12 @@ inline _LIBCPP_HIDE_FROM_ABI
12371310vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_type>& __a)
12381311 : __end_cap_(nullptr, __a)
12391312{
1240 std::__debug_db_insert_c(this);
12411313 if (__a == __x.__alloc())
12421314 {
12431315 this->__begin_ = __x.__begin_;
12441316 this->__end_ = __x.__end_;
12451317 this->__end_cap() = __x.__end_cap();
12461318 __x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;
1247 std::__debug_db_swap(this, std::addressof(__x));
12481319 }
12491320 else
12501321 {
......@@ -1263,7 +1334,6 @@ inline _LIBCPP_HIDE_FROM_ABI
12631334vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
12641335{
12651336 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
1266 std::__debug_db_insert_c(this);
12671337 if (__il.size() > 0)
12681338 {
12691339 __vallocate(__il.size());
......@@ -1279,7 +1349,6 @@ vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocat
12791349 : __end_cap_(nullptr, __a)
12801350{
12811351 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
1282 std::__debug_db_insert_c(this);
12831352 if (__il.size() > 0)
12841353 {
12851354 __vallocate(__il.size());
......@@ -1329,7 +1398,6 @@ vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type)
13291398 this->__end_ = __c.__end_;
13301399 this->__end_cap() = __c.__end_cap();
13311400 __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr;
1332 std::__debug_db_swap(this, std::addressof(__c));
13331401}
13341402
13351403template <class _Tp, class _Allocator>
......@@ -1347,40 +1415,52 @@ vector<_Tp, _Allocator>::operator=(const vector& __x)
13471415}
13481416
13491417template <class _Tp, class _Allocator>
1350template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
1418template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
13511419 is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value,
13521420 int> >
13531421_LIBCPP_CONSTEXPR_SINCE_CXX20 void
13541422vector<_Tp, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
13551423{
1424 __assign_with_sentinel(__first, __last);
1425}
1426
1427template <class _Tp, class _Allocator>
1428template <class _Iterator, class _Sentinel>
1429_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
1430void vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __last) {
13561431 clear();
13571432 for (; __first != __last; ++__first)
13581433 emplace_back(*__first);
13591434}
13601435
13611436template <class _Tp, class _Allocator>
1362template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
1437template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
13631438 is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value,
13641439 int> >
13651440_LIBCPP_CONSTEXPR_SINCE_CXX20 void
13661441vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
13671442{
1368 size_type __new_size = static_cast<size_type>(std::distance(__first, __last));
1443 __assign_with_size(__first, __last, std::distance(__first, __last));
1444}
1445
1446template <class _Tp, class _Allocator>
1447template <class _ForwardIterator, class _Sentinel>
1448_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
1449void vector<_Tp, _Allocator>::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n) {
1450 size_type __new_size = static_cast<size_type>(__n);
13691451 if (__new_size <= capacity())
13701452 {
1371 _ForwardIterator __mid = __last;
1372 bool __growing = false;
13731453 if (__new_size > size())
13741454 {
1375 __growing = true;
1376 __mid = __first;
1377 std::advance(__mid, size());
1378 }
1379 pointer __m = std::copy(__first, __mid, this->__begin_);
1380 if (__growing)
1455 _ForwardIterator __mid = std::next(__first, size());
1456 std::copy(__first, __mid, this->__begin_);
13811457 __construct_at_end(__mid, __last, __new_size - size());
1458 }
13821459 else
1460 {
1461 pointer __m = std::__copy<_ClassicAlgPolicy>(__first, __last, this->__begin_).second;
13831462 this->__destruct_at_end(__m);
1463 }
13841464 }
13851465 else
13861466 {
......@@ -1388,7 +1468,6 @@ vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __las
13881468 __vallocate(__recommend(__new_size));
13891469 __construct_at_end(__first, __last, __new_size);
13901470 }
1391 std::__debug_db_invalidate_all(this);
13921471}
13931472
13941473template <class _Tp, class _Allocator>
......@@ -1411,7 +1490,6 @@ vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u)
14111490 __vallocate(__recommend(static_cast<size_type>(__n)));
14121491 __construct_at_end(__n, __u);
14131492 }
1414 std::__debug_db_invalidate_all(this);
14151493}
14161494
14171495template <class _Tp, class _Allocator>
......@@ -1456,7 +1534,7 @@ inline _LIBCPP_HIDE_FROM_ABI
14561534typename vector<_Tp, _Allocator>::reference
14571535vector<_Tp, _Allocator>::operator[](size_type __n) _NOEXCEPT
14581536{
1459 _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
1537 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
14601538 return this->__begin_[__n];
14611539}
14621540
......@@ -1466,7 +1544,7 @@ inline _LIBCPP_HIDE_FROM_ABI
14661544typename vector<_Tp, _Allocator>::const_reference
14671545vector<_Tp, _Allocator>::operator[](size_type __n) const _NOEXCEPT
14681546{
1469 _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
1547 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
14701548 return this->__begin_[__n];
14711549}
14721550
......@@ -1512,19 +1590,19 @@ vector<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
15121590{
15131591 if (capacity() > size())
15141592 {
1515#ifndef _LIBCPP_NO_EXCEPTIONS
1593#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
15161594 try
15171595 {
1518#endif // _LIBCPP_NO_EXCEPTIONS
1596#endif // _LIBCPP_HAS_NO_EXCEPTIONS
15191597 allocator_type& __a = this->__alloc();
15201598 __split_buffer<value_type, allocator_type&> __v(size(), size(), __a);
15211599 __swap_out_circular_buffer(__v);
1522#ifndef _LIBCPP_NO_EXCEPTIONS
1600#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
15231601 }
15241602 catch (...)
15251603 {
15261604 }
1527#endif // _LIBCPP_NO_EXCEPTIONS
1605#endif // _LIBCPP_HAS_NO_EXCEPTIONS
15281606 }
15291607}
15301608
......@@ -1588,7 +1666,7 @@ template <class _Tp, class _Allocator>
15881666template <class... _Args>
15891667_LIBCPP_CONSTEXPR_SINCE_CXX20
15901668inline
1591#if _LIBCPP_STD_VER > 14
1669#if _LIBCPP_STD_VER >= 17
15921670typename vector<_Tp, _Allocator>::reference
15931671#else
15941672void
......@@ -1601,7 +1679,7 @@ vector<_Tp, _Allocator>::emplace_back(_Args&&... __args)
16011679 }
16021680 else
16031681 __emplace_back_slow_path(std::forward<_Args>(__args)...);
1604#if _LIBCPP_STD_VER > 14
1682#if _LIBCPP_STD_VER >= 17
16051683 return this->back();
16061684#endif
16071685}
......@@ -1612,7 +1690,7 @@ inline
16121690void
16131691vector<_Tp, _Allocator>::pop_back()
16141692{
1615 _LIBCPP_ASSERT(!empty(), "vector::pop_back called on an empty vector");
1693 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector::pop_back called on an empty vector");
16161694 this->__destruct_at_end(this->__end_ - 1);
16171695}
16181696
......@@ -1622,15 +1700,11 @@ inline _LIBCPP_HIDE_FROM_ABI
16221700typename vector<_Tp, _Allocator>::iterator
16231701vector<_Tp, _Allocator>::erase(const_iterator __position)
16241702{
1625 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
1626 "vector::erase(iterator) called with an iterator not referring to this vector");
1627 _LIBCPP_ASSERT(__position != end(),
1703 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__position != end(),
16281704 "vector::erase(iterator) called with a non-dereferenceable iterator");
16291705 difference_type __ps = __position - cbegin();
16301706 pointer __p = this->__begin_ + __ps;
16311707 this->__destruct_at_end(std::move(__p + 1, this->__end_, __p));
1632 if (!__libcpp_is_constant_evaluated())
1633 this->__invalidate_iterators_past(__p - 1);
16341708 return __make_iter(__p);
16351709}
16361710
......@@ -1639,17 +1713,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
16391713typename vector<_Tp, _Allocator>::iterator
16401714vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last)
16411715{
1642 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__first)) == this,
1643 "vector::erase(iterator, iterator) called with an iterator not referring to this vector");
1644 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__last)) == this,
1645 "vector::erase(iterator, iterator) called with an iterator not referring to this vector");
1646
1647 _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range");
1716 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "vector::erase(first, last) called with invalid range");
16481717 pointer __p = this->__begin_ + (__first - begin());
16491718 if (__first != __last) {
16501719 this->__destruct_at_end(std::move(__p + (__last - __first), this->__end_, __p));
1651 if (!__libcpp_is_constant_evaluated())
1652 this->__invalidate_iterators_past(__p - 1);
16531720 }
16541721 return __make_iter(__p);
16551722}
......@@ -1679,8 +1746,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
16791746typename vector<_Tp, _Allocator>::iterator
16801747vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
16811748{
1682 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
1683 "vector::insert(iterator, x) called with an iterator not referring to this vector");
16841749 pointer __p = this->__begin_ + (__position - begin());
16851750 // We can't compare unrelated pointers inside constant expressions
16861751 if (!__libcpp_is_constant_evaluated() && this->__end_ < this->__end_cap())
......@@ -1713,8 +1778,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
17131778typename vector<_Tp, _Allocator>::iterator
17141779vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x)
17151780{
1716 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
1717 "vector::insert(iterator, x) called with an iterator not referring to this vector");
17181781 pointer __p = this->__begin_ + (__position - begin());
17191782 if (this->__end_ < this->__end_cap())
17201783 {
......@@ -1744,8 +1807,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
17441807typename vector<_Tp, _Allocator>::iterator
17451808vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args)
17461809{
1747 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
1748 "vector::emplace(iterator, x) called with an iterator not referring to this vector");
17491810 pointer __p = this->__begin_ + (__position - begin());
17501811 if (this->__end_ < this->__end_cap())
17511812 {
......@@ -1775,8 +1836,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
17751836typename vector<_Tp, _Allocator>::iterator
17761837vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x)
17771838{
1778 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
1779 "vector::insert(iterator, n, x) called with an iterator not referring to this vector");
17801839 pointer __p = this->__begin_ + (__position - begin());
17811840 if (__n > 0)
17821841 {
......@@ -1810,16 +1869,21 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_
18101869 }
18111870 return __make_iter(__p);
18121871}
1813
18141872template <class _Tp, class _Allocator>
1815template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
1873template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value &&
18161874 is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value,
18171875 int> >
18181876_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
18191877vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)
18201878{
1821 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
1822 "vector::insert(iterator, range) called with an iterator not referring to this vector");
1879 return __insert_with_sentinel(__position, __first, __last);
1880}
1881
1882template <class _Tp, class _Allocator>
1883template <class _InputIterator, class _Sentinel>
1884_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
1885typename vector<_Tp, _Allocator>::iterator
1886vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) {
18231887 difference_type __off = __position - begin();
18241888 pointer __p = this->__begin_ + __off;
18251889 allocator_type& __a = this->__alloc();
......@@ -1831,24 +1895,24 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs
18311895 __split_buffer<value_type, allocator_type&> __v(__a);
18321896 if (__first != __last)
18331897 {
1834#ifndef _LIBCPP_NO_EXCEPTIONS
1898#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
18351899 try
18361900 {
1837#endif // _LIBCPP_NO_EXCEPTIONS
1838 __v.__construct_at_end(__first, __last);
1901#endif // _LIBCPP_HAS_NO_EXCEPTIONS
1902 __v.__construct_at_end_with_sentinel(std::move(__first), std::move(__last));
18391903 difference_type __old_size = __old_last - this->__begin_;
18401904 difference_type __old_p = __p - this->__begin_;
18411905 reserve(__recommend(size() + __v.size()));
18421906 __p = this->__begin_ + __old_p;
18431907 __old_last = this->__begin_ + __old_size;
1844#ifndef _LIBCPP_NO_EXCEPTIONS
1908#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
18451909 }
18461910 catch (...)
18471911 {
18481912 erase(__make_iter(__old_last), end());
18491913 throw;
18501914 }
1851#endif // _LIBCPP_NO_EXCEPTIONS
1915#endif // _LIBCPP_HAS_NO_EXCEPTIONS
18521916 }
18531917 __p = std::rotate(__p, __old_last, this->__end_);
18541918 insert(__make_iter(__p), std::make_move_iterator(__v.begin()),
......@@ -1857,23 +1921,30 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs
18571921}
18581922
18591923template <class _Tp, class _Allocator>
1860template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value &&
1924template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&
18611925 is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value,
18621926 int> >
18631927_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
18641928vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last)
18651929{
1866 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this,
1867 "vector::insert(iterator, range) called with an iterator not referring to this vector");
1930 return __insert_with_size(__position, __first, __last, std::distance(__first, __last));
1931}
1932
1933template <class _Tp, class _Allocator>
1934template <class _Iterator, class _Sentinel>
1935_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
1936typename vector<_Tp, _Allocator>::iterator
1937vector<_Tp, _Allocator>::__insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last,
1938 difference_type __n) {
1939 auto __insertion_size = __n;
18681940 pointer __p = this->__begin_ + (__position - begin());
1869 difference_type __n = std::distance(__first, __last);
18701941 if (__n > 0)
18711942 {
18721943 if (__n <= this->__end_cap() - this->__end_)
18731944 {
18741945 size_type __old_n = __n;
18751946 pointer __old_last = this->__end_;
1876 _ForwardIterator __m = __last;
1947 _Iterator __m = std::next(__first, __n);
18771948 difference_type __dx = this->__end_ - __p;
18781949 if (__n > __dx)
18791950 {
......@@ -1893,7 +1964,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __fi
18931964 {
18941965 allocator_type& __a = this->__alloc();
18951966 __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, __a);
1896 __v.__construct_at_end(__first, __last);
1967 __v.__construct_at_end_with_size(__first, __insertion_size);
18971968 __p = __swap_out_circular_buffer(__v, __p);
18981969 }
18991970 }
......@@ -1935,16 +2006,15 @@ vector<_Tp, _Allocator>::swap(vector& __x)
19352006 __is_nothrow_swappable<allocator_type>::value)
19362007#endif
19372008{
1938 _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
1939 this->__alloc() == __x.__alloc(),
1940 "vector::swap: Either propagate_on_container_swap must be true"
1941 " or the allocators must compare equal");
2009 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__alloc_traits::propagate_on_container_swap::value ||
2010 this->__alloc() == __x.__alloc(),
2011 "vector::swap: Either propagate_on_container_swap must be true"
2012 " or the allocators must compare equal");
19422013 std::swap(this->__begin_, __x.__begin_);
19432014 std::swap(this->__end_, __x.__end_);
19442015 std::swap(this->__end_cap(), __x.__end_cap());
19452016 std::__swap_allocator(this->__alloc(), __x.__alloc(),
19462017 integral_constant<bool,__alloc_traits::propagate_on_container_swap::value>());
1947 std::__debug_db_swap(this, std::addressof(__x));
19482018}
19492019
19502020template <class _Tp, class _Allocator>
......@@ -1969,61 +2039,6 @@ vector<_Tp, _Allocator>::__invariants() const
19692039 return true;
19702040}
19712041
1972#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1973
1974template <class _Tp, class _Allocator>
1975bool
1976vector<_Tp, _Allocator>::__dereferenceable(const const_iterator* __i) const
1977{
1978 return this->__begin_ <= __i->base() && __i->base() < this->__end_;
1979}
1980
1981template <class _Tp, class _Allocator>
1982bool
1983vector<_Tp, _Allocator>::__decrementable(const const_iterator* __i) const
1984{
1985 return this->__begin_ < __i->base() && __i->base() <= this->__end_;
1986}
1987
1988template <class _Tp, class _Allocator>
1989bool
1990vector<_Tp, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
1991{
1992 const_pointer __p = __i->base() + __n;
1993 return this->__begin_ <= __p && __p <= this->__end_;
1994}
1995
1996template <class _Tp, class _Allocator>
1997bool
1998vector<_Tp, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
1999{
2000 const_pointer __p = __i->base() + __n;
2001 return this->__begin_ <= __p && __p < this->__end_;
2002}
2003
2004#endif // _LIBCPP_ENABLE_DEBUG_MODE
2005
2006template <class _Tp, class _Allocator>
2007inline _LIBCPP_HIDE_FROM_ABI
2008void
2009vector<_Tp, _Allocator>::__invalidate_iterators_past(pointer __new_last) {
2010#ifdef _LIBCPP_ENABLE_DEBUG_MODE
2011 __c_node* __c = __get_db()->__find_c_and_lock(this);
2012 for (__i_node** __p = __c->end_; __p != __c->beg_; ) {
2013 --__p;
2014 const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
2015 if (__i->base() > __new_last) {
2016 (*__p)->__c_ = nullptr;
2017 if (--__c->end_ != __p)
2018 std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
2019 }
2020 }
2021 __get_db()->unlock();
2022#else
2023 ((void)__new_last);
2024#endif
2025}
2026
20272042// vector<bool>
20282043
20292044template <class _Allocator> class vector<bool, _Allocator>;
......@@ -2107,12 +2122,11 @@ public:
21072122private:
21082123 class __destroy_vector {
21092124 public:
2110 _LIBCPP_CONSTEXPR __destroy_vector(vector& __vec) : __vec_(__vec) {}
2125 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __destroy_vector(vector& __vec) : __vec_(__vec) {}
21112126
21122127 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator()() {
21132128 if (__vec_.__begin_ != nullptr)
21142129 __storage_traits::deallocate(__vec_.__alloc(), __vec_.__begin_, __vec_.__cap());
2115 std::__debug_db_invalidate_all(this);
21162130 }
21172131
21182132 private:
......@@ -2123,23 +2137,40 @@ public:
21232137 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~vector() { __destroy_vector(*this)(); }
21242138
21252139 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n);
2126#if _LIBCPP_STD_VER > 11
2140#if _LIBCPP_STD_VER >= 14
21272141 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n, const allocator_type& __a);
21282142#endif
21292143 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(size_type __n, const value_type& __v);
21302144 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(size_type __n, const value_type& __v, const allocator_type& __a);
21312145 template <class _InputIterator>
21322146 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_InputIterator __first, _InputIterator __last,
2133 typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type* = 0);
2147 typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value>::type* = 0);
21342148 template <class _InputIterator>
21352149 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
2136 typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type* = 0);
2150 typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value>::type* = 0);
21372151 template <class _ForwardIterator>
21382152 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_ForwardIterator __first, _ForwardIterator __last,
2139 typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0);
2153 typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value>::type* = 0);
21402154 template <class _ForwardIterator>
21412155 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
2142 typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0);
2156 typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value>::type* = 0);
2157
2158#if _LIBCPP_STD_VER >= 23
2159 template <_ContainerCompatibleRange<bool> _Range>
2160 _LIBCPP_HIDE_FROM_ABI constexpr
2161 vector(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type())
2162 : __begin_(nullptr),
2163 __size_(0),
2164 __cap_alloc_(0, static_cast<__storage_allocator>(__a)) {
2165 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
2166 auto __n = static_cast<size_type>(ranges::distance(__range));
2167 __init_with_size(ranges::begin(__range), ranges::end(__range), __n);
2168
2169 } else {
2170 __init_with_sentinel(ranges::begin(__range), ranges::end(__range));
2171 }
2172 }
2173#endif
21432174
21442175 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(const vector& __v);
21452176 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(const vector& __v, const allocator_type& __a);
......@@ -2157,7 +2188,7 @@ public:
21572188
21582189 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
21592190 vector(vector&& __v)
2160#if _LIBCPP_STD_VER > 14
2191#if _LIBCPP_STD_VER >= 17
21612192 noexcept;
21622193#else
21632194 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
......@@ -2168,18 +2199,32 @@ public:
21682199 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
21692200
21702201 template <class _InputIterator>
2171 typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
2202 typename enable_if <__has_exactly_input_iterator_category<_InputIterator>::value,
21722203 void
21732204 >::type
21742205 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 assign(_InputIterator __first, _InputIterator __last);
21752206 template <class _ForwardIterator>
21762207 typename enable_if
21772208 <
2178 __is_cpp17_forward_iterator<_ForwardIterator>::value,
2209 __has_forward_iterator_category<_ForwardIterator>::value,
21792210 void
21802211 >::type
21812212 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 assign(_ForwardIterator __first, _ForwardIterator __last);
21822213
2214#if _LIBCPP_STD_VER >= 23
2215 template <_ContainerCompatibleRange<bool> _Range>
2216 _LIBCPP_HIDE_FROM_ABI
2217 constexpr void assign_range(_Range&& __range) {
2218 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
2219 auto __n = static_cast<size_type>(ranges::distance(__range));
2220 __assign_with_size(ranges::begin(__range), ranges::end(__range), __n);
2221
2222 } else {
2223 __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
2224 }
2225 }
2226#endif
2227
21832228 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void assign(size_type __n, const value_type& __x);
21842229
21852230#ifndef _LIBCPP_CXX03_LANG
......@@ -2254,24 +2299,32 @@ public:
22542299 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const {return __make_ref(__size_ - 1);}
22552300
22562301 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(const value_type& __x);
2257#if _LIBCPP_STD_VER > 11
2302#if _LIBCPP_STD_VER >= 14
22582303 template <class... _Args>
2259#if _LIBCPP_STD_VER > 14
2304#if _LIBCPP_STD_VER >= 17
22602305 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference emplace_back(_Args&&... __args)
22612306#else
22622307 _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args)
22632308#endif
22642309 {
22652310 push_back ( value_type ( std::forward<_Args>(__args)... ));
2266#if _LIBCPP_STD_VER > 14
2311#if _LIBCPP_STD_VER >= 17
22672312 return this->back();
22682313#endif
22692314 }
22702315#endif
22712316
2317#if _LIBCPP_STD_VER >= 23
2318 template <_ContainerCompatibleRange<bool> _Range>
2319 _LIBCPP_HIDE_FROM_ABI
2320 constexpr void append_range(_Range&& __range) {
2321 insert_range(end(), std::forward<_Range>(__range));
2322 }
2323#endif
2324
22722325 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back() {--__size_;}
22732326
2274#if _LIBCPP_STD_VER > 11
2327#if _LIBCPP_STD_VER >= 14
22752328 template <class... _Args>
22762329 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator emplace(const_iterator __position, _Args&&... __args)
22772330 { return insert ( __position, value_type ( std::forward<_Args>(__args)... )); }
......@@ -2280,18 +2333,32 @@ public:
22802333 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __position, const value_type& __x);
22812334 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __position, size_type __n, const value_type& __x);
22822335 template <class _InputIterator>
2283 typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
2336 typename enable_if <__has_exactly_input_iterator_category<_InputIterator>::value,
22842337 iterator
22852338 >::type
22862339 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert(const_iterator __position, _InputIterator __first, _InputIterator __last);
22872340 template <class _ForwardIterator>
22882341 typename enable_if
22892342 <
2290 __is_cpp17_forward_iterator<_ForwardIterator>::value,
2343 __has_forward_iterator_category<_ForwardIterator>::value,
22912344 iterator
22922345 >::type
22932346 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last);
22942347
2348#if _LIBCPP_STD_VER >= 23
2349 template <_ContainerCompatibleRange<bool> _Range>
2350 _LIBCPP_HIDE_FROM_ABI
2351 constexpr iterator insert_range(const_iterator __position, _Range&& __range) {
2352 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
2353 auto __n = static_cast<size_type>(ranges::distance(__range));
2354 return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n);
2355
2356 } else {
2357 return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
2358 }
2359 }
2360#endif
2361
22952362#ifndef _LIBCPP_CXX03_LANG
22962363 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
22972364 iterator insert(const_iterator __position, initializer_list<value_type> __il)
......@@ -2304,7 +2371,7 @@ public:
23042371 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
23052372 void clear() _NOEXCEPT {__size_ = 0;}
23062373
2307 _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(vector&)
2374 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(vector&)
23082375#if _LIBCPP_STD_VER >= 14
23092376 _NOEXCEPT;
23102377#else
......@@ -2329,6 +2396,52 @@ private:
23292396 std::__throw_out_of_range("vector");
23302397 }
23312398
2399 template <class _InputIterator, class _Sentinel>
2400 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
2401 void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __n) {
2402 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
2403
2404 if (__n > 0) {
2405 __vallocate(__n);
2406 __construct_at_end(std::move(__first), std::move(__last), __n);
2407 }
2408
2409 __guard.__complete();
2410 }
2411
2412 template <class _InputIterator, class _Sentinel>
2413 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
2414 void __init_with_sentinel(_InputIterator __first, _Sentinel __last) {
2415#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
2416 try {
2417#endif // _LIBCPP_HAS_NO_EXCEPTIONS
2418 for (; __first != __last; ++__first)
2419 push_back(*__first);
2420#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
2421 } catch (...) {
2422 if (__begin_ != nullptr)
2423 __storage_traits::deallocate(__alloc(), __begin_, __cap());
2424 throw;
2425 }
2426#endif // _LIBCPP_HAS_NO_EXCEPTIONS
2427 }
2428
2429 template <class _Iterator, class _Sentinel>
2430 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
2431 void __assign_with_sentinel(_Iterator __first, _Sentinel __last);
2432
2433 template <class _ForwardIterator, class _Sentinel>
2434 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
2435 void __assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __ns);
2436
2437 template <class _InputIterator, class _Sentinel>
2438 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
2439 iterator __insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last);
2440
2441 template <class _Iterator, class _Sentinel>
2442 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
2443 iterator __insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n);
2444
23322445 // Allocate space for __n objects
23332446 // throws length_error if __n > max_size()
23342447 // throws (probably bad_alloc) if memory run out
......@@ -2355,13 +2468,9 @@ private:
23552468 {return (__new_size + (__bits_per_word-1)) & ~((size_type)__bits_per_word-1);}
23562469 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __new_size) const;
23572470 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_at_end(size_type __n, bool __x);
2358 template <class _ForwardIterator>
2359 typename enable_if
2360 <
2361 __is_cpp17_forward_iterator<_ForwardIterator>::value,
2362 void
2363 >::type
2364 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
2471 template <class _InputIterator, class _Sentinel>
2472 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
2473 void __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n);
23652474 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __append(size_type __n, const_reference __x);
23662475 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
23672476 reference __make_ref(size_type __pos) _NOEXCEPT
......@@ -2436,7 +2545,6 @@ vector<bool, _Allocator>::__vdeallocate() _NOEXCEPT
24362545 if (this->__begin_ != nullptr)
24372546 {
24382547 __storage_traits::deallocate(this->__alloc(), this->__begin_, __cap());
2439 std::__debug_db_invalidate_all(this);
24402548 this->__begin_ = nullptr;
24412549 this->__size_ = this->__cap() = 0;
24422550 }
......@@ -2491,17 +2599,11 @@ vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x)
24912599}
24922600
24932601template <class _Allocator>
2494template <class _ForwardIterator>
2602template <class _InputIterator, class _Sentinel>
24952603_LIBCPP_CONSTEXPR_SINCE_CXX20
2496typename enable_if
2497<
2498 __is_cpp17_forward_iterator<_ForwardIterator>::value,
2499 void
2500>::type
2501vector<bool, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
2502{
2604void vector<bool, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
25032605 size_type __old_size = this->__size_;
2504 this->__size_ += std::distance(__first, __last);
2606 this->__size_ += __n;
25052607 if (__old_size == 0 || ((__old_size - 1) / __bits_per_word) != ((this->__size_ - 1) / __bits_per_word))
25062608 {
25072609 if (this->__size_ <= __bits_per_word)
......@@ -2509,7 +2611,7 @@ vector<bool, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardI
25092611 else
25102612 this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);
25112613 }
2512 std::copy(__first, __last, __make_iter(__old_size));
2614 std::__copy<_ClassicAlgPolicy>(__first, __last, __make_iter(__old_size));
25132615}
25142616
25152617template <class _Allocator>
......@@ -2550,7 +2652,7 @@ vector<bool, _Allocator>::vector(size_type __n)
25502652 }
25512653}
25522654
2553#if _LIBCPP_STD_VER > 11
2655#if _LIBCPP_STD_VER >= 14
25542656template <class _Allocator>
25552657_LIBCPP_CONSTEXPR_SINCE_CXX20
25562658vector<bool, _Allocator>::vector(size_type __n, const allocator_type& __a)
......@@ -2598,92 +2700,50 @@ template <class _Allocator>
25982700template <class _InputIterator>
25992701_LIBCPP_CONSTEXPR_SINCE_CXX20
26002702vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
2601 typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type*)
2703 typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value>::type*)
26022704 : __begin_(nullptr),
26032705 __size_(0),
26042706 __cap_alloc_(0, __default_init_tag())
26052707{
2606#ifndef _LIBCPP_NO_EXCEPTIONS
2607 try
2608 {
2609#endif // _LIBCPP_NO_EXCEPTIONS
2610 for (; __first != __last; ++__first)
2611 push_back(*__first);
2612#ifndef _LIBCPP_NO_EXCEPTIONS
2613 }
2614 catch (...)
2615 {
2616 if (__begin_ != nullptr)
2617 __storage_traits::deallocate(__alloc(), __begin_, __cap());
2618 std::__debug_db_invalidate_all(this);
2619 throw;
2620 }
2621#endif // _LIBCPP_NO_EXCEPTIONS
2708 __init_with_sentinel(__first, __last);
26222709}
26232710
26242711template <class _Allocator>
26252712template <class _InputIterator>
26262713_LIBCPP_CONSTEXPR_SINCE_CXX20
26272714vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
2628 typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type*)
2715 typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value>::type*)
26292716 : __begin_(nullptr),
26302717 __size_(0),
26312718 __cap_alloc_(0, static_cast<__storage_allocator>(__a))
26322719{
2633#ifndef _LIBCPP_NO_EXCEPTIONS
2634 try
2635 {
2636#endif // _LIBCPP_NO_EXCEPTIONS
2637 for (; __first != __last; ++__first)
2638 push_back(*__first);
2639#ifndef _LIBCPP_NO_EXCEPTIONS
2640 }
2641 catch (...)
2642 {
2643 if (__begin_ != nullptr)
2644 __storage_traits::deallocate(__alloc(), __begin_, __cap());
2645 std::__debug_db_invalidate_all(this);
2646 throw;
2647 }
2648#endif // _LIBCPP_NO_EXCEPTIONS
2720 __init_with_sentinel(__first, __last);
26492721}
26502722
26512723template <class _Allocator>
26522724template <class _ForwardIterator>
26532725_LIBCPP_CONSTEXPR_SINCE_CXX20
26542726vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last,
2655 typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type*)
2727 typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value>::type*)
26562728 : __begin_(nullptr),
26572729 __size_(0),
26582730 __cap_alloc_(0, __default_init_tag())
26592731{
2660 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
2661 size_type __n = static_cast<size_type>(std::distance(__first, __last));
2662 if (__n > 0)
2663 {
2664 __vallocate(__n);
2665 __construct_at_end(__first, __last);
2666 }
2667 __guard.__complete();
2732 auto __n = static_cast<size_type>(std::distance(__first, __last));
2733 __init_with_size(__first, __last, __n);
26682734}
26692735
26702736template <class _Allocator>
26712737template <class _ForwardIterator>
26722738_LIBCPP_CONSTEXPR_SINCE_CXX20
26732739vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
2674 typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type*)
2740 typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value>::type*)
26752741 : __begin_(nullptr),
26762742 __size_(0),
26772743 __cap_alloc_(0, static_cast<__storage_allocator>(__a))
26782744{
2679 auto __guard = std::__make_exception_guard(__destroy_vector(*this));
2680 size_type __n = static_cast<size_type>(std::distance(__first, __last));
2681 if (__n > 0)
2682 {
2683 __vallocate(__n);
2684 __construct_at_end(__first, __last);
2685 }
2686 __guard.__complete();
2745 auto __n = static_cast<size_type>(std::distance(__first, __last));
2746 __init_with_size(__first, __last, __n);
26872747}
26882748
26892749#ifndef _LIBCPP_CXX03_LANG
......@@ -2699,7 +2759,7 @@ vector<bool, _Allocator>::vector(initializer_list<value_type> __il)
26992759 if (__n > 0)
27002760 {
27012761 __vallocate(__n);
2702 __construct_at_end(__il.begin(), __il.end());
2762 __construct_at_end(__il.begin(), __il.end(), __n);
27032763 }
27042764}
27052765
......@@ -2714,7 +2774,7 @@ vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const alloca
27142774 if (__n > 0)
27152775 {
27162776 __vallocate(__n);
2717 __construct_at_end(__il.begin(), __il.end());
2777 __construct_at_end(__il.begin(), __il.end(), __n);
27182778 }
27192779}
27202780
......@@ -2730,7 +2790,7 @@ vector<bool, _Allocator>::vector(const vector& __v)
27302790 if (__v.size() > 0)
27312791 {
27322792 __vallocate(__v.size());
2733 __construct_at_end(__v.begin(), __v.end());
2793 __construct_at_end(__v.begin(), __v.end(), __v.size());
27342794 }
27352795}
27362796
......@@ -2744,7 +2804,7 @@ vector<bool, _Allocator>::vector(const vector& __v, const allocator_type& __a)
27442804 if (__v.size() > 0)
27452805 {
27462806 __vallocate(__v.size());
2747 __construct_at_end(__v.begin(), __v.end());
2807 __construct_at_end(__v.begin(), __v.end(), __v.size());
27482808 }
27492809}
27502810
......@@ -2772,7 +2832,7 @@ vector<bool, _Allocator>::operator=(const vector& __v)
27722832
27732833template <class _Allocator>
27742834inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(vector&& __v)
2775#if _LIBCPP_STD_VER > 14
2835#if _LIBCPP_STD_VER >= 17
27762836 _NOEXCEPT
27772837#else
27782838 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
......@@ -2803,7 +2863,7 @@ vector<bool, _Allocator>::vector(vector&& __v, const __type_identity_t<allocator
28032863 else if (__v.size() > 0)
28042864 {
28052865 __vallocate(__v.size());
2806 __construct_at_end(__v.begin(), __v.end());
2866 __construct_at_end(__v.begin(), __v.end(), __v.size());
28072867 }
28082868}
28092869
......@@ -2861,16 +2921,22 @@ vector<bool, _Allocator>::assign(size_type __n, const value_type& __x)
28612921 }
28622922 std::fill_n(begin(), __n, __x);
28632923 }
2864 std::__debug_db_invalidate_all(this);
28652924}
28662925
28672926template <class _Allocator>
28682927template <class _InputIterator>
2869_LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
2928_LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__has_exactly_input_iterator_category<_InputIterator>::value,
28702929 void
28712930>::type
28722931vector<bool, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
28732932{
2933 __assign_with_sentinel(__first, __last);
2934}
2935
2936template <class _Allocator>
2937template <class _Iterator, class _Sentinel>
2938_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
2939void vector<bool, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __last) {
28742940 clear();
28752941 for (; __first != __last; ++__first)
28762942 push_back(*__first);
......@@ -2881,14 +2947,22 @@ template <class _ForwardIterator>
28812947_LIBCPP_CONSTEXPR_SINCE_CXX20
28822948typename enable_if
28832949<
2884 __is_cpp17_forward_iterator<_ForwardIterator>::value,
2950 __has_forward_iterator_category<_ForwardIterator>::value,
28852951 void
28862952>::type
28872953vector<bool, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
28882954{
2955 __assign_with_size(__first, __last, std::distance(__first, __last));
2956}
2957
2958template <class _Allocator>
2959template <class _ForwardIterator, class _Sentinel>
2960_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
2961void vector<bool, _Allocator>::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __ns) {
2962 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__ns >= 0, "invalid range specified");
2963
28892964 clear();
2890 difference_type __ns = std::distance(__first, __last);
2891 _LIBCPP_ASSERT(__ns >= 0, "invalid range specified");
2965
28922966 const size_t __n = static_cast<size_type>(__ns);
28932967 if (__n)
28942968 {
......@@ -2897,7 +2971,7 @@ vector<bool, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __la
28972971 __vdeallocate();
28982972 __vallocate(__n);
28992973 }
2900 __construct_at_end(__first, __last);
2974 __construct_at_end(__first, __last, __n);
29012975 }
29022976}
29032977
......@@ -2911,9 +2985,8 @@ vector<bool, _Allocator>::reserve(size_type __n)
29112985 this->__throw_length_error();
29122986 vector __v(this->get_allocator());
29132987 __v.__vallocate(__n);
2914 __v.__construct_at_end(this->begin(), this->end());
2988 __v.__construct_at_end(this->begin(), this->end(), this->size());
29152989 swap(__v);
2916 std::__debug_db_invalidate_all(this);
29172990 }
29182991}
29192992
......@@ -2923,17 +2996,17 @@ vector<bool, _Allocator>::shrink_to_fit() _NOEXCEPT
29232996{
29242997 if (__external_cap_to_internal(size()) > __cap())
29252998 {
2926#ifndef _LIBCPP_NO_EXCEPTIONS
2999#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
29273000 try
29283001 {
2929#endif // _LIBCPP_NO_EXCEPTIONS
3002#endif // _LIBCPP_HAS_NO_EXCEPTIONS
29303003 vector(*this, allocator_type(__alloc())).swap(*this);
2931#ifndef _LIBCPP_NO_EXCEPTIONS
3004#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
29323005 }
29333006 catch (...)
29343007 {
29353008 }
2936#endif // _LIBCPP_NO_EXCEPTIONS
3009#endif // _LIBCPP_HAS_NO_EXCEPTIONS
29373010 }
29383011}
29393012
......@@ -3018,11 +3091,19 @@ vector<bool, _Allocator>::insert(const_iterator __position, size_type __n, const
30183091
30193092template <class _Allocator>
30203093template <class _InputIterator>
3021_LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
3094_LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__has_exactly_input_iterator_category<_InputIterator>::value,
30223095 typename vector<bool, _Allocator>::iterator
30233096>::type
30243097vector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)
30253098{
3099 return __insert_with_sentinel(__position, __first, __last);
3100}
3101
3102template <class _Allocator>
3103template <class _InputIterator, class _Sentinel>
3104_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
3105typename vector<bool, _Allocator>::iterator
3106vector<bool, _Allocator>::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) {
30263107 difference_type __off = __position - begin();
30273108 iterator __p = __const_iterator_cast(__position);
30283109 iterator __old_end = end();
......@@ -3034,24 +3115,24 @@ vector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __fir
30343115 vector __v(get_allocator());
30353116 if (__first != __last)
30363117 {
3037#ifndef _LIBCPP_NO_EXCEPTIONS
3118#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
30383119 try
30393120 {
3040#endif // _LIBCPP_NO_EXCEPTIONS
3041 __v.assign(__first, __last);
3121#endif // _LIBCPP_HAS_NO_EXCEPTIONS
3122 __v.__assign_with_sentinel(std::move(__first), std::move(__last));
30423123 difference_type __old_size = static_cast<difference_type>(__old_end - begin());
30433124 difference_type __old_p = __p - begin();
30443125 reserve(__recommend(size() + __v.size()));
30453126 __p = begin() + __old_p;
30463127 __old_end = begin() + __old_size;
3047#ifndef _LIBCPP_NO_EXCEPTIONS
3128#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
30483129 }
30493130 catch (...)
30503131 {
30513132 erase(__old_end, end());
30523133 throw;
30533134 }
3054#endif // _LIBCPP_NO_EXCEPTIONS
3135#endif // _LIBCPP_HAS_NO_EXCEPTIONS
30553136 }
30563137 __p = std::rotate(__p, __old_end, end());
30573138 insert(__p, __v.begin(), __v.end());
......@@ -3063,13 +3144,21 @@ template <class _ForwardIterator>
30633144_LIBCPP_CONSTEXPR_SINCE_CXX20
30643145typename enable_if
30653146<
3066 __is_cpp17_forward_iterator<_ForwardIterator>::value,
3147 __has_forward_iterator_category<_ForwardIterator>::value,
30673148 typename vector<bool, _Allocator>::iterator
30683149>::type
30693150vector<bool, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last)
30703151{
3071 const difference_type __n_signed = std::distance(__first, __last);
3072 _LIBCPP_ASSERT(__n_signed >= 0, "invalid range specified");
3152 return __insert_with_size(__position, __first, __last, std::distance(__first, __last));
3153}
3154
3155template <class _Allocator>
3156template <class _ForwardIterator, class _Sentinel>
3157_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
3158typename vector<bool, _Allocator>::iterator
3159vector<bool, _Allocator>::__insert_with_size(const_iterator __position, _ForwardIterator __first, _Sentinel __last,
3160 difference_type __n_signed) {
3161 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__n_signed >= 0, "invalid range specified");
30733162 const size_type __n = static_cast<size_type>(__n_signed);
30743163 iterator __r;
30753164 size_type __c = capacity();
......@@ -3089,7 +3178,7 @@ vector<bool, _Allocator>::insert(const_iterator __position, _ForwardIterator __f
30893178 std::copy_backward(__position, cend(), __v.end());
30903179 swap(__v);
30913180 }
3092 std::copy(__first, __last, __r);
3181 std::__copy<_ClassicAlgPolicy>(__first, __last, __r);
30933182 return __r;
30943183}
30953184
......@@ -3238,8 +3327,9 @@ operator==(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __
32383327 return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
32393328}
32403329
3330#if _LIBCPP_STD_VER <= 17
3331
32413332template <class _Tp, class _Allocator>
3242_LIBCPP_CONSTEXPR_SINCE_CXX20
32433333inline _LIBCPP_HIDE_FROM_ABI
32443334bool
32453335operator!=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
......@@ -3248,7 +3338,6 @@ operator!=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __
32483338}
32493339
32503340template <class _Tp, class _Allocator>
3251_LIBCPP_CONSTEXPR_SINCE_CXX20
32523341inline _LIBCPP_HIDE_FROM_ABI
32533342bool
32543343operator< (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
......@@ -3257,7 +3346,6 @@ operator< (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __
32573346}
32583347
32593348template <class _Tp, class _Allocator>
3260_LIBCPP_CONSTEXPR_SINCE_CXX20
32613349inline _LIBCPP_HIDE_FROM_ABI
32623350bool
32633351operator> (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
......@@ -3266,7 +3354,6 @@ operator> (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __
32663354}
32673355
32683356template <class _Tp, class _Allocator>
3269_LIBCPP_CONSTEXPR_SINCE_CXX20
32703357inline _LIBCPP_HIDE_FROM_ABI
32713358bool
32723359operator>=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
......@@ -3275,7 +3362,6 @@ operator>=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __
32753362}
32763363
32773364template <class _Tp, class _Allocator>
3278_LIBCPP_CONSTEXPR_SINCE_CXX20
32793365inline _LIBCPP_HIDE_FROM_ABI
32803366bool
32813367operator<=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
......@@ -3283,6 +3369,17 @@ operator<=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __
32833369 return !(__y < __x);
32843370}
32853371
3372#else // _LIBCPP_STD_VER <= 17
3373
3374template <class _Tp, class _Allocator>
3375_LIBCPP_HIDE_FROM_ABI constexpr __synth_three_way_result<_Tp>
3376operator<=>(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) {
3377 return std::lexicographical_compare_three_way(
3378 __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>);
3379}
3380
3381#endif // _LIBCPP_STD_VER <= 17
3382
32863383template <class _Tp, class _Allocator>
32873384_LIBCPP_CONSTEXPR_SINCE_CXX20
32883385inline _LIBCPP_HIDE_FROM_ABI
......@@ -3293,7 +3390,7 @@ swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y)
32933390 __x.swap(__y);
32943391}
32953392
3296#if _LIBCPP_STD_VER > 17
3393#if _LIBCPP_STD_VER >= 20
32973394template <class _Tp, class _Allocator, class _Up>
32983395_LIBCPP_CONSTEXPR_SINCE_CXX20
32993396inline _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::size_type
......@@ -3319,15 +3416,15 @@ template <>
33193416inline constexpr bool __format::__enable_insertable<vector<wchar_t>> = true;
33203417#endif
33213418
3322#endif // _LIBCPP_STD_VER > 17
3419#endif // _LIBCPP_STD_VER >= 20
33233420
3324#if _LIBCPP_STD_VER > 20
3325template <class _Tp, class CharT>
3421#if _LIBCPP_STD_VER >= 23
3422template <class _Tp, class _CharT>
33263423// Since is-vector-bool-reference is only used once it's inlined here.
33273424 requires same_as<typename _Tp::__container, vector<bool, typename _Tp::__container::allocator_type>>
3328struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Tp, CharT> {
3425struct _LIBCPP_TEMPLATE_VIS formatter<_Tp, _CharT> {
33293426private:
3330 formatter<bool, CharT> __underlying_;
3427 formatter<bool, _CharT> __underlying_;
33313428
33323429public:
33333430 template <class _ParseContext>
......@@ -3340,15 +3437,15 @@ public:
33403437 return __underlying_.format(__ref, __ctx);
33413438 }
33423439};
3343#endif // _LIBCPP_STD_VER > 20
3440#endif // _LIBCPP_STD_VER >= 23
33443441
33453442_LIBCPP_END_NAMESPACE_STD
33463443
3347#if _LIBCPP_STD_VER > 14
3444#if _LIBCPP_STD_VER >= 17
33483445_LIBCPP_BEGIN_NAMESPACE_STD
33493446namespace pmr {
33503447template <class _ValueT>
3351using vector = std::vector<_ValueT, polymorphic_allocator<_ValueT>>;
3448using vector _LIBCPP_AVAILABILITY_PMR = std::vector<_ValueT, polymorphic_allocator<_ValueT>>;
33523449} // namespace pmr
33533450_LIBCPP_END_NAMESPACE_STD
33543451#endif
......@@ -3359,6 +3456,8 @@ _LIBCPP_POP_MACROS
33593456# include <algorithm>
33603457# include <atomic>
33613458# include <concepts>
3459# include <cstdlib>
3460# include <type_traits>
33623461# include <typeinfo>
33633462# include <utility>
33643463#endif
lib/libcxx/include/version+80-28
......@@ -28,6 +28,8 @@ __cpp_lib_array_constexpr 201811L <array> <iterato
2828__cpp_lib_as_const 201510L <utility>
2929__cpp_lib_associative_heterogeneous_erasure 202110L <map> <set> <unordered_map>
3030 <unordered_set>
31__cpp_lib_associative_heterogeneous_insertion 202306L <map> <set> <unordered_map>
32 <unordered_set>
3133__cpp_lib_assume_aligned 201811L <memory>
3234__cpp_lib_atomic_flag_test 201907L <atomic>
3335__cpp_lib_atomic_float 201711L <atomic>
......@@ -38,10 +40,13 @@ __cpp_lib_atomic_shared_ptr 201711L <atomic>
3840__cpp_lib_atomic_value_initialization 201911L <atomic> <memory>
3941__cpp_lib_atomic_wait 201907L <atomic>
4042__cpp_lib_barrier 201907L <barrier>
41__cpp_lib_bind_back 202202L <functional>
42__cpp_lib_bind_front 201907L <functional>
43__cpp_lib_bind_back 202306L <functional>
44 202202L // C++23
45__cpp_lib_bind_front 202306L <functional>
46 201907L // C++20
4347__cpp_lib_bit_cast 201806L <bit>
4448__cpp_lib_bitops 201907L <bit>
49__cpp_lib_bitset 202306L <bitset>
4550__cpp_lib_bool_constant 201505L <type_traits>
4651__cpp_lib_bounded_array_traits 201902L <type_traits>
4752__cpp_lib_boyer_moore_searcher 201603L <functional>
......@@ -72,6 +77,7 @@ __cpp_lib_constexpr_tuple 201811L <tuple>
7277__cpp_lib_constexpr_typeinfo 202106L <typeinfo>
7378__cpp_lib_constexpr_utility 201811L <utility>
7479__cpp_lib_constexpr_vector 201907L <vector>
80__cpp_lib_copyable_function 202306L <functional>
7581__cpp_lib_coroutine 201902L <coroutine>
7682__cpp_lib_destroying_delete 201806L <new>
7783__cpp_lib_enable_shared_from_this 201603L <memory>
......@@ -82,15 +88,20 @@ __cpp_lib_erase_if 202002L <deque> <forward
8288__cpp_lib_exchange_function 201304L <utility>
8389__cpp_lib_execution 201902L <execution>
8490 201603L // C++17
85__cpp_lib_expected 202202L <expected>
91__cpp_lib_expected 202211L <expected>
8692__cpp_lib_filesystem 201703L <filesystem>
8793__cpp_lib_format 202106L <format>
94__cpp_lib_format_ranges 202207L <format>
95__cpp_lib_formatters 202302L <stacktrace> <thread>
8896__cpp_lib_forward_like 202207L <utility>
97__cpp_lib_fstream_native_handle 202306L <fstream>
98__cpp_lib_function_ref 202306L <functional>
8999__cpp_lib_gcd_lcm 201606L <numeric>
90100__cpp_lib_generic_associative_lookup 201304L <map> <set>
91101__cpp_lib_generic_unordered_lookup 201811L <unordered_map> <unordered_set>
92102__cpp_lib_hardware_interference_size 201703L <new>
93103__cpp_lib_has_unique_object_representations 201606L <type_traits>
104__cpp_lib_hazard_pointer 202306L <hazard_pointer>
94105__cpp_lib_hypot 201603L <cmath>
95106__cpp_lib_incomplete_container_elements 201505L <forward_list> <list> <vector>
96107__cpp_lib_int_pow2 202002L <bit>
......@@ -121,7 +132,9 @@ __cpp_lib_make_unique 201304L <memory>
121132__cpp_lib_map_try_emplace 201411L <map>
122133__cpp_lib_math_constants 201907L <numbers>
123134__cpp_lib_math_special_functions 201603L <cmath>
135__cpp_lib_mdspan 202207L <mdspan>
124136__cpp_lib_memory_resource 201603L <memory_resource>
137__cpp_lib_move_iterator_concept 202207L <iterator>
125138__cpp_lib_move_only_function 202110L <functional>
126139__cpp_lib_node_extract 201606L <map> <set> <unordered_map>
127140 <unordered_set>
......@@ -136,22 +149,26 @@ __cpp_lib_optional 202110L <optional>
136149__cpp_lib_out_ptr 202106L <memory>
137150__cpp_lib_parallel_algorithm 201603L <algorithm> <numeric>
138151__cpp_lib_polymorphic_allocator 201902L <memory_resource>
152__cpp_lib_print 202207L <ostream> <print>
139153__cpp_lib_quoted_string_io 201304L <iomanip>
140__cpp_lib_ranges 202106L <algorithm> <functional> <iterator>
154__cpp_lib_ranges 202207L <algorithm> <functional> <iterator>
141155 <memory> <ranges>
142156__cpp_lib_ranges_as_rvalue 202207L <ranges>
143157__cpp_lib_ranges_chunk 202202L <ranges>
144158__cpp_lib_ranges_chunk_by 202202L <ranges>
145159__cpp_lib_ranges_iota 202202L <numeric>
146160__cpp_lib_ranges_join_with 202202L <ranges>
161__cpp_lib_ranges_repeat 202207L <ranges>
147162__cpp_lib_ranges_slide 202202L <ranges>
148163__cpp_lib_ranges_starts_ends_with 202106L <algorithm>
149164__cpp_lib_ranges_to_container 202202L <deque> <forward_list> <list>
150 <map> <priority_queue> <queue>
165 <map> <queue> <ranges>
151166 <set> <stack> <string>
152167 <unordered_map> <unordered_set> <vector>
153168__cpp_lib_ranges_zip 202110L <ranges> <tuple> <utility>
169__cpp_lib_ratio 202306L <ratio>
154170__cpp_lib_raw_memory_algorithms 201606L <memory>
171__cpp_lib_rcu 202306L <rcu>
155172__cpp_lib_reference_from_temporary 202202L <type_traits>
156173__cpp_lib_remove_cvref 201711L <type_traits>
157174__cpp_lib_result_of_sfinae 201210L <functional> <type_traits>
......@@ -166,10 +183,12 @@ __cpp_lib_shared_ptr_weak_type 201606L <memory>
166183__cpp_lib_shared_timed_mutex 201402L <shared_mutex>
167184__cpp_lib_shift 201806L <algorithm>
168185__cpp_lib_smart_ptr_for_overwrite 202002L <memory>
186__cpp_lib_smart_ptr_owner_equality 202306L <memory>
169187__cpp_lib_source_location 201907L <source_location>
170188__cpp_lib_span 202002L <span>
171189__cpp_lib_spanstream 202106L <spanstream>
172190__cpp_lib_ssize 201902L <iterator>
191__cpp_lib_sstream_from_string_view 202306L <sstream>
173192__cpp_lib_stacktrace 202011L <stacktrace>
174193__cpp_lib_starts_ends_with 201711L <string> <string_view>
175194__cpp_lib_stdatomic_h 202011L <stdatomic.h>
......@@ -178,11 +197,14 @@ __cpp_lib_string_resize_and_overwrite 202110L <string>
178197__cpp_lib_string_udls 201304L <string>
179198__cpp_lib_string_view 201803L <string> <string_view>
180199 201606L // C++17
200__cpp_lib_submdspan 202306L <mdspan>
181201__cpp_lib_syncbuf 201803L <syncstream>
202__cpp_lib_text_encoding 202306L <text_encoding>
182203__cpp_lib_three_way_comparison 201907L <compare>
183204__cpp_lib_to_address 201711L <memory>
184205__cpp_lib_to_array 201907L <array>
185206__cpp_lib_to_chars 201611L <charconv>
207__cpp_lib_to_string 202306L <string>
186208__cpp_lib_to_underlying 202102L <utility>
187209__cpp_lib_transformation_trait_aliases 201304L <type_traits>
188210__cpp_lib_transparent_operators 201510L <functional> <memory>
......@@ -197,6 +219,7 @@ __cpp_lib_unreachable 202202L <utility>
197219__cpp_lib_unwrap_ref 201811L <functional>
198220__cpp_lib_variant 202102L <variant>
199221__cpp_lib_void_t 201411L <type_traits>
222__cpp_lib_within_lifetime 202306L <type_traits>
200223
201224*/
202225
......@@ -209,7 +232,7 @@ __cpp_lib_void_t 201411L <type_traits>
209232
210233// clang-format off
211234
212#if _LIBCPP_STD_VER > 11
235#if _LIBCPP_STD_VER >= 14
213236# define __cpp_lib_chrono_udls 201304L
214237# define __cpp_lib_complex_udls 201309L
215238# define __cpp_lib_exchange_function 201304L
......@@ -224,7 +247,7 @@ __cpp_lib_void_t 201411L <type_traits>
224247# define __cpp_lib_quoted_string_io 201304L
225248# define __cpp_lib_result_of_sfinae 201210L
226249# define __cpp_lib_robust_nonmodifying_seq_ops 201304L
227# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)
250# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX)
228251# define __cpp_lib_shared_timed_mutex 201402L
229252# endif
230253# define __cpp_lib_string_udls 201304L
......@@ -234,7 +257,7 @@ __cpp_lib_void_t 201411L <type_traits>
234257# define __cpp_lib_tuples_by_type 201304L
235258#endif
236259
237#if _LIBCPP_STD_VER > 14
260#if _LIBCPP_STD_VER >= 17
238261# define __cpp_lib_addressof_constexpr 201603L
239262# define __cpp_lib_allocator_traits_is_always_equal 201411L
240263# define __cpp_lib_any 201606L
......@@ -249,7 +272,7 @@ __cpp_lib_void_t 201411L <type_traits>
249272# define __cpp_lib_clamp 201603L
250273# define __cpp_lib_enable_shared_from_this 201603L
251274// # define __cpp_lib_execution 201603L
252# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)
275# if !defined(_LIBCPP_AVAILABILITY_HAS_NO_FILESYSTEM_LIBRARY)
253276# define __cpp_lib_filesystem 201703L
254277# endif
255278# define __cpp_lib_gcd_lcm 201606L
......@@ -268,7 +291,9 @@ __cpp_lib_void_t 201411L <type_traits>
268291# define __cpp_lib_make_from_tuple 201606L
269292# define __cpp_lib_map_try_emplace 201411L
270293// # define __cpp_lib_math_special_functions 201603L
271# define __cpp_lib_memory_resource 201603L
294# if !defined(_LIBCPP_AVAILABILITY_HAS_NO_PMR)
295# define __cpp_lib_memory_resource 201603L
296# endif
272297# define __cpp_lib_node_extract 201606L
273298# define __cpp_lib_nonmember_container_access 201411L
274299# define __cpp_lib_not_fn 201603L
......@@ -277,7 +302,7 @@ __cpp_lib_void_t 201411L <type_traits>
277302# define __cpp_lib_raw_memory_algorithms 201606L
278303# define __cpp_lib_sample 201603L
279304# define __cpp_lib_scoped_lock 201703L
280# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)
305# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX)
281306# define __cpp_lib_shared_mutex 201505L
282307# endif
283308# define __cpp_lib_shared_ptr_arrays 201611L
......@@ -293,7 +318,7 @@ __cpp_lib_void_t 201411L <type_traits>
293318# define __cpp_lib_void_t 201411L
294319#endif
295320
296#if _LIBCPP_STD_VER > 17
321#if _LIBCPP_STD_VER >= 20
297322# undef __cpp_lib_array_constexpr
298323# define __cpp_lib_array_constexpr 201811L
299324# define __cpp_lib_assume_aligned 201811L
......@@ -303,15 +328,15 @@ __cpp_lib_void_t 201411L <type_traits>
303328// # define __cpp_lib_atomic_ref 201806L
304329// # define __cpp_lib_atomic_shared_ptr 201711L
305330# define __cpp_lib_atomic_value_initialization 201911L
306# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)
331# if !defined(_LIBCPP_AVAILABILITY_HAS_NO_SYNC)
307332# define __cpp_lib_atomic_wait 201907L
308333# endif
309# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)
334# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SYNC)
310335# define __cpp_lib_barrier 201907L
311336# endif
312337# define __cpp_lib_bind_front 201907L
313338# define __cpp_lib_bit_cast 201806L
314// # define __cpp_lib_bitops 201907L
339# define __cpp_lib_bitops 201907L
315340# define __cpp_lib_bounded_array_traits 201902L
316341# if !defined(_LIBCPP_HAS_NO_CHAR8_T)
317342# define __cpp_lib_char8_t 201907L
......@@ -330,16 +355,14 @@ __cpp_lib_void_t 201411L <type_traits>
330355# define __cpp_lib_constexpr_utility 201811L
331356# define __cpp_lib_constexpr_vector 201907L
332357# define __cpp_lib_coroutine 201902L
333# if _LIBCPP_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L
358# if _LIBCPP_STD_VER >= 20 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L
334359# define __cpp_lib_destroying_delete 201806L
335360# endif
336361# define __cpp_lib_endian 201907L
337362# define __cpp_lib_erase_if 202002L
338363# undef __cpp_lib_execution
339364// # define __cpp_lib_execution 201902L
340# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
341// # define __cpp_lib_format 202106L
342# endif
365// # define __cpp_lib_format 202106L
343366# define __cpp_lib_generic_unordered_lookup 201811L
344367# define __cpp_lib_int_pow2 202002L
345368# define __cpp_lib_integer_comparison_functions 202002L
......@@ -351,15 +374,18 @@ __cpp_lib_void_t 201411L <type_traits>
351374# if !defined(_LIBCPP_HAS_NO_THREADS)
352375// # define __cpp_lib_jthread 201911L
353376# endif
354# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)
377# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SYNC)
355378# define __cpp_lib_latch 201907L
356379# endif
357380# define __cpp_lib_list_remove_return_type 201806L
358381# define __cpp_lib_math_constants 201907L
359# define __cpp_lib_polymorphic_allocator 201902L
360# define __cpp_lib_ranges 202106L
382# define __cpp_lib_move_iterator_concept 202207L
383# if !defined(_LIBCPP_AVAILABILITY_HAS_NO_PMR)
384# define __cpp_lib_polymorphic_allocator 201902L
385# endif
386# define __cpp_lib_ranges 202207L
361387# define __cpp_lib_remove_cvref 201711L
362# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)
388# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SYNC)
363389# define __cpp_lib_semaphore 201907L
364390# endif
365391# undef __cpp_lib_shared_ptr_arrays
......@@ -382,7 +408,7 @@ __cpp_lib_void_t 201411L <type_traits>
382408# define __cpp_lib_unwrap_ref 201811L
383409#endif
384410
385#if _LIBCPP_STD_VER > 20
411#if _LIBCPP_STD_VER >= 23
386412# define __cpp_lib_adaptor_iterator_pair_constructor 202106L
387413# define __cpp_lib_allocate_at_least 202106L
388414// # define __cpp_lib_associative_heterogeneous_erasure 202110L
......@@ -393,23 +419,28 @@ __cpp_lib_void_t 201411L <type_traits>
393419// # define __cpp_lib_constexpr_cmath 202202L
394420# undef __cpp_lib_constexpr_memory
395421# define __cpp_lib_constexpr_memory 202202L
396// # define __cpp_lib_constexpr_typeinfo 202106L
397# define __cpp_lib_expected 202202L
422# define __cpp_lib_constexpr_typeinfo 202106L
423# define __cpp_lib_expected 202211L
424# define __cpp_lib_format_ranges 202207L
425// # define __cpp_lib_formatters 202302L
398426# define __cpp_lib_forward_like 202207L
399// # define __cpp_lib_invoke_r 202106L
427# define __cpp_lib_invoke_r 202106L
400428# define __cpp_lib_is_scoped_enum 202011L
429// # define __cpp_lib_mdspan 202207L
401430// # define __cpp_lib_move_only_function 202110L
402431# undef __cpp_lib_optional
403432# define __cpp_lib_optional 202110L
404433// # define __cpp_lib_out_ptr 202106L
434// # define __cpp_lib_print 202207L
405435# define __cpp_lib_ranges_as_rvalue 202207L
406436// # define __cpp_lib_ranges_chunk 202202L
407437// # define __cpp_lib_ranges_chunk_by 202202L
408438// # define __cpp_lib_ranges_iota 202202L
409439// # define __cpp_lib_ranges_join_with 202202L
440# define __cpp_lib_ranges_repeat 202207L
410441// # define __cpp_lib_ranges_slide 202202L
411442// # define __cpp_lib_ranges_starts_ends_with 202106L
412// # define __cpp_lib_ranges_to_container 202202L
443# define __cpp_lib_ranges_to_container 202202L
413444// # define __cpp_lib_ranges_zip 202110L
414445// # define __cpp_lib_reference_from_temporary 202202L
415446// # define __cpp_lib_spanstream 202106L
......@@ -417,10 +448,31 @@ __cpp_lib_void_t 201411L <type_traits>
417448# define __cpp_lib_stdatomic_h 202011L
418449# define __cpp_lib_string_contains 202011L
419450# define __cpp_lib_string_resize_and_overwrite 202110L
451// # define __cpp_lib_to_string 202306L
420452# define __cpp_lib_to_underlying 202102L
421453# define __cpp_lib_unreachable 202202L
422454#endif
423455
456#if _LIBCPP_STD_VER >= 26
457// # define __cpp_lib_associative_heterogeneous_insertion 202306L
458# undef __cpp_lib_bind_back
459// # define __cpp_lib_bind_back 202306L
460# undef __cpp_lib_bind_front
461# define __cpp_lib_bind_front 202306L
462// # define __cpp_lib_bitset 202306L
463// # define __cpp_lib_copyable_function 202306L
464// # define __cpp_lib_fstream_native_handle 202306L
465// # define __cpp_lib_function_ref 202306L
466// # define __cpp_lib_hazard_pointer 202306L
467# define __cpp_lib_ratio 202306L
468// # define __cpp_lib_rcu 202306L
469// # define __cpp_lib_smart_ptr_owner_equality 202306L
470// # define __cpp_lib_sstream_from_string_view 202306L
471// # define __cpp_lib_submdspan 202306L
472// # define __cpp_lib_text_encoding 202306L
473// # define __cpp_lib_within_lifetime 202306L
474#endif
475
424476// clang-format on
425477
426478#endif // _LIBCPP_VERSIONH
lib/libcxx/include/wchar.h+4
......@@ -116,12 +116,16 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
116116# pragma GCC system_header
117117#endif
118118
119// We define this here to support older versions of glibc <wchar.h> that do
120// not define this for clang.
119121#ifdef __cplusplus
120122#define __CORRECT_ISO_CPP_WCHAR_H_PROTO
121123#endif
122124
123125# if __has_include_next(<wchar.h>)
124126# include_next <wchar.h>
127# else
128# include <__mbstate_t.h> // make sure we have mbstate_t regardless of the existence of <wchar.h>
125129# endif
126130
127131// Determine whether we have const-correct overloads for wcschr and friends.
lib/libcxx/src/algorithm.cpp+16-21
......@@ -7,11 +7,25 @@
77//===----------------------------------------------------------------------===//
88
99#include <algorithm>
10#include <bit>
1011
1112_LIBCPP_BEGIN_NAMESPACE_STD
1213
13// TODO(varconst): this currently doesn't benefit `ranges::sort` because it uses `ranges::less` instead of `__less`.
14template <class Comp, class RandomAccessIterator>
15void __sort(RandomAccessIterator first, RandomAccessIterator last, Comp comp) {
16 auto depth_limit = 2 * std::__bit_log2(static_cast<size_t>(last - first));
1417
18 // Only use bitset partitioning for arithmetic types. We should also check
19 // that the default comparator is in use so that we are sure that there are no
20 // branches in the comparator.
21 std::__introsort<_ClassicAlgPolicy,
22 ranges::less,
23 RandomAccessIterator,
24 __use_branchless_sort<ranges::less, RandomAccessIterator>::value>(
25 first, last, ranges::less{}, depth_limit);
26}
27
28// clang-format off
1529template void __sort<__less<char>&, char*>(char*, char*, __less<char>&);
1630#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1731template void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
......@@ -29,25 +43,6 @@ template void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned
2943template void __sort<__less<float>&, float*>(float*, float*, __less<float>&);
3044template void __sort<__less<double>&, double*>(double*, double*, __less<double>&);
3145template void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
32
33template bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&);
34#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
35template bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
36#endif
37template bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
38template bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
39template bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&);
40template bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
41template bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&);
42template bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);
43template bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&);
44template bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
45template bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
46template bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&);
47template bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&);
48template bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&);
49template bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
50
51template unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&);
46// clang-format on
5247
5348_LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/any.cpp+1-1
......@@ -21,7 +21,7 @@ const char* bad_any_cast::what() const noexcept {
2121// Even though it no longer exists in a header file
2222_LIBCPP_BEGIN_NAMESPACE_LFTS
2323
24class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
24class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
2525{
2626public:
2727 virtual const char* what() const noexcept;
lib/libcxx/src/atomic.cpp+11-3
......@@ -9,11 +9,14 @@
99#include <__config>
1010#ifndef _LIBCPP_HAS_NO_THREADS
1111
12#include <__thread/timed_backoff_policy.h>
1213#include <atomic>
1314#include <climits>
1415#include <functional>
1516#include <thread>
1617
18#include "include/apple_availability.h"
19
1720#ifdef __linux__
1821
1922#include <unistd.h>
......@@ -77,20 +80,25 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo
7780 const_cast<__cxx_atomic_contention_t*>(__ptr), 0);
7881}
7982
80#elif defined(__FreeBSD__)
83#elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
84/*
85 * Since __cxx_contention_t is int64_t even on 32bit FreeBSD
86 * platforms, we have to use umtx ops that work on the long type, and
87 * limit its use to architectures where long and int64_t are synonyms.
88 */
8189
8290static void __libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr,
8391 __cxx_contention_t __val)
8492{
8593 _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr),
86 UMTX_OP_WAIT_UINT_PRIVATE, __val, NULL, NULL);
94 UMTX_OP_WAIT, __val, NULL, NULL);
8795}
8896
8997static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr,
9098 bool __notify_one)
9199{
92100 _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr),
93 UMTX_OP_WAKE_PRIVATE, __notify_one ? 1 : INT_MAX, NULL, NULL);
101 UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, NULL, NULL);
94102}
95103
96104#else // <- Add other operating systems here
lib/libcxx/src/charconv.cpp+2-2
......@@ -18,13 +18,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
1818namespace __itoa
1919{
2020
21_LIBCPP_FUNC_VIS char*
21_LIBCPP_EXPORTED_FROM_ABI char*
2222__u32toa(uint32_t value, char* buffer) noexcept
2323{
2424 return __base_10_u32(buffer, value);
2525}
2626
27_LIBCPP_FUNC_VIS char*
27_LIBCPP_EXPORTED_FROM_ABI char*
2828__u64toa(uint64_t value, char* buffer) noexcept
2929{
3030 return __base_10_u64(buffer, value);
lib/libcxx/src/chrono.cpp+7-62
......@@ -12,9 +12,9 @@
1212#define _LARGE_TIME_API
1313#endif
1414
15#include <cerrno> // errno
15#include <__system_error/system_error.h>
16#include <cerrno> // errno
1617#include <chrono>
17#include <system_error> // __throw_system_error
1818
1919#if defined(__MVS__)
2020#include <__support/ibm/gettod_zos.h> // gettimeofdayMonotonic
......@@ -24,15 +24,15 @@
2424#include "include/apple_availability.h"
2525
2626#if __has_include(<unistd.h>)
27# include <unistd.h>
27# include <unistd.h> // _POSIX_TIMERS
2828#endif
2929
3030#if __has_include(<sys/time.h>)
3131# include <sys/time.h> // for gettimeofday and timeval
3232#endif
3333
34#if !defined(__APPLE__) && defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0
35# define _LIBCPP_USE_CLOCK_GETTIME
34#if defined(__APPLE__) || defined (__gnu_hurd__) || (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0)
35# define _LIBCPP_HAS_CLOCK_GETTIME
3636#endif
3737
3838#if defined(_LIBCPP_WIN32API)
......@@ -116,7 +116,7 @@ static system_clock::time_point __libcpp_system_clock_now() {
116116 return system_clock::time_point(duration_cast<system_clock::duration>(d - nt_to_unix_epoch));
117117}
118118
119#elif defined(CLOCK_REALTIME) && defined(_LIBCPP_USE_CLOCK_GETTIME)
119#elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
120120
121121static system_clock::time_point __libcpp_system_clock_now() {
122122 struct timespec tp;
......@@ -167,59 +167,6 @@ system_clock::from_time_t(time_t t) noexcept
167167
168168#if defined(__APPLE__)
169169
170// TODO(ldionne):
171// This old implementation of steady_clock is retained until Chrome drops supports
172// for macOS < 10.12. The issue is that they link libc++ statically into their
173// application, which means that libc++ must support being built for such deployment
174// targets. See https://llvm.org/D74489 for details.
175#if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \
176 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
177 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \
178 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
179# define _LIBCPP_USE_OLD_MACH_ABSOLUTE_TIME
180#endif
181
182#if defined(_LIBCPP_USE_OLD_MACH_ABSOLUTE_TIME)
183
184// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
185// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom
186// are run time constants supplied by the OS. This clock has no relationship
187// to the Gregorian calendar. It's main use is as a high resolution timer.
188
189// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize
190// for that case as an optimization.
191
192static steady_clock::rep steady_simplified() {
193 return static_cast<steady_clock::rep>(mach_absolute_time());
194}
195static double compute_steady_factor() {
196 mach_timebase_info_data_t MachInfo;
197 mach_timebase_info(&MachInfo);
198 return static_cast<double>(MachInfo.numer) / MachInfo.denom;
199}
200
201static steady_clock::rep steady_full() {
202 static const double factor = compute_steady_factor();
203 return static_cast<steady_clock::rep>(mach_absolute_time() * factor);
204}
205
206typedef steady_clock::rep (*FP)();
207
208static FP init_steady_clock() {
209 mach_timebase_info_data_t MachInfo;
210 mach_timebase_info(&MachInfo);
211 if (MachInfo.numer == MachInfo.denom)
212 return &steady_simplified;
213 return &steady_full;
214}
215
216static steady_clock::time_point __libcpp_steady_clock_now() {
217 static FP fp = init_steady_clock();
218 return steady_clock::time_point(steady_clock::duration(fp()));
219}
220
221#else // vvvvv default behavior for Apple platforms vvvvv
222
223170// On Apple platforms, only CLOCK_UPTIME_RAW, CLOCK_MONOTONIC_RAW or
224171// mach_absolute_time are able to time functions in the nanosecond range.
225172// Furthermore, only CLOCK_MONOTONIC_RAW is truly monotonic, because it
......@@ -232,8 +179,6 @@ static steady_clock::time_point __libcpp_steady_clock_now() {
232179 return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
233180}
234181
235#endif
236
237182#elif defined(_LIBCPP_WIN32API)
238183
239184// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx says:
......@@ -281,7 +226,7 @@ static steady_clock::time_point __libcpp_steady_clock_now() noexcept {
281226 return steady_clock::time_point(nanoseconds(_zx_clock_get_monotonic()));
282227}
283228
284# elif defined(CLOCK_MONOTONIC)
229# elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
285230
286231static steady_clock::time_point __libcpp_steady_clock_now() {
287232 struct timespec tp;
lib/libcxx/src/condition_variable.cpp-1
......@@ -12,7 +12,6 @@
1212
1313#include <condition_variable>
1414#include <thread>
15#include <system_error>
1615
1716#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
1817# pragma comment(lib, "pthread")
lib/libcxx/src/condition_variable_destructor.cpp+1-1
......@@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2424
2525#ifdef NEEDS_CONDVAR_DESTRUCTOR
2626
27class _LIBCPP_TYPE_VIS condition_variable
27class _LIBCPP_EXPORTED_FROM_ABI condition_variable
2828{
2929 __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
3030public:
lib/libcxx/src/debug.cpp deleted-559
......@@ -1,559 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <__assert>
10#include <__config>
11#include <__debug>
12#include <__hash_table>
13#include <algorithm>
14#include <cstdio>
15#include <functional>
16#include <string>
17
18#ifndef _LIBCPP_HAS_NO_THREADS
19# include <mutex>
20# if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
21# pragma comment(lib, "pthread")
22# endif
23#endif
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27_LIBCPP_FUNC_VIS
28__libcpp_db*
29__get_db()
30{
31 static _LIBCPP_NO_DESTROY __libcpp_db db;
32 return &db;
33}
34
35_LIBCPP_FUNC_VIS
36const __libcpp_db*
37__get_const_db()
38{
39 return __get_db();
40}
41
42namespace
43{
44
45#ifndef _LIBCPP_HAS_NO_THREADS
46typedef mutex mutex_type;
47typedef lock_guard<mutex_type> WLock;
48typedef lock_guard<mutex_type> RLock;
49
50mutex_type&
51mut()
52{
53 static _LIBCPP_NO_DESTROY mutex_type m;
54 return m;
55}
56#endif // !_LIBCPP_HAS_NO_THREADS
57
58} // unnamed namespace
59
60__i_node::~__i_node()
61{
62 if (__next_)
63 {
64 __next_->~__i_node();
65 free(__next_);
66 }
67}
68
69__c_node::~__c_node()
70{
71 free(beg_);
72 if (__next_)
73 {
74 __next_->~__c_node();
75 free(__next_);
76 }
77}
78
79__libcpp_db::__libcpp_db()
80 : __cbeg_(nullptr),
81 __cend_(nullptr),
82 __csz_(0),
83 __ibeg_(nullptr),
84 __iend_(nullptr),
85 __isz_(0)
86{
87}
88
89__libcpp_db::~__libcpp_db()
90{
91 if (__cbeg_)
92 {
93 for (__c_node** p = __cbeg_; p != __cend_; ++p)
94 {
95 if (*p != nullptr)
96 {
97 (*p)->~__c_node();
98 free(*p);
99 }
100 }
101 free(__cbeg_);
102 }
103 if (__ibeg_)
104 {
105 for (__i_node** p = __ibeg_; p != __iend_; ++p)
106 {
107 if (*p != nullptr)
108 {
109 (*p)->~__i_node();
110 free(*p);
111 }
112 }
113 free(__ibeg_);
114 }
115}
116
117void*
118__libcpp_db::__find_c_from_i(void* __i) const
119{
120#ifndef _LIBCPP_HAS_NO_THREADS
121 RLock _(mut());
122#endif
123 __i_node* i = __find_iterator(__i);
124 _LIBCPP_ASSERT(i != nullptr, "iterator not found in debug database.");
125 return i->__c_ != nullptr ? i->__c_->__c_ : nullptr;
126}
127
128void
129__libcpp_db::__insert_ic(void* __i, const void* __c)
130{
131#ifndef _LIBCPP_HAS_NO_THREADS
132 WLock _(mut());
133#endif
134 if (__cbeg_ == __cend_)
135 return;
136 size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
137 __c_node* c = __cbeg_[hc];
138 if (c == nullptr)
139 return;
140 while (c->__c_ != __c)
141 {
142 c = c->__next_;
143 if (c == nullptr)
144 return;
145 }
146 __i_node* i = __insert_iterator(__i);
147 c->__add(i);
148 i->__c_ = c;
149}
150
151void
152__libcpp_db::__insert_c(void* __c, __libcpp_db::_InsertConstruct *__fn)
153{
154#ifndef _LIBCPP_HAS_NO_THREADS
155 WLock _(mut());
156#endif
157 if (__csz_ + 1 > static_cast<size_t>(__cend_ - __cbeg_))
158 {
159 size_t nc = __next_prime(2*static_cast<size_t>(__cend_ - __cbeg_) + 1);
160 __c_node** cbeg = static_cast<__c_node**>(calloc(nc, sizeof(__c_node*)));
161 if (cbeg == nullptr)
162 __throw_bad_alloc();
163
164 for (__c_node** p = __cbeg_; p != __cend_; ++p)
165 {
166 __c_node* q = *p;
167 while (q != nullptr)
168 {
169 size_t h = hash<void*>()(q->__c_) % nc;
170 __c_node* r = q->__next_;
171 q->__next_ = cbeg[h];
172 cbeg[h] = q;
173 q = r;
174 }
175 }
176 free(__cbeg_);
177 __cbeg_ = cbeg;
178 __cend_ = __cbeg_ + nc;
179 }
180 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
181 __c_node* p = __cbeg_[hc];
182 void *buf = malloc(sizeof(__c_node));
183 if (buf == nullptr)
184 __throw_bad_alloc();
185 __cbeg_[hc] = __fn(buf, __c, p);
186
187 ++__csz_;
188}
189
190void
191__libcpp_db::__erase_i(void* __i)
192{
193#ifndef _LIBCPP_HAS_NO_THREADS
194 WLock _(mut());
195#endif
196 if (__ibeg_ != __iend_)
197 {
198 size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
199 __i_node* p = __ibeg_[hi];
200 if (p != nullptr)
201 {
202 __i_node* q = nullptr;
203 while (p->__i_ != __i)
204 {
205 q = p;
206 p = p->__next_;
207 if (p == nullptr)
208 return;
209 }
210 if (q == nullptr)
211 __ibeg_[hi] = p->__next_;
212 else
213 q->__next_ = p->__next_;
214 __c_node* c = p->__c_;
215 --__isz_;
216 if (c != nullptr)
217 c->__remove(p);
218 free(p);
219 }
220 }
221}
222
223void
224__libcpp_db::__invalidate_all(void* __c)
225{
226#ifndef _LIBCPP_HAS_NO_THREADS
227 WLock _(mut());
228#endif
229 if (__cend_ != __cbeg_)
230 {
231 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
232 __c_node* p = __cbeg_[hc];
233 if (p == nullptr)
234 return;
235 while (p->__c_ != __c)
236 {
237 p = p->__next_;
238 if (p == nullptr)
239 return;
240 }
241 while (p->end_ != p->beg_)
242 {
243 --p->end_;
244 (*p->end_)->__c_ = nullptr;
245 }
246 }
247}
248
249__c_node*
250__libcpp_db::__find_c_and_lock(void* __c) const
251{
252#ifndef _LIBCPP_HAS_NO_THREADS
253 mut().lock();
254#endif
255 if (__cend_ == __cbeg_)
256 {
257#ifndef _LIBCPP_HAS_NO_THREADS
258 mut().unlock();
259#endif
260 return nullptr;
261 }
262 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
263 __c_node* p = __cbeg_[hc];
264 if (p == nullptr)
265 {
266#ifndef _LIBCPP_HAS_NO_THREADS
267 mut().unlock();
268#endif
269 return nullptr;
270 }
271 while (p->__c_ != __c)
272 {
273 p = p->__next_;
274 if (p == nullptr)
275 {
276#ifndef _LIBCPP_HAS_NO_THREADS
277 mut().unlock();
278#endif
279 return nullptr;
280 }
281 }
282 return p;
283}
284
285__c_node*
286__libcpp_db::__find_c(void* __c) const
287{
288 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
289 __c_node* p = __cbeg_[hc];
290 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c A");
291 while (p->__c_ != __c)
292 {
293 p = p->__next_;
294 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c B");
295 }
296 return p;
297}
298
299void
300__libcpp_db::unlock() const
301{
302#ifndef _LIBCPP_HAS_NO_THREADS
303 mut().unlock();
304#endif
305}
306
307void
308__libcpp_db::__erase_c(void* __c)
309{
310#ifndef _LIBCPP_HAS_NO_THREADS
311 WLock _(mut());
312#endif
313 if (__cend_ != __cbeg_)
314 {
315 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
316 __c_node* p = __cbeg_[hc];
317 if (p == nullptr)
318 return;
319 __c_node* q = nullptr;
320 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A");
321 while (p->__c_ != __c)
322 {
323 q = p;
324 p = p->__next_;
325 if (p == nullptr)
326 return;
327 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B");
328 }
329 if (q == nullptr)
330 __cbeg_[hc] = p->__next_;
331 else
332 q->__next_ = p->__next_;
333 while (p->end_ != p->beg_)
334 {
335 --p->end_;
336 (*p->end_)->__c_ = nullptr;
337 }
338 free(p->beg_);
339 free(p);
340 --__csz_;
341 }
342}
343
344void
345__libcpp_db::__iterator_copy(void* __i, const void* __i0)
346{
347#ifndef _LIBCPP_HAS_NO_THREADS
348 WLock _(mut());
349#endif
350 __i_node* i = __find_iterator(__i);
351 __i_node* i0 = __find_iterator(__i0);
352 __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr;
353 if (i == nullptr && i0 != nullptr)
354 i = __insert_iterator(__i);
355 __c_node* c = i != nullptr ? i->__c_ : nullptr;
356 if (c != c0)
357 {
358 if (c != nullptr)
359 c->__remove(i);
360 if (i != nullptr)
361 {
362 i->__c_ = nullptr;
363 if (c0 != nullptr)
364 {
365 i->__c_ = c0;
366 i->__c_->__add(i);
367 }
368 }
369 }
370}
371
372bool
373__libcpp_db::__dereferenceable(const void* __i) const
374{
375#ifndef _LIBCPP_HAS_NO_THREADS
376 RLock _(mut());
377#endif
378 __i_node* i = __find_iterator(__i);
379 return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i);
380}
381
382bool
383__libcpp_db::__decrementable(const void* __i) const
384{
385#ifndef _LIBCPP_HAS_NO_THREADS
386 RLock _(mut());
387#endif
388 __i_node* i = __find_iterator(__i);
389 return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i);
390}
391
392bool
393__libcpp_db::__addable(const void* __i, ptrdiff_t __n) const
394{
395#ifndef _LIBCPP_HAS_NO_THREADS
396 RLock _(mut());
397#endif
398 __i_node* i = __find_iterator(__i);
399 return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n);
400}
401
402bool
403__libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const
404{
405#ifndef _LIBCPP_HAS_NO_THREADS
406 RLock _(mut());
407#endif
408 __i_node* i = __find_iterator(__i);
409 return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n);
410}
411
412bool
413__libcpp_db::__less_than_comparable(const void* __i, const void* __j) const
414{
415#ifndef _LIBCPP_HAS_NO_THREADS
416 RLock _(mut());
417#endif
418 __i_node* i = __find_iterator(__i);
419 __i_node* j = __find_iterator(__j);
420 __c_node* ci = i != nullptr ? i->__c_ : nullptr;
421 __c_node* cj = j != nullptr ? j->__c_ : nullptr;
422 return ci == cj;
423}
424
425void
426__libcpp_db::swap(void* c1, void* c2)
427{
428#ifndef _LIBCPP_HAS_NO_THREADS
429 WLock _(mut());
430#endif
431 size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_);
432 __c_node* p1 = __cbeg_[hc];
433 _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A");
434 while (p1->__c_ != c1)
435 {
436 p1 = p1->__next_;
437 _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap B");
438 }
439 hc = hash<void*>()(c2) % static_cast<size_t>(__cend_ - __cbeg_);
440 __c_node* p2 = __cbeg_[hc];
441 _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap C");
442 while (p2->__c_ != c2)
443 {
444 p2 = p2->__next_;
445 _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap D");
446 }
447 std::swap(p1->beg_, p2->beg_);
448 std::swap(p1->end_, p2->end_);
449 std::swap(p1->cap_, p2->cap_);
450 for (__i_node** p = p1->beg_; p != p1->end_; ++p)
451 (*p)->__c_ = p1;
452 for (__i_node** p = p2->beg_; p != p2->end_; ++p)
453 (*p)->__c_ = p2;
454}
455
456void
457__libcpp_db::__insert_i(void* __i)
458{
459#ifndef _LIBCPP_HAS_NO_THREADS
460 WLock _(mut());
461#endif
462 __insert_iterator(__i);
463}
464
465void
466__c_node::__add(__i_node* i)
467{
468 if (end_ == cap_)
469 {
470 size_t nc = 2*static_cast<size_t>(cap_ - beg_);
471 if (nc == 0)
472 nc = 1;
473 __i_node** beg =
474 static_cast<__i_node**>(malloc(nc * sizeof(__i_node*)));
475 if (beg == nullptr)
476 __throw_bad_alloc();
477
478 if (nc > 1)
479 memcpy(beg, beg_, nc/2*sizeof(__i_node*));
480 free(beg_);
481 beg_ = beg;
482 end_ = beg_ + nc/2;
483 cap_ = beg_ + nc;
484 }
485 *end_++ = i;
486}
487
488// private api
489
490_LIBCPP_HIDDEN
491__i_node*
492__libcpp_db::__insert_iterator(void* __i)
493{
494 if (__isz_ + 1 > static_cast<size_t>(__iend_ - __ibeg_))
495 {
496 size_t nc = __next_prime(2*static_cast<size_t>(__iend_ - __ibeg_) + 1);
497 __i_node** ibeg = static_cast<__i_node**>(calloc(nc, sizeof(__i_node*)));
498 if (ibeg == nullptr)
499 __throw_bad_alloc();
500
501 for (__i_node** p = __ibeg_; p != __iend_; ++p)
502 {
503 __i_node* q = *p;
504 while (q != nullptr)
505 {
506 size_t h = hash<void*>()(q->__i_) % nc;
507 __i_node* r = q->__next_;
508 q->__next_ = ibeg[h];
509 ibeg[h] = q;
510 q = r;
511 }
512 }
513 free(__ibeg_);
514 __ibeg_ = ibeg;
515 __iend_ = __ibeg_ + nc;
516 }
517 size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
518 __i_node* p = __ibeg_[hi];
519 __i_node* r = __ibeg_[hi] =
520 static_cast<__i_node*>(malloc(sizeof(__i_node)));
521 if (r == nullptr)
522 __throw_bad_alloc();
523
524 ::new(r) __i_node(__i, p, nullptr);
525 ++__isz_;
526 return r;
527}
528
529_LIBCPP_HIDDEN
530__i_node*
531__libcpp_db::__find_iterator(const void* __i) const
532{
533 __i_node* r = nullptr;
534 if (__ibeg_ != __iend_)
535 {
536 size_t h = hash<const void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
537 for (__i_node* nd = __ibeg_[h]; nd != nullptr; nd = nd->__next_)
538 {
539 if (nd->__i_ == __i)
540 {
541 r = nd;
542 break;
543 }
544 }
545 }
546 return r;
547}
548
549_LIBCPP_HIDDEN
550void
551__c_node::__remove(__i_node* p)
552{
553 __i_node** r = find(beg_, end_, p);
554 _LIBCPP_ASSERT(r != end_, "debug mode internal logic error __c_node::__remove");
555 if (--end_ != r)
556 memmove(r, r+1, static_cast<size_t>(end_ - r)*sizeof(__i_node*));
557}
558
559_LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/experimental/memory_resource.cpp+2-2
......@@ -27,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
2727
2828// new_delete_resource()
2929
30class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp
30class _LIBCPP_EXPORTED_FROM_ABI __new_delete_memory_resource_imp
3131 : public memory_resource
3232{
3333 void *do_allocate(size_t size, size_t align) override {
......@@ -51,7 +51,7 @@ public:
5151
5252// null_memory_resource()
5353
54class _LIBCPP_TYPE_VIS __null_memory_resource_imp
54class _LIBCPP_EXPORTED_FROM_ABI __null_memory_resource_imp
5555 : public memory_resource
5656{
5757public:
lib/libcxx/src/filesystem/directory_entry.cpp created+74
......@@ -0,0 +1,74 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <__config>
10#include <cstdint>
11#include <filesystem>
12#include <system_error>
13
14#include "file_descriptor.h"
15#include "posix_compat.h"
16#include "time_utils.h"
17
18_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
19
20error_code directory_entry::__do_refresh() noexcept {
21 __data_.__reset();
22 error_code failure_ec;
23
24 detail::StatT full_st;
25 file_status st = detail::posix_lstat(__p_, full_st, &failure_ec);
26 if (!status_known(st)) {
27 __data_.__reset();
28 return failure_ec;
29 }
30
31 if (!_VSTD_FS::exists(st) || !_VSTD_FS::is_symlink(st)) {
32 __data_.__cache_type_ = directory_entry::_RefreshNonSymlink;
33 __data_.__type_ = st.type();
34 __data_.__non_sym_perms_ = st.permissions();
35 } else { // we have a symlink
36 __data_.__sym_perms_ = st.permissions();
37 // Get the information about the linked entity.
38 // Ignore errors from stat, since we don't want errors regarding symlink
39 // resolution to be reported to the user.
40 error_code ignored_ec;
41 st = detail::posix_stat(__p_, full_st, &ignored_ec);
42
43 __data_.__type_ = st.type();
44 __data_.__non_sym_perms_ = st.permissions();
45
46 // If we failed to resolve the link, then only partially populate the
47 // cache.
48 if (!status_known(st)) {
49 __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved;
50 return error_code{};
51 }
52 // Otherwise, we resolved the link, potentially as not existing.
53 // That's OK.
54 __data_.__cache_type_ = directory_entry::_RefreshSymlink;
55 }
56
57 if (_VSTD_FS::is_regular_file(st))
58 __data_.__size_ = static_cast<uintmax_t>(full_st.st_size);
59
60 if (_VSTD_FS::exists(st)) {
61 __data_.__nlink_ = static_cast<uintmax_t>(full_st.st_nlink);
62
63 // Attempt to extract the mtime, and fail if it's not representable using
64 // file_time_type. For now we ignore the error, as we'll report it when
65 // the value is actually used.
66 error_code ignored_ec;
67 __data_.__write_time_ =
68 detail::__extract_last_write_time(__p_, full_st, &ignored_ec);
69 }
70
71 return failure_ec;
72}
73
74_LIBCPP_END_NAMESPACE_FILESYSTEM
lib/libcxx/src/filesystem/directory_iterator.cpp+14-4
......@@ -11,8 +11,18 @@
1111#include <errno.h>
1212#include <filesystem>
1313#include <stack>
14#include <utility>
1415
15#include "filesystem_common.h"
16#include "error.h"
17#include "file_descriptor.h"
18
19#if defined(_LIBCPP_WIN32API)
20# define WIN32_LEAN_AND_MEAN
21# define NOMINMAX
22# include <windows.h>
23#else
24# include <dirent.h> // for DIR & friends
25#endif
1626
1727_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
1828
......@@ -182,7 +192,7 @@ directory_iterator::directory_iterator(const path& p, error_code* ec,
182192}
183193
184194directory_iterator& directory_iterator::__increment(error_code* ec) {
185 _LIBCPP_ASSERT(__imp_, "Attempting to increment an invalid iterator");
195 _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "Attempting to increment an invalid iterator");
186196 ErrorHandler<void> err("directory_iterator::operator++()", ec);
187197
188198 error_code m_ec;
......@@ -196,7 +206,7 @@ directory_iterator& directory_iterator::__increment(error_code* ec) {
196206}
197207
198208directory_entry const& directory_iterator::__dereference() const {
199 _LIBCPP_ASSERT(__imp_, "Attempting to dereference an invalid iterator");
209 _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "Attempting to dereference an invalid iterator");
200210 return __imp_->__entry_;
201211}
202212
......@@ -225,7 +235,7 @@ recursive_directory_iterator::recursive_directory_iterator(
225235}
226236
227237void recursive_directory_iterator::__pop(error_code* ec) {
228 _LIBCPP_ASSERT(__imp_, "Popping the end iterator");
238 _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "Popping the end iterator");
229239 if (ec)
230240 ec->clear();
231241 __imp_->__stack_.pop();
lib/libcxx/src/filesystem/error.h created+238
......@@ -0,0 +1,238 @@
1//===----------------------------------------------------------------------===////
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===////
8
9#ifndef FILESYSTEM_ERROR_H
10#define FILESYSTEM_ERROR_H
11
12#include <__assert>
13#include <__config>
14#include <cerrno>
15#include <cstdarg>
16#include <cstddef>
17#include <cstdint>
18#include <filesystem>
19#include <string>
20#include <system_error>
21#include <utility> // __libcpp_unreachable
22
23#include "format_string.h"
24
25#if defined(_LIBCPP_WIN32API)
26# define WIN32_LEAN_AND_MEAN
27# define NOMINMAX
28# include <windows.h> // ERROR_* macros
29#endif
30
31_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
32
33namespace detail {
34
35#if defined(_LIBCPP_WIN32API)
36
37inline errc __win_err_to_errc(int err) {
38 constexpr struct {
39 DWORD win;
40 errc errc;
41 } win_error_mapping[] = {
42 {ERROR_ACCESS_DENIED, errc::permission_denied},
43 {ERROR_ALREADY_EXISTS, errc::file_exists},
44 {ERROR_BAD_NETPATH, errc::no_such_file_or_directory},
45 {ERROR_BAD_PATHNAME, errc::no_such_file_or_directory},
46 {ERROR_BAD_UNIT, errc::no_such_device},
47 {ERROR_BROKEN_PIPE, errc::broken_pipe},
48 {ERROR_BUFFER_OVERFLOW, errc::filename_too_long},
49 {ERROR_BUSY, errc::device_or_resource_busy},
50 {ERROR_BUSY_DRIVE, errc::device_or_resource_busy},
51 {ERROR_CANNOT_MAKE, errc::permission_denied},
52 {ERROR_CANTOPEN, errc::io_error},
53 {ERROR_CANTREAD, errc::io_error},
54 {ERROR_CANTWRITE, errc::io_error},
55 {ERROR_CURRENT_DIRECTORY, errc::permission_denied},
56 {ERROR_DEV_NOT_EXIST, errc::no_such_device},
57 {ERROR_DEVICE_IN_USE, errc::device_or_resource_busy},
58 {ERROR_DIR_NOT_EMPTY, errc::directory_not_empty},
59 {ERROR_DIRECTORY, errc::invalid_argument},
60 {ERROR_DISK_FULL, errc::no_space_on_device},
61 {ERROR_FILE_EXISTS, errc::file_exists},
62 {ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory},
63 {ERROR_HANDLE_DISK_FULL, errc::no_space_on_device},
64 {ERROR_INVALID_ACCESS, errc::permission_denied},
65 {ERROR_INVALID_DRIVE, errc::no_such_device},
66 {ERROR_INVALID_FUNCTION, errc::function_not_supported},
67 {ERROR_INVALID_HANDLE, errc::invalid_argument},
68 {ERROR_INVALID_NAME, errc::no_such_file_or_directory},
69 {ERROR_INVALID_PARAMETER, errc::invalid_argument},
70 {ERROR_LOCK_VIOLATION, errc::no_lock_available},
71 {ERROR_LOCKED, errc::no_lock_available},
72 {ERROR_NEGATIVE_SEEK, errc::invalid_argument},
73 {ERROR_NOACCESS, errc::permission_denied},
74 {ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory},
75 {ERROR_NOT_READY, errc::resource_unavailable_try_again},
76 {ERROR_NOT_SAME_DEVICE, errc::cross_device_link},
77 {ERROR_NOT_SUPPORTED, errc::not_supported},
78 {ERROR_OPEN_FAILED, errc::io_error},
79 {ERROR_OPEN_FILES, errc::device_or_resource_busy},
80 {ERROR_OPERATION_ABORTED, errc::operation_canceled},
81 {ERROR_OUTOFMEMORY, errc::not_enough_memory},
82 {ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory},
83 {ERROR_READ_FAULT, errc::io_error},
84 {ERROR_REPARSE_TAG_INVALID, errc::invalid_argument},
85 {ERROR_RETRY, errc::resource_unavailable_try_again},
86 {ERROR_SEEK, errc::io_error},
87 {ERROR_SHARING_VIOLATION, errc::permission_denied},
88 {ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open},
89 {ERROR_WRITE_FAULT, errc::io_error},
90 {ERROR_WRITE_PROTECT, errc::permission_denied},
91 };
92
93 for (const auto &pair : win_error_mapping)
94 if (pair.win == static_cast<DWORD>(err))
95 return pair.errc;
96 return errc::invalid_argument;
97}
98
99#endif // _LIBCPP_WIN32API
100
101inline error_code capture_errno() {
102 _LIBCPP_ASSERT_UNCATEGORIZED(errno != 0, "Expected errno to be non-zero");
103 return error_code(errno, generic_category());
104}
105
106#if defined(_LIBCPP_WIN32API)
107inline error_code make_windows_error(int err) {
108 return make_error_code(__win_err_to_errc(err));
109}
110#endif
111
112template <class T>
113T error_value();
114template <>
115inline _LIBCPP_CONSTEXPR_SINCE_CXX14 void error_value<void>() {}
116template <>
117inline bool error_value<bool>() {
118 return false;
119}
120#if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__
121template <>
122inline size_t error_value<size_t>() {
123 return size_t(-1);
124}
125#endif
126template <>
127inline uintmax_t error_value<uintmax_t>() {
128 return uintmax_t(-1);
129}
130template <>
131inline _LIBCPP_CONSTEXPR_SINCE_CXX14 file_time_type error_value<file_time_type>() {
132 return file_time_type::min();
133}
134template <>
135inline path error_value<path>() {
136 return {};
137}
138
139template <class T>
140struct ErrorHandler {
141 const char* func_name_;
142 error_code* ec_ = nullptr;
143 const path* p1_ = nullptr;
144 const path* p2_ = nullptr;
145
146 ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr,
147 const path* p2 = nullptr)
148 : func_name_(fname), ec_(ec), p1_(p1), p2_(p2) {
149 if (ec_)
150 ec_->clear();
151 }
152
153 T report(const error_code& ec) const {
154 if (ec_) {
155 *ec_ = ec;
156 return error_value<T>();
157 }
158 string what = string("in ") + func_name_;
159 switch (bool(p1_) + bool(p2_)) {
160 case 0:
161 __throw_filesystem_error(what, ec);
162 case 1:
163 __throw_filesystem_error(what, *p1_, ec);
164 case 2:
165 __throw_filesystem_error(what, *p1_, *p2_, ec);
166 }
167 __libcpp_unreachable();
168 }
169
170 _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0)
171 void report_impl(const error_code& ec, const char* msg, va_list ap) const {
172 if (ec_) {
173 *ec_ = ec;
174 return;
175 }
176 string what =
177 string("in ") + func_name_ + ": " + detail::vformat_string(msg, ap);
178 switch (bool(p1_) + bool(p2_)) {
179 case 0:
180 __throw_filesystem_error(what, ec);
181 case 1:
182 __throw_filesystem_error(what, *p1_, ec);
183 case 2:
184 __throw_filesystem_error(what, *p1_, *p2_, ec);
185 }
186 __libcpp_unreachable();
187 }
188
189 _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
190 T report(const error_code& ec, const char* msg, ...) const {
191 va_list ap;
192 va_start(ap, msg);
193#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
194 try {
195#endif // _LIBCPP_HAS_NO_EXCEPTIONS
196 report_impl(ec, msg, ap);
197#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
198 } catch (...) {
199 va_end(ap);
200 throw;
201 }
202#endif // _LIBCPP_HAS_NO_EXCEPTIONS
203 va_end(ap);
204 return error_value<T>();
205 }
206
207 T report(errc const& err) const {
208 return report(make_error_code(err));
209 }
210
211 _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
212 T report(errc const& err, const char* msg, ...) const {
213 va_list ap;
214 va_start(ap, msg);
215#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
216 try {
217#endif // _LIBCPP_HAS_NO_EXCEPTIONS
218 report_impl(make_error_code(err), msg, ap);
219#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
220 } catch (...) {
221 va_end(ap);
222 throw;
223 }
224#endif // _LIBCPP_HAS_NO_EXCEPTIONS
225 va_end(ap);
226 return error_value<T>();
227 }
228
229private:
230 ErrorHandler(ErrorHandler const&) = delete;
231 ErrorHandler& operator=(ErrorHandler const&) = delete;
232};
233
234} // end namespace detail
235
236_LIBCPP_END_NAMESPACE_FILESYSTEM
237
238#endif // FILESYSTEM_ERROR_H
lib/libcxx/src/filesystem/file_descriptor.h created+298
......@@ -0,0 +1,298 @@
1//===----------------------------------------------------------------------===////
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===////
8
9#ifndef FILESYSTEM_FILE_DESCRIPTOR_H
10#define FILESYSTEM_FILE_DESCRIPTOR_H
11
12#include <__config>
13#include <cstdint>
14#include <filesystem>
15#include <string_view>
16#include <system_error>
17#include <utility>
18
19#include "error.h"
20#include "posix_compat.h"
21#include "time_utils.h"
22
23#if defined(_LIBCPP_WIN32API)
24# define WIN32_LEAN_AND_MEAN
25# define NOMINMAX
26# include <windows.h>
27#else
28# include <dirent.h> // for DIR & friends
29# include <fcntl.h> // values for fchmodat
30# include <sys/stat.h>
31# include <sys/statvfs.h>
32# include <unistd.h>
33#endif // defined(_LIBCPP_WIN32API)
34
35_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
36
37namespace detail {
38
39#if !defined(_LIBCPP_WIN32API)
40
41#if defined(DT_BLK)
42template <class DirEntT, class = decltype(DirEntT::d_type)>
43file_type get_file_type(DirEntT* ent, int) {
44 switch (ent->d_type) {
45 case DT_BLK:
46 return file_type::block;
47 case DT_CHR:
48 return file_type::character;
49 case DT_DIR:
50 return file_type::directory;
51 case DT_FIFO:
52 return file_type::fifo;
53 case DT_LNK:
54 return file_type::symlink;
55 case DT_REG:
56 return file_type::regular;
57 case DT_SOCK:
58 return file_type::socket;
59 // Unlike in lstat, hitting "unknown" here simply means that the underlying
60 // filesystem doesn't support d_type. Report is as 'none' so we correctly
61 // set the cache to empty.
62 case DT_UNKNOWN:
63 break;
64 }
65 return file_type::none;
66}
67#endif // defined(DT_BLK)
68
69template <class DirEntT>
70file_type get_file_type(DirEntT*, long) {
71 return file_type::none;
72}
73
74inline pair<string_view, file_type> posix_readdir(DIR* dir_stream,
75 error_code& ec) {
76 struct dirent* dir_entry_ptr = nullptr;
77 errno = 0; // zero errno in order to detect errors
78 ec.clear();
79 if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) {
80 if (errno)
81 ec = capture_errno();
82 return {};
83 } else {
84 return {dir_entry_ptr->d_name, get_file_type(dir_entry_ptr, 0)};
85 }
86}
87
88#else // _LIBCPP_WIN32API
89
90inline file_type get_file_type(const WIN32_FIND_DATAW& data) {
91 if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
92 data.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
93 return file_type::symlink;
94 if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
95 return file_type::directory;
96 return file_type::regular;
97}
98inline uintmax_t get_file_size(const WIN32_FIND_DATAW& data) {
99 return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow;
100}
101inline file_time_type get_write_time(const WIN32_FIND_DATAW& data) {
102 ULARGE_INTEGER tmp;
103 const FILETIME& time = data.ftLastWriteTime;
104 tmp.u.LowPart = time.dwLowDateTime;
105 tmp.u.HighPart = time.dwHighDateTime;
106 return file_time_type(file_time_type::duration(tmp.QuadPart));
107}
108
109#endif // !_LIBCPP_WIN32API
110
111// POSIX HELPERS
112
113using value_type = path::value_type;
114using string_type = path::string_type;
115
116struct FileDescriptor {
117 const path& name;
118 int fd = -1;
119 StatT m_stat;
120 file_status m_status;
121
122 template <class... Args>
123 static FileDescriptor create(const path* p, error_code& ec, Args... args) {
124 ec.clear();
125 int fd;
126#ifdef _LIBCPP_WIN32API
127 // TODO: most of the filesystem implementation uses native Win32 calls
128 // (mostly via posix_compat.h). However, here we use the C-runtime APIs to
129 // open a file, because we subsequently pass the C-runtime fd to
130 // `std::[io]fstream::__open(int fd)` in order to implement copy_file.
131 //
132 // Because we're calling the windows C-runtime, win32 error codes are
133 // translated into C error numbers by the C runtime, and returned in errno,
134 // rather than being accessible directly via GetLastError.
135 //
136 // Ideally copy_file should be calling the Win32 CopyFile2 function, which
137 // works on paths, not open files -- at which point this FileDescriptor type
138 // will no longer be needed on windows at all.
139 fd = ::_wopen(p->c_str(), args...);
140#else
141 fd = open(p->c_str(), args...);
142#endif
143
144 if (fd == -1) {
145 ec = capture_errno();
146 return FileDescriptor{p};
147 }
148 return FileDescriptor(p, fd);
149 }
150
151 template <class... Args>
152 static FileDescriptor create_with_status(const path* p, error_code& ec,
153 Args... args) {
154 FileDescriptor fd = create(p, ec, args...);
155 if (!ec)
156 fd.refresh_status(ec);
157
158 return fd;
159 }
160
161 file_status get_status() const { return m_status; }
162 StatT const& get_stat() const { return m_stat; }
163
164 bool status_known() const { return _VSTD_FS::status_known(m_status); }
165
166 file_status refresh_status(error_code& ec);
167
168 void close() noexcept {
169 if (fd != -1) {
170#ifdef _LIBCPP_WIN32API
171 ::_close(fd);
172#else
173 ::close(fd);
174#endif
175 // FIXME: shouldn't this return an error_code?
176 }
177 fd = -1;
178 }
179
180 FileDescriptor(FileDescriptor&& other)
181 : name(other.name), fd(other.fd), m_stat(other.m_stat),
182 m_status(other.m_status) {
183 other.fd = -1;
184 other.m_status = file_status{};
185 }
186
187 ~FileDescriptor() { close(); }
188
189 FileDescriptor(FileDescriptor const&) = delete;
190 FileDescriptor& operator=(FileDescriptor const&) = delete;
191
192private:
193 explicit FileDescriptor(const path* p, int descriptor = -1) : name(*p), fd(descriptor) {}
194};
195
196inline perms posix_get_perms(const StatT& st) noexcept {
197 return static_cast<perms>(st.st_mode) & perms::mask;
198}
199
200inline file_status create_file_status(error_code& m_ec, path const& p,
201 const StatT& path_stat, error_code* ec) {
202 if (ec)
203 *ec = m_ec;
204 if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) {
205 return file_status(file_type::not_found);
206 } else if (m_ec) {
207 ErrorHandler<void> err("posix_stat", ec, &p);
208 err.report(m_ec, "failed to determine attributes for the specified path");
209 return file_status(file_type::none);
210 }
211 // else
212
213 file_status fs_tmp;
214 auto const mode = path_stat.st_mode;
215 if (S_ISLNK(mode))
216 fs_tmp.type(file_type::symlink);
217 else if (S_ISREG(mode))
218 fs_tmp.type(file_type::regular);
219 else if (S_ISDIR(mode))
220 fs_tmp.type(file_type::directory);
221 else if (S_ISBLK(mode))
222 fs_tmp.type(file_type::block);
223 else if (S_ISCHR(mode))
224 fs_tmp.type(file_type::character);
225 else if (S_ISFIFO(mode))
226 fs_tmp.type(file_type::fifo);
227 else if (S_ISSOCK(mode))
228 fs_tmp.type(file_type::socket);
229 else
230 fs_tmp.type(file_type::unknown);
231
232 fs_tmp.permissions(detail::posix_get_perms(path_stat));
233 return fs_tmp;
234}
235
236inline file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) {
237 error_code m_ec;
238 if (detail::stat(p.c_str(), &path_stat) == -1)
239 m_ec = detail::capture_errno();
240 return create_file_status(m_ec, p, path_stat, ec);
241}
242
243inline file_status posix_stat(path const& p, error_code* ec) {
244 StatT path_stat;
245 return posix_stat(p, path_stat, ec);
246}
247
248inline file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) {
249 error_code m_ec;
250 if (detail::lstat(p.c_str(), &path_stat) == -1)
251 m_ec = detail::capture_errno();
252 return create_file_status(m_ec, p, path_stat, ec);
253}
254
255inline file_status posix_lstat(path const& p, error_code* ec) {
256 StatT path_stat;
257 return posix_lstat(p, path_stat, ec);
258}
259
260// http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
261inline bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) {
262 if (detail::ftruncate(fd.fd, to_size) == -1) {
263 ec = capture_errno();
264 return true;
265 }
266 ec.clear();
267 return false;
268}
269
270inline bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) {
271 if (detail::fchmod(fd.fd, st.st_mode) == -1) {
272 ec = capture_errno();
273 return true;
274 }
275 ec.clear();
276 return false;
277}
278
279inline bool stat_equivalent(const StatT& st1, const StatT& st2) {
280 return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
281}
282
283inline file_status FileDescriptor::refresh_status(error_code& ec) {
284 // FD must be open and good.
285 m_status = file_status{};
286 m_stat = {};
287 error_code m_ec;
288 if (detail::fstat(fd, &m_stat) == -1)
289 m_ec = capture_errno();
290 m_status = create_file_status(m_ec, name, m_stat, &ec);
291 return m_status;
292}
293
294} // end namespace detail
295
296_LIBCPP_END_NAMESPACE_FILESYSTEM
297
298#endif // FILESYSTEM_FILE_DESCRIPTOR_H
lib/libcxx/src/filesystem/filesystem_clock.cpp created+64
......@@ -0,0 +1,64 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <__config>
10#include <chrono>
11#include <filesystem>
12#include <time.h>
13
14#if defined(_LIBCPP_WIN32API)
15# include "time_utils.h"
16#endif
17
18#if defined(_LIBCPP_WIN32API)
19# define WIN32_LEAN_AND_MEAN
20# define NOMINMAX
21# include <windows.h>
22#endif
23
24#if __has_include(<unistd.h>)
25# include <unistd.h> // _POSIX_TIMERS
26#endif
27
28#if __has_include(<sys/time.h>)
29# include <sys/time.h> // for gettimeofday and timeval
30#endif
31
32#if defined(__APPLE__) || defined (__gnu_hurd__) || (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0)
33# define _LIBCPP_HAS_CLOCK_GETTIME
34#endif
35
36_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
37
38const bool _FilesystemClock::is_steady;
39
40_FilesystemClock::time_point _FilesystemClock::now() noexcept {
41 typedef chrono::duration<rep> __secs;
42#if defined(_LIBCPP_WIN32API)
43 typedef chrono::duration<rep, nano> __nsecs;
44 FILETIME time;
45 GetSystemTimeAsFileTime(&time);
46 detail::TimeSpec tp = detail::filetime_to_timespec(time);
47 return time_point(__secs(tp.tv_sec) +
48 chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
49#elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
50 typedef chrono::duration<rep, nano> __nsecs;
51 struct timespec tp;
52 if (0 != clock_gettime(CLOCK_REALTIME, &tp))
53 __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
54 return time_point(__secs(tp.tv_sec) +
55 chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
56#else
57 typedef chrono::duration<rep, micro> __microsecs;
58 timeval tv;
59 gettimeofday(&tv, 0);
60 return time_point(__secs(tv.tv_sec) + __microsecs(tv.tv_usec));
61#endif
62}
63
64_LIBCPP_END_NAMESPACE_FILESYSTEM
lib/libcxx/src/filesystem/filesystem_common.h deleted-613
......@@ -1,613 +0,0 @@
1//===----------------------------------------------------------------------===////
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===////
8
9#ifndef FILESYSTEM_COMMON_H
10#define FILESYSTEM_COMMON_H
11
12#include <__assert>
13#include <__config>
14#include <array>
15#include <chrono>
16#include <climits>
17#include <cstdarg>
18#include <ctime>
19#include <filesystem>
20#include <ratio>
21#include <system_error>
22#include <utility>
23
24#if defined(_LIBCPP_WIN32API)
25# define WIN32_LEAN_AND_MEAN
26# define NOMINMAX
27# include <windows.h>
28#else
29# include <dirent.h> // for DIR & friends
30# include <fcntl.h> /* values for fchmodat */
31# include <sys/stat.h>
32# include <sys/statvfs.h>
33# include <sys/time.h> // for ::utimes as used in __last_write_time
34# include <unistd.h>
35#endif // defined(_LIBCPP_WIN32API)
36
37#include "../include/apple_availability.h"
38
39#if !defined(__APPLE__)
40// We can use the presence of UTIME_OMIT to detect platforms that provide
41// utimensat.
42#if defined(UTIME_OMIT)
43#define _LIBCPP_USE_UTIMENSAT
44#endif
45#endif
46
47_LIBCPP_DIAGNOSTIC_PUSH
48_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wunused-function")
49_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-function")
50
51#if defined(_LIBCPP_WIN32API)
52# define PATHSTR(x) (L##x)
53# define PATH_CSTR_FMT "\"%ls\""
54#else
55# define PATHSTR(x) (x)
56# define PATH_CSTR_FMT "\"%s\""
57#endif
58
59_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
60
61namespace detail {
62
63#if defined(_LIBCPP_WIN32API)
64// Non anonymous, to allow access from two translation units.
65errc __win_err_to_errc(int err);
66#endif
67
68namespace {
69
70static _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string
71format_string_impl(const char* msg, va_list ap) {
72 array<char, 256> buf;
73
74 va_list apcopy;
75 va_copy(apcopy, ap);
76 int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);
77 va_end(apcopy);
78
79 string result;
80 if (static_cast<size_t>(ret) < buf.size()) {
81 result.assign(buf.data(), static_cast<size_t>(ret));
82 } else {
83 // we did not provide a long enough buffer on our first attempt. The
84 // return value is the number of bytes (excluding the null byte) that are
85 // needed for formatting.
86 size_t size_with_null = static_cast<size_t>(ret) + 1;
87 result.__resize_default_init(size_with_null - 1);
88 ret = ::vsnprintf(&result[0], size_with_null, msg, ap);
89 _LIBCPP_ASSERT(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
90 }
91 return result;
92}
93
94static _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string
95format_string(const char* msg, ...) {
96 string ret;
97 va_list ap;
98 va_start(ap, msg);
99#ifndef _LIBCPP_NO_EXCEPTIONS
100 try {
101#endif // _LIBCPP_NO_EXCEPTIONS
102 ret = format_string_impl(msg, ap);
103#ifndef _LIBCPP_NO_EXCEPTIONS
104 } catch (...) {
105 va_end(ap);
106 throw;
107 }
108#endif // _LIBCPP_NO_EXCEPTIONS
109 va_end(ap);
110 return ret;
111}
112
113error_code capture_errno() {
114 _LIBCPP_ASSERT(errno != 0, "Expected errno to be non-zero");
115 return error_code(errno, generic_category());
116}
117
118#if defined(_LIBCPP_WIN32API)
119error_code make_windows_error(int err) {
120 return make_error_code(__win_err_to_errc(err));
121}
122#endif
123
124template <class T>
125T error_value();
126template <>
127_LIBCPP_CONSTEXPR_SINCE_CXX14 void error_value<void>() {}
128template <>
129bool error_value<bool>() {
130 return false;
131}
132#if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__
133template <>
134size_t error_value<size_t>() {
135 return size_t(-1);
136}
137#endif
138template <>
139uintmax_t error_value<uintmax_t>() {
140 return uintmax_t(-1);
141}
142template <>
143_LIBCPP_CONSTEXPR_SINCE_CXX14 file_time_type error_value<file_time_type>() {
144 return file_time_type::min();
145}
146template <>
147path error_value<path>() {
148 return {};
149}
150
151template <class T>
152struct ErrorHandler {
153 const char* func_name_;
154 error_code* ec_ = nullptr;
155 const path* p1_ = nullptr;
156 const path* p2_ = nullptr;
157
158 ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr,
159 const path* p2 = nullptr)
160 : func_name_(fname), ec_(ec), p1_(p1), p2_(p2) {
161 if (ec_)
162 ec_->clear();
163 }
164
165 T report(const error_code& ec) const {
166 if (ec_) {
167 *ec_ = ec;
168 return error_value<T>();
169 }
170 string what = string("in ") + func_name_;
171 switch (bool(p1_) + bool(p2_)) {
172 case 0:
173 __throw_filesystem_error(what, ec);
174 case 1:
175 __throw_filesystem_error(what, *p1_, ec);
176 case 2:
177 __throw_filesystem_error(what, *p1_, *p2_, ec);
178 }
179 __libcpp_unreachable();
180 }
181
182 _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0)
183 void report_impl(const error_code& ec, const char* msg, va_list ap) const {
184 if (ec_) {
185 *ec_ = ec;
186 return;
187 }
188 string what =
189 string("in ") + func_name_ + ": " + format_string_impl(msg, ap);
190 switch (bool(p1_) + bool(p2_)) {
191 case 0:
192 __throw_filesystem_error(what, ec);
193 case 1:
194 __throw_filesystem_error(what, *p1_, ec);
195 case 2:
196 __throw_filesystem_error(what, *p1_, *p2_, ec);
197 }
198 __libcpp_unreachable();
199 }
200
201 _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
202 T report(const error_code& ec, const char* msg, ...) const {
203 va_list ap;
204 va_start(ap, msg);
205#ifndef _LIBCPP_NO_EXCEPTIONS
206 try {
207#endif // _LIBCPP_NO_EXCEPTIONS
208 report_impl(ec, msg, ap);
209#ifndef _LIBCPP_NO_EXCEPTIONS
210 } catch (...) {
211 va_end(ap);
212 throw;
213 }
214#endif // _LIBCPP_NO_EXCEPTIONS
215 va_end(ap);
216 return error_value<T>();
217 }
218
219 T report(errc const& err) const {
220 return report(make_error_code(err));
221 }
222
223 _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
224 T report(errc const& err, const char* msg, ...) const {
225 va_list ap;
226 va_start(ap, msg);
227#ifndef _LIBCPP_NO_EXCEPTIONS
228 try {
229#endif // _LIBCPP_NO_EXCEPTIONS
230 report_impl(make_error_code(err), msg, ap);
231#ifndef _LIBCPP_NO_EXCEPTIONS
232 } catch (...) {
233 va_end(ap);
234 throw;
235 }
236#endif // _LIBCPP_NO_EXCEPTIONS
237 va_end(ap);
238 return error_value<T>();
239 }
240
241private:
242 ErrorHandler(ErrorHandler const&) = delete;
243 ErrorHandler& operator=(ErrorHandler const&) = delete;
244};
245
246using chrono::duration;
247using chrono::duration_cast;
248
249#if defined(_LIBCPP_WIN32API)
250// Various C runtime versions (UCRT, or the legacy msvcrt.dll used by
251// some mingw toolchains) provide different stat function implementations,
252// with a number of limitations with respect to what we want from the
253// stat function. Instead provide our own (in the anonymous detail namespace
254// in posix_compat.h) which does exactly what we want, along with our own
255// stat structure and flag macros.
256
257struct TimeSpec {
258 int64_t tv_sec;
259 int64_t tv_nsec;
260};
261struct StatT {
262 unsigned st_mode;
263 TimeSpec st_atim;
264 TimeSpec st_mtim;
265 uint64_t st_dev; // FILE_ID_INFO::VolumeSerialNumber
266 struct FileIdStruct {
267 unsigned char id[16]; // FILE_ID_INFO::FileId
268 bool operator==(const FileIdStruct &other) const {
269 for (int i = 0; i < 16; i++)
270 if (id[i] != other.id[i])
271 return false;
272 return true;
273 }
274 } st_ino;
275 uint32_t st_nlink;
276 uintmax_t st_size;
277};
278
279#else
280using TimeSpec = struct timespec;
281using TimeVal = struct timeval;
282using StatT = struct stat;
283#endif
284
285template <class FileTimeT, class TimeT,
286 bool IsFloat = is_floating_point<typename FileTimeT::rep>::value>
287struct time_util_base {
288 using rep = typename FileTimeT::rep;
289 using fs_duration = typename FileTimeT::duration;
290 using fs_seconds = duration<rep>;
291 using fs_nanoseconds = duration<rep, nano>;
292 using fs_microseconds = duration<rep, micro>;
293
294 static constexpr rep max_seconds =
295 duration_cast<fs_seconds>(FileTimeT::duration::max()).count();
296
297 static constexpr rep max_nsec =
298 duration_cast<fs_nanoseconds>(FileTimeT::duration::max() -
299 fs_seconds(max_seconds))
300 .count();
301
302 static constexpr rep min_seconds =
303 duration_cast<fs_seconds>(FileTimeT::duration::min()).count();
304
305 static constexpr rep min_nsec_timespec =
306 duration_cast<fs_nanoseconds>(
307 (FileTimeT::duration::min() - fs_seconds(min_seconds)) +
308 fs_seconds(1))
309 .count();
310
311private:
312 static _LIBCPP_CONSTEXPR_SINCE_CXX14 fs_duration get_min_nsecs() {
313 return duration_cast<fs_duration>(
314 fs_nanoseconds(min_nsec_timespec) -
315 duration_cast<fs_nanoseconds>(fs_seconds(1)));
316 }
317 // Static assert that these values properly round trip.
318 static_assert(fs_seconds(min_seconds) + get_min_nsecs() ==
319 FileTimeT::duration::min(),
320 "value doesn't roundtrip");
321
322 static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool check_range() {
323 // This kinda sucks, but it's what happens when we don't have __int128_t.
324 if (sizeof(TimeT) == sizeof(rep)) {
325 typedef duration<long long, ratio<3600 * 24 * 365> > Years;
326 return duration_cast<Years>(fs_seconds(max_seconds)) > Years(250) &&
327 duration_cast<Years>(fs_seconds(min_seconds)) < Years(-250);
328 }
329 return max_seconds >= numeric_limits<TimeT>::max() &&
330 min_seconds <= numeric_limits<TimeT>::min();
331 }
332 static_assert(check_range(), "the representable range is unacceptable small");
333};
334
335template <class FileTimeT, class TimeT>
336struct time_util_base<FileTimeT, TimeT, true> {
337 using rep = typename FileTimeT::rep;
338 using fs_duration = typename FileTimeT::duration;
339 using fs_seconds = duration<rep>;
340 using fs_nanoseconds = duration<rep, nano>;
341 using fs_microseconds = duration<rep, micro>;
342
343 static const rep max_seconds;
344 static const rep max_nsec;
345 static const rep min_seconds;
346 static const rep min_nsec_timespec;
347};
348
349template <class FileTimeT, class TimeT>
350const typename FileTimeT::rep
351 time_util_base<FileTimeT, TimeT, true>::max_seconds =
352 duration_cast<fs_seconds>(FileTimeT::duration::max()).count();
353
354template <class FileTimeT, class TimeT>
355const typename FileTimeT::rep time_util_base<FileTimeT, TimeT, true>::max_nsec =
356 duration_cast<fs_nanoseconds>(FileTimeT::duration::max() -
357 fs_seconds(max_seconds))
358 .count();
359
360template <class FileTimeT, class TimeT>
361const typename FileTimeT::rep
362 time_util_base<FileTimeT, TimeT, true>::min_seconds =
363 duration_cast<fs_seconds>(FileTimeT::duration::min()).count();
364
365template <class FileTimeT, class TimeT>
366const typename FileTimeT::rep
367 time_util_base<FileTimeT, TimeT, true>::min_nsec_timespec =
368 duration_cast<fs_nanoseconds>((FileTimeT::duration::min() -
369 fs_seconds(min_seconds)) +
370 fs_seconds(1))
371 .count();
372
373template <class FileTimeT, class TimeT, class TimeSpecT>
374struct time_util : time_util_base<FileTimeT, TimeT> {
375 using Base = time_util_base<FileTimeT, TimeT>;
376 using Base::max_nsec;
377 using Base::max_seconds;
378 using Base::min_nsec_timespec;
379 using Base::min_seconds;
380
381 using typename Base::fs_duration;
382 using typename Base::fs_microseconds;
383 using typename Base::fs_nanoseconds;
384 using typename Base::fs_seconds;
385
386public:
387 template <class CType, class ChronoType>
388 static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool checked_set(CType* out,
389 ChronoType time) {
390 using Lim = numeric_limits<CType>;
391 if (time > Lim::max() || time < Lim::min())
392 return false;
393 *out = static_cast<CType>(time);
394 return true;
395 }
396
397 static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool is_representable(TimeSpecT tm) {
398 if (tm.tv_sec >= 0) {
399 return tm.tv_sec < max_seconds ||
400 (tm.tv_sec == max_seconds && tm.tv_nsec <= max_nsec);
401 } else if (tm.tv_sec == (min_seconds - 1)) {
402 return tm.tv_nsec >= min_nsec_timespec;
403 } else {
404 return tm.tv_sec >= min_seconds;
405 }
406 }
407
408 static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool is_representable(FileTimeT tm) {
409 auto secs = duration_cast<fs_seconds>(tm.time_since_epoch());
410 auto nsecs = duration_cast<fs_nanoseconds>(tm.time_since_epoch() - secs);
411 if (nsecs.count() < 0) {
412 secs = secs + fs_seconds(1);
413 nsecs = nsecs + fs_seconds(1);
414 }
415 using TLim = numeric_limits<TimeT>;
416 if (secs.count() >= 0)
417 return secs.count() <= TLim::max();
418 return secs.count() >= TLim::min();
419 }
420
421 static _LIBCPP_CONSTEXPR_SINCE_CXX14 FileTimeT
422 convert_from_timespec(TimeSpecT tm) {
423 if (tm.tv_sec >= 0 || tm.tv_nsec == 0) {
424 return FileTimeT(fs_seconds(tm.tv_sec) +
425 duration_cast<fs_duration>(fs_nanoseconds(tm.tv_nsec)));
426 } else { // tm.tv_sec < 0
427 auto adj_subsec = duration_cast<fs_duration>(fs_seconds(1) -
428 fs_nanoseconds(tm.tv_nsec));
429 auto Dur = fs_seconds(tm.tv_sec + 1) - adj_subsec;
430 return FileTimeT(Dur);
431 }
432 }
433
434 template <class SubSecT>
435 static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
436 set_times_checked(TimeT* sec_out, SubSecT* subsec_out, FileTimeT tp) {
437 auto dur = tp.time_since_epoch();
438 auto sec_dur = duration_cast<fs_seconds>(dur);
439 auto subsec_dur = duration_cast<fs_nanoseconds>(dur - sec_dur);
440 // The tv_nsec and tv_usec fields must not be negative so adjust accordingly
441 if (subsec_dur.count() < 0) {
442 if (sec_dur.count() > min_seconds) {
443 sec_dur = sec_dur - fs_seconds(1);
444 subsec_dur = subsec_dur + fs_seconds(1);
445 } else {
446 subsec_dur = fs_nanoseconds::zero();
447 }
448 }
449 return checked_set(sec_out, sec_dur.count()) &&
450 checked_set(subsec_out, subsec_dur.count());
451 }
452 static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool convert_to_timespec(TimeSpecT& dest,
453 FileTimeT tp) {
454 if (!is_representable(tp))
455 return false;
456 return set_times_checked(&dest.tv_sec, &dest.tv_nsec, tp);
457 }
458};
459
460#if defined(_LIBCPP_WIN32API)
461using fs_time = time_util<file_time_type, int64_t, TimeSpec>;
462#else
463using fs_time = time_util<file_time_type, time_t, TimeSpec>;
464#endif
465
466#if defined(__APPLE__)
467inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
468inline TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; }
469#elif defined(__MVS__)
470inline TimeSpec extract_mtime(StatT const& st) {
471 TimeSpec TS = {st.st_mtime, 0};
472 return TS;
473}
474inline TimeSpec extract_atime(StatT const& st) {
475 TimeSpec TS = {st.st_atime, 0};
476 return TS;
477}
478#elif defined(_AIX)
479inline TimeSpec extract_mtime(StatT const& st) {
480 TimeSpec TS = {st.st_mtime, st.st_mtime_n};
481 return TS;
482}
483inline TimeSpec extract_atime(StatT const& st) {
484 TimeSpec TS = {st.st_atime, st.st_atime_n};
485 return TS;
486}
487#else
488inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
489inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
490#endif
491
492#if !defined(_LIBCPP_WIN32API)
493inline TimeVal make_timeval(TimeSpec const& ts) {
494 using namespace chrono;
495 auto Convert = [](long nsec) {
496 using int_type = decltype(std::declval<TimeVal>().tv_usec);
497 auto dur = duration_cast<microseconds>(nanoseconds(nsec)).count();
498 return static_cast<int_type>(dur);
499 };
500 TimeVal TV = {};
501 TV.tv_sec = ts.tv_sec;
502 TV.tv_usec = Convert(ts.tv_nsec);
503 return TV;
504}
505
506inline bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
507 error_code& ec) {
508 TimeVal ConvertedTS[2] = {make_timeval(TS[0]), make_timeval(TS[1])};
509 if (::utimes(p.c_str(), ConvertedTS) == -1) {
510 ec = capture_errno();
511 return true;
512 }
513 return false;
514}
515
516#if defined(_LIBCPP_USE_UTIMENSAT)
517bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS,
518 error_code& ec) {
519 if (::utimensat(AT_FDCWD, p.c_str(), TS.data(), 0) == -1) {
520 ec = capture_errno();
521 return true;
522 }
523 return false;
524}
525#endif
526
527bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
528 error_code& ec) {
529#if !defined(_LIBCPP_USE_UTIMENSAT)
530 return posix_utimes(p, TS, ec);
531#else
532 return posix_utimensat(p, TS, ec);
533#endif
534}
535
536#if defined(DT_BLK)
537template <class DirEntT, class = decltype(DirEntT::d_type)>
538static file_type get_file_type(DirEntT* ent, int) {
539 switch (ent->d_type) {
540 case DT_BLK:
541 return file_type::block;
542 case DT_CHR:
543 return file_type::character;
544 case DT_DIR:
545 return file_type::directory;
546 case DT_FIFO:
547 return file_type::fifo;
548 case DT_LNK:
549 return file_type::symlink;
550 case DT_REG:
551 return file_type::regular;
552 case DT_SOCK:
553 return file_type::socket;
554 // Unlike in lstat, hitting "unknown" here simply means that the underlying
555 // filesystem doesn't support d_type. Report is as 'none' so we correctly
556 // set the cache to empty.
557 case DT_UNKNOWN:
558 break;
559 }
560 return file_type::none;
561}
562#endif // defined(DT_BLK)
563
564template <class DirEntT>
565static file_type get_file_type(DirEntT*, long) {
566 return file_type::none;
567}
568
569static pair<string_view, file_type> posix_readdir(DIR* dir_stream,
570 error_code& ec) {
571 struct dirent* dir_entry_ptr = nullptr;
572 errno = 0; // zero errno in order to detect errors
573 ec.clear();
574 if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) {
575 if (errno)
576 ec = capture_errno();
577 return {};
578 } else {
579 return {dir_entry_ptr->d_name, get_file_type(dir_entry_ptr, 0)};
580 }
581}
582
583#else // _LIBCPP_WIN32API
584
585static file_type get_file_type(const WIN32_FIND_DATAW& data) {
586 if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
587 data.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
588 return file_type::symlink;
589 if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
590 return file_type::directory;
591 return file_type::regular;
592}
593static uintmax_t get_file_size(const WIN32_FIND_DATAW& data) {
594 return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow;
595}
596static file_time_type get_write_time(const WIN32_FIND_DATAW& data) {
597 ULARGE_INTEGER tmp;
598 const FILETIME& time = data.ftLastWriteTime;
599 tmp.u.LowPart = time.dwLowDateTime;
600 tmp.u.HighPart = time.dwHighDateTime;
601 return file_time_type(file_time_type::duration(tmp.QuadPart));
602}
603
604#endif // !_LIBCPP_WIN32API
605
606} // namespace
607} // end namespace detail
608
609_LIBCPP_END_NAMESPACE_FILESYSTEM
610
611_LIBCPP_DIAGNOSTIC_POP
612
613#endif // FILESYSTEM_COMMON_H
lib/libcxx/src/filesystem/filesystem_error.cpp created+37
......@@ -0,0 +1,37 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <__config>
10#include <__utility/unreachable.h>
11#include <filesystem>
12#include <system_error>
13
14#include "format_string.h"
15
16_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
17
18filesystem_error::~filesystem_error() {}
19
20void filesystem_error::__create_what(int __num_paths) {
21 const char* derived_what = system_error::what();
22 __storage_->__what_ = [&]() -> string {
23 switch (__num_paths) {
24 case 0:
25 return detail::format_string("filesystem error: %s", derived_what);
26 case 1:
27 return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "]",
28 derived_what, path1().c_str());
29 case 2:
30 return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "] [" PATH_CSTR_FMT "]",
31 derived_what, path1().c_str(), path2().c_str());
32 }
33 __libcpp_unreachable();
34 }();
35}
36
37_LIBCPP_END_NAMESPACE_FILESYSTEM
lib/libcxx/src/filesystem/format_string.h created+77
......@@ -0,0 +1,77 @@
1//===----------------------------------------------------------------------===////
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===////
8
9#ifndef FILESYSTEM_FORMAT_STRING_H
10#define FILESYSTEM_FORMAT_STRING_H
11
12#include <__assert>
13#include <__config>
14#include <array>
15#include <cstdarg>
16#include <cstddef>
17#include <cstdio>
18#include <string>
19
20#if defined(_LIBCPP_WIN32API)
21# define PATHSTR(x) (L##x)
22# define PATH_CSTR_FMT "\"%ls\""
23#else
24# define PATHSTR(x) (x)
25# define PATH_CSTR_FMT "\"%s\""
26#endif
27
28_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
29
30namespace detail {
31
32inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string vformat_string(const char* msg, va_list ap) {
33 array<char, 256> buf;
34
35 va_list apcopy;
36 va_copy(apcopy, ap);
37 int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);
38 va_end(apcopy);
39
40 string result;
41 if (static_cast<size_t>(ret) < buf.size()) {
42 result.assign(buf.data(), static_cast<size_t>(ret));
43 } else {
44 // we did not provide a long enough buffer on our first attempt. The
45 // return value is the number of bytes (excluding the null byte) that are
46 // needed for formatting.
47 size_t size_with_null = static_cast<size_t>(ret) + 1;
48 result.__resize_default_init(size_with_null - 1);
49 ret = ::vsnprintf(&result[0], size_with_null, msg, ap);
50 _LIBCPP_ASSERT_UNCATEGORIZED(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
51 }
52 return result;
53}
54
55inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string format_string(const char* msg, ...) {
56 string ret;
57 va_list ap;
58 va_start(ap, msg);
59#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
60 try {
61#endif // _LIBCPP_HAS_NO_EXCEPTIONS
62 ret = detail::vformat_string(msg, ap);
63#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
64 } catch (...) {
65 va_end(ap);
66 throw;
67 }
68#endif // _LIBCPP_HAS_NO_EXCEPTIONS
69 va_end(ap);
70 return ret;
71}
72
73} // end namespace detail
74
75_LIBCPP_END_NAMESPACE_FILESYSTEM
76
77#endif // FILESYSTEM_FORMAT_STRING_H
lib/libcxx/src/filesystem/int128_builtins.cpp+1-1
......@@ -18,7 +18,7 @@
1818
1919#if !defined(_LIBCPP_HAS_NO_INT128)
2020
21extern "C" __attribute__((no_sanitize("undefined"))) _LIBCPP_FUNC_VIS
21extern "C" __attribute__((no_sanitize("undefined"))) _LIBCPP_EXPORTED_FROM_ABI
2222__int128_t __muloti4(__int128_t a, __int128_t b, int* overflow) {
2323 const int N = (int)(sizeof(__int128_t) * CHAR_BIT);
2424 const __int128_t MIN = (__int128_t)1 << (N - 1);
lib/libcxx/src/filesystem/operations.cpp+17-1145
......@@ -7,6 +7,7 @@
77//===----------------------------------------------------------------------===//
88
99#include <__assert>
10#include <__config>
1011#include <__utility/unreachable.h>
1112#include <array>
1213#include <climits>
......@@ -17,9 +18,11 @@
1718#include <type_traits>
1819#include <vector>
1920
20#include "filesystem_common.h"
21
21#include "error.h"
22#include "file_descriptor.h"
23#include "path_parser.h"
2224#include "posix_compat.h"
25#include "time_utils.h"
2326
2427#if defined(_LIBCPP_WIN32API)
2528# define WIN32_LEAN_AND_MEAN
......@@ -45,595 +48,12 @@
4548# define _LIBCPP_FILESYSTEM_USE_FSTREAM
4649#endif
4750
48#if !defined(CLOCK_REALTIME) && !defined(_LIBCPP_WIN32API)
49# include <sys/time.h> // for gettimeofday and timeval
50#endif
51
5251#if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB)
5352# pragma comment(lib, "rt")
5453#endif
5554
5655_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
5756
58namespace {
59
60bool isSeparator(path::value_type C) {
61 if (C == '/')
62 return true;
63#if defined(_LIBCPP_WIN32API)
64 if (C == '\\')
65 return true;
66#endif
67 return false;
68}
69
70bool isDriveLetter(path::value_type C) {
71 return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z');
72}
73
74namespace parser {
75
76using string_view_t = path::__string_view;
77using string_view_pair = pair<string_view_t, string_view_t>;
78using PosPtr = path::value_type const*;
79
80struct PathParser {
81 enum ParserState : unsigned char {
82 // Zero is a special sentinel value used by default constructed iterators.
83 PS_BeforeBegin = path::iterator::_BeforeBegin,
84 PS_InRootName = path::iterator::_InRootName,
85 PS_InRootDir = path::iterator::_InRootDir,
86 PS_InFilenames = path::iterator::_InFilenames,
87 PS_InTrailingSep = path::iterator::_InTrailingSep,
88 PS_AtEnd = path::iterator::_AtEnd
89 };
90
91 const string_view_t Path;
92 string_view_t RawEntry;
93 ParserState State;
94
95private:
96 PathParser(string_view_t P, ParserState State) noexcept : Path(P),
97 State(State) {}
98
99public:
100 PathParser(string_view_t P, string_view_t E, unsigned char S)
101 : Path(P), RawEntry(E), State(static_cast<ParserState>(S)) {
102 // S cannot be '0' or PS_BeforeBegin.
103 }
104
105 static PathParser CreateBegin(string_view_t P) noexcept {
106 PathParser PP(P, PS_BeforeBegin);
107 PP.increment();
108 return PP;
109 }
110
111 static PathParser CreateEnd(string_view_t P) noexcept {
112 PathParser PP(P, PS_AtEnd);
113 return PP;
114 }
115
116 PosPtr peek() const noexcept {
117 auto TkEnd = getNextTokenStartPos();
118 auto End = getAfterBack();
119 return TkEnd == End ? nullptr : TkEnd;
120 }
121
122 void increment() noexcept {
123 const PosPtr End = getAfterBack();
124 const PosPtr Start = getNextTokenStartPos();
125 if (Start == End)
126 return makeState(PS_AtEnd);
127
128 switch (State) {
129 case PS_BeforeBegin: {
130 PosPtr TkEnd = consumeRootName(Start, End);
131 if (TkEnd)
132 return makeState(PS_InRootName, Start, TkEnd);
133 }
134 _LIBCPP_FALLTHROUGH();
135 case PS_InRootName: {
136 PosPtr TkEnd = consumeAllSeparators(Start, End);
137 if (TkEnd)
138 return makeState(PS_InRootDir, Start, TkEnd);
139 else
140 return makeState(PS_InFilenames, Start, consumeName(Start, End));
141 }
142 case PS_InRootDir:
143 return makeState(PS_InFilenames, Start, consumeName(Start, End));
144
145 case PS_InFilenames: {
146 PosPtr SepEnd = consumeAllSeparators(Start, End);
147 if (SepEnd != End) {
148 PosPtr TkEnd = consumeName(SepEnd, End);
149 if (TkEnd)
150 return makeState(PS_InFilenames, SepEnd, TkEnd);
151 }
152 return makeState(PS_InTrailingSep, Start, SepEnd);
153 }
154
155 case PS_InTrailingSep:
156 return makeState(PS_AtEnd);
157
158 case PS_AtEnd:
159 __libcpp_unreachable();
160 }
161 }
162
163 void decrement() noexcept {
164 const PosPtr REnd = getBeforeFront();
165 const PosPtr RStart = getCurrentTokenStartPos() - 1;
166 if (RStart == REnd) // we're decrementing the begin
167 return makeState(PS_BeforeBegin);
168
169 switch (State) {
170 case PS_AtEnd: {
171 // Try to consume a trailing separator or root directory first.
172 if (PosPtr SepEnd = consumeAllSeparators(RStart, REnd)) {
173 if (SepEnd == REnd)
174 return makeState(PS_InRootDir, Path.data(), RStart + 1);
175 PosPtr TkStart = consumeRootName(SepEnd, REnd);
176 if (TkStart == REnd)
177 return makeState(PS_InRootDir, RStart, RStart + 1);
178 return makeState(PS_InTrailingSep, SepEnd + 1, RStart + 1);
179 } else {
180 PosPtr TkStart = consumeRootName(RStart, REnd);
181 if (TkStart == REnd)
182 return makeState(PS_InRootName, TkStart + 1, RStart + 1);
183 TkStart = consumeName(RStart, REnd);
184 return makeState(PS_InFilenames, TkStart + 1, RStart + 1);
185 }
186 }
187 case PS_InTrailingSep:
188 return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1,
189 RStart + 1);
190 case PS_InFilenames: {
191 PosPtr SepEnd = consumeAllSeparators(RStart, REnd);
192 if (SepEnd == REnd)
193 return makeState(PS_InRootDir, Path.data(), RStart + 1);
194 PosPtr TkStart = consumeRootName(SepEnd ? SepEnd : RStart, REnd);
195 if (TkStart == REnd) {
196 if (SepEnd)
197 return makeState(PS_InRootDir, SepEnd + 1, RStart + 1);
198 return makeState(PS_InRootName, TkStart + 1, RStart + 1);
199 }
200 TkStart = consumeName(SepEnd, REnd);
201 return makeState(PS_InFilenames, TkStart + 1, SepEnd + 1);
202 }
203 case PS_InRootDir:
204 return makeState(PS_InRootName, Path.data(), RStart + 1);
205 case PS_InRootName:
206 case PS_BeforeBegin:
207 __libcpp_unreachable();
208 }
209 }
210
211 /// \brief Return a view with the "preferred representation" of the current
212 /// element. For example trailing separators are represented as a '.'
213 string_view_t operator*() const noexcept {
214 switch (State) {
215 case PS_BeforeBegin:
216 case PS_AtEnd:
217 return PATHSTR("");
218 case PS_InRootDir:
219 if (RawEntry[0] == '\\')
220 return PATHSTR("\\");
221 else
222 return PATHSTR("/");
223 case PS_InTrailingSep:
224 return PATHSTR("");
225 case PS_InRootName:
226 case PS_InFilenames:
227 return RawEntry;
228 }
229 __libcpp_unreachable();
230 }
231
232 explicit operator bool() const noexcept {
233 return State != PS_BeforeBegin && State != PS_AtEnd;
234 }
235
236 PathParser& operator++() noexcept {
237 increment();
238 return *this;
239 }
240
241 PathParser& operator--() noexcept {
242 decrement();
243 return *this;
244 }
245
246 bool atEnd() const noexcept {
247 return State == PS_AtEnd;
248 }
249
250 bool inRootDir() const noexcept {
251 return State == PS_InRootDir;
252 }
253
254 bool inRootName() const noexcept {
255 return State == PS_InRootName;
256 }
257
258 bool inRootPath() const noexcept {
259 return inRootName() || inRootDir();
260 }
261
262private:
263 void makeState(ParserState NewState, PosPtr Start, PosPtr End) noexcept {
264 State = NewState;
265 RawEntry = string_view_t(Start, End - Start);
266 }
267 void makeState(ParserState NewState) noexcept {
268 State = NewState;
269 RawEntry = {};
270 }
271
272 PosPtr getAfterBack() const noexcept { return Path.data() + Path.size(); }
273
274 PosPtr getBeforeFront() const noexcept { return Path.data() - 1; }
275
276 /// \brief Return a pointer to the first character after the currently
277 /// lexed element.
278 PosPtr getNextTokenStartPos() const noexcept {
279 switch (State) {
280 case PS_BeforeBegin:
281 return Path.data();
282 case PS_InRootName:
283 case PS_InRootDir:
284 case PS_InFilenames:
285 return &RawEntry.back() + 1;
286 case PS_InTrailingSep:
287 case PS_AtEnd:
288 return getAfterBack();
289 }
290 __libcpp_unreachable();
291 }
292
293 /// \brief Return a pointer to the first character in the currently lexed
294 /// element.
295 PosPtr getCurrentTokenStartPos() const noexcept {
296 switch (State) {
297 case PS_BeforeBegin:
298 case PS_InRootName:
299 return &Path.front();
300 case PS_InRootDir:
301 case PS_InFilenames:
302 case PS_InTrailingSep:
303 return &RawEntry.front();
304 case PS_AtEnd:
305 return &Path.back() + 1;
306 }
307 __libcpp_unreachable();
308 }
309
310 // Consume all consecutive separators.
311 PosPtr consumeAllSeparators(PosPtr P, PosPtr End) const noexcept {
312 if (P == nullptr || P == End || !isSeparator(*P))
313 return nullptr;
314 const int Inc = P < End ? 1 : -1;
315 P += Inc;
316 while (P != End && isSeparator(*P))
317 P += Inc;
318 return P;
319 }
320
321 // Consume exactly N separators, or return nullptr.
322 PosPtr consumeNSeparators(PosPtr P, PosPtr End, int N) const noexcept {
323 PosPtr Ret = consumeAllSeparators(P, End);
324 if (Ret == nullptr)
325 return nullptr;
326 if (P < End) {
327 if (Ret == P + N)
328 return Ret;
329 } else {
330 if (Ret == P - N)
331 return Ret;
332 }
333 return nullptr;
334 }
335
336 PosPtr consumeName(PosPtr P, PosPtr End) const noexcept {
337 PosPtr Start = P;
338 if (P == nullptr || P == End || isSeparator(*P))
339 return nullptr;
340 const int Inc = P < End ? 1 : -1;
341 P += Inc;
342 while (P != End && !isSeparator(*P))
343 P += Inc;
344 if (P == End && Inc < 0) {
345 // Iterating backwards and consumed all the rest of the input.
346 // Check if the start of the string would have been considered
347 // a root name.
348 PosPtr RootEnd = consumeRootName(End + 1, Start);
349 if (RootEnd)
350 return RootEnd - 1;
351 }
352 return P;
353 }
354
355 PosPtr consumeDriveLetter(PosPtr P, PosPtr End) const noexcept {
356 if (P == End)
357 return nullptr;
358 if (P < End) {
359 if (P + 1 == End || !isDriveLetter(P[0]) || P[1] != ':')
360 return nullptr;
361 return P + 2;
362 } else {
363 if (P - 1 == End || !isDriveLetter(P[-1]) || P[0] != ':')
364 return nullptr;
365 return P - 2;
366 }
367 }
368
369 PosPtr consumeNetworkRoot(PosPtr P, PosPtr End) const noexcept {
370 if (P == End)
371 return nullptr;
372 if (P < End)
373 return consumeName(consumeNSeparators(P, End, 2), End);
374 else
375 return consumeNSeparators(consumeName(P, End), End, 2);
376 }
377
378 PosPtr consumeRootName(PosPtr P, PosPtr End) const noexcept {
379#if defined(_LIBCPP_WIN32API)
380 if (PosPtr Ret = consumeDriveLetter(P, End))
381 return Ret;
382 if (PosPtr Ret = consumeNetworkRoot(P, End))
383 return Ret;
384#endif
385 return nullptr;
386 }
387};
388
389string_view_pair separate_filename(string_view_t const& s) {
390 if (s == PATHSTR(".") || s == PATHSTR("..") || s.empty())
391 return string_view_pair{s, PATHSTR("")};
392 auto pos = s.find_last_of('.');
393 if (pos == string_view_t::npos || pos == 0)
394 return string_view_pair{s, string_view_t{}};
395 return string_view_pair{s.substr(0, pos), s.substr(pos)};
396}
397
398string_view_t createView(PosPtr S, PosPtr E) noexcept {
399 return {S, static_cast<size_t>(E - S) + 1};
400}
401
402} // namespace parser
403} // namespace
404
405// POSIX HELPERS
406
407#if defined(_LIBCPP_WIN32API)
408namespace detail {
409
410errc __win_err_to_errc(int err) {
411 constexpr struct {
412 DWORD win;
413 errc errc;
414 } win_error_mapping[] = {
415 {ERROR_ACCESS_DENIED, errc::permission_denied},
416 {ERROR_ALREADY_EXISTS, errc::file_exists},
417 {ERROR_BAD_NETPATH, errc::no_such_file_or_directory},
418 {ERROR_BAD_PATHNAME, errc::no_such_file_or_directory},
419 {ERROR_BAD_UNIT, errc::no_such_device},
420 {ERROR_BROKEN_PIPE, errc::broken_pipe},
421 {ERROR_BUFFER_OVERFLOW, errc::filename_too_long},
422 {ERROR_BUSY, errc::device_or_resource_busy},
423 {ERROR_BUSY_DRIVE, errc::device_or_resource_busy},
424 {ERROR_CANNOT_MAKE, errc::permission_denied},
425 {ERROR_CANTOPEN, errc::io_error},
426 {ERROR_CANTREAD, errc::io_error},
427 {ERROR_CANTWRITE, errc::io_error},
428 {ERROR_CURRENT_DIRECTORY, errc::permission_denied},
429 {ERROR_DEV_NOT_EXIST, errc::no_such_device},
430 {ERROR_DEVICE_IN_USE, errc::device_or_resource_busy},
431 {ERROR_DIR_NOT_EMPTY, errc::directory_not_empty},
432 {ERROR_DIRECTORY, errc::invalid_argument},
433 {ERROR_DISK_FULL, errc::no_space_on_device},
434 {ERROR_FILE_EXISTS, errc::file_exists},
435 {ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory},
436 {ERROR_HANDLE_DISK_FULL, errc::no_space_on_device},
437 {ERROR_INVALID_ACCESS, errc::permission_denied},
438 {ERROR_INVALID_DRIVE, errc::no_such_device},
439 {ERROR_INVALID_FUNCTION, errc::function_not_supported},
440 {ERROR_INVALID_HANDLE, errc::invalid_argument},
441 {ERROR_INVALID_NAME, errc::no_such_file_or_directory},
442 {ERROR_INVALID_PARAMETER, errc::invalid_argument},
443 {ERROR_LOCK_VIOLATION, errc::no_lock_available},
444 {ERROR_LOCKED, errc::no_lock_available},
445 {ERROR_NEGATIVE_SEEK, errc::invalid_argument},
446 {ERROR_NOACCESS, errc::permission_denied},
447 {ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory},
448 {ERROR_NOT_READY, errc::resource_unavailable_try_again},
449 {ERROR_NOT_SAME_DEVICE, errc::cross_device_link},
450 {ERROR_NOT_SUPPORTED, errc::not_supported},
451 {ERROR_OPEN_FAILED, errc::io_error},
452 {ERROR_OPEN_FILES, errc::device_or_resource_busy},
453 {ERROR_OPERATION_ABORTED, errc::operation_canceled},
454 {ERROR_OUTOFMEMORY, errc::not_enough_memory},
455 {ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory},
456 {ERROR_READ_FAULT, errc::io_error},
457 {ERROR_REPARSE_TAG_INVALID, errc::invalid_argument},
458 {ERROR_RETRY, errc::resource_unavailable_try_again},
459 {ERROR_SEEK, errc::io_error},
460 {ERROR_SHARING_VIOLATION, errc::permission_denied},
461 {ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open},
462 {ERROR_WRITE_FAULT, errc::io_error},
463 {ERROR_WRITE_PROTECT, errc::permission_denied},
464 };
465
466 for (const auto &pair : win_error_mapping)
467 if (pair.win == static_cast<DWORD>(err))
468 return pair.errc;
469 return errc::invalid_argument;
470}
471
472} // namespace detail
473#endif
474
475namespace detail {
476namespace {
477
478using value_type = path::value_type;
479using string_type = path::string_type;
480
481struct FileDescriptor {
482 const path& name;
483 int fd = -1;
484 StatT m_stat;
485 file_status m_status;
486
487 template <class... Args>
488 static FileDescriptor create(const path* p, error_code& ec, Args... args) {
489 ec.clear();
490 int fd;
491 if ((fd = detail::open(p->c_str(), args...)) == -1) {
492 ec = capture_errno();
493 return FileDescriptor{p};
494 }
495 return FileDescriptor(p, fd);
496 }
497
498 template <class... Args>
499 static FileDescriptor create_with_status(const path* p, error_code& ec,
500 Args... args) {
501 FileDescriptor fd = create(p, ec, args...);
502 if (!ec)
503 fd.refresh_status(ec);
504
505 return fd;
506 }
507
508 file_status get_status() const { return m_status; }
509 StatT const& get_stat() const { return m_stat; }
510
511 bool status_known() const { return _VSTD_FS::status_known(m_status); }
512
513 file_status refresh_status(error_code& ec);
514
515 void close() noexcept {
516 if (fd != -1)
517 detail::close(fd);
518 fd = -1;
519 }
520
521 FileDescriptor(FileDescriptor&& other)
522 : name(other.name), fd(other.fd), m_stat(other.m_stat),
523 m_status(other.m_status) {
524 other.fd = -1;
525 other.m_status = file_status{};
526 }
527
528 ~FileDescriptor() { close(); }
529
530 FileDescriptor(FileDescriptor const&) = delete;
531 FileDescriptor& operator=(FileDescriptor const&) = delete;
532
533private:
534 explicit FileDescriptor(const path* p, int fd = -1) : name(*p), fd(fd) {}
535};
536
537perms posix_get_perms(const StatT& st) noexcept {
538 return static_cast<perms>(st.st_mode) & perms::mask;
539}
540
541file_status create_file_status(error_code& m_ec, path const& p,
542 const StatT& path_stat, error_code* ec) {
543 if (ec)
544 *ec = m_ec;
545 if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) {
546 return file_status(file_type::not_found);
547 } else if (m_ec) {
548 ErrorHandler<void> err("posix_stat", ec, &p);
549 err.report(m_ec, "failed to determine attributes for the specified path");
550 return file_status(file_type::none);
551 }
552 // else
553
554 file_status fs_tmp;
555 auto const mode = path_stat.st_mode;
556 if (S_ISLNK(mode))
557 fs_tmp.type(file_type::symlink);
558 else if (S_ISREG(mode))
559 fs_tmp.type(file_type::regular);
560 else if (S_ISDIR(mode))
561 fs_tmp.type(file_type::directory);
562 else if (S_ISBLK(mode))
563 fs_tmp.type(file_type::block);
564 else if (S_ISCHR(mode))
565 fs_tmp.type(file_type::character);
566 else if (S_ISFIFO(mode))
567 fs_tmp.type(file_type::fifo);
568 else if (S_ISSOCK(mode))
569 fs_tmp.type(file_type::socket);
570 else
571 fs_tmp.type(file_type::unknown);
572
573 fs_tmp.permissions(detail::posix_get_perms(path_stat));
574 return fs_tmp;
575}
576
577file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) {
578 error_code m_ec;
579 if (detail::stat(p.c_str(), &path_stat) == -1)
580 m_ec = detail::capture_errno();
581 return create_file_status(m_ec, p, path_stat, ec);
582}
583
584file_status posix_stat(path const& p, error_code* ec) {
585 StatT path_stat;
586 return posix_stat(p, path_stat, ec);
587}
588
589file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) {
590 error_code m_ec;
591 if (detail::lstat(p.c_str(), &path_stat) == -1)
592 m_ec = detail::capture_errno();
593 return create_file_status(m_ec, p, path_stat, ec);
594}
595
596file_status posix_lstat(path const& p, error_code* ec) {
597 StatT path_stat;
598 return posix_lstat(p, path_stat, ec);
599}
600
601// http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
602bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) {
603 if (detail::ftruncate(fd.fd, to_size) == -1) {
604 ec = capture_errno();
605 return true;
606 }
607 ec.clear();
608 return false;
609}
610
611bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) {
612 if (detail::fchmod(fd.fd, st.st_mode) == -1) {
613 ec = capture_errno();
614 return true;
615 }
616 ec.clear();
617 return false;
618}
619
620bool stat_equivalent(const StatT& st1, const StatT& st2) {
621 return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
622}
623
624file_status FileDescriptor::refresh_status(error_code& ec) {
625 // FD must be open and good.
626 m_status = file_status{};
627 m_stat = {};
628 error_code m_ec;
629 if (detail::fstat(fd, &m_stat) == -1)
630 m_ec = capture_errno();
631 m_status = create_file_status(m_ec, name, m_stat, &ec);
632 return m_status;
633}
634} // namespace
635} // end namespace detail
636
63757using detail::capture_errno;
63858using detail::ErrorHandler;
63959using detail::StatT;
......@@ -642,51 +62,6 @@ using parser::createView;
64262using parser::PathParser;
64363using parser::string_view_t;
64464
645const bool _FilesystemClock::is_steady;
646
647_FilesystemClock::time_point _FilesystemClock::now() noexcept {
648 typedef chrono::duration<rep> __secs;
649#if defined(_LIBCPP_WIN32API)
650 typedef chrono::duration<rep, nano> __nsecs;
651 FILETIME time;
652 GetSystemTimeAsFileTime(&time);
653 TimeSpec tp = detail::filetime_to_timespec(time);
654 return time_point(__secs(tp.tv_sec) +
655 chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
656#elif defined(CLOCK_REALTIME)
657 typedef chrono::duration<rep, nano> __nsecs;
658 struct timespec tp;
659 if (0 != clock_gettime(CLOCK_REALTIME, &tp))
660 __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
661 return time_point(__secs(tp.tv_sec) +
662 chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
663#else
664 typedef chrono::duration<rep, micro> __microsecs;
665 timeval tv;
666 gettimeofday(&tv, 0);
667 return time_point(__secs(tv.tv_sec) + __microsecs(tv.tv_usec));
668#endif // CLOCK_REALTIME
669}
670
671filesystem_error::~filesystem_error() {}
672
673void filesystem_error::__create_what(int __num_paths) {
674 const char* derived_what = system_error::what();
675 __storage_->__what_ = [&]() -> string {
676 switch (__num_paths) {
677 case 0:
678 return detail::format_string("filesystem error: %s", derived_what);
679 case 1:
680 return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "]",
681 derived_what, path1().c_str());
682 case 2:
683 return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "] [" PATH_CSTR_FMT "]",
684 derived_what, path1().c_str(), path2().c_str());
685 }
686 __libcpp_unreachable();
687 }();
688}
689
69065static path __do_absolute(const path& p, path* cwd, error_code* ec) {
69166 if (ec)
69267 ec->clear();
......@@ -975,7 +350,7 @@ bool __copy_file(const path& from, const path& to, copy_options options,
975350 return err.report(m_ec);
976351 }
977352
978 if (!copy_file_impl(from_fd, to_fd, m_ec)) {
353 if (!detail::copy_file_impl(from_fd, to_fd, m_ec)) {
979354 // FIXME: Remove the dest file if we failed, and it didn't exist previously.
980355 return err.report(m_ec);
981356 }
......@@ -1104,7 +479,7 @@ path __current_path(error_code* ec) {
1104479 Deleter deleter = &::free;
1105480#else
1106481 auto size = ::pathconf(".", _PC_PATH_MAX);
1107 _LIBCPP_ASSERT(size >= 0, "pathconf returned a 0 as max size");
482 _LIBCPP_ASSERT_UNCATEGORIZED(size >= 0, "pathconf returned a 0 as max size");
1108483
1109484 auto buff = unique_ptr<path::value_type[]>(new path::value_type[size + 1]);
1110485 path::value_type* ptr = buff.get();
......@@ -1193,18 +568,6 @@ bool __fs_is_empty(const path& p, error_code* ec) {
1193568 __libcpp_unreachable();
1194569}
1195570
1196static file_time_type __extract_last_write_time(const path& p, const StatT& st,
1197 error_code* ec) {
1198 using detail::fs_time;
1199 ErrorHandler<file_time_type> err("last_write_time", ec, &p);
1200
1201 auto ts = detail::extract_mtime(st);
1202 if (!fs_time::is_representable(ts))
1203 return err.report(errc::value_too_large);
1204
1205 return fs_time::convert_from_timespec(ts);
1206}
1207
1208571file_time_type __last_write_time(const path& p, error_code* ec) {
1209572 using namespace chrono;
1210573 ErrorHandler<file_time_type> err("last_write_time", ec, &p);
......@@ -1214,7 +577,7 @@ file_time_type __last_write_time(const path& p, error_code* ec) {
1214577 detail::posix_stat(p, st, &m_ec);
1215578 if (m_ec)
1216579 return err.report(m_ec);
1217 return __extract_last_write_time(p, st, ec);
580 return detail::__extract_last_write_time(p, st, ec);
1218581}
1219582
1220583void __last_write_time(const path& p, file_time_type new_time, error_code* ec) {
......@@ -1264,7 +627,7 @@ void __permissions(const path& p, perms prms, perm_options opts,
1264627 const bool resolve_symlinks = !has_opt(perm_options::nofollow);
1265628 const bool add_perms = has_opt(perm_options::add);
1266629 const bool remove_perms = has_opt(perm_options::remove);
1267 _LIBCPP_ASSERT(
630 _LIBCPP_ASSERT_UNCATEGORIZED(
1268631 (add_perms + remove_perms + has_opt(perm_options::replace)) == 1,
1269632 "One and only one of the perm_options constants replace, add, or remove "
1270633 "is present in opts");
......@@ -1278,7 +641,7 @@ void __permissions(const path& p, perms prms, perm_options opts,
1278641 set_sym_perms = is_symlink(st);
1279642 if (m_ec)
1280643 return err.report(m_ec);
1281 _LIBCPP_ASSERT(st.permissions() != perms::unknown,
644 _LIBCPP_ASSERT_UNCATEGORIZED(st.permissions() != perms::unknown,
1282645 "Permissions unexpectedly unknown");
1283646 if (add_perms)
1284647 prms |= st.permissions();
......@@ -1324,7 +687,7 @@ path __read_symlink(const path& p, error_code* ec) {
1324687 detail::SSizeT ret;
1325688 if ((ret = detail::readlink(p.c_str(), buff.get(), size)) == -1)
1326689 return err.report(capture_errno());
1327 _LIBCPP_ASSERT(ret > 0, "TODO");
690 _LIBCPP_ASSERT_UNCATEGORIZED(ret > 0, "TODO");
1328691 if (static_cast<size_t>(ret) >= size)
1329692 return err.report(errc::value_too_large);
1330693 buff[ret] = 0;
......@@ -1550,8 +913,13 @@ path __temp_directory_path(error_code* ec) {
1550913 for (auto& ep : env_paths)
1551914 if ((ret = getenv(ep)))
1552915 break;
1553 if (ret == nullptr)
916 if (ret == nullptr) {
917#if defined(__ANDROID__)
918 ret = "/data/local/tmp";
919#else
1554920 ret = "/tmp";
921#endif
922 }
1555923
1556924 path p(ret);
1557925#endif
......@@ -1604,500 +972,4 @@ path __weakly_canonical(const path& p, error_code* ec) {
1604972 return result.lexically_normal();
1605973}
1606974
1607///////////////////////////////////////////////////////////////////////////////
1608// path definitions
1609///////////////////////////////////////////////////////////////////////////////
1610
1611constexpr path::value_type path::preferred_separator;
1612
1613path& path::replace_extension(path const& replacement) {
1614 path p = extension();
1615 if (not p.empty()) {
1616 __pn_.erase(__pn_.size() - p.native().size());
1617 }
1618 if (!replacement.empty()) {
1619 if (replacement.native()[0] != '.') {
1620 __pn_ += PATHSTR(".");
1621 }
1622 __pn_.append(replacement.__pn_);
1623 }
1624 return *this;
1625}
1626
1627///////////////////////////////////////////////////////////////////////////////
1628// path.decompose
1629
1630string_view_t path::__root_name() const {
1631 auto PP = PathParser::CreateBegin(__pn_);
1632 if (PP.State == PathParser::PS_InRootName)
1633 return *PP;
1634 return {};
1635}
1636
1637string_view_t path::__root_directory() const {
1638 auto PP = PathParser::CreateBegin(__pn_);
1639 if (PP.State == PathParser::PS_InRootName)
1640 ++PP;
1641 if (PP.State == PathParser::PS_InRootDir)
1642 return *PP;
1643 return {};
1644}
1645
1646string_view_t path::__root_path_raw() const {
1647 auto PP = PathParser::CreateBegin(__pn_);
1648 if (PP.State == PathParser::PS_InRootName) {
1649 auto NextCh = PP.peek();
1650 if (NextCh && isSeparator(*NextCh)) {
1651 ++PP;
1652 return createView(__pn_.data(), &PP.RawEntry.back());
1653 }
1654 return PP.RawEntry;
1655 }
1656 if (PP.State == PathParser::PS_InRootDir)
1657 return *PP;
1658 return {};
1659}
1660
1661static bool ConsumeRootName(PathParser *PP) {
1662 static_assert(PathParser::PS_BeforeBegin == 1 &&
1663 PathParser::PS_InRootName == 2,
1664 "Values for enums are incorrect");
1665 while (PP->State <= PathParser::PS_InRootName)
1666 ++(*PP);
1667 return PP->State == PathParser::PS_AtEnd;
1668}
1669
1670static bool ConsumeRootDir(PathParser* PP) {
1671 static_assert(PathParser::PS_BeforeBegin == 1 &&
1672 PathParser::PS_InRootName == 2 &&
1673 PathParser::PS_InRootDir == 3, "Values for enums are incorrect");
1674 while (PP->State <= PathParser::PS_InRootDir)
1675 ++(*PP);
1676 return PP->State == PathParser::PS_AtEnd;
1677}
1678
1679string_view_t path::__relative_path() const {
1680 auto PP = PathParser::CreateBegin(__pn_);
1681 if (ConsumeRootDir(&PP))
1682 return {};
1683 return createView(PP.RawEntry.data(), &__pn_.back());
1684}
1685
1686string_view_t path::__parent_path() const {
1687 if (empty())
1688 return {};
1689 // Determine if we have a root path but not a relative path. In that case
1690 // return *this.
1691 {
1692 auto PP = PathParser::CreateBegin(__pn_);
1693 if (ConsumeRootDir(&PP))
1694 return __pn_;
1695 }
1696 // Otherwise remove a single element from the end of the path, and return
1697 // a string representing that path
1698 {
1699 auto PP = PathParser::CreateEnd(__pn_);
1700 --PP;
1701 if (PP.RawEntry.data() == __pn_.data())
1702 return {};
1703 --PP;
1704 return createView(__pn_.data(), &PP.RawEntry.back());
1705 }
1706}
1707
1708string_view_t path::__filename() const {
1709 if (empty())
1710 return {};
1711 {
1712 PathParser PP = PathParser::CreateBegin(__pn_);
1713 if (ConsumeRootDir(&PP))
1714 return {};
1715 }
1716 return *(--PathParser::CreateEnd(__pn_));
1717}
1718
1719string_view_t path::__stem() const {
1720 return parser::separate_filename(__filename()).first;
1721}
1722
1723string_view_t path::__extension() const {
1724 return parser::separate_filename(__filename()).second;
1725}
1726
1727////////////////////////////////////////////////////////////////////////////
1728// path.gen
1729
1730enum PathPartKind : unsigned char {
1731 PK_None,
1732 PK_RootSep,
1733 PK_Filename,
1734 PK_Dot,
1735 PK_DotDot,
1736 PK_TrailingSep
1737};
1738
1739static PathPartKind ClassifyPathPart(string_view_t Part) {
1740 if (Part.empty())
1741 return PK_TrailingSep;
1742 if (Part == PATHSTR("."))
1743 return PK_Dot;
1744 if (Part == PATHSTR(".."))
1745 return PK_DotDot;
1746 if (Part == PATHSTR("/"))
1747 return PK_RootSep;
1748#if defined(_LIBCPP_WIN32API)
1749 if (Part == PATHSTR("\\"))
1750 return PK_RootSep;
1751#endif
1752 return PK_Filename;
1753}
1754
1755path path::lexically_normal() const {
1756 if (__pn_.empty())
1757 return *this;
1758
1759 using PartKindPair = pair<string_view_t, PathPartKind>;
1760 vector<PartKindPair> Parts;
1761 // Guess as to how many elements the path has to avoid reallocating.
1762 Parts.reserve(32);
1763
1764 // Track the total size of the parts as we collect them. This allows the
1765 // resulting path to reserve the correct amount of memory.
1766 size_t NewPathSize = 0;
1767 auto AddPart = [&](PathPartKind K, string_view_t P) {
1768 NewPathSize += P.size();
1769 Parts.emplace_back(P, K);
1770 };
1771 auto LastPartKind = [&]() {
1772 if (Parts.empty())
1773 return PK_None;
1774 return Parts.back().second;
1775 };
1776
1777 bool MaybeNeedTrailingSep = false;
1778 // Build a stack containing the remaining elements of the path, popping off
1779 // elements which occur before a '..' entry.
1780 for (auto PP = PathParser::CreateBegin(__pn_); PP; ++PP) {
1781 auto Part = *PP;
1782 PathPartKind Kind = ClassifyPathPart(Part);
1783 switch (Kind) {
1784 case PK_Filename:
1785 case PK_RootSep: {
1786 // Add all non-dot and non-dot-dot elements to the stack of elements.
1787 AddPart(Kind, Part);
1788 MaybeNeedTrailingSep = false;
1789 break;
1790 }
1791 case PK_DotDot: {
1792 // Only push a ".." element if there are no elements preceding the "..",
1793 // or if the preceding element is itself "..".
1794 auto LastKind = LastPartKind();
1795 if (LastKind == PK_Filename) {
1796 NewPathSize -= Parts.back().first.size();
1797 Parts.pop_back();
1798 } else if (LastKind != PK_RootSep)
1799 AddPart(PK_DotDot, PATHSTR(".."));
1800 MaybeNeedTrailingSep = LastKind == PK_Filename;
1801 break;
1802 }
1803 case PK_Dot:
1804 case PK_TrailingSep: {
1805 MaybeNeedTrailingSep = true;
1806 break;
1807 }
1808 case PK_None:
1809 __libcpp_unreachable();
1810 }
1811 }
1812 // [fs.path.generic]p6.8: If the path is empty, add a dot.
1813 if (Parts.empty())
1814 return PATHSTR(".");
1815
1816 // [fs.path.generic]p6.7: If the last filename is dot-dot, remove any
1817 // trailing directory-separator.
1818 bool NeedTrailingSep = MaybeNeedTrailingSep && LastPartKind() == PK_Filename;
1819
1820 path Result;
1821 Result.__pn_.reserve(Parts.size() + NewPathSize + NeedTrailingSep);
1822 for (auto& PK : Parts)
1823 Result /= PK.first;
1824
1825 if (NeedTrailingSep)
1826 Result /= PATHSTR("");
1827
1828 Result.make_preferred();
1829 return Result;
1830}
1831
1832static int DetermineLexicalElementCount(PathParser PP) {
1833 int Count = 0;
1834 for (; PP; ++PP) {
1835 auto Elem = *PP;
1836 if (Elem == PATHSTR(".."))
1837 --Count;
1838 else if (Elem != PATHSTR(".") && Elem != PATHSTR(""))
1839 ++Count;
1840 }
1841 return Count;
1842}
1843
1844path path::lexically_relative(const path& base) const {
1845 { // perform root-name/root-directory mismatch checks
1846 auto PP = PathParser::CreateBegin(__pn_);
1847 auto PPBase = PathParser::CreateBegin(base.__pn_);
1848 auto CheckIterMismatchAtBase = [&]() {
1849 return PP.State != PPBase.State &&
1850 (PP.inRootPath() || PPBase.inRootPath());
1851 };
1852 if (PP.inRootName() && PPBase.inRootName()) {
1853 if (*PP != *PPBase)
1854 return {};
1855 } else if (CheckIterMismatchAtBase())
1856 return {};
1857
1858 if (PP.inRootPath())
1859 ++PP;
1860 if (PPBase.inRootPath())
1861 ++PPBase;
1862 if (CheckIterMismatchAtBase())
1863 return {};
1864 }
1865
1866 // Find the first mismatching element
1867 auto PP = PathParser::CreateBegin(__pn_);
1868 auto PPBase = PathParser::CreateBegin(base.__pn_);
1869 while (PP && PPBase && PP.State == PPBase.State && *PP == *PPBase) {
1870 ++PP;
1871 ++PPBase;
1872 }
1873
1874 // If there is no mismatch, return ".".
1875 if (!PP && !PPBase)
1876 return ".";
1877
1878 // Otherwise, determine the number of elements, 'n', which are not dot or
1879 // dot-dot minus the number of dot-dot elements.
1880 int ElemCount = DetermineLexicalElementCount(PPBase);
1881 if (ElemCount < 0)
1882 return {};
1883
1884 // if n == 0 and (a == end() || a->empty()), returns path("."); otherwise
1885 if (ElemCount == 0 && (PP.atEnd() || *PP == PATHSTR("")))
1886 return PATHSTR(".");
1887
1888 // return a path constructed with 'n' dot-dot elements, followed by the
1889 // elements of '*this' after the mismatch.
1890 path Result;
1891 // FIXME: Reserve enough room in Result that it won't have to re-allocate.
1892 while (ElemCount--)
1893 Result /= PATHSTR("..");
1894 for (; PP; ++PP)
1895 Result /= *PP;
1896 return Result;
1897}
1898
1899////////////////////////////////////////////////////////////////////////////
1900// path.comparisons
1901static int CompareRootName(PathParser *LHS, PathParser *RHS) {
1902 if (!LHS->inRootName() && !RHS->inRootName())
1903 return 0;
1904
1905 auto GetRootName = [](PathParser *Parser) -> string_view_t {
1906 return Parser->inRootName() ? **Parser : PATHSTR("");
1907 };
1908 int res = GetRootName(LHS).compare(GetRootName(RHS));
1909 ConsumeRootName(LHS);
1910 ConsumeRootName(RHS);
1911 return res;
1912}
1913
1914static int CompareRootDir(PathParser *LHS, PathParser *RHS) {
1915 if (!LHS->inRootDir() && RHS->inRootDir())
1916 return -1;
1917 else if (LHS->inRootDir() && !RHS->inRootDir())
1918 return 1;
1919 else {
1920 ConsumeRootDir(LHS);
1921 ConsumeRootDir(RHS);
1922 return 0;
1923 }
1924}
1925
1926static int CompareRelative(PathParser *LHSPtr, PathParser *RHSPtr) {
1927 auto &LHS = *LHSPtr;
1928 auto &RHS = *RHSPtr;
1929
1930 int res;
1931 while (LHS && RHS) {
1932 if ((res = (*LHS).compare(*RHS)) != 0)
1933 return res;
1934 ++LHS;
1935 ++RHS;
1936 }
1937 return 0;
1938}
1939
1940static int CompareEndState(PathParser *LHS, PathParser *RHS) {
1941 if (LHS->atEnd() && !RHS->atEnd())
1942 return -1;
1943 else if (!LHS->atEnd() && RHS->atEnd())
1944 return 1;
1945 return 0;
1946}
1947
1948int path::__compare(string_view_t __s) const {
1949 auto LHS = PathParser::CreateBegin(__pn_);
1950 auto RHS = PathParser::CreateBegin(__s);
1951 int res;
1952
1953 if ((res = CompareRootName(&LHS, &RHS)) != 0)
1954 return res;
1955
1956 if ((res = CompareRootDir(&LHS, &RHS)) != 0)
1957 return res;
1958
1959 if ((res = CompareRelative(&LHS, &RHS)) != 0)
1960 return res;
1961
1962 return CompareEndState(&LHS, &RHS);
1963}
1964
1965////////////////////////////////////////////////////////////////////////////
1966// path.nonmembers
1967size_t hash_value(const path& __p) noexcept {
1968 auto PP = PathParser::CreateBegin(__p.native());
1969 size_t hash_value = 0;
1970 hash<string_view_t> hasher;
1971 while (PP) {
1972 hash_value = __hash_combine(hash_value, hasher(*PP));
1973 ++PP;
1974 }
1975 return hash_value;
1976}
1977
1978////////////////////////////////////////////////////////////////////////////
1979// path.itr
1980path::iterator path::begin() const {
1981 auto PP = PathParser::CreateBegin(__pn_);
1982 iterator it;
1983 it.__path_ptr_ = this;
1984 it.__state_ = static_cast<path::iterator::_ParserState>(PP.State);
1985 it.__entry_ = PP.RawEntry;
1986 it.__stashed_elem_.__assign_view(*PP);
1987 return it;
1988}
1989
1990path::iterator path::end() const {
1991 iterator it{};
1992 it.__state_ = path::iterator::_AtEnd;
1993 it.__path_ptr_ = this;
1994 return it;
1995}
1996
1997path::iterator& path::iterator::__increment() {
1998 PathParser PP(__path_ptr_->native(), __entry_, __state_);
1999 ++PP;
2000 __state_ = static_cast<_ParserState>(PP.State);
2001 __entry_ = PP.RawEntry;
2002 __stashed_elem_.__assign_view(*PP);
2003 return *this;
2004}
2005
2006path::iterator& path::iterator::__decrement() {
2007 PathParser PP(__path_ptr_->native(), __entry_, __state_);
2008 --PP;
2009 __state_ = static_cast<_ParserState>(PP.State);
2010 __entry_ = PP.RawEntry;
2011 __stashed_elem_.__assign_view(*PP);
2012 return *this;
2013}
2014
2015#if defined(_LIBCPP_WIN32API)
2016////////////////////////////////////////////////////////////////////////////
2017// Windows path conversions
2018size_t __wide_to_char(const wstring &str, char *out, size_t outlen) {
2019 if (str.empty())
2020 return 0;
2021 ErrorHandler<size_t> err("__wide_to_char", nullptr);
2022 UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
2023 BOOL used_default = FALSE;
2024 int ret = WideCharToMultiByte(codepage, 0, str.data(), str.size(), out,
2025 outlen, nullptr, &used_default);
2026 if (ret <= 0 || used_default)
2027 return err.report(errc::illegal_byte_sequence);
2028 return ret;
2029}
2030
2031size_t __char_to_wide(const string &str, wchar_t *out, size_t outlen) {
2032 if (str.empty())
2033 return 0;
2034 ErrorHandler<size_t> err("__char_to_wide", nullptr);
2035 UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
2036 int ret = MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, str.data(),
2037 str.size(), out, outlen);
2038 if (ret <= 0)
2039 return err.report(errc::illegal_byte_sequence);
2040 return ret;
2041}
2042#endif
2043
2044
2045///////////////////////////////////////////////////////////////////////////////
2046// directory entry definitions
2047///////////////////////////////////////////////////////////////////////////////
2048
2049error_code directory_entry::__do_refresh() noexcept {
2050 __data_.__reset();
2051 error_code failure_ec;
2052
2053 StatT full_st;
2054 file_status st = detail::posix_lstat(__p_, full_st, &failure_ec);
2055 if (!status_known(st)) {
2056 __data_.__reset();
2057 return failure_ec;
2058 }
2059
2060 if (!_VSTD_FS::exists(st) || !_VSTD_FS::is_symlink(st)) {
2061 __data_.__cache_type_ = directory_entry::_RefreshNonSymlink;
2062 __data_.__type_ = st.type();
2063 __data_.__non_sym_perms_ = st.permissions();
2064 } else { // we have a symlink
2065 __data_.__sym_perms_ = st.permissions();
2066 // Get the information about the linked entity.
2067 // Ignore errors from stat, since we don't want errors regarding symlink
2068 // resolution to be reported to the user.
2069 error_code ignored_ec;
2070 st = detail::posix_stat(__p_, full_st, &ignored_ec);
2071
2072 __data_.__type_ = st.type();
2073 __data_.__non_sym_perms_ = st.permissions();
2074
2075 // If we failed to resolve the link, then only partially populate the
2076 // cache.
2077 if (!status_known(st)) {
2078 __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved;
2079 return error_code{};
2080 }
2081 // Otherwise, we resolved the link, potentially as not existing.
2082 // That's OK.
2083 __data_.__cache_type_ = directory_entry::_RefreshSymlink;
2084 }
2085
2086 if (_VSTD_FS::is_regular_file(st))
2087 __data_.__size_ = static_cast<uintmax_t>(full_st.st_size);
2088
2089 if (_VSTD_FS::exists(st)) {
2090 __data_.__nlink_ = static_cast<uintmax_t>(full_st.st_nlink);
2091
2092 // Attempt to extract the mtime, and fail if it's not representable using
2093 // file_time_type. For now we ignore the error, as we'll report it when
2094 // the value is actually used.
2095 error_code ignored_ec;
2096 __data_.__write_time_ =
2097 __extract_last_write_time(__p_, full_st, &ignored_ec);
2098 }
2099
2100 return failure_ec;
2101}
2102
2103975_LIBCPP_END_NAMESPACE_FILESYSTEM
lib/libcxx/src/filesystem/path.cpp created+460
......@@ -0,0 +1,460 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <__config>
10#include <filesystem>
11#include <vector>
12
13#include "error.h"
14#include "path_parser.h"
15
16_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
17
18using detail::ErrorHandler;
19using parser::createView;
20using parser::PathParser;
21using parser::string_view_t;
22
23///////////////////////////////////////////////////////////////////////////////
24// path definitions
25///////////////////////////////////////////////////////////////////////////////
26
27constexpr path::value_type path::preferred_separator;
28
29path& path::replace_extension(path const& replacement) {
30 path p = extension();
31 if (not p.empty()) {
32 __pn_.erase(__pn_.size() - p.native().size());
33 }
34 if (!replacement.empty()) {
35 if (replacement.native()[0] != '.') {
36 __pn_ += PATHSTR(".");
37 }
38 __pn_.append(replacement.__pn_);
39 }
40 return *this;
41}
42
43///////////////////////////////////////////////////////////////////////////////
44// path.decompose
45
46string_view_t path::__root_name() const {
47 auto PP = PathParser::CreateBegin(__pn_);
48 if (PP.State == PathParser::PS_InRootName)
49 return *PP;
50 return {};
51}
52
53string_view_t path::__root_directory() const {
54 auto PP = PathParser::CreateBegin(__pn_);
55 if (PP.State == PathParser::PS_InRootName)
56 ++PP;
57 if (PP.State == PathParser::PS_InRootDir)
58 return *PP;
59 return {};
60}
61
62string_view_t path::__root_path_raw() const {
63 auto PP = PathParser::CreateBegin(__pn_);
64 if (PP.State == PathParser::PS_InRootName) {
65 auto NextCh = PP.peek();
66 if (NextCh && isSeparator(*NextCh)) {
67 ++PP;
68 return createView(__pn_.data(), &PP.RawEntry.back());
69 }
70 return PP.RawEntry;
71 }
72 if (PP.State == PathParser::PS_InRootDir)
73 return *PP;
74 return {};
75}
76
77static bool ConsumeRootName(PathParser *PP) {
78 static_assert(PathParser::PS_BeforeBegin == 1 &&
79 PathParser::PS_InRootName == 2,
80 "Values for enums are incorrect");
81 while (PP->State <= PathParser::PS_InRootName)
82 ++(*PP);
83 return PP->State == PathParser::PS_AtEnd;
84}
85
86static bool ConsumeRootDir(PathParser* PP) {
87 static_assert(PathParser::PS_BeforeBegin == 1 &&
88 PathParser::PS_InRootName == 2 &&
89 PathParser::PS_InRootDir == 3, "Values for enums are incorrect");
90 while (PP->State <= PathParser::PS_InRootDir)
91 ++(*PP);
92 return PP->State == PathParser::PS_AtEnd;
93}
94
95string_view_t path::__relative_path() const {
96 auto PP = PathParser::CreateBegin(__pn_);
97 if (ConsumeRootDir(&PP))
98 return {};
99 return createView(PP.RawEntry.data(), &__pn_.back());
100}
101
102string_view_t path::__parent_path() const {
103 if (empty())
104 return {};
105 // Determine if we have a root path but not a relative path. In that case
106 // return *this.
107 {
108 auto PP = PathParser::CreateBegin(__pn_);
109 if (ConsumeRootDir(&PP))
110 return __pn_;
111 }
112 // Otherwise remove a single element from the end of the path, and return
113 // a string representing that path
114 {
115 auto PP = PathParser::CreateEnd(__pn_);
116 --PP;
117 if (PP.RawEntry.data() == __pn_.data())
118 return {};
119 --PP;
120 return createView(__pn_.data(), &PP.RawEntry.back());
121 }
122}
123
124string_view_t path::__filename() const {
125 if (empty())
126 return {};
127 {
128 PathParser PP = PathParser::CreateBegin(__pn_);
129 if (ConsumeRootDir(&PP))
130 return {};
131 }
132 return *(--PathParser::CreateEnd(__pn_));
133}
134
135string_view_t path::__stem() const {
136 return parser::separate_filename(__filename()).first;
137}
138
139string_view_t path::__extension() const {
140 return parser::separate_filename(__filename()).second;
141}
142
143////////////////////////////////////////////////////////////////////////////
144// path.gen
145
146enum PathPartKind : unsigned char {
147 PK_None,
148 PK_RootSep,
149 PK_Filename,
150 PK_Dot,
151 PK_DotDot,
152 PK_TrailingSep
153};
154
155static PathPartKind ClassifyPathPart(string_view_t Part) {
156 if (Part.empty())
157 return PK_TrailingSep;
158 if (Part == PATHSTR("."))
159 return PK_Dot;
160 if (Part == PATHSTR(".."))
161 return PK_DotDot;
162 if (Part == PATHSTR("/"))
163 return PK_RootSep;
164#if defined(_LIBCPP_WIN32API)
165 if (Part == PATHSTR("\\"))
166 return PK_RootSep;
167#endif
168 return PK_Filename;
169}
170
171path path::lexically_normal() const {
172 if (__pn_.empty())
173 return *this;
174
175 using PartKindPair = pair<string_view_t, PathPartKind>;
176 vector<PartKindPair> Parts;
177 // Guess as to how many elements the path has to avoid reallocating.
178 Parts.reserve(32);
179
180 // Track the total size of the parts as we collect them. This allows the
181 // resulting path to reserve the correct amount of memory.
182 size_t NewPathSize = 0;
183 auto AddPart = [&](PathPartKind K, string_view_t P) {
184 NewPathSize += P.size();
185 Parts.emplace_back(P, K);
186 };
187 auto LastPartKind = [&]() {
188 if (Parts.empty())
189 return PK_None;
190 return Parts.back().second;
191 };
192
193 bool MaybeNeedTrailingSep = false;
194 // Build a stack containing the remaining elements of the path, popping off
195 // elements which occur before a '..' entry.
196 for (auto PP = PathParser::CreateBegin(__pn_); PP; ++PP) {
197 auto Part = *PP;
198 PathPartKind Kind = ClassifyPathPart(Part);
199 switch (Kind) {
200 case PK_Filename:
201 case PK_RootSep: {
202 // Add all non-dot and non-dot-dot elements to the stack of elements.
203 AddPart(Kind, Part);
204 MaybeNeedTrailingSep = false;
205 break;
206 }
207 case PK_DotDot: {
208 // Only push a ".." element if there are no elements preceding the "..",
209 // or if the preceding element is itself "..".
210 auto LastKind = LastPartKind();
211 if (LastKind == PK_Filename) {
212 NewPathSize -= Parts.back().first.size();
213 Parts.pop_back();
214 } else if (LastKind != PK_RootSep)
215 AddPart(PK_DotDot, PATHSTR(".."));
216 MaybeNeedTrailingSep = LastKind == PK_Filename;
217 break;
218 }
219 case PK_Dot:
220 case PK_TrailingSep: {
221 MaybeNeedTrailingSep = true;
222 break;
223 }
224 case PK_None:
225 __libcpp_unreachable();
226 }
227 }
228 // [fs.path.generic]p6.8: If the path is empty, add a dot.
229 if (Parts.empty())
230 return PATHSTR(".");
231
232 // [fs.path.generic]p6.7: If the last filename is dot-dot, remove any
233 // trailing directory-separator.
234 bool NeedTrailingSep = MaybeNeedTrailingSep && LastPartKind() == PK_Filename;
235
236 path Result;
237 Result.__pn_.reserve(Parts.size() + NewPathSize + NeedTrailingSep);
238 for (auto& PK : Parts)
239 Result /= PK.first;
240
241 if (NeedTrailingSep)
242 Result /= PATHSTR("");
243
244 Result.make_preferred();
245 return Result;
246}
247
248static int DetermineLexicalElementCount(PathParser PP) {
249 int Count = 0;
250 for (; PP; ++PP) {
251 auto Elem = *PP;
252 if (Elem == PATHSTR(".."))
253 --Count;
254 else if (Elem != PATHSTR(".") && Elem != PATHSTR(""))
255 ++Count;
256 }
257 return Count;
258}
259
260path path::lexically_relative(const path& base) const {
261 { // perform root-name/root-directory mismatch checks
262 auto PP = PathParser::CreateBegin(__pn_);
263 auto PPBase = PathParser::CreateBegin(base.__pn_);
264 auto CheckIterMismatchAtBase = [&]() {
265 return PP.State != PPBase.State &&
266 (PP.inRootPath() || PPBase.inRootPath());
267 };
268 if (PP.inRootName() && PPBase.inRootName()) {
269 if (*PP != *PPBase)
270 return {};
271 } else if (CheckIterMismatchAtBase())
272 return {};
273
274 if (PP.inRootPath())
275 ++PP;
276 if (PPBase.inRootPath())
277 ++PPBase;
278 if (CheckIterMismatchAtBase())
279 return {};
280 }
281
282 // Find the first mismatching element
283 auto PP = PathParser::CreateBegin(__pn_);
284 auto PPBase = PathParser::CreateBegin(base.__pn_);
285 while (PP && PPBase && PP.State == PPBase.State && *PP == *PPBase) {
286 ++PP;
287 ++PPBase;
288 }
289
290 // If there is no mismatch, return ".".
291 if (!PP && !PPBase)
292 return ".";
293
294 // Otherwise, determine the number of elements, 'n', which are not dot or
295 // dot-dot minus the number of dot-dot elements.
296 int ElemCount = DetermineLexicalElementCount(PPBase);
297 if (ElemCount < 0)
298 return {};
299
300 // if n == 0 and (a == end() || a->empty()), returns path("."); otherwise
301 if (ElemCount == 0 && (PP.atEnd() || *PP == PATHSTR("")))
302 return PATHSTR(".");
303
304 // return a path constructed with 'n' dot-dot elements, followed by the
305 // elements of '*this' after the mismatch.
306 path Result;
307 // FIXME: Reserve enough room in Result that it won't have to re-allocate.
308 while (ElemCount--)
309 Result /= PATHSTR("..");
310 for (; PP; ++PP)
311 Result /= *PP;
312 return Result;
313}
314
315////////////////////////////////////////////////////////////////////////////
316// path.comparisons
317static int CompareRootName(PathParser *LHS, PathParser *RHS) {
318 if (!LHS->inRootName() && !RHS->inRootName())
319 return 0;
320
321 auto GetRootName = [](PathParser *Parser) -> string_view_t {
322 return Parser->inRootName() ? **Parser : PATHSTR("");
323 };
324 int res = GetRootName(LHS).compare(GetRootName(RHS));
325 ConsumeRootName(LHS);
326 ConsumeRootName(RHS);
327 return res;
328}
329
330static int CompareRootDir(PathParser *LHS, PathParser *RHS) {
331 if (!LHS->inRootDir() && RHS->inRootDir())
332 return -1;
333 else if (LHS->inRootDir() && !RHS->inRootDir())
334 return 1;
335 else {
336 ConsumeRootDir(LHS);
337 ConsumeRootDir(RHS);
338 return 0;
339 }
340}
341
342static int CompareRelative(PathParser *LHSPtr, PathParser *RHSPtr) {
343 auto &LHS = *LHSPtr;
344 auto &RHS = *RHSPtr;
345
346 int res;
347 while (LHS && RHS) {
348 if ((res = (*LHS).compare(*RHS)) != 0)
349 return res;
350 ++LHS;
351 ++RHS;
352 }
353 return 0;
354}
355
356static int CompareEndState(PathParser *LHS, PathParser *RHS) {
357 if (LHS->atEnd() && !RHS->atEnd())
358 return -1;
359 else if (!LHS->atEnd() && RHS->atEnd())
360 return 1;
361 return 0;
362}
363
364int path::__compare(string_view_t __s) const {
365 auto LHS = PathParser::CreateBegin(__pn_);
366 auto RHS = PathParser::CreateBegin(__s);
367 int res;
368
369 if ((res = CompareRootName(&LHS, &RHS)) != 0)
370 return res;
371
372 if ((res = CompareRootDir(&LHS, &RHS)) != 0)
373 return res;
374
375 if ((res = CompareRelative(&LHS, &RHS)) != 0)
376 return res;
377
378 return CompareEndState(&LHS, &RHS);
379}
380
381////////////////////////////////////////////////////////////////////////////
382// path.nonmembers
383size_t hash_value(const path& __p) noexcept {
384 auto PP = PathParser::CreateBegin(__p.native());
385 size_t hash_value = 0;
386 hash<string_view_t> hasher;
387 while (PP) {
388 hash_value = __hash_combine(hash_value, hasher(*PP));
389 ++PP;
390 }
391 return hash_value;
392}
393
394////////////////////////////////////////////////////////////////////////////
395// path.itr
396path::iterator path::begin() const {
397 auto PP = PathParser::CreateBegin(__pn_);
398 iterator it;
399 it.__path_ptr_ = this;
400 it.__state_ = static_cast<path::iterator::_ParserState>(PP.State);
401 it.__entry_ = PP.RawEntry;
402 it.__stashed_elem_.__assign_view(*PP);
403 return it;
404}
405
406path::iterator path::end() const {
407 iterator it{};
408 it.__state_ = path::iterator::_AtEnd;
409 it.__path_ptr_ = this;
410 return it;
411}
412
413path::iterator& path::iterator::__increment() {
414 PathParser PP(__path_ptr_->native(), __entry_, __state_);
415 ++PP;
416 __state_ = static_cast<_ParserState>(PP.State);
417 __entry_ = PP.RawEntry;
418 __stashed_elem_.__assign_view(*PP);
419 return *this;
420}
421
422path::iterator& path::iterator::__decrement() {
423 PathParser PP(__path_ptr_->native(), __entry_, __state_);
424 --PP;
425 __state_ = static_cast<_ParserState>(PP.State);
426 __entry_ = PP.RawEntry;
427 __stashed_elem_.__assign_view(*PP);
428 return *this;
429}
430
431#if defined(_LIBCPP_WIN32API)
432////////////////////////////////////////////////////////////////////////////
433// Windows path conversions
434size_t __wide_to_char(const wstring &str, char *out, size_t outlen) {
435 if (str.empty())
436 return 0;
437 ErrorHandler<size_t> err("__wide_to_char", nullptr);
438 UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
439 BOOL used_default = FALSE;
440 int ret = WideCharToMultiByte(codepage, 0, str.data(), str.size(), out,
441 outlen, nullptr, &used_default);
442 if (ret <= 0 || used_default)
443 return err.report(errc::illegal_byte_sequence);
444 return ret;
445}
446
447size_t __char_to_wide(const string &str, wchar_t *out, size_t outlen) {
448 if (str.empty())
449 return 0;
450 ErrorHandler<size_t> err("__char_to_wide", nullptr);
451 UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
452 int ret = MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, str.data(),
453 str.size(), out, outlen);
454 if (ret <= 0)
455 return err.report(errc::illegal_byte_sequence);
456 return ret;
457}
458#endif
459
460_LIBCPP_END_NAMESPACE_FILESYSTEM
lib/libcxx/src/filesystem/path_parser.h created+368
......@@ -0,0 +1,368 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef PATH_PARSER_H
10#define PATH_PARSER_H
11
12#include <__config>
13#include <__utility/unreachable.h>
14#include <cstddef>
15#include <filesystem>
16#include <utility>
17
18#include "format_string.h"
19
20_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
21
22inline bool isSeparator(path::value_type C) {
23 if (C == '/')
24 return true;
25#if defined(_LIBCPP_WIN32API)
26 if (C == '\\')
27 return true;
28#endif
29 return false;
30}
31
32inline bool isDriveLetter(path::value_type C) {
33 return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z');
34}
35
36namespace parser {
37
38using string_view_t = path::__string_view;
39using string_view_pair = pair<string_view_t, string_view_t>;
40using PosPtr = path::value_type const*;
41
42struct PathParser {
43 enum ParserState : unsigned char {
44 // Zero is a special sentinel value used by default constructed iterators.
45 PS_BeforeBegin = path::iterator::_BeforeBegin,
46 PS_InRootName = path::iterator::_InRootName,
47 PS_InRootDir = path::iterator::_InRootDir,
48 PS_InFilenames = path::iterator::_InFilenames,
49 PS_InTrailingSep = path::iterator::_InTrailingSep,
50 PS_AtEnd = path::iterator::_AtEnd
51 };
52
53 const string_view_t Path;
54 string_view_t RawEntry;
55 ParserState State;
56
57private:
58 PathParser(string_view_t P, ParserState State) noexcept : Path(P),
59 State(State) {}
60
61public:
62 PathParser(string_view_t P, string_view_t E, unsigned char S)
63 : Path(P), RawEntry(E), State(static_cast<ParserState>(S)) {
64 // S cannot be '0' or PS_BeforeBegin.
65 }
66
67 static PathParser CreateBegin(string_view_t P) noexcept {
68 PathParser PP(P, PS_BeforeBegin);
69 PP.increment();
70 return PP;
71 }
72
73 static PathParser CreateEnd(string_view_t P) noexcept {
74 PathParser PP(P, PS_AtEnd);
75 return PP;
76 }
77
78 PosPtr peek() const noexcept {
79 auto TkEnd = getNextTokenStartPos();
80 auto End = getAfterBack();
81 return TkEnd == End ? nullptr : TkEnd;
82 }
83
84 void increment() noexcept {
85 const PosPtr End = getAfterBack();
86 const PosPtr Start = getNextTokenStartPos();
87 if (Start == End)
88 return makeState(PS_AtEnd);
89
90 switch (State) {
91 case PS_BeforeBegin: {
92 PosPtr TkEnd = consumeRootName(Start, End);
93 if (TkEnd)
94 return makeState(PS_InRootName, Start, TkEnd);
95 }
96 _LIBCPP_FALLTHROUGH();
97 case PS_InRootName: {
98 PosPtr TkEnd = consumeAllSeparators(Start, End);
99 if (TkEnd)
100 return makeState(PS_InRootDir, Start, TkEnd);
101 else
102 return makeState(PS_InFilenames, Start, consumeName(Start, End));
103 }
104 case PS_InRootDir:
105 return makeState(PS_InFilenames, Start, consumeName(Start, End));
106
107 case PS_InFilenames: {
108 PosPtr SepEnd = consumeAllSeparators(Start, End);
109 if (SepEnd != End) {
110 PosPtr TkEnd = consumeName(SepEnd, End);
111 if (TkEnd)
112 return makeState(PS_InFilenames, SepEnd, TkEnd);
113 }
114 return makeState(PS_InTrailingSep, Start, SepEnd);
115 }
116
117 case PS_InTrailingSep:
118 return makeState(PS_AtEnd);
119
120 case PS_AtEnd:
121 __libcpp_unreachable();
122 }
123 }
124
125 void decrement() noexcept {
126 const PosPtr REnd = getBeforeFront();
127 const PosPtr RStart = getCurrentTokenStartPos() - 1;
128 if (RStart == REnd) // we're decrementing the begin
129 return makeState(PS_BeforeBegin);
130
131 switch (State) {
132 case PS_AtEnd: {
133 // Try to consume a trailing separator or root directory first.
134 if (PosPtr SepEnd = consumeAllSeparators(RStart, REnd)) {
135 if (SepEnd == REnd)
136 return makeState(PS_InRootDir, Path.data(), RStart + 1);
137 PosPtr TkStart = consumeRootName(SepEnd, REnd);
138 if (TkStart == REnd)
139 return makeState(PS_InRootDir, RStart, RStart + 1);
140 return makeState(PS_InTrailingSep, SepEnd + 1, RStart + 1);
141 } else {
142 PosPtr TkStart = consumeRootName(RStart, REnd);
143 if (TkStart == REnd)
144 return makeState(PS_InRootName, TkStart + 1, RStart + 1);
145 TkStart = consumeName(RStart, REnd);
146 return makeState(PS_InFilenames, TkStart + 1, RStart + 1);
147 }
148 }
149 case PS_InTrailingSep:
150 return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1,
151 RStart + 1);
152 case PS_InFilenames: {
153 PosPtr SepEnd = consumeAllSeparators(RStart, REnd);
154 if (SepEnd == REnd)
155 return makeState(PS_InRootDir, Path.data(), RStart + 1);
156 PosPtr TkStart = consumeRootName(SepEnd ? SepEnd : RStart, REnd);
157 if (TkStart == REnd) {
158 if (SepEnd)
159 return makeState(PS_InRootDir, SepEnd + 1, RStart + 1);
160 return makeState(PS_InRootName, TkStart + 1, RStart + 1);
161 }
162 TkStart = consumeName(SepEnd, REnd);
163 return makeState(PS_InFilenames, TkStart + 1, SepEnd + 1);
164 }
165 case PS_InRootDir:
166 return makeState(PS_InRootName, Path.data(), RStart + 1);
167 case PS_InRootName:
168 case PS_BeforeBegin:
169 __libcpp_unreachable();
170 }
171 }
172
173 /// \brief Return a view with the "preferred representation" of the current
174 /// element. For example trailing separators are represented as a '.'
175 string_view_t operator*() const noexcept {
176 switch (State) {
177 case PS_BeforeBegin:
178 case PS_AtEnd:
179 return PATHSTR("");
180 case PS_InRootDir:
181 if (RawEntry[0] == '\\')
182 return PATHSTR("\\");
183 else
184 return PATHSTR("/");
185 case PS_InTrailingSep:
186 return PATHSTR("");
187 case PS_InRootName:
188 case PS_InFilenames:
189 return RawEntry;
190 }
191 __libcpp_unreachable();
192 }
193
194 explicit operator bool() const noexcept {
195 return State != PS_BeforeBegin && State != PS_AtEnd;
196 }
197
198 PathParser& operator++() noexcept {
199 increment();
200 return *this;
201 }
202
203 PathParser& operator--() noexcept {
204 decrement();
205 return *this;
206 }
207
208 bool atEnd() const noexcept {
209 return State == PS_AtEnd;
210 }
211
212 bool inRootDir() const noexcept {
213 return State == PS_InRootDir;
214 }
215
216 bool inRootName() const noexcept {
217 return State == PS_InRootName;
218 }
219
220 bool inRootPath() const noexcept {
221 return inRootName() || inRootDir();
222 }
223
224private:
225 void makeState(ParserState NewState, PosPtr Start, PosPtr End) noexcept {
226 State = NewState;
227 RawEntry = string_view_t(Start, End - Start);
228 }
229 void makeState(ParserState NewState) noexcept {
230 State = NewState;
231 RawEntry = {};
232 }
233
234 PosPtr getAfterBack() const noexcept { return Path.data() + Path.size(); }
235
236 PosPtr getBeforeFront() const noexcept { return Path.data() - 1; }
237
238 /// \brief Return a pointer to the first character after the currently
239 /// lexed element.
240 PosPtr getNextTokenStartPos() const noexcept {
241 switch (State) {
242 case PS_BeforeBegin:
243 return Path.data();
244 case PS_InRootName:
245 case PS_InRootDir:
246 case PS_InFilenames:
247 return &RawEntry.back() + 1;
248 case PS_InTrailingSep:
249 case PS_AtEnd:
250 return getAfterBack();
251 }
252 __libcpp_unreachable();
253 }
254
255 /// \brief Return a pointer to the first character in the currently lexed
256 /// element.
257 PosPtr getCurrentTokenStartPos() const noexcept {
258 switch (State) {
259 case PS_BeforeBegin:
260 case PS_InRootName:
261 return &Path.front();
262 case PS_InRootDir:
263 case PS_InFilenames:
264 case PS_InTrailingSep:
265 return &RawEntry.front();
266 case PS_AtEnd:
267 return &Path.back() + 1;
268 }
269 __libcpp_unreachable();
270 }
271
272 // Consume all consecutive separators.
273 PosPtr consumeAllSeparators(PosPtr P, PosPtr End) const noexcept {
274 if (P == nullptr || P == End || !isSeparator(*P))
275 return nullptr;
276 const int Inc = P < End ? 1 : -1;
277 P += Inc;
278 while (P != End && isSeparator(*P))
279 P += Inc;
280 return P;
281 }
282
283 // Consume exactly N separators, or return nullptr.
284 PosPtr consumeNSeparators(PosPtr P, PosPtr End, int N) const noexcept {
285 PosPtr Ret = consumeAllSeparators(P, End);
286 if (Ret == nullptr)
287 return nullptr;
288 if (P < End) {
289 if (Ret == P + N)
290 return Ret;
291 } else {
292 if (Ret == P - N)
293 return Ret;
294 }
295 return nullptr;
296 }
297
298 PosPtr consumeName(PosPtr P, PosPtr End) const noexcept {
299 PosPtr Start = P;
300 if (P == nullptr || P == End || isSeparator(*P))
301 return nullptr;
302 const int Inc = P < End ? 1 : -1;
303 P += Inc;
304 while (P != End && !isSeparator(*P))
305 P += Inc;
306 if (P == End && Inc < 0) {
307 // Iterating backwards and consumed all the rest of the input.
308 // Check if the start of the string would have been considered
309 // a root name.
310 PosPtr RootEnd = consumeRootName(End + 1, Start);
311 if (RootEnd)
312 return RootEnd - 1;
313 }
314 return P;
315 }
316
317 PosPtr consumeDriveLetter(PosPtr P, PosPtr End) const noexcept {
318 if (P == End)
319 return nullptr;
320 if (P < End) {
321 if (P + 1 == End || !isDriveLetter(P[0]) || P[1] != ':')
322 return nullptr;
323 return P + 2;
324 } else {
325 if (P - 1 == End || !isDriveLetter(P[-1]) || P[0] != ':')
326 return nullptr;
327 return P - 2;
328 }
329 }
330
331 PosPtr consumeNetworkRoot(PosPtr P, PosPtr End) const noexcept {
332 if (P == End)
333 return nullptr;
334 if (P < End)
335 return consumeName(consumeNSeparators(P, End, 2), End);
336 else
337 return consumeNSeparators(consumeName(P, End), End, 2);
338 }
339
340 PosPtr consumeRootName(PosPtr P, PosPtr End) const noexcept {
341#if defined(_LIBCPP_WIN32API)
342 if (PosPtr Ret = consumeDriveLetter(P, End))
343 return Ret;
344 if (PosPtr Ret = consumeNetworkRoot(P, End))
345 return Ret;
346#endif
347 return nullptr;
348 }
349};
350
351inline string_view_pair separate_filename(string_view_t const& s) {
352 if (s == PATHSTR(".") || s == PATHSTR("..") || s.empty())
353 return string_view_pair{s, PATHSTR("")};
354 auto pos = s.find_last_of('.');
355 if (pos == string_view_t::npos || pos == 0)
356 return string_view_pair{s, string_view_t{}};
357 return string_view_pair{s.substr(0, pos), s.substr(pos)};
358}
359
360inline string_view_t createView(PosPtr S, PosPtr E) noexcept {
361 return {S, static_cast<size_t>(E - S) + 1};
362}
363
364} // namespace parser
365
366_LIBCPP_END_NAMESPACE_FILESYSTEM
367
368#endif // PATH_PARSER_H
lib/libcxx/src/filesystem/posix_compat.h+58-66
......@@ -24,9 +24,11 @@
2424#define POSIX_COMPAT_H
2525
2626#include <__assert>
27#include <__config>
2728#include <filesystem>
2829
29#include "filesystem_common.h"
30#include "error.h"
31#include "time_utils.h"
3032
3133#if defined(_LIBCPP_WIN32API)
3234# define WIN32_LEAN_AND_MEAN
......@@ -35,10 +37,13 @@
3537# include <io.h>
3638# include <winioctl.h>
3739#else
40# include <fcntl.h>
3841# include <unistd.h>
3942# include <sys/stat.h>
4043# include <sys/statvfs.h>
44# include <sys/time.h>
4145#endif
46#include <stdlib.h>
4247#include <time.h>
4348
4449#if defined(_LIBCPP_WIN32API)
......@@ -74,7 +79,6 @@ struct LIBCPP_REPARSE_DATA_BUFFER {
7479_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
7580
7681namespace detail {
77namespace {
7882
7983#if defined(_LIBCPP_WIN32API)
8084
......@@ -118,36 +122,7 @@ namespace {
118122
119123#define O_NONBLOCK 0
120124
121
122// There were 369 years and 89 leap days from the Windows epoch
123// (1601) to the Unix epoch (1970).
124#define FILE_TIME_OFFSET_SECS (uint64_t(369 * 365 + 89) * (24 * 60 * 60))
125
126TimeSpec filetime_to_timespec(LARGE_INTEGER li) {
127 TimeSpec ret;
128 ret.tv_sec = li.QuadPart / 10000000 - FILE_TIME_OFFSET_SECS;
129 ret.tv_nsec = (li.QuadPart % 10000000) * 100;
130 return ret;
131}
132
133TimeSpec filetime_to_timespec(FILETIME ft) {
134 LARGE_INTEGER li;
135 li.LowPart = ft.dwLowDateTime;
136 li.HighPart = ft.dwHighDateTime;
137 return filetime_to_timespec(li);
138}
139
140FILETIME timespec_to_filetime(TimeSpec ts) {
141 LARGE_INTEGER li;
142 li.QuadPart =
143 ts.tv_nsec / 100 + (ts.tv_sec + FILE_TIME_OFFSET_SECS) * 10000000;
144 FILETIME ft;
145 ft.dwLowDateTime = li.LowPart;
146 ft.dwHighDateTime = li.HighPart;
147 return ft;
148}
149
150int set_errno(int e = GetLastError()) {
125inline int set_errno(int e = GetLastError()) {
151126 errno = static_cast<int>(__win_err_to_errc(e));
152127 return -1;
153128}
......@@ -170,7 +145,7 @@ private:
170145 HANDLE h;
171146};
172147
173int stat_handle(HANDLE h, StatT *buf) {
148inline int stat_handle(HANDLE h, StatT *buf) {
174149 FILE_BASIC_INFO basic;
175150 if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
176151 return set_errno();
......@@ -208,7 +183,7 @@ int stat_handle(HANDLE h, StatT *buf) {
208183 return 0;
209184}
210185
211int stat_file(const wchar_t *path, StatT *buf, DWORD flags) {
186inline int stat_file(const wchar_t *path, StatT *buf, DWORD flags) {
212187 WinHandle h(path, FILE_READ_ATTRIBUTES, flags);
213188 if (!h)
214189 return set_errno();
......@@ -216,24 +191,26 @@ int stat_file(const wchar_t *path, StatT *buf, DWORD flags) {
216191 return ret;
217192}
218193
219int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); }
194inline int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); }
220195
221int lstat(const wchar_t *path, StatT *buf) {
196inline int lstat(const wchar_t *path, StatT *buf) {
222197 return stat_file(path, buf, FILE_FLAG_OPEN_REPARSE_POINT);
223198}
224199
225int fstat(int fd, StatT *buf) {
200inline int fstat(int fd, StatT *buf) {
226201 HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
227202 return stat_handle(h, buf);
228203}
229204
230int mkdir(const wchar_t *path, int permissions) {
205inline int mkdir(const wchar_t *path, int permissions) {
231206 (void)permissions;
232 return _wmkdir(path);
207 if (!CreateDirectoryW(path, nullptr))
208 return set_errno();
209 return 0;
233210}
234211
235int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
236 bool is_dir) {
212inline int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
213 bool is_dir) {
237214 path dest(oldname);
238215 dest.make_preferred();
239216 oldname = dest.c_str();
......@@ -249,21 +226,21 @@ int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
249226 return set_errno();
250227}
251228
252int symlink_file(const wchar_t *oldname, const wchar_t *newname) {
229inline int symlink_file(const wchar_t *oldname, const wchar_t *newname) {
253230 return symlink_file_dir(oldname, newname, false);
254231}
255232
256int symlink_dir(const wchar_t *oldname, const wchar_t *newname) {
233inline int symlink_dir(const wchar_t *oldname, const wchar_t *newname) {
257234 return symlink_file_dir(oldname, newname, true);
258235}
259236
260int link(const wchar_t *oldname, const wchar_t *newname) {
237inline int link(const wchar_t *oldname, const wchar_t *newname) {
261238 if (CreateHardLinkW(newname, oldname, nullptr))
262239 return 0;
263240 return set_errno();
264241}
265242
266int remove(const wchar_t *path) {
243inline int remove(const wchar_t *path) {
267244 detail::WinHandle h(path, DELETE, FILE_FLAG_OPEN_REPARSE_POINT);
268245 if (!h)
269246 return set_errno();
......@@ -274,7 +251,7 @@ int remove(const wchar_t *path) {
274251 return 0;
275252}
276253
277int truncate_handle(HANDLE h, off_t length) {
254inline int truncate_handle(HANDLE h, off_t length) {
278255 LARGE_INTEGER size_param;
279256 size_param.QuadPart = length;
280257 if (!SetFilePointerEx(h, size_param, 0, FILE_BEGIN))
......@@ -284,19 +261,19 @@ int truncate_handle(HANDLE h, off_t length) {
284261 return 0;
285262}
286263
287int ftruncate(int fd, off_t length) {
264inline int ftruncate(int fd, off_t length) {
288265 HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
289266 return truncate_handle(h, length);
290267}
291268
292int truncate(const wchar_t *path, off_t length) {
269inline int truncate(const wchar_t *path, off_t length) {
293270 detail::WinHandle h(path, GENERIC_WRITE, 0);
294271 if (!h)
295272 return set_errno();
296273 return truncate_handle(h, length);
297274}
298275
299int rename(const wchar_t *from, const wchar_t *to) {
276inline int rename(const wchar_t *from, const wchar_t *to) {
300277 if (!(MoveFileExW(from, to,
301278 MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING |
302279 MOVEFILE_WRITE_THROUGH)))
......@@ -304,11 +281,11 @@ int rename(const wchar_t *from, const wchar_t *to) {
304281 return 0;
305282}
306283
307template <class... Args> int open(const wchar_t *filename, Args... args) {
308 return _wopen(filename, args...);
284inline int chdir(const wchar_t* path) {
285 if (!SetCurrentDirectoryW(path))
286 return set_errno();
287 return 0;
309288}
310int close(int fd) { return _close(fd); }
311int chdir(const wchar_t *path) { return _wchdir(path); }
312289
313290struct StatVFS {
314291 uint64_t f_frsize;
......@@ -317,7 +294,7 @@ struct StatVFS {
317294 uint64_t f_bavail;
318295};
319296
320int statvfs(const wchar_t *p, StatVFS *buf) {
297inline int statvfs(const wchar_t *p, StatVFS *buf) {
321298 path dir = p;
322299 while (true) {
323300 error_code local_ec;
......@@ -343,11 +320,29 @@ int statvfs(const wchar_t *p, StatVFS *buf) {
343320 return 0;
344321}
345322
346wchar_t *getcwd(wchar_t *buff, size_t size) { return _wgetcwd(buff, size); }
323inline wchar_t* getcwd([[maybe_unused]] wchar_t* in_buf, [[maybe_unused]] size_t in_size) {
324 // Only expected to be used with us allocating the buffer.
325 _LIBCPP_ASSERT(in_buf == nullptr, "Windows getcwd() assumes in_buf==nullptr");
326 _LIBCPP_ASSERT(in_size == 0, "Windows getcwd() assumes in_size==0");
327
328 size_t buff_size = MAX_PATH + 10;
329 std::unique_ptr<wchar_t, decltype(&::free)> buff(static_cast<wchar_t*>(malloc(buff_size * sizeof(wchar_t))), &::free);
330 DWORD retval = GetCurrentDirectoryW(buff_size, buff.get());
331 if (retval > buff_size) {
332 buff_size = retval;
333 buff.reset(static_cast<wchar_t*>(malloc(buff_size * sizeof(wchar_t))));
334 retval = GetCurrentDirectoryW(buff_size, buff.get());
335 }
336 if (!retval) {
337 set_errno();
338 return nullptr;
339 }
340 return buff.release();
341}
347342
348wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) {
343inline wchar_t *realpath(const wchar_t *path, [[maybe_unused]] wchar_t *resolved_name) {
349344 // Only expected to be used with us allocating the buffer.
350 _LIBCPP_ASSERT(resolved_name == nullptr,
345 _LIBCPP_ASSERT_UNCATEGORIZED(resolved_name == nullptr,
351346 "Windows realpath() assumes a null resolved_name");
352347
353348 WinHandle h(path, FILE_READ_ATTRIBUTES, 0);
......@@ -386,7 +381,7 @@ wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) {
386381#define AT_SYMLINK_NOFOLLOW 1
387382using ModeT = int;
388383
389int fchmod_handle(HANDLE h, int perms) {
384inline int fchmod_handle(HANDLE h, int perms) {
390385 FILE_BASIC_INFO basic;
391386 if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
392387 return set_errno();
......@@ -400,7 +395,7 @@ int fchmod_handle(HANDLE h, int perms) {
400395 return 0;
401396}
402397
403int fchmodat(int fd, const wchar_t *path, int perms, int flag) {
398inline int fchmodat(int /*fd*/, const wchar_t *path, int perms, int flag) {
404399 DWORD attributes = GetFileAttributesW(path);
405400 if (attributes == INVALID_FILE_ATTRIBUTES)
406401 return set_errno();
......@@ -427,7 +422,7 @@ int fchmodat(int fd, const wchar_t *path, int perms, int flag) {
427422 return 0;
428423}
429424
430int fchmod(int fd, int perms) {
425inline int fchmod(int fd, int perms) {
431426 HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
432427 return fchmod_handle(h, perms);
433428}
......@@ -435,7 +430,7 @@ int fchmod(int fd, int perms) {
435430#define MAX_SYMLINK_SIZE MAXIMUM_REPARSE_DATA_BUFFER_SIZE
436431using SSizeT = ::int64_t;
437432
438SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) {
433inline SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) {
439434 uint8_t buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
440435 detail::WinHandle h(path, FILE_READ_ATTRIBUTES, FILE_FLAG_OPEN_REPARSE_POINT);
441436 if (!h)
......@@ -479,14 +474,13 @@ SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) {
479474}
480475
481476#else
482int symlink_file(const char *oldname, const char *newname) {
477inline int symlink_file(const char *oldname, const char *newname) {
483478 return ::symlink(oldname, newname);
484479}
485int symlink_dir(const char *oldname, const char *newname) {
480inline int symlink_dir(const char *oldname, const char *newname) {
486481 return ::symlink(oldname, newname);
487482}
488483using ::chdir;
489using ::close;
490484using ::fchmod;
491485#if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD)
492486using ::fchmodat;
......@@ -497,7 +491,6 @@ using ::getcwd;
497491using ::link;
498492using ::lstat;
499493using ::mkdir;
500using ::open;
501494using ::readlink;
502495using ::realpath;
503496using ::remove;
......@@ -514,7 +507,6 @@ using SSizeT = ::ssize_t;
514507
515508#endif
516509
517} // namespace
518510} // end namespace detail
519511
520512_LIBCPP_END_NAMESPACE_FILESYSTEM
lib/libcxx/src/filesystem/time_utils.h created+385
......@@ -0,0 +1,385 @@
1//===----------------------------------------------------------------------===////
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===////
8
9#ifndef FILESYSTEM_TIME_UTILS_H
10#define FILESYSTEM_TIME_UTILS_H
11
12#include <__config>
13#include <array>
14#include <chrono>
15#include <filesystem>
16#include <limits>
17#include <ratio>
18#include <system_error>
19#include <type_traits>
20#include <utility>
21
22#include "error.h"
23#include "format_string.h"
24
25#if defined(_LIBCPP_WIN32API)
26# define WIN32_LEAN_AND_MEAN
27# define NOMINMAX
28# include <windows.h>
29#else
30# include <fcntl.h>
31# include <sys/stat.h>
32# include <sys/time.h> // for ::utimes as used in __last_write_time
33#endif
34
35// We can use the presence of UTIME_OMIT to detect platforms that provide utimensat.
36#if defined(UTIME_OMIT)
37# define _LIBCPP_USE_UTIMENSAT
38#endif
39
40_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
41
42namespace detail {
43
44#if defined(_LIBCPP_WIN32API)
45// Various C runtime versions (UCRT, or the legacy msvcrt.dll used by
46// some mingw toolchains) provide different stat function implementations,
47// with a number of limitations with respect to what we want from the
48// stat function. Instead provide our own which does exactly what we want,
49// along with our own stat structure and flag macros.
50
51struct TimeSpec {
52 int64_t tv_sec;
53 int64_t tv_nsec;
54};
55struct StatT {
56 unsigned st_mode;
57 TimeSpec st_atim;
58 TimeSpec st_mtim;
59 uint64_t st_dev; // FILE_ID_INFO::VolumeSerialNumber
60 struct FileIdStruct {
61 unsigned char id[16]; // FILE_ID_INFO::FileId
62 bool operator==(const FileIdStruct &other) const {
63 for (int i = 0; i < 16; i++)
64 if (id[i] != other.id[i])
65 return false;
66 return true;
67 }
68 } st_ino;
69 uint32_t st_nlink;
70 uintmax_t st_size;
71};
72
73// There were 369 years and 89 leap days from the Windows epoch
74// (1601) to the Unix epoch (1970).
75#define FILE_TIME_OFFSET_SECS (uint64_t(369 * 365 + 89) * (24 * 60 * 60))
76
77inline TimeSpec filetime_to_timespec(LARGE_INTEGER li) {
78 TimeSpec ret;
79 ret.tv_sec = li.QuadPart / 10000000 - FILE_TIME_OFFSET_SECS;
80 ret.tv_nsec = (li.QuadPart % 10000000) * 100;
81 return ret;
82}
83
84inline TimeSpec filetime_to_timespec(FILETIME ft) {
85 LARGE_INTEGER li;
86 li.LowPart = ft.dwLowDateTime;
87 li.HighPart = ft.dwHighDateTime;
88 return filetime_to_timespec(li);
89}
90
91inline FILETIME timespec_to_filetime(TimeSpec ts) {
92 LARGE_INTEGER li;
93 li.QuadPart =
94 ts.tv_nsec / 100 + (ts.tv_sec + FILE_TIME_OFFSET_SECS) * 10000000;
95 FILETIME ft;
96 ft.dwLowDateTime = li.LowPart;
97 ft.dwHighDateTime = li.HighPart;
98 return ft;
99}
100
101#else
102using TimeSpec = struct timespec;
103using TimeVal = struct timeval;
104using StatT = struct stat;
105
106inline TimeVal make_timeval(TimeSpec const& ts) {
107 using namespace chrono;
108 auto Convert = [](long nsec) {
109 using int_type = decltype(std::declval<TimeVal>().tv_usec);
110 auto dur = duration_cast<microseconds>(nanoseconds(nsec)).count();
111 return static_cast<int_type>(dur);
112 };
113 TimeVal TV = {};
114 TV.tv_sec = ts.tv_sec;
115 TV.tv_usec = Convert(ts.tv_nsec);
116 return TV;
117}
118#endif
119
120using chrono::duration;
121using chrono::duration_cast;
122
123template <class FileTimeT, class TimeT,
124 bool IsFloat = is_floating_point<typename FileTimeT::rep>::value>
125struct time_util_base {
126 using rep = typename FileTimeT::rep;
127 using fs_duration = typename FileTimeT::duration;
128 using fs_seconds = duration<rep>;
129 using fs_nanoseconds = duration<rep, nano>;
130 using fs_microseconds = duration<rep, micro>;
131
132 static constexpr rep max_seconds =
133 duration_cast<fs_seconds>(FileTimeT::duration::max()).count();
134
135 static constexpr rep max_nsec =
136 duration_cast<fs_nanoseconds>(FileTimeT::duration::max() -
137 fs_seconds(max_seconds))
138 .count();
139
140 static constexpr rep min_seconds =
141 duration_cast<fs_seconds>(FileTimeT::duration::min()).count();
142
143 static constexpr rep min_nsec_timespec =
144 duration_cast<fs_nanoseconds>(
145 (FileTimeT::duration::min() - fs_seconds(min_seconds)) +
146 fs_seconds(1))
147 .count();
148
149private:
150 static _LIBCPP_CONSTEXPR fs_duration get_min_nsecs() {
151 return duration_cast<fs_duration>(
152 fs_nanoseconds(min_nsec_timespec) -
153 duration_cast<fs_nanoseconds>(fs_seconds(1)));
154 }
155 // Static assert that these values properly round trip.
156 static_assert(fs_seconds(min_seconds) + get_min_nsecs() ==
157 FileTimeT::duration::min(),
158 "value doesn't roundtrip");
159
160 static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool check_range() {
161 // This kinda sucks, but it's what happens when we don't have __int128_t.
162 if (sizeof(TimeT) == sizeof(rep)) {
163 typedef duration<long long, ratio<3600 * 24 * 365> > Years;
164 return duration_cast<Years>(fs_seconds(max_seconds)) > Years(250) &&
165 duration_cast<Years>(fs_seconds(min_seconds)) < Years(-250);
166 }
167 return max_seconds >= numeric_limits<TimeT>::max() &&
168 min_seconds <= numeric_limits<TimeT>::min();
169 }
170#if _LIBCPP_STD_VER >= 14
171 static_assert(check_range(), "the representable range is unacceptable small");
172#endif
173};
174
175template <class FileTimeT, class TimeT>
176struct time_util_base<FileTimeT, TimeT, true> {
177 using rep = typename FileTimeT::rep;
178 using fs_duration = typename FileTimeT::duration;
179 using fs_seconds = duration<rep>;
180 using fs_nanoseconds = duration<rep, nano>;
181 using fs_microseconds = duration<rep, micro>;
182
183 static const rep max_seconds;
184 static const rep max_nsec;
185 static const rep min_seconds;
186 static const rep min_nsec_timespec;
187};
188
189template <class FileTimeT, class TimeT>
190const typename FileTimeT::rep
191 time_util_base<FileTimeT, TimeT, true>::max_seconds =
192 duration_cast<fs_seconds>(FileTimeT::duration::max()).count();
193
194template <class FileTimeT, class TimeT>
195const typename FileTimeT::rep time_util_base<FileTimeT, TimeT, true>::max_nsec =
196 duration_cast<fs_nanoseconds>(FileTimeT::duration::max() -
197 fs_seconds(max_seconds))
198 .count();
199
200template <class FileTimeT, class TimeT>
201const typename FileTimeT::rep
202 time_util_base<FileTimeT, TimeT, true>::min_seconds =
203 duration_cast<fs_seconds>(FileTimeT::duration::min()).count();
204
205template <class FileTimeT, class TimeT>
206const typename FileTimeT::rep
207 time_util_base<FileTimeT, TimeT, true>::min_nsec_timespec =
208 duration_cast<fs_nanoseconds>((FileTimeT::duration::min() -
209 fs_seconds(min_seconds)) +
210 fs_seconds(1))
211 .count();
212
213template <class FileTimeT, class TimeT, class TimeSpecT>
214struct time_util : time_util_base<FileTimeT, TimeT> {
215 using Base = time_util_base<FileTimeT, TimeT>;
216 using Base::max_nsec;
217 using Base::max_seconds;
218 using Base::min_nsec_timespec;
219 using Base::min_seconds;
220
221 using typename Base::fs_duration;
222 using typename Base::fs_microseconds;
223 using typename Base::fs_nanoseconds;
224 using typename Base::fs_seconds;
225
226public:
227 template <class CType, class ChronoType>
228 static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool checked_set(CType* out,
229 ChronoType time) {
230 using Lim = numeric_limits<CType>;
231 if (time > Lim::max() || time < Lim::min())
232 return false;
233 *out = static_cast<CType>(time);
234 return true;
235 }
236
237 static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool is_representable(TimeSpecT tm) {
238 if (tm.tv_sec >= 0) {
239 return tm.tv_sec < max_seconds ||
240 (tm.tv_sec == max_seconds && tm.tv_nsec <= max_nsec);
241 } else if (tm.tv_sec == (min_seconds - 1)) {
242 return tm.tv_nsec >= min_nsec_timespec;
243 } else {
244 return tm.tv_sec >= min_seconds;
245 }
246 }
247
248 static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool is_representable(FileTimeT tm) {
249 auto secs = duration_cast<fs_seconds>(tm.time_since_epoch());
250 auto nsecs = duration_cast<fs_nanoseconds>(tm.time_since_epoch() - secs);
251 if (nsecs.count() < 0) {
252 secs = secs + fs_seconds(1);
253 nsecs = nsecs + fs_seconds(1);
254 }
255 using TLim = numeric_limits<TimeT>;
256 if (secs.count() >= 0)
257 return secs.count() <= TLim::max();
258 return secs.count() >= TLim::min();
259 }
260
261 static _LIBCPP_CONSTEXPR_SINCE_CXX14 FileTimeT
262 convert_from_timespec(TimeSpecT tm) {
263 if (tm.tv_sec >= 0 || tm.tv_nsec == 0) {
264 return FileTimeT(fs_seconds(tm.tv_sec) +
265 duration_cast<fs_duration>(fs_nanoseconds(tm.tv_nsec)));
266 } else { // tm.tv_sec < 0
267 auto adj_subsec = duration_cast<fs_duration>(fs_seconds(1) -
268 fs_nanoseconds(tm.tv_nsec));
269 auto Dur = fs_seconds(tm.tv_sec + 1) - adj_subsec;
270 return FileTimeT(Dur);
271 }
272 }
273
274 template <class SubSecT>
275 static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
276 set_times_checked(TimeT* sec_out, SubSecT* subsec_out, FileTimeT tp) {
277 auto dur = tp.time_since_epoch();
278 auto sec_dur = duration_cast<fs_seconds>(dur);
279 auto subsec_dur = duration_cast<fs_nanoseconds>(dur - sec_dur);
280 // The tv_nsec and tv_usec fields must not be negative so adjust accordingly
281 if (subsec_dur.count() < 0) {
282 if (sec_dur.count() > min_seconds) {
283 sec_dur = sec_dur - fs_seconds(1);
284 subsec_dur = subsec_dur + fs_seconds(1);
285 } else {
286 subsec_dur = fs_nanoseconds::zero();
287 }
288 }
289 return checked_set(sec_out, sec_dur.count()) &&
290 checked_set(subsec_out, subsec_dur.count());
291 }
292 static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool convert_to_timespec(TimeSpecT& dest,
293 FileTimeT tp) {
294 if (!is_representable(tp))
295 return false;
296 return set_times_checked(&dest.tv_sec, &dest.tv_nsec, tp);
297 }
298};
299
300#if defined(_LIBCPP_WIN32API)
301using fs_time = time_util<file_time_type, int64_t, TimeSpec>;
302#else
303using fs_time = time_util<file_time_type, time_t, TimeSpec>;
304#endif
305
306#if defined(__APPLE__)
307inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
308inline TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; }
309#elif defined(__MVS__)
310inline TimeSpec extract_mtime(StatT const& st) {
311 TimeSpec TS = {st.st_mtime, 0};
312 return TS;
313}
314inline TimeSpec extract_atime(StatT const& st) {
315 TimeSpec TS = {st.st_atime, 0};
316 return TS;
317}
318#elif defined(_AIX)
319inline TimeSpec extract_mtime(StatT const& st) {
320 TimeSpec TS = {st.st_mtime, st.st_mtime_n};
321 return TS;
322}
323inline TimeSpec extract_atime(StatT const& st) {
324 TimeSpec TS = {st.st_atime, st.st_atime_n};
325 return TS;
326}
327#else
328inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
329inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
330#endif
331
332#ifndef _LIBCPP_HAS_NO_FILESYSTEM
333
334#if !defined(_LIBCPP_WIN32API)
335inline bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
336 error_code& ec) {
337 TimeVal ConvertedTS[2] = {make_timeval(TS[0]), make_timeval(TS[1])};
338 if (::utimes(p.c_str(), ConvertedTS) == -1) {
339 ec = capture_errno();
340 return true;
341 }
342 return false;
343}
344
345#if defined(_LIBCPP_USE_UTIMENSAT)
346inline bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS,
347 error_code& ec) {
348 if (::utimensat(AT_FDCWD, p.c_str(), TS.data(), 0) == -1) {
349 ec = capture_errno();
350 return true;
351 }
352 return false;
353}
354#endif
355
356inline bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
357 error_code& ec) {
358#if !defined(_LIBCPP_USE_UTIMENSAT)
359 return posix_utimes(p, TS, ec);
360#else
361 return posix_utimensat(p, TS, ec);
362#endif
363}
364
365#endif // !_LIBCPP_WIN32API
366
367inline file_time_type __extract_last_write_time(const path& p, const StatT& st,
368 error_code* ec) {
369 using detail::fs_time;
370 ErrorHandler<file_time_type> err("last_write_time", ec, &p);
371
372 auto ts = detail::extract_mtime(st);
373 if (!fs_time::is_representable(ts))
374 return err.report(errc::value_too_large);
375
376 return fs_time::convert_from_timespec(ts);
377}
378
379#endif // !_LIBCPP_HAS_NO_FILESYSTEM
380
381} // end namespace detail
382
383_LIBCPP_END_NAMESPACE_FILESYSTEM
384
385#endif // FILESYSTEM_TIME_UTILS_H
lib/libcxx/src/format.cpp deleted-17
......@@ -1,17 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <format>
10
11_LIBCPP_BEGIN_NAMESPACE_STD
12
13#ifndef _LIBCPP_INLINE_FORMAT_ERROR_DTOR
14format_error::~format_error() noexcept = default;
15#endif
16
17_LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/future.cpp+2-2
......@@ -197,12 +197,12 @@ promise<void>::~promise()
197197{
198198 if (__state_)
199199 {
200#ifndef _LIBCPP_NO_EXCEPTIONS
200#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
201201 if (!__state_->__has_value() && __state_->use_count() > 1)
202202 __state_->set_exception(make_exception_ptr(
203203 future_error(make_error_code(future_errc::broken_promise))
204204 ));
205#endif // _LIBCPP_NO_EXCEPTIONS
205#endif // _LIBCPP_HAS_NO_EXCEPTIONS
206206 __state_->__release_shared();
207207 }
208208}
lib/libcxx/src/include/apple_availability.h-18
......@@ -11,24 +11,6 @@
1111
1212#if defined(__APPLE__)
1313
14#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
15#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101300
16#define _LIBCPP_USE_UTIMENSAT
17#endif
18#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
19#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 110000
20#define _LIBCPP_USE_UTIMENSAT
21#endif
22#elif defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__)
23#if __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 110000
24#define _LIBCPP_USE_UTIMENSAT
25#endif
26#elif defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__)
27#if __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 40000
28#define _LIBCPP_USE_UTIMENSAT
29#endif
30#endif // __ENVIRONMENT_.*_VERSION_MIN_REQUIRED__
31
3214#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
3315#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500
3416#define _LIBCPP_USE_ULOCK
lib/libcxx/src/include/config_elast.h-2
......@@ -35,8 +35,6 @@
3535#define _LIBCPP_ELAST 4095
3636#elif defined(__APPLE__)
3737// No _LIBCPP_ELAST needed on Apple
38#elif defined(__sun__)
39#define _LIBCPP_ELAST ESTALE
4038#elif defined(__MVS__)
4139#define _LIBCPP_ELAST 1160
4240#elif defined(_LIBCPP_MSVCRT_LIKE)
lib/libcxx/src/include/ryu/common.h+11-10
......@@ -43,7 +43,8 @@
4343// clang-format off
4444
4545#include <__assert>
46#include "__config"
46#include <__config>
47#include <cstring>
4748
4849_LIBCPP_BEGIN_NAMESPACE_STD
4950
......@@ -51,7 +52,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
5152 // Function precondition: __v is not a 10-digit number.
5253 // (f2s: 9 digits are sufficient for round-tripping.)
5354 // (d2fixed: We print 9-digit blocks.)
54 _LIBCPP_ASSERT(__v < 1000000000, "");
55 _LIBCPP_ASSERT_UNCATEGORIZED(__v < 1000000000, "");
5556 if (__v >= 100000000) { return 9; }
5657 if (__v >= 10000000) { return 8; }
5758 if (__v >= 1000000) { return 7; }
......@@ -68,36 +69,36 @@ _LIBCPP_BEGIN_NAMESPACE_STD
6869 // This approximation works up to the point that the multiplication overflows at __e = 3529.
6970 // If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater
7071 // than 2^9297.
71 _LIBCPP_ASSERT(__e >= 0, "");
72 _LIBCPP_ASSERT(__e <= 3528, "");
72 _LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, "");
73 _LIBCPP_ASSERT_UNCATEGORIZED(__e <= 3528, "");
7374 return static_cast<int32_t>(((static_cast<uint32_t>(__e) * 1217359) >> 19) + 1);
7475}
7576
7677// Returns floor(log_10(2^__e)).
7778[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __log10Pow2(const int32_t __e) {
7879 // The first value this approximation fails for is 2^1651 which is just greater than 10^297.
79 _LIBCPP_ASSERT(__e >= 0, "");
80 _LIBCPP_ASSERT(__e <= 1650, "");
80 _LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, "");
81 _LIBCPP_ASSERT_UNCATEGORIZED(__e <= 1650, "");
8182 return (static_cast<uint32_t>(__e) * 78913) >> 18;
8283}
8384
8485// Returns floor(log_10(5^__e)).
8586[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __log10Pow5(const int32_t __e) {
8687 // The first value this approximation fails for is 5^2621 which is just greater than 10^1832.
87 _LIBCPP_ASSERT(__e >= 0, "");
88 _LIBCPP_ASSERT(__e <= 2620, "");
88 _LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, "");
89 _LIBCPP_ASSERT_UNCATEGORIZED(__e <= 2620, "");
8990 return (static_cast<uint32_t>(__e) * 732923) >> 20;
9091}
9192
9293[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __float_to_bits(const float __f) {
9394 uint32_t __bits = 0;
94 _VSTD::memcpy(&__bits, &__f, sizeof(float));
95 std::memcpy(&__bits, &__f, sizeof(float));
9596 return __bits;
9697}
9798
9899[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __double_to_bits(const double __d) {
99100 uint64_t __bits = 0;
100 _VSTD::memcpy(&__bits, &__d, sizeof(double));
101 std::memcpy(&__bits, &__d, sizeof(double));
101102 return __bits;
102103}
103104
lib/libcxx/src/include/ryu/d2s_intrinsics.h+8-8
......@@ -63,7 +63,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
6363 // (The shift value is in the range [49, 58].)
6464 // Check this here in case a future change requires larger shift
6565 // values. In this case this function needs to be adjusted.
66 _LIBCPP_ASSERT(__dist < 64, "");
66 _LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, "");
6767 return __shiftright128(__lo, __hi, static_cast<unsigned char>(__dist));
6868}
6969
......@@ -85,7 +85,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
8585 // (The shift value is in the range [49, 58].)
8686 // Check this here in case a future change requires larger shift
8787 // values. In this case this function needs to be adjusted.
88 _LIBCPP_ASSERT(__dist < 64, "");
88 _LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, "");
8989 auto __temp = __lo | ((unsigned __int128)__hi << 64);
9090 // For x64 128-bit shfits using the `shrd` instruction and two 64-bit
9191 // registers, the shift value is modulo 64. Thus the `& 63` is free.
......@@ -126,13 +126,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
126126
127127[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __ryu_shiftright128(const uint64_t __lo, const uint64_t __hi, const uint32_t __dist) {
128128 // We don't need to handle the case __dist >= 64 here (see above).
129 _LIBCPP_ASSERT(__dist < 64, "");
129 _LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, "");
130130#ifdef _LIBCPP_64_BIT
131 _LIBCPP_ASSERT(__dist > 0, "");
131 _LIBCPP_ASSERT_UNCATEGORIZED(__dist > 0, "");
132132 return (__hi << (64 - __dist)) | (__lo >> __dist);
133133#else // ^^^ 64-bit ^^^ / vvv 32-bit vvv
134134 // Avoid a 64-bit shift by taking advantage of the range of shift values.
135 _LIBCPP_ASSERT(__dist >= 32, "");
135 _LIBCPP_ASSERT_UNCATEGORIZED(__dist >= 32, "");
136136 return (__hi << (64 - __dist)) | (static_cast<uint32_t>(__lo >> 32) >> (__dist - 32));
137137#endif // ^^^ 32-bit ^^^
138138}
......@@ -227,7 +227,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
227227[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow5Factor(uint64_t __value) {
228228 uint32_t __count = 0;
229229 for (;;) {
230 _LIBCPP_ASSERT(__value != 0, "");
230 _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
231231 const uint64_t __q = __div5(__value);
232232 const uint32_t __r = static_cast<uint32_t>(__value) - 5 * static_cast<uint32_t>(__q);
233233 if (__r != 0) {
......@@ -247,8 +247,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
247247
248248// Returns true if __value is divisible by 2^__p.
249249[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf2(const uint64_t __value, const uint32_t __p) {
250 _LIBCPP_ASSERT(__value != 0, "");
251 _LIBCPP_ASSERT(__p < 64, "");
250 _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
251 _LIBCPP_ASSERT_UNCATEGORIZED(__p < 64, "");
252252 // __builtin_ctzll doesn't appear to be faster here.
253253 return (__value & ((1ull << __p) - 1)) == 0;
254254}
lib/libcxx/src/include/ryu/ryu.h+1-2
......@@ -47,8 +47,7 @@
4747#include <__charconv/chars_format.h>
4848#include <__charconv/to_chars_result.h>
4949#include <__config>
50#include <__debug>
51#include <__errc>
50#include <__system_error/errc.h>
5251#include <cstdint>
5352#include <cstring>
5453#include <type_traits>
lib/libcxx/src/include/to_chars_floating_point.h+12-12
......@@ -269,7 +269,7 @@ to_chars_result _Floating_to_chars_hex_precision(
269269 // * Print the leading hexit, then mask it away.
270270 {
271271 const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Adjusted_explicit_bits);
272 _LIBCPP_ASSERT(_Nibble < 3, "");
272 _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 3, "");
273273 const char _Leading_hexit = static_cast<char>('0' + _Nibble);
274274
275275 *_First++ = _Leading_hexit;
......@@ -288,12 +288,12 @@ to_chars_result _Floating_to_chars_hex_precision(
288288 int32_t _Number_of_bits_remaining = _Adjusted_explicit_bits; // 24 for float, 52 for double
289289
290290 for (;;) {
291 _LIBCPP_ASSERT(_Number_of_bits_remaining >= 4, "");
292 _LIBCPP_ASSERT(_Number_of_bits_remaining % 4 == 0, "");
291 _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining >= 4, "");
292 _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining % 4 == 0, "");
293293 _Number_of_bits_remaining -= 4;
294294
295295 const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Number_of_bits_remaining);
296 _LIBCPP_ASSERT(_Nibble < 16, "");
296 _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 16, "");
297297 const char _Hexit = __itoa::_Charconv_digits[_Nibble];
298298
299299 *_First++ = _Hexit;
......@@ -415,12 +415,12 @@ to_chars_result _Floating_to_chars_hex_shortest(
415415 // '0' hexits, the same condition works (as we print the final hexit and mask it away); we don't need to test
416416 // _Number_of_bits_remaining.
417417 do {
418 _LIBCPP_ASSERT(_Number_of_bits_remaining >= 4, "");
419 _LIBCPP_ASSERT(_Number_of_bits_remaining % 4 == 0, "");
418 _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining >= 4, "");
419 _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining % 4 == 0, "");
420420 _Number_of_bits_remaining -= 4;
421421
422422 const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Number_of_bits_remaining);
423 _LIBCPP_ASSERT(_Nibble < 16, "");
423 _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 16, "");
424424 const char _Hexit = __itoa::_Charconv_digits[_Nibble];
425425
426426 if (_First == _Last) {
......@@ -940,13 +940,13 @@ to_chars_result _Floating_to_chars_general_precision(
940940 _Effective_precision = _VSTD::min(_Precision - (_Scientific_exponent_X + 1), _Max_fixed_precision);
941941 const to_chars_result _Buf_result =
942942 _Floating_to_chars_fixed_precision(_Buffer, _VSTD::end(_Buffer), _Value, _Effective_precision);
943 _LIBCPP_ASSERT(_Buf_result.ec == errc{}, "");
943 _LIBCPP_ASSERT_UNCATEGORIZED(_Buf_result.ec == errc{}, "");
944944 _Significand_last = _Buf_result.ptr;
945945 } else {
946946 _Effective_precision = _VSTD::min(_Precision - 1, _Max_scientific_precision);
947947 const to_chars_result _Buf_result =
948948 _Floating_to_chars_scientific_precision(_Buffer, _VSTD::end(_Buffer), _Value, _Effective_precision);
949 _LIBCPP_ASSERT(_Buf_result.ec == errc{}, "");
949 _LIBCPP_ASSERT_UNCATEGORIZED(_Buf_result.ec == errc{}, "");
950950 _Significand_last = _VSTD::find(_Buffer, _Buf_result.ptr, 'e');
951951 _Exponent_first = _Significand_last;
952952 _Exponent_last = _Buf_result.ptr;
......@@ -992,10 +992,10 @@ to_chars_result _Floating_to_chars(
992992 char* _First, char* const _Last, _Floating _Value, const chars_format _Fmt, const int _Precision) noexcept {
993993
994994 if constexpr (_Overload == _Floating_to_chars_overload::_Plain) {
995 _LIBCPP_ASSERT(_Fmt == chars_format{}, ""); // plain overload must pass chars_format{} internally
995 _LIBCPP_ASSERT_UNCATEGORIZED(_Fmt == chars_format{}, ""); // plain overload must pass chars_format{} internally
996996 } else {
997 _LIBCPP_ASSERT(_Fmt == chars_format::general || _Fmt == chars_format::scientific || _Fmt == chars_format::fixed
998 || _Fmt == chars_format::hex,
997 _LIBCPP_ASSERT_UNCATEGORIZED(_Fmt == chars_format::general || _Fmt == chars_format::scientific
998 || _Fmt == chars_format::fixed || _Fmt == chars_format::hex,
999999 "invalid format in to_chars()");
10001000 }
10011001
lib/libcxx/src/ios.cpp+4-4
......@@ -413,20 +413,20 @@ void
413413ios_base::__set_badbit_and_consider_rethrow()
414414{
415415 __rdstate_ |= badbit;
416#ifndef _LIBCPP_NO_EXCEPTIONS
416#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
417417 if (__exceptions_ & badbit)
418418 throw;
419#endif // _LIBCPP_NO_EXCEPTIONS
419#endif // _LIBCPP_HAS_NO_EXCEPTIONS
420420}
421421
422422void
423423ios_base::__set_failbit_and_consider_rethrow()
424424{
425425 __rdstate_ |= failbit;
426#ifndef _LIBCPP_NO_EXCEPTIONS
426#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
427427 if (__exceptions_ & failbit)
428428 throw;
429#endif // _LIBCPP_NO_EXCEPTIONS
429#endif // _LIBCPP_HAS_NO_EXCEPTIONS
430430}
431431
432432bool
lib/libcxx/src/ios.instantiations.cpp+1-1
......@@ -37,7 +37,7 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringstream<char>
3737template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostringstream<char>;
3838template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istringstream<char>;
3939
40#ifndef _LIBCPP_HAS_NO_FSTREAM
40#ifndef _LIBCPP_HAS_NO_FILESYSTEM
4141template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ifstream<char>;
4242template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ofstream<char>;
4343template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_filebuf<char>;
lib/libcxx/src/iostream.cpp+13-9
......@@ -7,17 +7,21 @@
77//===----------------------------------------------------------------------===//
88
99#include <__locale>
10#include <__std_stream>
10#include "std_stream.h"
1111#include <new>
1212#include <string>
1313
14#ifdef _LIBCPP_MSVCRT_LIKE
15# include <__locale_dir/locale_base_api/locale_guard.h>
16#endif
17
1418#define _str(s) #s
1519#define str(s) _str(s)
1620#define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE)
1721
1822_LIBCPP_BEGIN_NAMESPACE_STD
1923
20_ALIGNAS_TYPE (istream) _LIBCPP_FUNC_VIS char cin[sizeof(istream)]
24_ALIGNAS_TYPE (istream) _LIBCPP_EXPORTED_FROM_ABI char cin[sizeof(istream)]
2125#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
2226__asm__("?cin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
2327#endif
......@@ -26,7 +30,7 @@ _ALIGNAS_TYPE (__stdinbuf<char> ) static char __cin[sizeof(__stdinbuf <char>)];
2630static mbstate_t mb_cin;
2731
2832#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
29_ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin[sizeof(wistream)]
33_ALIGNAS_TYPE (wistream) _LIBCPP_EXPORTED_FROM_ABI char wcin[sizeof(wistream)]
3034#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
3135__asm__("?wcin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
3236#endif
......@@ -35,7 +39,7 @@ _ALIGNAS_TYPE (__stdinbuf<wchar_t> ) static char __wcin[sizeof(__stdinbuf <wchar
3539static mbstate_t mb_wcin;
3640#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3741
38_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cout[sizeof(ostream)]
42_ALIGNAS_TYPE (ostream) _LIBCPP_EXPORTED_FROM_ABI char cout[sizeof(ostream)]
3943#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
4044__asm__("?cout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
4145#endif
......@@ -44,7 +48,7 @@ _ALIGNAS_TYPE (__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)];
4448static mbstate_t mb_cout;
4549
4650#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
47_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcout[sizeof(wostream)]
51_ALIGNAS_TYPE (wostream) _LIBCPP_EXPORTED_FROM_ABI char wcout[sizeof(wostream)]
4852#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
4953__asm__("?wcout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
5054#endif
......@@ -53,7 +57,7 @@ _ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wcha
5357static mbstate_t mb_wcout;
5458#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5559
56_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)]
60_ALIGNAS_TYPE (ostream) _LIBCPP_EXPORTED_FROM_ABI char cerr[sizeof(ostream)]
5761#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
5862__asm__("?cerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
5963#endif
......@@ -62,7 +66,7 @@ _ALIGNAS_TYPE (__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)];
6266static mbstate_t mb_cerr;
6367
6468#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
65_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcerr[sizeof(wostream)]
69_ALIGNAS_TYPE (wostream) _LIBCPP_EXPORTED_FROM_ABI char wcerr[sizeof(wostream)]
6670#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
6771__asm__("?wcerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
6872#endif
......@@ -71,14 +75,14 @@ _ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wcha
7175static mbstate_t mb_wcerr;
7276#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
7377
74_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char clog[sizeof(ostream)]
78_ALIGNAS_TYPE (ostream) _LIBCPP_EXPORTED_FROM_ABI char clog[sizeof(ostream)]
7579#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
7680__asm__("?clog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
7781#endif
7882;
7983
8084#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
81_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)]
85_ALIGNAS_TYPE (wostream) _LIBCPP_EXPORTED_FROM_ABI char wclog[sizeof(wostream)]
8286#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
8387__asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
8488#endif
lib/libcxx/src/legacy_pointer_safety.cpp+4-4
......@@ -15,9 +15,9 @@
1515
1616_LIBCPP_BEGIN_NAMESPACE_STD
1717
18_LIBCPP_FUNC_VIS void declare_reachable(void*) {}
19_LIBCPP_FUNC_VIS void declare_no_pointers(char*, size_t) {}
20_LIBCPP_FUNC_VIS void undeclare_no_pointers(char*, size_t) {}
21_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* p) { return p; }
18_LIBCPP_EXPORTED_FROM_ABI void declare_reachable(void*) {}
19_LIBCPP_EXPORTED_FROM_ABI void declare_no_pointers(char*, size_t) {}
20_LIBCPP_EXPORTED_FROM_ABI void undeclare_no_pointers(char*, size_t) {}
21_LIBCPP_EXPORTED_FROM_ABI void* __undeclare_reachable(void* p) { return p; }
2222
2323_LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/locale.cpp+31-32
......@@ -6,13 +6,8 @@
66//
77//===----------------------------------------------------------------------===//
88
9// On Solaris, we need to define something to make the C99 parts of localeconv
10// visible.
11#ifdef __sun__
12#define _LCONV_C99
13#endif
14
159#include <__utility/unreachable.h>
10#include <__verbose_abort>
1611#include <algorithm>
1712#include <clocale>
1813#include <codecvt>
......@@ -118,16 +113,27 @@ countof(const T * const begin, const T * const end)
118113
119114_LIBCPP_NORETURN static void __throw_runtime_error(const string &msg)
120115{
121#ifndef _LIBCPP_NO_EXCEPTIONS
116#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
122117 throw runtime_error(msg);
123118#else
124 (void)msg;
125 _VSTD::abort();
119 _LIBCPP_VERBOSE_ABORT("runtime_error was thrown in -fno-exceptions mode with message \"%s\"", msg.c_str());
126120#endif
127121}
128122
129123}
130124
125string
126build_name(const string& other, const string& one, locale::category c) {
127 if (other == "*" || one == "*")
128 return "*";
129 if (c == locale::none || other == one)
130 return other;
131
132 // FIXME: Handle the more complicated cases, such as when the locale has
133 // different names for different categories.
134 return "*";
135}
136
131137const locale::category locale::none;
132138const locale::category locale::collate;
133139const locale::category locale::ctype;
......@@ -236,10 +242,10 @@ locale::__imp::__imp(const string& name, size_t refs)
236242 facets_(N),
237243 name_(name)
238244{
239#ifndef _LIBCPP_NO_EXCEPTIONS
245#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
240246 try
241247 {
242#endif // _LIBCPP_NO_EXCEPTIONS
248#endif // _LIBCPP_HAS_NO_EXCEPTIONS
243249 facets_ = locale::classic().__locale_->facets_;
244250 for (unsigned i = 0; i < facets_.size(); ++i)
245251 if (facets_[i])
......@@ -286,7 +292,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
286292#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
287293 install(new messages_byname<wchar_t>(name_));
288294#endif
289#ifndef _LIBCPP_NO_EXCEPTIONS
295#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
290296 }
291297 catch (...)
292298 {
......@@ -295,7 +301,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
295301 facets_[i]->__release_shared();
296302 throw;
297303 }
298#endif // _LIBCPP_NO_EXCEPTIONS
304#endif // _LIBCPP_HAS_NO_EXCEPTIONS
299305}
300306
301307locale::__imp::__imp(const __imp& other)
......@@ -309,17 +315,16 @@ locale::__imp::__imp(const __imp& other)
309315}
310316
311317locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
312 : facets_(N),
313 name_("*")
318 : facets_(N), name_(build_name(other.name_, name, c))
314319{
315320 facets_ = other.facets_;
316321 for (unsigned i = 0; i < facets_.size(); ++i)
317322 if (facets_[i])
318323 facets_[i]->__add_shared();
319#ifndef _LIBCPP_NO_EXCEPTIONS
324#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
320325 try
321326 {
322#endif // _LIBCPP_NO_EXCEPTIONS
327#endif // _LIBCPP_HAS_NO_EXCEPTIONS
323328 if (c & locale::collate)
324329 {
325330 install(new collate_byname<char>(name));
......@@ -380,7 +385,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
380385 install(new messages_byname<wchar_t>(name));
381386#endif
382387 }
383#ifndef _LIBCPP_NO_EXCEPTIONS
388#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
384389 }
385390 catch (...)
386391 {
......@@ -389,7 +394,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
389394 facets_[i]->__release_shared();
390395 throw;
391396 }
392#endif // _LIBCPP_NO_EXCEPTIONS
397#endif // _LIBCPP_HAS_NO_EXCEPTIONS
393398}
394399
395400template<class F>
......@@ -402,17 +407,16 @@ locale::__imp::install_from(const locale::__imp& one)
402407}
403408
404409locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
405 : facets_(N),
406 name_("*")
410 : facets_(N), name_(build_name(other.name_, one.name_, c))
407411{
408412 facets_ = other.facets_;
409413 for (unsigned i = 0; i < facets_.size(); ++i)
410414 if (facets_[i])
411415 facets_[i]->__add_shared();
412#ifndef _LIBCPP_NO_EXCEPTIONS
416#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
413417 try
414418 {
415#endif // _LIBCPP_NO_EXCEPTIONS
419#endif // _LIBCPP_HAS_NO_EXCEPTIONS
416420 if (c & locale::collate)
417421 {
418422 install_from<_VSTD::collate<char> >(one);
......@@ -489,7 +493,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
489493 install_from<_VSTD::messages<wchar_t> >(one);
490494#endif
491495 }
492#ifndef _LIBCPP_NO_EXCEPTIONS
496#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
493497 }
494498 catch (...)
495499 {
......@@ -498,7 +502,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
498502 facets_[i]->__release_shared();
499503 throw;
500504 }
501#endif // _LIBCPP_NO_EXCEPTIONS
505#endif // _LIBCPP_HAS_NO_EXCEPTIONS
502506}
503507
504508locale::__imp::__imp(const __imp& other, facet* f, long id)
......@@ -1189,8 +1193,6 @@ ctype<char>::classic_table() noexcept
11891193 return _C_ctype_tab_ + 1;
11901194#elif defined(__GLIBC__)
11911195 return _LIBCPP_GET_C_LOCALE->__ctype_b;
1192#elif defined(__sun__)
1193 return __ctype_mask;
11941196#elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
11951197 return __pctype_func();
11961198#elif defined(__EMSCRIPTEN__)
......@@ -1411,10 +1413,8 @@ ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask*
14111413 if (iswxdigit_l(ch, __l_))
14121414 *vec |= xdigit;
14131415#endif
1414#if !defined(__sun__)
14151416 if (iswblank_l(ch, __l_))
14161417 *vec |= blank;
1417#endif
14181418 }
14191419 }
14201420 return low;
......@@ -6529,11 +6529,10 @@ void __do_nothing(void*) {}
65296529
65306530void __throw_runtime_error(const char* msg)
65316531{
6532#ifndef _LIBCPP_NO_EXCEPTIONS
6532#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
65336533 throw runtime_error(msg);
65346534#else
6535 (void)msg;
6536 _VSTD::abort();
6535 _LIBCPP_VERBOSE_ABORT("runtime_error was thrown in -fno-exceptions mode with message \"%s\"", msg);
65376536#endif
65386537}
65396538
lib/libcxx/src/memory.cpp-2
......@@ -25,8 +25,6 @@
2525
2626_LIBCPP_BEGIN_NAMESPACE_STD
2727
28const allocator_arg_t allocator_arg = allocator_arg_t();
29
3028bad_weak_ptr::~bad_weak_ptr() noexcept {}
3129
3230const char*
lib/libcxx/src/memory_resource.cpp+8-7
......@@ -37,7 +37,7 @@ static bool is_aligned_to(void* ptr, size_t align) {
3737}
3838#endif
3939
40class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp : public memory_resource {
40class _LIBCPP_EXPORTED_FROM_ABI __new_delete_memory_resource_imp : public memory_resource {
4141 void* do_allocate(size_t bytes, size_t align) override {
4242#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
4343 return std::__libcpp_allocate(bytes, align);
......@@ -60,7 +60,7 @@ class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp : public memory_resource
6060
6161// null_memory_resource()
6262
63class _LIBCPP_TYPE_VIS __null_memory_resource_imp : public memory_resource {
63class _LIBCPP_EXPORTED_FROM_ABI __null_memory_resource_imp : public memory_resource {
6464 void* do_allocate(size_t, size_t) override { __throw_bad_alloc(); }
6565 void do_deallocate(void*, size_t, size_t) override {}
6666 bool do_is_equal(const memory_resource& other) const noexcept override { return &other == this; }
......@@ -107,7 +107,7 @@ static memory_resource* __default_memory_resource(bool set = false, memory_resou
107107 new_res = new_res ? new_res : new_delete_resource();
108108 lock_guard<mutex> guard(res_lock);
109109 memory_resource* old_res = res;
110 res = new_res;
110 res = new_res;
111111 return old_res;
112112 } else {
113113 lock_guard<mutex> guard(res_lock);
......@@ -175,7 +175,7 @@ void* unsynchronized_pool_resource::__adhoc_pool::__do_allocate(memory_resource*
175175
176176void unsynchronized_pool_resource::__adhoc_pool::__do_deallocate(
177177 memory_resource* upstream, void* p, size_t bytes, size_t align) {
178 _LIBCPP_ASSERT(__first_ != nullptr, "deallocating a block that was not allocated with this allocator");
178 _LIBCPP_ASSERT_UNCATEGORIZED(__first_ != nullptr, "deallocating a block that was not allocated with this allocator");
179179 if (__first_->__start_ == p) {
180180 __chunk_footer* next = __first_->__next_;
181181 upstream->deallocate(p, __first_->__allocation_size(), __first_->__align_);
......@@ -189,7 +189,7 @@ void unsynchronized_pool_resource::__adhoc_pool::__do_deallocate(
189189 return;
190190 }
191191 }
192 _LIBCPP_ASSERT(false, "deallocating a block that was not allocated with this allocator");
192 _LIBCPP_ASSERT_UNCATEGORIZED(false, "deallocating a block that was not allocated with this allocator");
193193 }
194194}
195195
......@@ -230,7 +230,7 @@ public:
230230 }
231231
232232 void* __allocate_in_new_chunk(memory_resource* upstream, size_t block_size, size_t chunk_size) {
233 _LIBCPP_ASSERT(chunk_size % block_size == 0, "");
233 _LIBCPP_ASSERT_UNCATEGORIZED(chunk_size % block_size == 0, "");
234234 static_assert(__default_alignment >= alignof(std::max_align_t), "");
235235 static_assert(__default_alignment >= alignof(__chunk_footer), "");
236236 static_assert(__default_alignment >= alignof(__vacancy_header), "");
......@@ -401,7 +401,8 @@ void unsynchronized_pool_resource::do_deallocate(void* p, size_t bytes, size_t a
401401 if (i == __num_fixed_pools_)
402402 return __adhoc_pool_.__do_deallocate(__res_, p, bytes, align);
403403 else {
404 _LIBCPP_ASSERT(__fixed_pools_ != nullptr, "deallocating a block that was not allocated with this allocator");
404 _LIBCPP_ASSERT_UNCATEGORIZED(
405 __fixed_pools_ != nullptr, "deallocating a block that was not allocated with this allocator");
405406 __fixed_pools_[i].__evacuate(p);
406407 }
407408}
lib/libcxx/src/mutex.cpp+12-16
......@@ -7,9 +7,9 @@
77//===----------------------------------------------------------------------===//
88
99#include <__assert>
10#include <__thread/id.h>
1011#include <limits>
1112#include <mutex>
12#include <system_error>
1313
1414#include "include/atomic_support.h"
1515
......@@ -26,10 +26,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2626
2727#ifndef _LIBCPP_HAS_NO_THREADS
2828
29const defer_lock_t defer_lock{};
30const try_to_lock_t try_to_lock{};
31const adopt_lock_t adopt_lock{};
32
3329// ~mutex is defined elsewhere
3430
3531void
......@@ -51,7 +47,7 @@ mutex::unlock() noexcept
5147{
5248 int ec = __libcpp_mutex_unlock(&__m_);
5349 (void)ec;
54 _LIBCPP_ASSERT(ec == 0, "call to mutex::unlock failed");
50 _LIBCPP_ASSERT_UNCATEGORIZED(ec == 0, "call to mutex::unlock failed");
5551}
5652
5753// recursive_mutex
......@@ -67,7 +63,7 @@ recursive_mutex::~recursive_mutex()
6763{
6864 int e = __libcpp_recursive_mutex_destroy(&__m_);
6965 (void)e;
70 _LIBCPP_ASSERT(e == 0, "call to ~recursive_mutex() failed");
66 _LIBCPP_ASSERT_UNCATEGORIZED(e == 0, "call to ~recursive_mutex() failed");
7167}
7268
7369void
......@@ -83,7 +79,7 @@ recursive_mutex::unlock() noexcept
8379{
8480 int e = __libcpp_recursive_mutex_unlock(&__m_);
8581 (void)e;
86 _LIBCPP_ASSERT(e == 0, "call to recursive_mutex::unlock() failed");
82 _LIBCPP_ASSERT_UNCATEGORIZED(e == 0, "call to recursive_mutex::unlock() failed");
8783}
8884
8985bool
......@@ -211,21 +207,21 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
211207#if defined(_LIBCPP_HAS_NO_THREADS)
212208 if (flag == 0)
213209 {
214#ifndef _LIBCPP_NO_EXCEPTIONS
210#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
215211 try
216212 {
217#endif // _LIBCPP_NO_EXCEPTIONS
213#endif // _LIBCPP_HAS_NO_EXCEPTIONS
218214 flag = 1;
219215 func(arg);
220216 flag = ~once_flag::_State_type(0);
221#ifndef _LIBCPP_NO_EXCEPTIONS
217#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
222218 }
223219 catch (...)
224220 {
225221 flag = 0;
226222 throw;
227223 }
228#endif // _LIBCPP_NO_EXCEPTIONS
224#endif // _LIBCPP_HAS_NO_EXCEPTIONS
229225 }
230226#else // !_LIBCPP_HAS_NO_THREADS
231227 __libcpp_mutex_lock(&mut);
......@@ -233,10 +229,10 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
233229 __libcpp_condvar_wait(&cv, &mut);
234230 if (flag == 0)
235231 {
236#ifndef _LIBCPP_NO_EXCEPTIONS
232#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
237233 try
238234 {
239#endif // _LIBCPP_NO_EXCEPTIONS
235#endif // _LIBCPP_HAS_NO_EXCEPTIONS
240236 __libcpp_relaxed_store(&flag, once_flag::_State_type(1));
241237 __libcpp_mutex_unlock(&mut);
242238 func(arg);
......@@ -245,7 +241,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
245241 _AO_Release);
246242 __libcpp_mutex_unlock(&mut);
247243 __libcpp_condvar_broadcast(&cv);
248#ifndef _LIBCPP_NO_EXCEPTIONS
244#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
249245 }
250246 catch (...)
251247 {
......@@ -255,7 +251,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
255251 __libcpp_condvar_broadcast(&cv);
256252 throw;
257253 }
258#endif // _LIBCPP_NO_EXCEPTIONS
254#endif // _LIBCPP_HAS_NO_EXCEPTIONS
259255 }
260256 else
261257 __libcpp_mutex_unlock(&mut);
lib/libcxx/src/mutex_destructor.cpp+1-1
......@@ -28,7 +28,7 @@
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
3030#ifdef NEEDS_MUTEX_DESTRUCTOR
31class _LIBCPP_TYPE_VIS mutex
31class _LIBCPP_EXPORTED_FROM_ABI mutex
3232{
3333 __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
3434
lib/libcxx/src/new.cpp+29-64
......@@ -6,53 +6,16 @@
66//
77//===----------------------------------------------------------------------===//
88
9#include <__memory/aligned_alloc.h>
10#include <cstdlib>
911#include <new>
10#include <stdlib.h>
1112
12#include "include/atomic_support.h"
13#if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_VCRUNTIME)
1314
14#if defined(_LIBCPP_ABI_MICROSOFT)
15# if !defined(_LIBCPP_ABI_VCRUNTIME)
16# include "support/runtime/new_handler_fallback.ipp"
17# endif
18#elif defined(LIBCXX_BUILDING_LIBCXXABI)
19# include <cxxabi.h>
20#elif defined(LIBCXXRT)
21# include <cxxabi.h>
22# include "support/runtime/new_handler_fallback.ipp"
23#elif defined(__GLIBCXX__)
24 // nothing to do
25#else
26# include "support/runtime/new_handler_fallback.ipp"
27#endif
28
29namespace std
30{
31
32#ifndef __GLIBCXX__
33const nothrow_t nothrow{};
34#endif
35
36#ifndef LIBSTDCXX
37
38void
39__throw_bad_alloc()
40{
41#ifndef _LIBCPP_NO_EXCEPTIONS
42 throw bad_alloc();
43#else
44 _VSTD::abort();
45#endif
46}
47
48#endif // !LIBSTDCXX
49
50} // std
51
52#if !defined(__GLIBCXX__) && \
53 !defined(_LIBCPP_ABI_VCRUNTIME) && \
54 !defined(_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS)
15// The code below is copied as-is into libc++abi's libcxxabi/src/stdlib_new_delete.cpp
16// file. The version in this file is the canonical one.
5517
18// ------------------ BEGIN COPY ------------------
5619// Implement all new and delete operators as weak definitions
5720// in this shared library, so that they can be overridden by programs
5821// that define non-weak copies of the functions.
......@@ -64,7 +27,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
6427 if (size == 0)
6528 size = 1;
6629 void* p;
67 while ((p = ::malloc(size)) == nullptr)
30 while ((p = std::malloc(size)) == nullptr)
6831 {
6932 // If malloc fails and there is a new_handler,
7033 // call it to try free up memory.
......@@ -72,7 +35,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
7235 if (nh)
7336 nh();
7437 else
75#ifndef _LIBCPP_NO_EXCEPTIONS
38#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
7639 throw std::bad_alloc();
7740#else
7841 break;
......@@ -86,17 +49,17 @@ void*
8649operator new(size_t size, const std::nothrow_t&) noexcept
8750{
8851 void* p = nullptr;
89#ifndef _LIBCPP_NO_EXCEPTIONS
52#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
9053 try
9154 {
92#endif // _LIBCPP_NO_EXCEPTIONS
55#endif // _LIBCPP_HAS_NO_EXCEPTIONS
9356 p = ::operator new(size);
94#ifndef _LIBCPP_NO_EXCEPTIONS
57#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
9558 }
9659 catch (...)
9760 {
9861 }
99#endif // _LIBCPP_NO_EXCEPTIONS
62#endif // _LIBCPP_HAS_NO_EXCEPTIONS
10063 return p;
10164}
10265
......@@ -112,17 +75,17 @@ void*
11275operator new[](size_t size, const std::nothrow_t&) noexcept
11376{
11477 void* p = nullptr;
115#ifndef _LIBCPP_NO_EXCEPTIONS
78#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
11679 try
11780 {
118#endif // _LIBCPP_NO_EXCEPTIONS
81#endif // _LIBCPP_HAS_NO_EXCEPTIONS
11982 p = ::operator new[](size);
120#ifndef _LIBCPP_NO_EXCEPTIONS
83#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
12184 }
12285 catch (...)
12386 {
12487 }
125#endif // _LIBCPP_NO_EXCEPTIONS
88#endif // _LIBCPP_HAS_NO_EXCEPTIONS
12689 return p;
12790}
12891
......@@ -130,7 +93,7 @@ _LIBCPP_WEAK
13093void
13194operator delete(void* ptr) noexcept
13295{
133 ::free(ptr);
96 std::free(ptr);
13497}
13598
13699_LIBCPP_WEAK
......@@ -192,7 +155,7 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
192155 if (nh)
193156 nh();
194157 else {
195#ifndef _LIBCPP_NO_EXCEPTIONS
158#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
196159 throw std::bad_alloc();
197160#else
198161 break;
......@@ -207,17 +170,17 @@ void*
207170operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
208171{
209172 void* p = nullptr;
210#ifndef _LIBCPP_NO_EXCEPTIONS
173#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
211174 try
212175 {
213#endif // _LIBCPP_NO_EXCEPTIONS
176#endif // _LIBCPP_HAS_NO_EXCEPTIONS
214177 p = ::operator new(size, alignment);
215#ifndef _LIBCPP_NO_EXCEPTIONS
178#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
216179 }
217180 catch (...)
218181 {
219182 }
220#endif // _LIBCPP_NO_EXCEPTIONS
183#endif // _LIBCPP_HAS_NO_EXCEPTIONS
221184 return p;
222185}
223186
......@@ -233,17 +196,17 @@ void*
233196operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
234197{
235198 void* p = nullptr;
236#ifndef _LIBCPP_NO_EXCEPTIONS
199#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
237200 try
238201 {
239#endif // _LIBCPP_NO_EXCEPTIONS
202#endif // _LIBCPP_HAS_NO_EXCEPTIONS
240203 p = ::operator new[](size, alignment);
241#ifndef _LIBCPP_NO_EXCEPTIONS
204#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
242205 }
243206 catch (...)
244207 {
245208 }
246#endif // _LIBCPP_NO_EXCEPTIONS
209#endif // _LIBCPP_HAS_NO_EXCEPTIONS
247210 return p;
248211}
249212
......@@ -290,4 +253,6 @@ operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept
290253}
291254
292255#endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
293#endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME && !_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS
256// ------------------ END COPY ------------------
257
258#endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME
lib/libcxx/src/new_handler.cpp created+39
......@@ -0,0 +1,39 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <new>
10
11#include "include/atomic_support.h"
12
13#if defined(_LIBCPP_ABI_MICROSOFT)
14# if !defined(_LIBCPP_ABI_VCRUNTIME)
15# define _LIBPCPP_DEFINE_NEW_HANDLER
16# endif
17#elif defined(LIBCXX_BUILDING_LIBCXXABI)
18// nothing to do, we use the one from libc++abi
19#elif defined(LIBCXXRT)
20# define _LIBPCPP_DEFINE_NEW_HANDLER
21#elif defined(__GLIBCXX__)
22// nothing to do, we use the one from libstdc++/libsupc++
23#else
24# define _LIBPCPP_DEFINE_NEW_HANDLER
25#endif
26
27#if defined(_LIBPCPP_DEFINE_NEW_HANDLER)
28
29namespace std { // purposefully not versioned
30
31static constinit std::new_handler __new_handler = nullptr;
32
33new_handler set_new_handler(new_handler handler) noexcept { return __libcpp_atomic_exchange(&__new_handler, handler); }
34
35new_handler get_new_handler() noexcept { return __libcpp_atomic_load(&__new_handler); }
36
37} // namespace std
38
39#endif // _LIBPCPP_DEFINE_NEW_HANDLER
lib/libcxx/src/new_helpers.cpp created+30
......@@ -0,0 +1,30 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <cstdlib>
10#include <new>
11
12namespace std { // purposefully not versioned
13
14#ifndef __GLIBCXX__
15const nothrow_t nothrow{};
16#endif
17
18#ifndef LIBSTDCXX
19
20void __throw_bad_alloc() {
21# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
22 throw bad_alloc();
23# else
24 std::abort();
25# endif
26}
27
28#endif // !LIBSTDCXX
29
30} // namespace std
lib/libcxx/src/optional.cpp+1-1
......@@ -27,7 +27,7 @@ const char* bad_optional_access::what() const noexcept {
2727// Even though it no longer exists in a header file
2828_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
2929
30class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
30class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
3131 : public std::logic_error
3232{
3333public:
lib/libcxx/src/print.cpp created+62
......@@ -0,0 +1,62 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <__config>
10#include <cstdlib>
11#include <print>
12
13#if defined(_LIBCPP_WIN32API)
14# define WIN32_LEAN_AND_MEAN
15# define NOMINMAX
16# include <io.h>
17# include <windows.h>
18
19# include <__system_error/system_error.h>
20
21# include "filesystem/error.h"
22#endif
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26#ifdef _WIN32
27_LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream) {
28 // Note the Standard does this in one call, but it's unclear whether
29 // an invalid handle is allowed when calling GetConsoleMode.
30 //
31 // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=msvc-170
32 // https://learn.microsoft.com/en-us/windows/console/getconsolemode
33 intptr_t __handle = _get_osfhandle(fileno(__stream));
34 if (__handle == -1)
35 return false;
36
37 unsigned long __mode;
38 return GetConsoleMode(reinterpret_cast<void*>(__handle), &__mode);
39}
40
41# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
42_LIBCPP_EXPORTED_FROM_ABI void
43__write_to_windows_console([[maybe_unused]] FILE* __stream, [[maybe_unused]] wstring_view __view) {
44 // https://learn.microsoft.com/en-us/windows/console/writeconsole
45 if (WriteConsoleW(reinterpret_cast<void*>(_get_osfhandle(fileno(__stream))), // clang-format aid
46 __view.data(),
47 __view.size(),
48 nullptr,
49 nullptr) == 0) {
50# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
51 // There is no __throw_system_error overload that takes an error code.
52 throw system_error{filesystem::detail::make_windows_error(GetLastError()), "failed to write formatted output"};
53# else // _LIBCPP_HAS_NO_EXCEPTIONS
54 std::abort();
55# endif // _LIBCPP_HAS_NO_EXCEPTIONS
56 }
57}
58# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
59
60#endif // _WIN32
61
62_LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/pstl/libdispatch.cpp created+72
......@@ -0,0 +1,72 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <__algorithm/min.h>
10#include <__algorithm/pstl_backends/cpu_backends/libdispatch.h>
11#include <__config>
12#include <dispatch/dispatch.h>
13#include <thread>
14
15_LIBCPP_BEGIN_NAMESPACE_STD
16
17namespace __par_backend::inline __libdispatch {
18
19
20void __dispatch_apply(size_t chunk_count, void* context, void (*func)(void* context, size_t chunk)) noexcept {
21 ::dispatch_apply_f(chunk_count, DISPATCH_APPLY_AUTO, context, func);
22}
23
24__chunk_partitions __partition_chunks(ptrdiff_t element_count) {
25 if (element_count == 0) {
26 return __chunk_partitions{1, 0, 0};
27 } else if (element_count == 1) {
28 return __chunk_partitions{1, 0, 1};
29 }
30
31 __chunk_partitions partitions;
32 partitions.__chunk_count_ = [&] {
33 ptrdiff_t cores = std::max(1u, thread::hardware_concurrency());
34
35 auto medium = [&](ptrdiff_t n) { return cores + ((n - cores) / cores); };
36
37 // This is an approximation of `log(1.01, sqrt(n))` which seemes to be reasonable for `n` larger than 500 and tops
38 // at 800 tasks for n ~ 8 million
39 auto large = [](ptrdiff_t n) { return static_cast<ptrdiff_t>(100.499 * std::log(std::sqrt(n))); };
40
41 if (element_count < cores)
42 return element_count;
43 else if (element_count < 500)
44 return medium(element_count);
45 else
46 return std::min(medium(element_count), large(element_count)); // provide a "smooth" transition
47 }();
48 partitions.__chunk_size_ = element_count / partitions.__chunk_count_;
49 partitions.__first_chunk_size_ = partitions.__chunk_size_;
50
51 const ptrdiff_t leftover_item_count = element_count - (partitions.__chunk_count_ * partitions.__chunk_size_);
52
53 if (leftover_item_count == 0)
54 return partitions;
55
56 if (leftover_item_count == partitions.__chunk_size_) {
57 partitions.__chunk_count_ += 1;
58 return partitions;
59 }
60
61 const ptrdiff_t n_extra_items_per_chunk = leftover_item_count / partitions.__chunk_count_;
62 const ptrdiff_t n_final_leftover_items = leftover_item_count - (n_extra_items_per_chunk * partitions.__chunk_count_);
63
64 partitions.__chunk_size_ += n_extra_items_per_chunk;
65 partitions.__first_chunk_size_ = partitions.__chunk_size_ + n_final_leftover_items;
66 return partitions;
67}
68
69// NOLINTNEXTLINE(llvm-namespace-comment) // This is https://llvm.org/PR56804
70} // namespace __par_backend::inline __libdispatch
71
72_LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/random.cpp+1-5
......@@ -13,13 +13,9 @@
1313# define _CRT_RAND_S
1414#endif // defined(_LIBCPP_USING_WIN32_RANDOM)
1515
16#include <__system_error/system_error.h>
1617#include <limits>
1718#include <random>
18#include <system_error>
19
20#if defined(__sun__)
21# define rename solaris_headers_are_broken
22#endif // defined(__sun__)
2319
2420#include <errno.h>
2521#include <stdio.h>
lib/libcxx/src/ryu/d2fixed.cpp+23-24
......@@ -43,7 +43,6 @@
4343#include <__config>
4444#include <charconv>
4545#include <cstring>
46#include <system_error>
4746
4847#include "include/ryu/common.h"
4948#include "include/ryu/d2fixed.h"
......@@ -103,8 +102,8 @@ inline constexpr int __POW10_ADDITIONAL_BITS = 120;
103102 const uint64_t __s1low = __low2 + __high1 + __c1; // 128
104103 const uint32_t __c2 = __s1low < __low2; // __high1 + __c1 can't overflow, so compare against __low2
105104 const uint64_t __s1high = __high2 + __c2; // 192
106 _LIBCPP_ASSERT(__j >= 128, "");
107 _LIBCPP_ASSERT(__j <= 180, "");
105 _LIBCPP_ASSERT_UNCATEGORIZED(__j >= 128, "");
106 _LIBCPP_ASSERT_UNCATEGORIZED(__j <= 180, "");
108107#ifdef _LIBCPP_INTRINSIC128
109108 const uint32_t __dist = static_cast<uint32_t>(__j - 128); // __dist: [0, 52]
110109 const uint64_t __shiftedhigh = __s1high >> __dist;
......@@ -135,19 +134,19 @@ void __append_n_digits(const uint32_t __olength, uint32_t __digits, char* const
135134 __digits /= 10000;
136135 const uint32_t __c0 = (__c % 100) << 1;
137136 const uint32_t __c1 = (__c / 100) << 1;
138 _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c0, 2);
139 _VSTD::memcpy(__result + __olength - __i - 4, __DIGIT_TABLE + __c1, 2);
137 std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c0, 2);
138 std::memcpy(__result + __olength - __i - 4, __DIGIT_TABLE + __c1, 2);
140139 __i += 4;
141140 }
142141 if (__digits >= 100) {
143142 const uint32_t __c = (__digits % 100) << 1;
144143 __digits /= 100;
145 _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
144 std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
146145 __i += 2;
147146 }
148147 if (__digits >= 10) {
149148 const uint32_t __c = __digits << 1;
150 _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
149 std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
151150 } else {
152151 __result[0] = static_cast<char>('0' + __digits);
153152 }
......@@ -164,14 +163,14 @@ _LIBCPP_HIDE_FROM_ABI inline void __append_d_digits(const uint32_t __olength, ui
164163 __digits /= 10000;
165164 const uint32_t __c0 = (__c % 100) << 1;
166165 const uint32_t __c1 = (__c / 100) << 1;
167 _VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c0, 2);
168 _VSTD::memcpy(__result + __olength + 1 - __i - 4, __DIGIT_TABLE + __c1, 2);
166 std::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c0, 2);
167 std::memcpy(__result + __olength + 1 - __i - 4, __DIGIT_TABLE + __c1, 2);
169168 __i += 4;
170169 }
171170 if (__digits >= 100) {
172171 const uint32_t __c = (__digits % 100) << 1;
173172 __digits /= 100;
174 _VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c, 2);
173 std::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c, 2);
175174 __i += 2;
176175 }
177176 if (__digits >= 10) {
......@@ -190,7 +189,7 @@ _LIBCPP_HIDE_FROM_ABI inline void __append_c_digits(const uint32_t __count, uint
190189 for (; __i < __count - 1; __i += 2) {
191190 const uint32_t __c = (__digits % 100) << 1;
192191 __digits /= 100;
193 _VSTD::memcpy(__result + __count - __i - 2, __DIGIT_TABLE + __c, 2);
192 std::memcpy(__result + __count - __i - 2, __DIGIT_TABLE + __c, 2);
194193 }
195194 if (__i < __count) {
196195 const char __c = static_cast<char>('0' + (__digits % 10));
......@@ -200,7 +199,7 @@ _LIBCPP_HIDE_FROM_ABI inline void __append_c_digits(const uint32_t __count, uint
200199
201200void __append_nine_digits(uint32_t __digits, char* const __result) {
202201 if (__digits == 0) {
203 _VSTD::memset(__result, '0', 9);
202 std::memset(__result, '0', 9);
204203 return;
205204 }
206205
......@@ -213,8 +212,8 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
213212 __digits /= 10000;
214213 const uint32_t __c0 = (__c % 100) << 1;
215214 const uint32_t __c1 = (__c / 100) << 1;
216 _VSTD::memcpy(__result + 7 - __i, __DIGIT_TABLE + __c0, 2);
217 _VSTD::memcpy(__result + 5 - __i, __DIGIT_TABLE + __c1, 2);
215 std::memcpy(__result + 7 - __i, __DIGIT_TABLE + __c0, 2);
216 std::memcpy(__result + 5 - __i, __DIGIT_TABLE + __c1, 2);
218217 }
219218 __result[0] = static_cast<char>('0' + __digits);
220219}
......@@ -251,7 +250,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
251250 *_First++ = '0';
252251 if (__precision > 0) {
253252 *_First++ = '.';
254 _VSTD::memset(_First, '0', __precision);
253 std::memset(_First, '0', __precision);
255254 _First += __precision;
256255 }
257256 return { _First, errc{} };
......@@ -322,14 +321,14 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
322321 if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
323322 return { _Last, errc::value_too_large };
324323 }
325 _VSTD::memset(_First, '0', __precision);
324 std::memset(_First, '0', __precision);
326325 _First += __precision;
327326 } else if (__i < __MIN_BLOCK_2[__idx]) {
328327 __i = __MIN_BLOCK_2[__idx];
329328 if (_Last - _First < static_cast<ptrdiff_t>(9 * __i)) {
330329 return { _Last, errc::value_too_large };
331330 }
332 _VSTD::memset(_First, '0', 9 * __i);
331 std::memset(_First, '0', 9 * __i);
333332 _First += 9 * __i;
334333 }
335334 for (; __i < __blocks; ++__i) {
......@@ -342,7 +341,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
342341 if (_Last - _First < static_cast<ptrdiff_t>(__fill)) {
343342 return { _Last, errc::value_too_large };
344343 }
345 _VSTD::memset(_First, '0', __fill);
344 std::memset(_First, '0', __fill);
346345 _First += __fill;
347346 break;
348347 }
......@@ -416,7 +415,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
416415 if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
417416 return { _Last, errc::value_too_large };
418417 }
419 _VSTD::memset(_First, '0', __precision);
418 std::memset(_First, '0', __precision);
420419 _First += __precision;
421420 }
422421 return { _First, errc{} };
......@@ -440,10 +439,10 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
440439 *_First++ = '0';
441440 if (__precision > 0) {
442441 *_First++ = '.';
443 _VSTD::memset(_First, '0', __precision);
442 std::memset(_First, '0', __precision);
444443 _First += __precision;
445444 }
446 _VSTD::memcpy(_First, "e+00", 4);
445 std::memcpy(_First, "e+00", 4);
447446 _First += 4;
448447 return { _First, errc{} };
449448 }
......@@ -589,7 +588,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
589588 return { _Last, errc::value_too_large };
590589 }
591590 if (__digits == 0) {
592 _VSTD::memset(_First, '0', __maximum);
591 std::memset(_First, '0', __maximum);
593592 } else {
594593 __append_c_digits(__maximum, __digits, _First);
595594 }
......@@ -654,11 +653,11 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
654653
655654 if (__exp >= 100) {
656655 const int32_t __c = __exp % 10;
657 _VSTD::memcpy(_First, __DIGIT_TABLE + 2 * (__exp / 10), 2);
656 std::memcpy(_First, __DIGIT_TABLE + 2 * (__exp / 10), 2);
658657 _First[2] = static_cast<char>('0' + __c);
659658 _First += 3;
660659 } else {
661 _VSTD::memcpy(_First, __DIGIT_TABLE + 2 * __exp, 2);
660 std::memcpy(_First, __DIGIT_TABLE + 2 * __exp, 2);
662661 _First += 2;
663662 }
664663
lib/libcxx/src/ryu/d2s.cpp+22-22
......@@ -154,7 +154,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
154154 // The average output length is 16.38 digits, so we check high-to-low.
155155 // Function precondition: __v is not an 18, 19, or 20-digit number.
156156 // (17 digits are sufficient for round-tripping.)
157 _LIBCPP_ASSERT(__v < 100000000000000000u, "");
157 _LIBCPP_ASSERT_UNCATEGORIZED(__v < 100000000000000000u, "");
158158 if (__v >= 10000000000000000u) { return 17; }
159159 if (__v >= 1000000000000000u) { return 16; }
160160 if (__v >= 100000000000000u) { return 15; }
......@@ -527,10 +527,10 @@ struct __floating_decimal_64 {
527527 const uint32_t __d0 = (__d % 100) << 1;
528528 const uint32_t __d1 = (__d / 100) << 1;
529529
530 _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
531 _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
532 _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __d0, 2);
533 _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __d1, 2);
530 std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
531 std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
532 std::memcpy(_Mid -= 2, __DIGIT_TABLE + __d0, 2);
533 std::memcpy(_Mid -= 2, __DIGIT_TABLE + __d1, 2);
534534 }
535535 uint32_t __output2 = static_cast<uint32_t>(_Output);
536536 while (__output2 >= 10000) {
......@@ -542,35 +542,35 @@ struct __floating_decimal_64 {
542542 __output2 /= 10000;
543543 const uint32_t __c0 = (__c % 100) << 1;
544544 const uint32_t __c1 = (__c / 100) << 1;
545 _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
546 _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
545 std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
546 std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
547547 }
548548 if (__output2 >= 100) {
549549 const uint32_t __c = (__output2 % 100) << 1;
550550 __output2 /= 100;
551 _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
551 std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
552552 }
553553 if (__output2 >= 10) {
554554 const uint32_t __c = __output2 << 1;
555 _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
555 std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
556556 } else {
557557 *--_Mid = static_cast<char>('0' + __output2);
558558 }
559559
560560 if (_Ryu_exponent > 0) { // case "172900" with _Can_use_ryu
561561 // Performance note: it might be more efficient to do this immediately after setting _Mid.
562 _VSTD::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
562 std::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
563563 } else if (_Ryu_exponent == 0) { // case "1729"
564564 // Done!
565565 } else if (_Whole_digits > 0) { // case "17.29"
566566 // Performance note: moving digits might not be optimal.
567 _VSTD::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
567 std::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
568568 _First[_Whole_digits] = '.';
569569 } else { // case "0.001729"
570570 // Performance note: a larger memset() followed by overwriting '.' might be more efficient.
571571 _First[0] = '0';
572572 _First[1] = '.';
573 _VSTD::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
573 std::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
574574 }
575575
576576 return { _First + _Total_fixed_length, errc{} };
......@@ -602,10 +602,10 @@ struct __floating_decimal_64 {
602602 const uint32_t __c1 = (__c / 100) << 1;
603603 const uint32_t __d0 = (__d % 100) << 1;
604604 const uint32_t __d1 = (__d / 100) << 1;
605 _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
606 _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
607 _VSTD::memcpy(__result + __olength - __i - 5, __DIGIT_TABLE + __d0, 2);
608 _VSTD::memcpy(__result + __olength - __i - 7, __DIGIT_TABLE + __d1, 2);
605 std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
606 std::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
607 std::memcpy(__result + __olength - __i - 5, __DIGIT_TABLE + __d0, 2);
608 std::memcpy(__result + __olength - __i - 7, __DIGIT_TABLE + __d1, 2);
609609 __i += 8;
610610 }
611611 uint32_t __output2 = static_cast<uint32_t>(_Output);
......@@ -618,14 +618,14 @@ struct __floating_decimal_64 {
618618 __output2 /= 10000;
619619 const uint32_t __c0 = (__c % 100) << 1;
620620 const uint32_t __c1 = (__c / 100) << 1;
621 _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
622 _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
621 std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
622 std::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
623623 __i += 4;
624624 }
625625 if (__output2 >= 100) {
626626 const uint32_t __c = (__output2 % 100) << 1;
627627 __output2 /= 100;
628 _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
628 std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
629629 __i += 2;
630630 }
631631 if (__output2 >= 10) {
......@@ -657,11 +657,11 @@ struct __floating_decimal_64 {
657657
658658 if (_Scientific_exponent >= 100) {
659659 const int32_t __c = _Scientific_exponent % 10;
660 _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * (_Scientific_exponent / 10), 2);
660 std::memcpy(__result + __index, __DIGIT_TABLE + 2 * (_Scientific_exponent / 10), 2);
661661 __result[__index + 2] = static_cast<char>('0' + __c);
662662 __index += 3;
663663 } else {
664 _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
664 std::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
665665 __index += 2;
666666 }
667667
......@@ -713,7 +713,7 @@ struct __floating_decimal_64 {
713713 return { _Last, errc::value_too_large };
714714 }
715715
716 _VSTD::memcpy(_First, "0e+00", 5);
716 std::memcpy(_First, "0e+00", 5);
717717
718718 return { _First + 5, errc{} };
719719 }
lib/libcxx/src/ryu/f2s.cpp+22-22
......@@ -86,7 +86,7 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = {
8686[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow5Factor(uint32_t __value) {
8787 uint32_t __count = 0;
8888 for (;;) {
89 _LIBCPP_ASSERT(__value != 0, "");
89 _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
9090 const uint32_t __q = __value / 5;
9191 const uint32_t __r = __value % 5;
9292 if (__r != 0) {
......@@ -105,14 +105,14 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = {
105105
106106// Returns true if __value is divisible by 2^__p.
107107[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf2(const uint32_t __value, const uint32_t __p) {
108 _LIBCPP_ASSERT(__value != 0, "");
109 _LIBCPP_ASSERT(__p < 32, "");
108 _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
109 _LIBCPP_ASSERT_UNCATEGORIZED(__p < 32, "");
110110 // __builtin_ctz doesn't appear to be faster here.
111111 return (__value & ((1u << __p) - 1)) == 0;
112112}
113113
114114[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mulShift(const uint32_t __m, const uint64_t __factor, const int32_t __shift) {
115 _LIBCPP_ASSERT(__shift > 32, "");
115 _LIBCPP_ASSERT_UNCATEGORIZED(__shift > 32, "");
116116
117117 // The casts here help MSVC to avoid calls to the __allmul library
118118 // function.
......@@ -134,7 +134,7 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = {
134134#else // ^^^ 32-bit ^^^ / vvv 64-bit vvv
135135 const uint64_t __sum = (__bits0 >> 32) + __bits1;
136136 const uint64_t __shiftedSum = __sum >> (__shift - 32);
137 _LIBCPP_ASSERT(__shiftedSum <= UINT32_MAX, "");
137 _LIBCPP_ASSERT_UNCATEGORIZED(__shiftedSum <= UINT32_MAX, "");
138138 return static_cast<uint32_t>(__shiftedSum);
139139#endif // ^^^ 64-bit ^^^
140140}
......@@ -309,8 +309,8 @@ struct __floating_decimal_32 {
309309 // Performance note: Long division appears to be faster than losslessly widening float to double and calling
310310 // __d2fixed_buffered_n(). If __f2fixed_buffered_n() is implemented, it might be faster than long division.
311311
312 _LIBCPP_ASSERT(_Exponent2 > 0, "");
313 _LIBCPP_ASSERT(_Exponent2 <= 104, ""); // because __ieeeExponent <= 254
312 _LIBCPP_ASSERT_UNCATEGORIZED(_Exponent2 > 0, "");
313 _LIBCPP_ASSERT_UNCATEGORIZED(_Exponent2 <= 104, ""); // because __ieeeExponent <= 254
314314
315315 // Manually represent _Mantissa2 * 2^_Exponent2 as a large integer. _Mantissa2 is always 24 bits
316316 // (due to the implicit bit), while _Exponent2 indicates a shift of at most 104 bits.
......@@ -328,7 +328,7 @@ struct __floating_decimal_32 {
328328
329329 // _Maxidx is the index of the most significant nonzero element.
330330 uint32_t _Maxidx = ((24 + static_cast<uint32_t>(_Exponent2) + 31) / 32) - 1;
331 _LIBCPP_ASSERT(_Maxidx < _Data_size, "");
331 _LIBCPP_ASSERT_UNCATEGORIZED(_Maxidx < _Data_size, "");
332332
333333 const uint32_t _Bit_shift = static_cast<uint32_t>(_Exponent2) % 32;
334334 if (_Bit_shift <= 8) { // _Mantissa2's 24 bits don't cross an element boundary
......@@ -388,9 +388,9 @@ struct __floating_decimal_32 {
388388 }
389389 }
390390
391 _LIBCPP_ASSERT(_Data[0] != 0, "");
391 _LIBCPP_ASSERT_UNCATEGORIZED(_Data[0] != 0, "");
392392 for (uint32_t _Idx = 1; _Idx < _Data_size; ++_Idx) {
393 _LIBCPP_ASSERT(_Data[_Idx] == 0, "");
393 _LIBCPP_ASSERT_UNCATEGORIZED(_Data[_Idx] == 0, "");
394394 }
395395
396396 const uint32_t _Data_olength = _Data[0] >= 1000000000 ? 10 : __decimalLength9(_Data[0]);
......@@ -565,35 +565,35 @@ struct __floating_decimal_32 {
565565 _Output /= 10000;
566566 const uint32_t __c0 = (__c % 100) << 1;
567567 const uint32_t __c1 = (__c / 100) << 1;
568 _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
569 _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
568 std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
569 std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
570570 }
571571 if (_Output >= 100) {
572572 const uint32_t __c = (_Output % 100) << 1;
573573 _Output /= 100;
574 _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
574 std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
575575 }
576576 if (_Output >= 10) {
577577 const uint32_t __c = _Output << 1;
578 _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
578 std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
579579 } else {
580580 *--_Mid = static_cast<char>('0' + _Output);
581581 }
582582
583583 if (_Ryu_exponent > 0) { // case "172900" with _Can_use_ryu
584584 // Performance note: it might be more efficient to do this immediately after setting _Mid.
585 _VSTD::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
585 std::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
586586 } else if (_Ryu_exponent == 0) { // case "1729"
587587 // Done!
588588 } else if (_Whole_digits > 0) { // case "17.29"
589589 // Performance note: moving digits might not be optimal.
590 _VSTD::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
590 std::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
591591 _First[_Whole_digits] = '.';
592592 } else { // case "0.001729"
593593 // Performance note: a larger memset() followed by overwriting '.' might be more efficient.
594594 _First[0] = '0';
595595 _First[1] = '.';
596 _VSTD::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
596 std::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
597597 }
598598
599599 return { _First + _Total_fixed_length, errc{} };
......@@ -617,14 +617,14 @@ struct __floating_decimal_32 {
617617 _Output /= 10000;
618618 const uint32_t __c0 = (__c % 100) << 1;
619619 const uint32_t __c1 = (__c / 100) << 1;
620 _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
621 _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
620 std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
621 std::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
622622 __i += 4;
623623 }
624624 if (_Output >= 100) {
625625 const uint32_t __c = (_Output % 100) << 1;
626626 _Output /= 100;
627 _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
627 std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
628628 __i += 2;
629629 }
630630 if (_Output >= 10) {
......@@ -654,7 +654,7 @@ struct __floating_decimal_32 {
654654 __result[__index++] = '+';
655655 }
656656
657 _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
657 std::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
658658 __index += 2;
659659
660660 return { _First + _Total_scientific_length, errc{} };
......@@ -673,7 +673,7 @@ struct __floating_decimal_32 {
673673 return { _Last, errc::value_too_large };
674674 }
675675
676 _VSTD::memcpy(_First, "0e+00", 5);
676 std::memcpy(_First, "0e+00", 5);
677677
678678 return { _First + 5, errc{} };
679679 }
lib/libcxx/src/shared_mutex.cpp+54-74
......@@ -10,106 +10,86 @@
1010
1111#ifndef _LIBCPP_HAS_NO_THREADS
1212
13#include <shared_mutex>
14#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
15# pragma comment(lib, "pthread")
16#endif
13# include <mutex>
14# include <shared_mutex>
15# if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
16# pragma comment(lib, "pthread")
17# endif
1718
1819_LIBCPP_BEGIN_NAMESPACE_STD
1920
2021// Shared Mutex Base
21__shared_mutex_base::__shared_mutex_base()
22 : __state_(0)
23{
24}
22__shared_mutex_base::__shared_mutex_base() : __state_(0) {}
2523
2624// Exclusive ownership
2725
28void
29__shared_mutex_base::lock()
30{
31 unique_lock<mutex> lk(__mut_);
32 while (__state_ & __write_entered_)
33 __gate1_.wait(lk);
34 __state_ |= __write_entered_;
35 while (__state_ & __n_readers_)
36 __gate2_.wait(lk);
26void __shared_mutex_base::lock() {
27 unique_lock<mutex> lk(__mut_);
28 while (__state_ & __write_entered_)
29 __gate1_.wait(lk);
30 __state_ |= __write_entered_;
31 while (__state_ & __n_readers_)
32 __gate2_.wait(lk);
3733}
3834
39bool
40__shared_mutex_base::try_lock()
41{
42 unique_lock<mutex> lk(__mut_);
43 if (__state_ == 0)
44 {
45 __state_ = __write_entered_;
46 return true;
47 }
48 return false;
35bool __shared_mutex_base::try_lock() {
36 unique_lock<mutex> lk(__mut_);
37 if (__state_ == 0) {
38 __state_ = __write_entered_;
39 return true;
40 }
41 return false;
4942}
5043
51void
52__shared_mutex_base::unlock()
53{
54 lock_guard<mutex> _(__mut_);
55 __state_ = 0;
56 __gate1_.notify_all();
44void __shared_mutex_base::unlock() {
45 lock_guard<mutex> _(__mut_);
46 __state_ = 0;
47 __gate1_.notify_all();
5748}
5849
5950// Shared ownership
6051
61void
62__shared_mutex_base::lock_shared()
63{
64 unique_lock<mutex> lk(__mut_);
65 while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
66 __gate1_.wait(lk);
67 unsigned num_readers = (__state_ & __n_readers_) + 1;
68 __state_ &= ~__n_readers_;
69 __state_ |= num_readers;
70}
71
72bool
73__shared_mutex_base::try_lock_shared()
74{
75 unique_lock<mutex> lk(__mut_);
76 unsigned num_readers = __state_ & __n_readers_;
77 if (!(__state_ & __write_entered_) && num_readers != __n_readers_)
78 {
79 ++num_readers;
80 __state_ &= ~__n_readers_;
81 __state_ |= num_readers;
82 return true;
83 }
84 return false;
52void __shared_mutex_base::lock_shared() {
53 unique_lock<mutex> lk(__mut_);
54 while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
55 __gate1_.wait(lk);
56 unsigned num_readers = (__state_ & __n_readers_) + 1;
57 __state_ &= ~__n_readers_;
58 __state_ |= num_readers;
8559}
8660
87void
88__shared_mutex_base::unlock_shared()
89{
90 lock_guard<mutex> _(__mut_);
91 unsigned num_readers = (__state_ & __n_readers_) - 1;
61bool __shared_mutex_base::try_lock_shared() {
62 unique_lock<mutex> lk(__mut_);
63 unsigned num_readers = __state_ & __n_readers_;
64 if (!(__state_ & __write_entered_) && num_readers != __n_readers_) {
65 ++num_readers;
9266 __state_ &= ~__n_readers_;
9367 __state_ |= num_readers;
94 if (__state_ & __write_entered_)
95 {
96 if (num_readers == 0)
97 __gate2_.notify_one();
98 }
99 else
100 {
101 if (num_readers == __n_readers_ - 1)
102 __gate1_.notify_one();
103 }
68 return true;
69 }
70 return false;
10471}
10572
73void __shared_mutex_base::unlock_shared() {
74 lock_guard<mutex> _(__mut_);
75 unsigned num_readers = (__state_ & __n_readers_) - 1;
76 __state_ &= ~__n_readers_;
77 __state_ |= num_readers;
78 if (__state_ & __write_entered_) {
79 if (num_readers == 0)
80 __gate2_.notify_one();
81 } else {
82 if (num_readers == __n_readers_ - 1)
83 __gate1_.notify_one();
84 }
85}
10686
10787// Shared Timed Mutex
10888// These routines are here for ABI stability
10989shared_timed_mutex::shared_timed_mutex() : __base_() {}
110void shared_timed_mutex::lock() { return __base_.lock(); }
90void shared_timed_mutex::lock() { return __base_.lock(); }
11191bool shared_timed_mutex::try_lock() { return __base_.try_lock(); }
112void shared_timed_mutex::unlock() { return __base_.unlock(); }
92void shared_timed_mutex::unlock() { return __base_.unlock(); }
11393void shared_timed_mutex::lock_shared() { return __base_.lock_shared(); }
11494bool shared_timed_mutex::try_lock_shared() { return __base_.try_lock_shared(); }
11595void shared_timed_mutex::unlock_shared() { return __base_.unlock_shared(); }
lib/libcxx/src/std_stream.h created+447
......@@ -0,0 +1,447 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_STD_STREAM_H
11#define _LIBCPP_STD_STREAM_H
12
13#include <__config>
14#include <__locale>
15#include <cstdio>
16#include <istream>
17#include <ostream>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29static const int __limit = 8;
30
31// __stdinbuf
32
33template <class _CharT>
34class _LIBCPP_HIDDEN __stdinbuf
35 : public basic_streambuf<_CharT, char_traits<_CharT> >
36{
37public:
38 typedef _CharT char_type;
39 typedef char_traits<char_type> traits_type;
40 typedef typename traits_type::int_type int_type;
41 typedef typename traits_type::pos_type pos_type;
42 typedef typename traits_type::off_type off_type;
43 typedef typename traits_type::state_type state_type;
44
45 __stdinbuf(FILE* __fp, state_type* __st);
46
47protected:
48 virtual int_type underflow();
49 virtual int_type uflow();
50 virtual int_type pbackfail(int_type __c = traits_type::eof());
51 virtual void imbue(const locale& __loc);
52
53private:
54
55 FILE* __file_;
56 const codecvt<char_type, char, state_type>* __cv_;
57 state_type* __st_;
58 int __encoding_;
59 int_type __last_consumed_;
60 bool __last_consumed_is_next_;
61 bool __always_noconv_;
62
63#if defined(_LIBCPP_WIN32API)
64 static constexpr bool __is_win32api_wide_char = !is_same_v<_CharT, char>;
65#else
66 static constexpr bool __is_win32api_wide_char = false;
67#endif
68
69 __stdinbuf(const __stdinbuf&);
70 __stdinbuf& operator=(const __stdinbuf&);
71
72 int_type __getchar(bool __consume);
73};
74
75template <class _CharT>
76__stdinbuf<_CharT>::__stdinbuf(FILE* __fp, state_type* __st)
77 : __file_(__fp),
78 __st_(__st),
79 __last_consumed_(traits_type::eof()),
80 __last_consumed_is_next_(false)
81{
82 imbue(this->getloc());
83 // On Windows, in wchar_t mode, ignore the codecvt from the locale by
84 // default and assume noconv; this passes wchar_t through unmodified from
85 // getwc. If the user sets a custom locale with imbue(), that gets honored,
86 // the IO is done with getc() and converted with the provided codecvt.
87 if constexpr (__is_win32api_wide_char)
88 __always_noconv_ = true;
89}
90
91template <class _CharT>
92void
93__stdinbuf<_CharT>::imbue(const locale& __loc)
94{
95 __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
96 __encoding_ = __cv_->encoding();
97 __always_noconv_ = __cv_->always_noconv();
98 if (__encoding_ > __limit)
99 __throw_runtime_error("unsupported locale for standard input");
100}
101
102template <class _CharT>
103typename __stdinbuf<_CharT>::int_type
104__stdinbuf<_CharT>::underflow()
105{
106 return __getchar(false);
107}
108
109template <class _CharT>
110typename __stdinbuf<_CharT>::int_type
111__stdinbuf<_CharT>::uflow()
112{
113 return __getchar(true);
114}
115
116static bool __do_getc(FILE *__fp, char *__pbuf) {
117 int __c = getc(__fp);
118 if (__c == EOF)
119 return false;
120 *__pbuf = static_cast<char>(__c);
121 return true;
122}
123#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
124static bool __do_getc(FILE *__fp, wchar_t *__pbuf) {
125 wint_t __c = getwc(__fp);
126 if (__c == WEOF)
127 return false;
128 *__pbuf = static_cast<wchar_t>(__c);
129 return true;
130}
131#endif
132
133static bool __do_ungetc(int __c, FILE *__fp, char __dummy) {
134 if (ungetc(__c, __fp) == EOF)
135 return false;
136 return true;
137}
138#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
139static bool __do_ungetc(std::wint_t __c, FILE *__fp, wchar_t __dummy) {
140 if (ungetwc(__c, __fp) == WEOF)
141 return false;
142 return true;
143}
144#endif
145
146template <class _CharT>
147typename __stdinbuf<_CharT>::int_type
148__stdinbuf<_CharT>::__getchar(bool __consume)
149{
150 if (__last_consumed_is_next_)
151 {
152 int_type __result = __last_consumed_;
153 if (__consume)
154 {
155 __last_consumed_ = traits_type::eof();
156 __last_consumed_is_next_ = false;
157 }
158 return __result;
159 }
160 if (__always_noconv_) {
161 char_type __1buf;
162 if (!__do_getc(__file_, &__1buf))
163 return traits_type::eof();
164 if (!__consume)
165 {
166 if (!__do_ungetc(traits_type::to_int_type(__1buf), __file_, __1buf))
167 return traits_type::eof();
168 }
169 else
170 __last_consumed_ = traits_type::to_int_type(__1buf);
171 return traits_type::to_int_type(__1buf);
172 }
173
174 char __extbuf[__limit];
175 int __nread = _VSTD::max(1, __encoding_);
176 for (int __i = 0; __i < __nread; ++__i)
177 {
178 int __c = getc(__file_);
179 if (__c == EOF)
180 return traits_type::eof();
181 __extbuf[__i] = static_cast<char>(__c);
182 }
183 char_type __1buf;
184 const char* __enxt;
185 char_type* __inxt;
186 codecvt_base::result __r;
187 do
188 {
189 state_type __sv_st = *__st_;
190 __r = __cv_->in(*__st_, __extbuf, __extbuf + __nread, __enxt,
191 &__1buf, &__1buf + 1, __inxt);
192 switch (__r)
193 {
194 case _VSTD::codecvt_base::ok:
195 break;
196 case codecvt_base::partial:
197 *__st_ = __sv_st;
198 if (__nread == sizeof(__extbuf))
199 return traits_type::eof();
200 {
201 int __c = getc(__file_);
202 if (__c == EOF)
203 return traits_type::eof();
204 __extbuf[__nread] = static_cast<char>(__c);
205 }
206 ++__nread;
207 break;
208 case codecvt_base::error:
209 return traits_type::eof();
210 case _VSTD::codecvt_base::noconv:
211 __1buf = static_cast<char_type>(__extbuf[0]);
212 break;
213 }
214 } while (__r == _VSTD::codecvt_base::partial);
215 if (!__consume)
216 {
217 for (int __i = __nread; __i > 0;)
218 {
219 if (ungetc(traits_type::to_int_type(__extbuf[--__i]), __file_) == EOF)
220 return traits_type::eof();
221 }
222 }
223 else
224 __last_consumed_ = traits_type::to_int_type(__1buf);
225 return traits_type::to_int_type(__1buf);
226}
227
228template <class _CharT>
229typename __stdinbuf<_CharT>::int_type
230__stdinbuf<_CharT>::pbackfail(int_type __c)
231{
232 if (traits_type::eq_int_type(__c, traits_type::eof()))
233 {
234 if (!__last_consumed_is_next_)
235 {
236 __c = __last_consumed_;
237 __last_consumed_is_next_ = !traits_type::eq_int_type(__last_consumed_,
238 traits_type::eof());
239 }
240 return __c;
241 }
242 if (__always_noconv_ && __last_consumed_is_next_) {
243 if (!__do_ungetc(__last_consumed_, __file_,
244 traits_type::to_char_type(__last_consumed_)))
245 return traits_type::eof();
246 } else if (__last_consumed_is_next_) {
247 char __extbuf[__limit];
248 char* __enxt;
249 const char_type __ci = traits_type::to_char_type(__last_consumed_);
250 const char_type* __inxt;
251 switch (__cv_->out(*__st_, &__ci, &__ci + 1, __inxt,
252 __extbuf, __extbuf + sizeof(__extbuf), __enxt))
253 {
254 case _VSTD::codecvt_base::ok:
255 break;
256 case _VSTD::codecvt_base::noconv:
257 __extbuf[0] = static_cast<char>(__last_consumed_);
258 __enxt = __extbuf + 1;
259 break;
260 case codecvt_base::partial:
261 case codecvt_base::error:
262 return traits_type::eof();
263 }
264 while (__enxt > __extbuf)
265 if (ungetc(*--__enxt, __file_) == EOF)
266 return traits_type::eof();
267 }
268 __last_consumed_ = __c;
269 __last_consumed_is_next_ = true;
270 return __c;
271}
272
273// __stdoutbuf
274
275template <class _CharT>
276class _LIBCPP_HIDDEN __stdoutbuf
277 : public basic_streambuf<_CharT, char_traits<_CharT> >
278{
279public:
280 typedef _CharT char_type;
281 typedef char_traits<char_type> traits_type;
282 typedef typename traits_type::int_type int_type;
283 typedef typename traits_type::pos_type pos_type;
284 typedef typename traits_type::off_type off_type;
285 typedef typename traits_type::state_type state_type;
286
287 __stdoutbuf(FILE* __fp, state_type* __st);
288
289protected:
290 virtual int_type overflow (int_type __c = traits_type::eof());
291 virtual streamsize xsputn(const char_type* __s, streamsize __n);
292 virtual int sync();
293 virtual void imbue(const locale& __loc);
294
295private:
296 FILE* __file_;
297 const codecvt<char_type, char, state_type>* __cv_;
298 state_type* __st_;
299 bool __always_noconv_;
300
301#if defined(_LIBCPP_WIN32API)
302 static constexpr bool __is_win32api_wide_char = !is_same_v<_CharT, char>;
303#else
304 static constexpr bool __is_win32api_wide_char = false;
305#endif
306
307 __stdoutbuf(const __stdoutbuf&);
308 __stdoutbuf& operator=(const __stdoutbuf&);
309};
310
311template <class _CharT>
312__stdoutbuf<_CharT>::__stdoutbuf(FILE* __fp, state_type* __st)
313 : __file_(__fp),
314 __cv_(&use_facet<codecvt<char_type, char, state_type> >(this->getloc())),
315 __st_(__st),
316 __always_noconv_(__cv_->always_noconv())
317{
318 // On Windows, in wchar_t mode, ignore the codecvt from the locale by
319 // default and assume noconv; this passes wchar_t through unmodified to
320 // fputwc, which handles it correctly depending on the actual mode of the
321 // output stream. If the user sets a custom locale with imbue(), that
322 // gets honored.
323 if constexpr (__is_win32api_wide_char)
324 __always_noconv_ = true;
325}
326
327static bool __do_fputc(char __c, FILE* __fp) {
328 if (fwrite(&__c, sizeof(__c), 1, __fp) != 1)
329 return false;
330 return true;
331}
332#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
333static bool __do_fputc(wchar_t __c, FILE* __fp) {
334 // fputwc works regardless of wide/narrow mode of stdout, while
335 // fwrite of wchar_t only works if the stream actually has been set
336 // into wide mode.
337 if (fputwc(__c, __fp) == WEOF)
338 return false;
339 return true;
340}
341#endif
342
343template <class _CharT>
344typename __stdoutbuf<_CharT>::int_type
345__stdoutbuf<_CharT>::overflow(int_type __c)
346{
347 char __extbuf[__limit];
348 char_type __1buf;
349 if (!traits_type::eq_int_type(__c, traits_type::eof()))
350 {
351 __1buf = traits_type::to_char_type(__c);
352 if (__always_noconv_)
353 {
354 if (!__do_fputc(__1buf, __file_))
355 return traits_type::eof();
356 }
357 else
358 {
359 char* __extbe = __extbuf;
360 codecvt_base::result __r;
361 char_type* pbase = &__1buf;
362 char_type* pptr = pbase + 1;
363 do
364 {
365 const char_type* __e;
366 __r = __cv_->out(*__st_, pbase, pptr, __e,
367 __extbuf,
368 __extbuf + sizeof(__extbuf),
369 __extbe);
370 if (__e == pbase)
371 return traits_type::eof();
372 if (__r == codecvt_base::noconv)
373 {
374 if (fwrite(pbase, 1, 1, __file_) != 1)
375 return traits_type::eof();
376 }
377 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
378 {
379 size_t __nmemb = static_cast<size_t>(__extbe - __extbuf);
380 if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb)
381 return traits_type::eof();
382 if (__r == codecvt_base::partial)
383 {
384 pbase = const_cast<char_type*>(__e);
385 }
386 }
387 else
388 return traits_type::eof();
389 } while (__r == codecvt_base::partial);
390 }
391 }
392 return traits_type::not_eof(__c);
393}
394
395template <class _CharT>
396streamsize
397__stdoutbuf<_CharT>::xsputn(const char_type* __s, streamsize __n)
398{
399 // For wchar_t on Windows, don't call fwrite(), but write characters one
400 // at a time with fputwc(); that works both when stdout is in the default
401 // mode and when it is set to Unicode mode.
402 if (__always_noconv_ && !__is_win32api_wide_char)
403 return fwrite(__s, sizeof(char_type), __n, __file_);
404 streamsize __i = 0;
405 for (; __i < __n; ++__i, ++__s)
406 if (overflow(traits_type::to_int_type(*__s)) == traits_type::eof())
407 break;
408 return __i;
409}
410
411template <class _CharT>
412int
413__stdoutbuf<_CharT>::sync()
414{
415 char __extbuf[__limit];
416 codecvt_base::result __r;
417 do
418 {
419 char* __extbe;
420 __r = __cv_->unshift(*__st_, __extbuf,
421 __extbuf + sizeof(__extbuf),
422 __extbe);
423 size_t __nmemb = static_cast<size_t>(__extbe - __extbuf);
424 if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb)
425 return -1;
426 } while (__r == codecvt_base::partial);
427 if (__r == codecvt_base::error)
428 return -1;
429 if (fflush(__file_))
430 return -1;
431 return 0;
432}
433
434template <class _CharT>
435void
436__stdoutbuf<_CharT>::imbue(const locale& __loc)
437{
438 sync();
439 __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
440 __always_noconv_ = __cv_->always_noconv();
441}
442
443_LIBCPP_END_NAMESPACE_STD
444
445_LIBCPP_POP_MACROS
446
447#endif // _LIBCPP_STD_STREAM_H
lib/libcxx/src/stdexcept.cpp-1
......@@ -9,7 +9,6 @@
99#include <new>
1010#include <stdexcept>
1111#include <string>
12#include <system_error>
1312
1413#ifdef _LIBCPP_ABI_VCRUNTIME
1514#include "support/runtime/stdexcept_vcruntime.ipp"
lib/libcxx/src/string.cpp+3-14
......@@ -12,7 +12,6 @@
1212#include <cstdlib>
1313#include <limits>
1414#include <stdexcept>
15#include <stdio.h>
1615#include <string>
1716
1817#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
......@@ -61,22 +60,12 @@ template string operator+<char, char_traits<char>, allocator<char>>(char const*,
6160namespace
6261{
6362
64template<typename T>
65inline void throw_helper(const string& msg) {
66#ifndef _LIBCPP_NO_EXCEPTIONS
67 throw T(msg);
68#else
69 fprintf(stderr, "%s\n", msg.c_str());
70 _VSTD::abort();
71#endif
72}
73
7463inline void throw_from_string_out_of_range(const string& func) {
75 throw_helper<out_of_range>(func + ": out of range");
64 std::__throw_out_of_range((func + ": out of range").c_str());
7665}
7766
7867inline void throw_from_string_invalid_arg(const string& func) {
79 throw_helper<invalid_argument>(func + ": no conversion");
68 std::__throw_invalid_argument((func + ": no conversion").c_str());
8069}
8170
8271// as_integer
......@@ -357,7 +346,7 @@ S i_to_string(V v) {
357346 constexpr size_t bufsize = numeric_limits<V>::digits10 + 2; // +1 for minus, +1 for digits10
358347 char buf[bufsize];
359348 const auto res = to_chars(buf, buf + bufsize, v);
360 _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value");
349 _LIBCPP_ASSERT_INTERNAL(res.ec == errc(), "bufsize must be large enough to accomodate the value");
361350 return S(buf, res.ptr);
362351}
363352
lib/libcxx/src/strstream.cpp+1-1
......@@ -173,7 +173,7 @@ strstreambuf::overflow(int_type __c)
173173 if (buf == nullptr)
174174 return int_type(EOF);
175175 if (old_size != 0) {
176 _LIBCPP_ASSERT(eback(), "overflow copying from NULL");
176 _LIBCPP_ASSERT_UNCATEGORIZED(eback(), "overflow copying from NULL");
177177 memcpy(buf, eback(), static_cast<size_t>(old_size));
178178 }
179179 ptrdiff_t ninp = gptr() - eback();
lib/libcxx/src/support/ibm/mbsnrtowcs.cpp+1-1
......@@ -18,7 +18,7 @@
1818// Returns (size_t) -1 when an invalid sequence is encountered.
1919// Leaves *`src` pointing to the next character to convert or NULL
2020// if a null character was converted from *`src`.
21_LIBCPP_FUNC_VIS
21_LIBCPP_EXPORTED_FROM_ABI
2222size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,
2323 size_t src_size_bytes, size_t max_dest_chars,
2424 mbstate_t *__restrict ps) {
lib/libcxx/src/support/ibm/wcsnrtombs.cpp+1-1
......@@ -17,7 +17,7 @@
1717// converted from *src, excluding the null terminator.
1818// Returns (size_t) -1 if an error occurs and sets errno.
1919// If `dst` is NULL, `dst_size_bytes` is ignored and no bytes are copied to `dst`.
20_LIBCPP_FUNC_VIS
20_LIBCPP_EXPORTED_FROM_ABI
2121size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src,
2222 size_t max_source_chars, size_t dst_size_bytes,
2323 mbstate_t *__restrict ps) {
lib/libcxx/src/support/ibm/xlocale_zos.cpp+1-1
......@@ -111,7 +111,7 @@ locale_t uselocale(locale_t newloc) {
111111 tokenized.push_back(s);
112112 }
113113
114 _LIBCPP_ASSERT(tokenized.size() >= _NCAT, "locale-name list is too short");
114 _LIBCPP_ASSERT_UNCATEGORIZED(tokenized.size() >= _NCAT, "locale-name list is too short");
115115
116116 previous_loc->lc_collate = tokenized[LC_COLLATE];
117117 previous_loc->lc_ctype = tokenized[LC_CTYPE];
lib/libcxx/src/support/runtime/exception_fallback.ipp+4-4
......@@ -51,15 +51,15 @@ _LIBCPP_NORETURN
5151void
5252terminate() noexcept
5353{
54#ifndef _LIBCPP_NO_EXCEPTIONS
54#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
5555 try
5656 {
57#endif // _LIBCPP_NO_EXCEPTIONS
57#endif // _LIBCPP_HAS_NO_EXCEPTIONS
5858 (*get_terminate())();
5959 // handler should not return
6060 fprintf(stderr, "terminate_handler unexpectedly returned\n");
6161 ::abort();
62#ifndef _LIBCPP_NO_EXCEPTIONS
62#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
6363 }
6464 catch (...)
6565 {
......@@ -67,7 +67,7 @@ terminate() noexcept
6767 fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
6868 ::abort();
6969 }
70#endif // _LIBCPP_NO_EXCEPTIONS
70#endif // _LIBCPP_HAS_NO_EXCEPTIONS
7171}
7272
7373bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; }
lib/libcxx/src/support/runtime/exception_msvc.ipp+4-4
......@@ -57,15 +57,15 @@ terminate_handler get_terminate() noexcept {
5757_LIBCPP_NORETURN
5858void terminate() noexcept
5959{
60#ifndef _LIBCPP_NO_EXCEPTIONS
60#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
6161 try
6262 {
63#endif // _LIBCPP_NO_EXCEPTIONS
63#endif // _LIBCPP_HAS_NO_EXCEPTIONS
6464 (*get_terminate())();
6565 // handler should not return
6666 fprintf(stderr, "terminate_handler unexpectedly returned\n");
6767 ::abort();
68#ifndef _LIBCPP_NO_EXCEPTIONS
68#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
6969 }
7070 catch (...)
7171 {
......@@ -73,7 +73,7 @@ void terminate() noexcept
7373 fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
7474 ::abort();
7575 }
76#endif // _LIBCPP_NO_EXCEPTIONS
76#endif // _LIBCPP_HAS_NO_EXCEPTIONS
7777}
7878
7979bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; }
lib/libcxx/src/support/runtime/new_handler_fallback.ipp deleted-26
......@@ -1,26 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10namespace std {
11
12static constinit std::new_handler __new_handler = nullptr;
13
14new_handler
15set_new_handler(new_handler handler) noexcept
16{
17 return __libcpp_atomic_exchange(&__new_handler, handler);
18}
19
20new_handler
21get_new_handler() noexcept
22{
23 return __libcpp_atomic_load(&__new_handler);
24}
25
26} // namespace std
lib/libcxx/src/support/solaris/mbsnrtowcs.inc deleted-76
......@@ -1,76 +0,0 @@
1
2
3/*-
4 * As noted in the source, some portions of this implementation are copied from
5 * FreeBSD libc. These are covered by the following copyright:
6 *
7 * Copyright (c) 2002-2004 Tim J. Robbins.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31size_t
32mbsnrtowcs_l(wchar_t * __restrict dst, const char ** __restrict src,
33 size_t nms, size_t len, mbstate_t * __restrict ps, locale_t loc)
34{
35 const char *s;
36 size_t nchr;
37 wchar_t wc;
38 size_t nb;
39 FIX_LOCALE(loc);
40
41 s = *src;
42 nchr = 0;
43
44 if (dst == NULL) {
45 for (;;) {
46 if ((nb = mbrtowc_l(&wc, s, nms, ps, loc)) == (size_t)-1)
47 /* Invalid sequence - mbrtowc() sets errno. */
48 return ((size_t)-1);
49 else if (nb == 0 || nb == (size_t)-2)
50 return (nchr);
51 s += nb;
52 nms -= nb;
53 nchr++;
54 }
55 /*NOTREACHED*/
56 }
57
58 while (len-- > 0) {
59 if ((nb = mbrtowc_l(dst, s, nms, ps, loc)) == (size_t)-1) {
60 *src = s;
61 return ((size_t)-1);
62 } else if (nb == (size_t)-2) {
63 *src = s + nms;
64 return (nchr);
65 } else if (nb == 0) {
66 *src = NULL;
67 return (nchr);
68 }
69 s += nb;
70 nms -= nb;
71 nchr++;
72 dst++;
73 }
74 *src = s;
75 return (nchr);
76}
lib/libcxx/src/support/solaris/wcsnrtombs.inc deleted-92
......@@ -1,92 +0,0 @@
1/*-
2 * Copyright (c) 2002-2004 Tim J. Robbins.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26
27size_t
28wcsnrtombs_l(char * __restrict dst, const wchar_t ** __restrict src,
29 size_t nwc, size_t len, mbstate_t * __restrict ps, locale_t loc)
30{
31 FIX_LOCALE(loc);
32 mbstate_t mbsbak;
33 char buf[MB_CUR_MAX_L(loc)];
34 const wchar_t *s;
35 size_t nbytes;
36 size_t nb;
37
38 s = *src;
39 nbytes = 0;
40
41 if (dst == NULL) {
42 while (nwc-- > 0) {
43 if ((nb = wcrtomb_l(buf, *s, ps, loc)) == (size_t)-1)
44 /* Invalid character - wcrtomb() sets errno. */
45 return ((size_t)-1);
46 else if (*s == L'\0')
47 return (nbytes + nb - 1);
48 s++;
49 nbytes += nb;
50 }
51 return (nbytes);
52 }
53
54 while (len > 0 && nwc-- > 0) {
55 if (len > (size_t)MB_CUR_MAX_L(loc)) {
56 /* Enough space to translate in-place. */
57 if ((nb = wcrtomb_l(dst, *s, ps, loc)) == (size_t)-1) {
58 *src = s;
59 return ((size_t)-1);
60 }
61 } else {
62 /*
63 * May not be enough space; use temp. buffer.
64 *
65 * We need to save a copy of the conversion state
66 * here so we can restore it if the multibyte
67 * character is too long for the buffer.
68 */
69 mbsbak = *ps;
70 if ((nb = wcrtomb_l(buf, *s, ps, loc)) == (size_t)-1) {
71 *src = s;
72 return ((size_t)-1);
73 }
74 if (nb > (int)len) {
75 /* MB sequence for character won't fit. */
76 *ps = mbsbak;
77 break;
78 }
79 memcpy(dst, buf, nb);
80 }
81 if (*s == L'\0') {
82 *src = NULL;
83 return (nbytes + nb - 1);
84 }
85 s++;
86 dst += nb;
87 len -= nb;
88 nbytes += nb;
89 }
90 *src = s;
91 return (nbytes);
92}
lib/libcxx/src/support/solaris/xlocale.cpp deleted-68
......@@ -1,68 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifdef __sun__
10
11#include "__support/solaris/xlocale.h"
12#include <stdarg.h>
13#include <stdio.h>
14#include <sys/localedef.h>
15
16extern "C" {
17
18int isxdigit_l(int __c, locale_t __l) {
19 return isxdigit(__c);
20}
21
22int iswxdigit_l(wint_t __c, locale_t __l) {
23 return isxdigit(__c);
24}
25
26// FIXME: This disregards the locale, which is Very Wrong
27#define vsnprintf_l(__s, __n, __l, __format, __va) \
28 vsnprintf(__s, __n, __format, __va)
29
30int snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...)
31{
32 va_list __va;
33 va_start(__va, __format);
34 int __res = vsnprintf_l(__s, __n , __l, __format, __va);
35 va_end(__va);
36 return __res;
37}
38
39int asprintf_l(char **__s, locale_t __l, const char *__format, ...) {
40 va_list __va;
41 va_start(__va, __format);
42 // FIXME:
43 int __res = vasprintf(__s, __format, __va);
44 va_end(__va);
45 return __res;
46}
47
48int sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {
49 va_list __va;
50 va_start(__va, __format);
51 // FIXME:
52 int __res = vsscanf(__s, __format, __va);
53 va_end(__va);
54 return __res;
55}
56
57size_t mbrtowc_l(wchar_t *__pwc, const char *__pmb,
58 size_t __max, mbstate_t *__ps, locale_t __loc) {
59 return mbrtowc(__pwc, __pmb, __max, __ps);
60}
61
62struct lconv *localeconv_l(locale_t __l) {
63 return localeconv();
64}
65
66};
67
68#endif // __sun__
lib/libcxx/src/support/win32/locale_win32.cpp+2
......@@ -11,6 +11,8 @@
1111#include <memory>
1212#include <type_traits>
1313
14#include <__locale_dir/locale_base_api/locale_guard.h>
15
1416int __libcpp_vasprintf(char **sptr, const char *__restrict fmt, va_list ap);
1517
1618using std::__libcpp_locale_guard;
lib/libcxx/src/system_error.cpp+4-5
......@@ -12,6 +12,7 @@
1212#endif
1313
1414#include <__assert>
15#include <__verbose_abort>
1516#include <cerrno>
1617#include <cstdio>
1718#include <cstdlib>
......@@ -103,7 +104,7 @@ handle_strerror_r_return(int strerror_return, char *buffer) {
103104 if (new_errno == EINVAL)
104105 return "";
105106
106 _LIBCPP_ASSERT(new_errno == ERANGE, "unexpected error from ::strerror_r");
107 _LIBCPP_ASSERT_UNCATEGORIZED(new_errno == ERANGE, "unexpected error from ::strerror_r");
107108 // FIXME maybe? 'strerror_buff_size' is likely to exceed the
108109 // maximum error size so ERANGE shouldn't be returned.
109110 std::abort();
......@@ -286,12 +287,10 @@ system_error::~system_error() noexcept
286287void
287288__throw_system_error(int ev, const char* what_arg)
288289{
289#ifndef _LIBCPP_NO_EXCEPTIONS
290#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
290291 throw system_error(error_code(ev, system_category()), what_arg);
291292#else
292 (void)ev;
293 (void)what_arg;
294 _VSTD::abort();
293 _LIBCPP_VERBOSE_ABORT("system_error was thrown in -fno-exceptions mode with error %i and message \"%s\"", ev, what_arg);
295294#endif
296295}
297296
lib/libcxx/src/thread.cpp+2
......@@ -10,6 +10,8 @@
1010
1111#ifndef _LIBCPP_HAS_NO_THREADS
1212
13#include <__thread/poll_with_backoff.h>
14#include <__thread/timed_backoff_policy.h>
1315#include <exception>
1416#include <future>
1517#include <limits>
lib/libcxx/src/utility.cpp deleted-15
......@@ -1,15 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <utility>
10
11_LIBCPP_BEGIN_NAMESPACE_STD
12
13const piecewise_construct_t piecewise_construct{};
14
15_LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/valarray.cpp+2-2
......@@ -12,8 +12,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
1212
1313// These two symbols are part of the v1 ABI but not part of the >=v2 ABI.
1414#if _LIBCPP_ABI_VERSION == 1
15template _LIBCPP_FUNC_VIS valarray<size_t>::valarray(size_t);
16template _LIBCPP_FUNC_VIS valarray<size_t>::~valarray();
15template _LIBCPP_EXPORTED_FROM_ABI valarray<size_t>::valarray(size_t);
16template _LIBCPP_EXPORTED_FROM_ABI valarray<size_t>::~valarray();
1717#endif
1818
1919template void valarray<size_t>::resize(size_t, size_t);
lib/libcxxabi/include/__cxxabi_config.h+1-1
......@@ -32,7 +32,7 @@
3232#endif
3333
3434#if defined(_WIN32)
35 #if defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS)
35 #if defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS) || (defined(__MINGW32__) && !defined(_LIBCXXABI_BUILDING_LIBRARY))
3636 #define _LIBCXXABI_HIDDEN
3737 #define _LIBCXXABI_DATA_VIS
3838 #define _LIBCXXABI_FUNC_VIS
lib/libcxxabi/src/aix_state_tab_eh.inc+56-29
......@@ -14,10 +14,6 @@
1414#include <stdio.h>
1515#include <sys/debug.h>
1616
17#if !__has_cpp_attribute(clang::optnone)
18#error This file requires clang::optnone attribute support
19#endif
20
2117/*
2218 The legacy IBM xlC and xlclang++ compilers use the state table for EH
2319 instead of the range table. Destructors, or addresses of the possible catch
......@@ -563,7 +559,8 @@ __xlcxx_personality_v0(int version, _Unwind_Action actions, uint64_t exceptionCl
563559 uintptr_t *currentSP = reinterpret_cast<uintptr_t*>(_Unwind_GetGR(context, 1));
564560 uintptr_t *callersSP = reinterpret_cast<uintptr_t*>(currentSP[0]);
565561 callersSP[3] = reinterpret_cast<uintptr_t>(unwind_exception);
566 _LIBCXXABI_TRACE_STATETAB("Handshake: set unwind_exception=%p in stack=%p\n", reinterpret_cast<void*>(unwind_exception), reinterpret_cast<void*>(callersSP));
562 _LIBCXXABI_TRACE_STATETAB("Handshake: save unwind_exception=%p in stack=%p\n",
563 reinterpret_cast<void*>(unwind_exception), reinterpret_cast<void*>(callersSP));
567564 // Jump to the handler.
568565 _Unwind_SetIP(context, results.landingPad);
569566 return _URC_INSTALL_CONTEXT;
......@@ -641,38 +638,68 @@ _LIBCXXABI_FUNC_VIS void __xlc_throw_badexception() {
641638 __cxa_throw(newexception, const_cast<std::type_info*>(&typeid(std::bad_exception)), 0);
642639}
643640
644// force_a_stackframe
645// This function is called by __xlc_exception_handle() to ensure a stack frame
646// is created for __xlc_exception_handle().
647__attribute__((noinline, optnone))
648static void force_a_stackframe() {}
641// skip_non_cxx_eh_aware_frames
642// This function skips non-C++ EH aware stack frames by unwinding from the
643// stack frame pointed by 'Sp' and returns the first C++ EH aware stack frame
644// found. 'Pc' is an instruction address inside the function that owns the
645// stack frame pointed to by 'Sp'.
646static uintptr_t* skip_non_cxx_eh_aware_frames(uint32_t* Pc, uintptr_t* Sp) {
647 uint32_t* currentPc = Pc;
648 uintptr_t* currentStack = Sp;
649
650 // Loop until a C++ EH aware frame is found or the return address is 0,
651 // which is the return address of the startup function '__start'.
652 while (currentPc != 0) {
653 uint32_t* p = currentPc;
654
655 // Keep looking forward until a word of 0 is found. The traceback
656 // table starts at the following word.
657 while (*p)
658 ++p;
659 tbtable* TBTable = reinterpret_cast<tbtable*>(p + 1);
660
661 // A stack frame with a C++ state table is C++ EH aware.
662 if (TBTable->tb.lang == TB_CPLUSPLUS && TBTable->tb.has_ctl)
663 return currentStack;
664
665 // Move up one stack frame.
666 currentStack = reinterpret_cast<uintptr_t*>(currentStack[0]);
667 // Get the value of the LR (saved, prior to incrementing the SP, by the
668 // prolog of the function just inspected) from the frame.
669 currentPc = reinterpret_cast<uint32_t*>(currentStack[2]);
670 }
671 // This should not happen.
672 _LIBCXXABI_TRACE_STATETAB0("skip_non_cxx_eh_aware_frames() reached the end of stack frames, aborting\n");
673 abort();
674}
649675
650676// __xlc_exception_handle
651677// This function is for xlclang++. It returns the address of the exception
652678// object stored in the reserved field in the stack of the caller of the
653679// function that calls __xlc_exception_handle() (within the link area for the
654680// call to the latter). The address is stored by the personality routine for
655// xlclang++ compiled code. The implementation of __xlc_exception_handle()
656// assumes a stack frame is created for it. The following ensures this
657// assumption holds true: 1) a call to force_a_stackframe() is made inside
658// __xlc_exception_handle() to make it non-leaf; and 2) optimizations are
659// disabled for this function with attribute 'optnone'. Note: this function
660// may not work as expected if these are changed.
661__attribute__((optnone))
681// xlclang++ compiled code. If __xlc_exception_handle() is called by
682// non-C++ EH aware functions, their frames are skipped until a C++ EH aware
683// frame is found.
684// Note: make sure __xlc_excpetion_handle() is a non-leaf function. Currently
685// it calls skip_non_cxx_eh_aware_frames(), which in turn calls abort().
662686_LIBCXXABI_FUNC_VIS uintptr_t __xlc_exception_handle() {
663 // Make a call to force_a_stackframe() so that the compiler creates a stack
664 // frame for this function.
665 force_a_stackframe();
666
667687 // Get the SP of this function, i.e., __xlc_exception_handle().
668 uintptr_t *lastStack;
669 asm("mr %0, 1" : "=r"(lastStack));
670 // Get the SP of the caller of __xlc_exception_handle().
671 uintptr_t *callerStack = reinterpret_cast<uintptr_t*>(lastStack[0]);
672 // Get the SP of the caller of the caller.
673 uintptr_t *callerStack2 = reinterpret_cast<uintptr_t*>(callerStack[0]);
674 uintptr_t exceptionObject = callerStack2[3];
675 _LIBCXXABI_TRACE_STATETAB("Handshake: exceptionObject=%p from stack=%p\n", reinterpret_cast<void*>(exceptionObject), reinterpret_cast<void*>(callerStack2));
688 uintptr_t* lastStack = reinterpret_cast<uintptr_t*>(__builtin_frame_address(0));
689 // Move one frame up to the frame of the caller of __xlc_exception_handle().
690 lastStack = reinterpret_cast<uintptr_t*>(lastStack[0]);
691 // Get the return address of this function, i.e., __xlc_exception_handle().
692 uint32_t* returnAddress = reinterpret_cast<uint32_t*>(__builtin_return_address(0));
693
694 // Skip non-C++ EH aware frames and get the first C++ EH aware frame.
695 uintptr_t* callerStack = skip_non_cxx_eh_aware_frames(returnAddress, lastStack);
696
697 // Get the SP of the caller of the C++ EH aware caller.
698 callerStack = reinterpret_cast<uintptr_t*>(callerStack[0]);
699 // Retrieve the exception object in the stack slot saved by the personality.
700 uintptr_t exceptionObject = callerStack[3];
701 _LIBCXXABI_TRACE_STATETAB("Handshake: retrieve exceptionObject=%p from stack=%p\n",
702 reinterpret_cast<void*>(exceptionObject), reinterpret_cast<void*>(callerStack));
676703 return exceptionObject;
677704}
678705
lib/libcxxabi/src/cxa_aux_runtime.cpp+1
......@@ -10,6 +10,7 @@
1010//===----------------------------------------------------------------------===//
1111
1212#include "cxxabi.h"
13#include <exception>
1314#include <new>
1415#include <typeinfo>
1516
lib/libcxxabi/src/cxa_demangle.cpp+4-2
......@@ -10,6 +10,7 @@
1010// file does not yet support:
1111// - C++ modules TS
1212
13#include "demangle/DemangleConfig.h"
1314#include "demangle/ItaniumDemangle.h"
1415#include "__cxxabi_config.h"
1516#include <cassert>
......@@ -19,6 +20,7 @@
1920#include <cstring>
2021#include <functional>
2122#include <numeric>
23#include <string_view>
2224#include <utility>
2325
2426using namespace itanium_demangle;
......@@ -77,8 +79,8 @@ struct DumpVisitor {
7779 }
7880
7981 void printStr(const char *S) { fprintf(stderr, "%s", S); }
80 void print(StringView SV) {
81 fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.begin());
82 void print(std::string_view SV) {
83 fprintf(stderr, "\"%.*s\"", (int)SV.size(), &*SV.begin());
8284 }
8385 void print(const Node *N) {
8486 if (N)
lib/libcxxabi/src/cxa_guard_impl.h+3-3
......@@ -255,7 +255,7 @@ struct InitByteNoThreads {
255255 if (*init_byte_address == COMPLETE_BIT)
256256 return true;
257257 if (*init_byte_address & PENDING_BIT)
258 ABORT_WITH_MESSAGE("__cxa_guard_acquire detected recursive initialization");
258 ABORT_WITH_MESSAGE("__cxa_guard_acquire detected recursive initialization: do you have a function-local static variable whose initialization depends on that function?");
259259 *init_byte_address = PENDING_BIT;
260260 return false;
261261 }
......@@ -325,7 +325,7 @@ public:
325325 // Check for possible recursive initialization.
326326 if (has_thread_id_support && (*init_byte_address & PENDING_BIT)) {
327327 if (*thread_id_address == current_thread_id.get())
328 ABORT_WITH_MESSAGE("__cxa_guard_acquire detected recursive initialization");
328 ABORT_WITH_MESSAGE("__cxa_guard_acquire detected recursive initialization: do you have a function-local static variable whose initialization depends on that function?");
329329 }
330330
331331 // Wait until the pending bit is not set.
......@@ -460,7 +460,7 @@ public:
460460
461461 // Check for recursive initialization
462462 if (has_thread_id_support && thread_id.load(std::_AO_Relaxed) == current_thread_id.get()) {
463 ABORT_WITH_MESSAGE("__cxa_guard_acquire detected recursive initialization");
463 ABORT_WITH_MESSAGE("__cxa_guard_acquire detected recursive initialization: do you have a function-local static variable whose initialization depends on that function?");
464464 }
465465
466466 if ((last_val & WAITING_BIT) == 0) {
lib/libcxxabi/src/demangle/DemangleConfig.h+8
......@@ -11,6 +11,14 @@
1111#ifndef LIBCXXABI_DEMANGLE_DEMANGLE_CONFIG_H
1212#define LIBCXXABI_DEMANGLE_DEMANGLE_CONFIG_H
1313
14// Must be defined before pulling in headers from libc++. Allow downstream
15// build systems to override this value.
16// https://libcxx.llvm.org/UsingLibcxx.html#enabling-the-safe-libc-mode
17#ifndef _LIBCPP_VERBOSE_ABORT
18#define _LIBCPP_VERBOSE_ABORT(...) abort_message(__VA_ARGS__)
19#include "../abort_message.h"
20#endif
21
1422#include <ciso646>
1523
1624#ifdef _MSC_VER
lib/libcxxabi/src/demangle/ItaniumDemangle.h+154-134
......@@ -17,8 +17,9 @@
1717#define DEMANGLE_ITANIUMDEMANGLE_H
1818
1919#include "DemangleConfig.h"
20#include "StringView.h"
20#include "StringViewExtras.h"
2121#include "Utility.h"
22#include <__cxxabi_config.h>
2223#include <algorithm>
2324#include <cassert>
2425#include <cctype>
......@@ -27,8 +28,15 @@
2728#include <cstring>
2829#include <limits>
2930#include <new>
31#include <string_view>
32#include <type_traits>
3033#include <utility>
3134
35#ifdef _LIBCXXABI_COMPILER_CLANG
36#pragma clang diagnostic push
37#pragma clang diagnostic ignored "-Wunused-template"
38#endif
39
3240DEMANGLE_NAMESPACE_BEGIN
3341
3442template <class T, size_t N> class PODSmallVector {
......@@ -286,7 +294,7 @@ public:
286294 // implementation.
287295 virtual void printRight(OutputBuffer &) const {}
288296
289 virtual StringView getBaseName() const { return StringView(); }
297 virtual std::string_view getBaseName() const { return {}; }
290298
291299 // Silence compiler warnings, this dtor will never be called.
292300 virtual ~Node() = default;
......@@ -345,10 +353,10 @@ struct NodeArrayNode : Node {
345353
346354class DotSuffix final : public Node {
347355 const Node *Prefix;
348 const StringView Suffix;
356 const std::string_view Suffix;
349357
350358public:
351 DotSuffix(const Node *Prefix_, StringView Suffix_)
359 DotSuffix(const Node *Prefix_, std::string_view Suffix_)
352360 : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
353361
354362 template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); }
......@@ -363,15 +371,15 @@ public:
363371
364372class VendorExtQualType final : public Node {
365373 const Node *Ty;
366 StringView Ext;
374 std::string_view Ext;
367375 const Node *TA;
368376
369377public:
370 VendorExtQualType(const Node *Ty_, StringView Ext_, const Node *TA_)
378 VendorExtQualType(const Node *Ty_, std::string_view Ext_, const Node *TA_)
371379 : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {}
372380
373381 const Node *getTy() const { return Ty; }
374 StringView getExt() const { return Ext; }
382 std::string_view getExt() const { return Ext; }
375383 const Node *getTA() const { return TA; }
376384
377385 template <typename Fn> void match(Fn F) const { F(Ty, Ext, TA); }
......@@ -462,10 +470,10 @@ public:
462470
463471class PostfixQualifiedType final : public Node {
464472 const Node *Ty;
465 const StringView Postfix;
473 const std::string_view Postfix;
466474
467475public:
468 PostfixQualifiedType(const Node *Ty_, StringView Postfix_)
476 PostfixQualifiedType(const Node *Ty_, std::string_view Postfix_)
469477 : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {}
470478
471479 template<typename Fn> void match(Fn F) const { F(Ty, Postfix); }
......@@ -477,15 +485,15 @@ public:
477485};
478486
479487class NameType final : public Node {
480 const StringView Name;
488 const std::string_view Name;
481489
482490public:
483 NameType(StringView Name_) : Node(KNameType), Name(Name_) {}
491 NameType(std::string_view Name_) : Node(KNameType), Name(Name_) {}
484492
485493 template<typename Fn> void match(Fn F) const { F(Name); }
486494
487 StringView getName() const { return Name; }
488 StringView getBaseName() const override { return Name; }
495 std::string_view getName() const { return Name; }
496 std::string_view getBaseName() const override { return Name; }
489497
490498 void printLeft(OutputBuffer &OB) const override { OB += Name; }
491499};
......@@ -511,10 +519,10 @@ public:
511519};
512520
513521class ElaboratedTypeSpefType : public Node {
514 StringView Kind;
522 std::string_view Kind;
515523 Node *Child;
516524public:
517 ElaboratedTypeSpefType(StringView Kind_, Node *Child_)
525 ElaboratedTypeSpefType(std::string_view Kind_, Node *Child_)
518526 : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {}
519527
520528 template<typename Fn> void match(Fn F) const { F(Kind, Child); }
......@@ -528,15 +536,17 @@ public:
528536
529537struct AbiTagAttr : Node {
530538 Node *Base;
531 StringView Tag;
539 std::string_view Tag;
532540
533 AbiTagAttr(Node* Base_, StringView Tag_)
534 : Node(KAbiTagAttr, Base_->RHSComponentCache,
535 Base_->ArrayCache, Base_->FunctionCache),
541 AbiTagAttr(Node *Base_, std::string_view Tag_)
542 : Node(KAbiTagAttr, Base_->RHSComponentCache, Base_->ArrayCache,
543 Base_->FunctionCache),
536544 Base(Base_), Tag(Tag_) {}
537545
538546 template<typename Fn> void match(Fn F) const { F(Base, Tag); }
539547
548 std::string_view getBaseName() const override { return Base->getBaseName(); }
549
540550 void printLeft(OutputBuffer &OB) const override {
541551 Base->printLeft(OB);
542552 OB += "[abi:";
......@@ -562,12 +572,12 @@ public:
562572
563573class ObjCProtoName : public Node {
564574 const Node *Ty;
565 StringView Protocol;
575 std::string_view Protocol;
566576
567577 friend class PointerType;
568578
569579public:
570 ObjCProtoName(const Node *Ty_, StringView Protocol_)
580 ObjCProtoName(const Node *Ty_, std::string_view Protocol_)
571581 : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
572582
573583 template<typename Fn> void match(Fn F) const { F(Ty, Protocol); }
......@@ -944,11 +954,11 @@ public:
944954};
945955
946956class SpecialName final : public Node {
947 const StringView Special;
957 const std::string_view Special;
948958 const Node *Child;
949959
950960public:
951 SpecialName(StringView Special_, const Node *Child_)
961 SpecialName(std::string_view Special_, const Node *Child_)
952962 : Node(KSpecialName), Special(Special_), Child(Child_) {}
953963
954964 template<typename Fn> void match(Fn F) const { F(Special, Child); }
......@@ -987,7 +997,7 @@ struct NestedName : Node {
987997
988998 template<typename Fn> void match(Fn F) const { F(Qual, Name); }
989999
990 StringView getBaseName() const override { return Name->getBaseName(); }
1000 std::string_view getBaseName() const override { return Name->getBaseName(); }
9911001
9921002 void printLeft(OutputBuffer &OB) const override {
9931003 Qual->print(OB);
......@@ -1027,7 +1037,7 @@ struct ModuleEntity : Node {
10271037
10281038 template <typename Fn> void match(Fn F) const { F(Module, Name); }
10291039
1030 StringView getBaseName() const override { return Name->getBaseName(); }
1040 std::string_view getBaseName() const override { return Name->getBaseName(); }
10311041
10321042 void printLeft(OutputBuffer &OB) const override {
10331043 Name->print(OB);
......@@ -1063,7 +1073,7 @@ public:
10631073
10641074 template<typename Fn> void match(Fn F) const { F(Qualifier, Name); }
10651075
1066 StringView getBaseName() const override { return Name->getBaseName(); }
1076 std::string_view getBaseName() const override { return Name->getBaseName(); }
10671077
10681078 void printLeft(OutputBuffer &OB) const override {
10691079 Qualifier->print(OB);
......@@ -1485,7 +1495,7 @@ struct NameWithTemplateArgs : Node {
14851495
14861496 template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); }
14871497
1488 StringView getBaseName() const override { return Name->getBaseName(); }
1498 std::string_view getBaseName() const override { return Name->getBaseName(); }
14891499
14901500 void printLeft(OutputBuffer &OB) const override {
14911501 Name->print(OB);
......@@ -1502,7 +1512,7 @@ public:
15021512
15031513 template<typename Fn> void match(Fn F) const { F(Child); }
15041514
1505 StringView getBaseName() const override { return Child->getBaseName(); }
1515 std::string_view getBaseName() const override { return Child->getBaseName(); }
15061516
15071517 void printLeft(OutputBuffer &OB) const override {
15081518 OB += "::";
......@@ -1538,20 +1548,20 @@ protected:
15381548 return unsigned(SSK) >= unsigned(SpecialSubKind::string);
15391549 }
15401550
1541 StringView getBaseName() const override {
1551 std::string_view getBaseName() const override {
15421552 switch (SSK) {
15431553 case SpecialSubKind::allocator:
1544 return StringView("allocator");
1554 return {"allocator"};
15451555 case SpecialSubKind::basic_string:
1546 return StringView("basic_string");
1556 return {"basic_string"};
15471557 case SpecialSubKind::string:
1548 return StringView("basic_string");
1558 return {"basic_string"};
15491559 case SpecialSubKind::istream:
1550 return StringView("basic_istream");
1560 return {"basic_istream"};
15511561 case SpecialSubKind::ostream:
1552 return StringView("basic_ostream");
1562 return {"basic_ostream"};
15531563 case SpecialSubKind::iostream:
1554 return StringView("basic_iostream");
1564 return {"basic_iostream"};
15551565 }
15561566 DEMANGLE_UNREACHABLE;
15571567 }
......@@ -1575,12 +1585,12 @@ public:
15751585
15761586 template<typename Fn> void match(Fn F) const { F(SSK); }
15771587
1578 StringView getBaseName() const override {
1579 auto SV = ExpandedSpecialSubstitution::getBaseName ();
1588 std::string_view getBaseName() const override {
1589 std::string_view SV = ExpandedSpecialSubstitution::getBaseName();
15801590 if (isInstantiation()) {
15811591 // The instantiations are typedefs that drop the "basic_" prefix.
1582 assert(SV.startsWith("basic_"));
1583 SV = SV.dropFront(sizeof("basic_") - 1);
1592 assert(starts_with(SV, "basic_"));
1593 SV.remove_prefix(sizeof("basic_") - 1);
15841594 }
15851595 return SV;
15861596 }
......@@ -1628,10 +1638,11 @@ public:
16281638};
16291639
16301640class UnnamedTypeName : public Node {
1631 const StringView Count;
1641 const std::string_view Count;
16321642
16331643public:
1634 UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {}
1644 UnnamedTypeName(std::string_view Count_)
1645 : Node(KUnnamedTypeName), Count(Count_) {}
16351646
16361647 template<typename Fn> void match(Fn F) const { F(Count); }
16371648
......@@ -1645,11 +1656,11 @@ public:
16451656class ClosureTypeName : public Node {
16461657 NodeArray TemplateParams;
16471658 NodeArray Params;
1648 StringView Count;
1659 std::string_view Count;
16491660
16501661public:
16511662 ClosureTypeName(NodeArray TemplateParams_, NodeArray Params_,
1652 StringView Count_)
1663 std::string_view Count_)
16531664 : Node(KClosureTypeName), TemplateParams(TemplateParams_),
16541665 Params(Params_), Count(Count_) {}
16551666
......@@ -1696,12 +1707,12 @@ public:
16961707
16971708class BinaryExpr : public Node {
16981709 const Node *LHS;
1699 const StringView InfixOperator;
1710 const std::string_view InfixOperator;
17001711 const Node *RHS;
17011712
17021713public:
1703 BinaryExpr(const Node *LHS_, StringView InfixOperator_, const Node *RHS_,
1704 Prec Prec_)
1714 BinaryExpr(const Node *LHS_, std::string_view InfixOperator_,
1715 const Node *RHS_, Prec Prec_)
17051716 : Node(KBinaryExpr, Prec_), LHS(LHS_), InfixOperator(InfixOperator_),
17061717 RHS(RHS_) {}
17071718
......@@ -1750,10 +1761,10 @@ public:
17501761
17511762class PostfixExpr : public Node {
17521763 const Node *Child;
1753 const StringView Operator;
1764 const std::string_view Operator;
17541765
17551766public:
1756 PostfixExpr(const Node *Child_, StringView Operator_, Prec Prec_)
1767 PostfixExpr(const Node *Child_, std::string_view Operator_, Prec Prec_)
17571768 : Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {}
17581769
17591770 template <typename Fn> void match(Fn F) const {
......@@ -1791,11 +1802,12 @@ public:
17911802
17921803class MemberExpr : public Node {
17931804 const Node *LHS;
1794 const StringView Kind;
1805 const std::string_view Kind;
17951806 const Node *RHS;
17961807
17971808public:
1798 MemberExpr(const Node *LHS_, StringView Kind_, const Node *RHS_, Prec Prec_)
1809 MemberExpr(const Node *LHS_, std::string_view Kind_, const Node *RHS_,
1810 Prec Prec_)
17991811 : Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
18001812
18011813 template <typename Fn> void match(Fn F) const {
......@@ -1812,13 +1824,14 @@ public:
18121824class SubobjectExpr : public Node {
18131825 const Node *Type;
18141826 const Node *SubExpr;
1815 StringView Offset;
1827 std::string_view Offset;
18161828 NodeArray UnionSelectors;
18171829 bool OnePastTheEnd;
18181830
18191831public:
1820 SubobjectExpr(const Node *Type_, const Node *SubExpr_, StringView Offset_,
1821 NodeArray UnionSelectors_, bool OnePastTheEnd_)
1832 SubobjectExpr(const Node *Type_, const Node *SubExpr_,
1833 std::string_view Offset_, NodeArray UnionSelectors_,
1834 bool OnePastTheEnd_)
18221835 : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
18231836 UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
18241837
......@@ -1835,7 +1848,7 @@ public:
18351848 OB += "0";
18361849 } else if (Offset[0] == 'n') {
18371850 OB += "-";
1838 OB += Offset.dropFront();
1851 OB += std::string_view(Offset.data() + 1, Offset.size() - 1);
18391852 } else {
18401853 OB += Offset;
18411854 }
......@@ -1844,12 +1857,12 @@ public:
18441857};
18451858
18461859class EnclosingExpr : public Node {
1847 const StringView Prefix;
1860 const std::string_view Prefix;
18481861 const Node *Infix;
1849 const StringView Postfix;
1862 const std::string_view Postfix;
18501863
18511864public:
1852 EnclosingExpr(StringView Prefix_, const Node *Infix_,
1865 EnclosingExpr(std::string_view Prefix_, const Node *Infix_,
18531866 Prec Prec_ = Prec::Primary)
18541867 : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {}
18551868
......@@ -1868,12 +1881,13 @@ public:
18681881
18691882class CastExpr : public Node {
18701883 // cast_kind<to>(from)
1871 const StringView CastKind;
1884 const std::string_view CastKind;
18721885 const Node *To;
18731886 const Node *From;
18741887
18751888public:
1876 CastExpr(StringView CastKind_, const Node *To_, const Node *From_, Prec Prec_)
1889 CastExpr(std::string_view CastKind_, const Node *To_, const Node *From_,
1890 Prec Prec_)
18771891 : Node(KCastExpr, Prec_), CastKind(CastKind_), To(To_), From(From_) {}
18781892
18791893 template <typename Fn> void match(Fn F) const {
......@@ -1996,11 +2010,11 @@ public:
19962010};
19972011
19982012class PrefixExpr : public Node {
1999 StringView Prefix;
2013 std::string_view Prefix;
20002014 Node *Child;
20012015
20022016public:
2003 PrefixExpr(StringView Prefix_, Node *Child_, Prec Prec_)
2017 PrefixExpr(std::string_view Prefix_, Node *Child_, Prec Prec_)
20042018 : Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {}
20052019
20062020 template <typename Fn> void match(Fn F) const {
......@@ -2014,10 +2028,11 @@ public:
20142028};
20152029
20162030class FunctionParam : public Node {
2017 StringView Number;
2031 std::string_view Number;
20182032
20192033public:
2020 FunctionParam(StringView Number_) : Node(KFunctionParam), Number(Number_) {}
2034 FunctionParam(std::string_view Number_)
2035 : Node(KFunctionParam), Number(Number_) {}
20212036
20222037 template<typename Fn> void match(Fn F) const { F(Number); }
20232038
......@@ -2052,11 +2067,11 @@ public:
20522067class PointerToMemberConversionExpr : public Node {
20532068 const Node *Type;
20542069 const Node *SubExpr;
2055 StringView Offset;
2070 std::string_view Offset;
20562071
20572072public:
20582073 PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
2059 StringView Offset_, Prec Prec_)
2074 std::string_view Offset_, Prec Prec_)
20602075 : Node(KPointerToMemberConversionExpr, Prec_), Type(Type_),
20612076 SubExpr(SubExpr_), Offset(Offset_) {}
20622077
......@@ -2141,11 +2156,11 @@ public:
21412156
21422157class FoldExpr : public Node {
21432158 const Node *Pack, *Init;
2144 StringView OperatorName;
2159 std::string_view OperatorName;
21452160 bool IsLeftFold;
21462161
21472162public:
2148 FoldExpr(bool IsLeftFold_, StringView OperatorName_, const Node *Pack_,
2163 FoldExpr(bool IsLeftFold_, std::string_view OperatorName_, const Node *Pack_,
21492164 const Node *Init_)
21502165 : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
21512166 IsLeftFold(IsLeftFold_) {}
......@@ -2209,7 +2224,7 @@ public:
22092224 template<typename Fn> void match(Fn F) const { F(Value); }
22102225
22112226 void printLeft(OutputBuffer &OB) const override {
2212 OB += Value ? StringView("true") : StringView("false");
2227 OB += Value ? std::string_view("true") : std::string_view("false");
22132228 }
22142229};
22152230
......@@ -2247,10 +2262,10 @@ public:
22472262class EnumLiteral : public Node {
22482263 // ty(integer)
22492264 const Node *Ty;
2250 StringView Integer;
2265 std::string_view Integer;
22512266
22522267public:
2253 EnumLiteral(const Node *Ty_, StringView Integer_)
2268 EnumLiteral(const Node *Ty_, std::string_view Integer_)
22542269 : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
22552270
22562271 template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
......@@ -2261,18 +2276,18 @@ public:
22612276 OB.printClose();
22622277
22632278 if (Integer[0] == 'n')
2264 OB << "-" << Integer.dropFront(1);
2279 OB << '-' << std::string_view(Integer.data() + 1, Integer.size() - 1);
22652280 else
22662281 OB << Integer;
22672282 }
22682283};
22692284
22702285class IntegerLiteral : public Node {
2271 StringView Type;
2272 StringView Value;
2286 std::string_view Type;
2287 std::string_view Value;
22732288
22742289public:
2275 IntegerLiteral(StringView Type_, StringView Value_)
2290 IntegerLiteral(std::string_view Type_, std::string_view Value_)
22762291 : Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
22772292
22782293 template<typename Fn> void match(Fn F) const { F(Type, Value); }
......@@ -2284,10 +2299,9 @@ public:
22842299 OB.printClose();
22852300 }
22862301
2287 if (Value[0] == 'n') {
2288 OB += '-';
2289 OB += Value.dropFront(1);
2290 } else
2302 if (Value[0] == 'n')
2303 OB << '-' << std::string_view(Value.data() + 1, Value.size() - 1);
2304 else
22912305 OB += Value;
22922306
22932307 if (Type.size() <= 3)
......@@ -2310,29 +2324,26 @@ constexpr Node::Kind getFloatLiteralKind(long double *) {
23102324}
23112325
23122326template <class Float> class FloatLiteralImpl : public Node {
2313 const StringView Contents;
2327 const std::string_view Contents;
23142328
23152329 static constexpr Kind KindForClass =
23162330 float_literal_impl::getFloatLiteralKind((Float *)nullptr);
23172331
23182332public:
2319 FloatLiteralImpl(StringView Contents_)
2333 FloatLiteralImpl(std::string_view Contents_)
23202334 : Node(KindForClass), Contents(Contents_) {}
23212335
23222336 template<typename Fn> void match(Fn F) const { F(Contents); }
23232337
23242338 void printLeft(OutputBuffer &OB) const override {
2325 const char *first = Contents.begin();
2326 const char *last = Contents.end() + 1;
2327
23282339 const size_t N = FloatData<Float>::mangled_size;
2329 if (static_cast<std::size_t>(last - first) > N) {
2330 last = first + N;
2340 if (Contents.size() >= N) {
23312341 union {
23322342 Float value;
23332343 char buf[sizeof(Float)];
23342344 };
2335 const char *t = first;
2345 const char *t = Contents.data();
2346 const char *last = t + N;
23362347 char *e = buf;
23372348 for (; t != last; ++t, ++e) {
23382349 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
......@@ -2347,7 +2358,7 @@ public:
23472358#endif
23482359 char num[FloatData<Float>::max_demangled_size] = {0};
23492360 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
2350 OB += StringView(num, num + n);
2361 OB += std::string_view(num, n);
23512362 }
23522363 }
23532364};
......@@ -2474,8 +2485,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
24742485 return res;
24752486 }
24762487
2477 bool consumeIf(StringView S) {
2478 if (StringView(First, Last).startsWith(S)) {
2488 bool consumeIf(std::string_view S) {
2489 if (starts_with(std::string_view(First, Last - First), S)) {
24792490 First += S.size();
24802491 return true;
24812492 }
......@@ -2500,10 +2511,10 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
25002511
25012512 size_t numLeft() const { return static_cast<size_t>(Last - First); }
25022513
2503 StringView parseNumber(bool AllowNegative = false);
2514 std::string_view parseNumber(bool AllowNegative = false);
25042515 Qualifiers parseCVQualifiers();
25052516 bool parsePositiveInteger(size_t *Out);
2506 StringView parseBareSourceName();
2517 std::string_view parseBareSourceName();
25072518
25082519 bool parseSeqId(size_t *Out);
25092520 Node *parseSubstitution();
......@@ -2514,9 +2525,9 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
25142525
25152526 /// Parse the <expr> production.
25162527 Node *parseExpr();
2517 Node *parsePrefixExpr(StringView Kind, Node::Prec Prec);
2518 Node *parseBinaryExpr(StringView Kind, Node::Prec Prec);
2519 Node *parseIntegerLiteral(StringView Lit);
2528 Node *parsePrefixExpr(std::string_view Kind, Node::Prec Prec);
2529 Node *parseBinaryExpr(std::string_view Kind, Node::Prec Prec);
2530 Node *parseIntegerLiteral(std::string_view Lit);
25202531 Node *parseExprPrimary();
25212532 template <class Float> Node *parseFloatingLiteral();
25222533 Node *parseFunctionParam();
......@@ -2624,17 +2635,18 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
26242635 bool operator!=(const char *Peek) const { return !this->operator==(Peek); }
26252636
26262637 public:
2627 StringView getSymbol() const {
2628 StringView Res = Name;
2638 std::string_view getSymbol() const {
2639 std::string_view Res = Name;
26292640 if (Kind < Unnameable) {
2630 assert(Res.startsWith("operator") &&
2641 assert(starts_with(Res, "operator") &&
26312642 "operator name does not start with 'operator'");
2632 Res = Res.dropFront(sizeof("operator") - 1);
2633 Res.consumeFront(' ');
2643 Res.remove_prefix(sizeof("operator") - 1);
2644 if (starts_with(Res, ' '))
2645 Res.remove_prefix(1);
26342646 }
26352647 return Res;
26362648 }
2637 StringView getName() const { return Name; }
2649 std::string_view getName() const { return Name; }
26382650 OIKind getKind() const { return Kind; }
26392651 bool getFlag() const { return Flag; }
26402652 Node::Prec getPrecedence() const { return Prec; }
......@@ -2854,7 +2866,7 @@ AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
28542866 TemplateParams.clear();
28552867
28562868 if (consumeIf("Ut")) {
2857 StringView Count = parseNumber();
2869 std::string_view Count = parseNumber();
28582870 if (!consumeIf('_'))
28592871 return nullptr;
28602872 return make<UnnamedTypeName>(Count);
......@@ -2866,7 +2878,7 @@ AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
28662878
28672879 size_t ParamsBegin = Names.size();
28682880 while (look() == 'T' &&
2869 StringView("yptn").find(look(1)) != StringView::npos) {
2881 std::string_view("yptn").find(look(1)) != std::string_view::npos) {
28702882 Node *T = parseTemplateParamDecl();
28712883 if (!T)
28722884 return nullptr;
......@@ -2909,7 +2921,7 @@ AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
29092921 }
29102922 NodeArray Params = popTrailingNodeArray(ParamsBegin);
29112923
2912 StringView Count = parseNumber();
2924 std::string_view Count = parseNumber();
29132925 if (!consumeIf('_'))
29142926 return nullptr;
29152927 return make<ClosureTypeName>(TempParams, Params, Count);
......@@ -2931,9 +2943,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) {
29312943 return nullptr;
29322944 if (numLeft() < Length || Length == 0)
29332945 return nullptr;
2934 StringView Name(First, First + Length);
2946 std::string_view Name(First, Length);
29352947 First += Length;
2936 if (Name.startsWith("_GLOBAL__N"))
2948 if (starts_with(Name, "_GLOBAL__N"))
29372949 return make<NameType>("(anonymous namespace)");
29382950 return make<NameType>(Name);
29392951}
......@@ -3447,7 +3459,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) {
34473459template <typename Derived, typename Alloc>
34483460Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
34493461 while (consumeIf('B')) {
3450 StringView SN = parseBareSourceName();
3462 std::string_view SN = parseBareSourceName();
34513463 if (SN.empty())
34523464 return nullptr;
34533465 N = make<AbiTagAttr>(N, SN);
......@@ -3459,16 +3471,16 @@ Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
34593471
34603472// <number> ::= [n] <non-negative decimal integer>
34613473template <typename Alloc, typename Derived>
3462StringView
3474std::string_view
34633475AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) {
34643476 const char *Tmp = First;
34653477 if (AllowNegative)
34663478 consumeIf('n');
34673479 if (numLeft() == 0 || !std::isdigit(*First))
3468 return StringView();
3480 return std::string_view();
34693481 while (numLeft() != 0 && std::isdigit(*First))
34703482 ++First;
3471 return StringView(Tmp, First);
3483 return std::string_view(Tmp, First - Tmp);
34723484}
34733485
34743486// <positive length number> ::= [0-9]*
......@@ -3485,11 +3497,11 @@ bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) {
34853497}
34863498
34873499template <typename Alloc, typename Derived>
3488StringView AbstractManglingParser<Alloc, Derived>::parseBareSourceName() {
3500std::string_view AbstractManglingParser<Alloc, Derived>::parseBareSourceName() {
34893501 size_t Int = 0;
34903502 if (parsePositiveInteger(&Int) || numLeft() < Int)
3491 return StringView();
3492 StringView R(First, First + Int);
3503 return {};
3504 std::string_view R(First, Int);
34933505 First += Int;
34943506 return R;
34953507}
......@@ -3673,7 +3685,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() {
36733685// ::= Te <name> # dependent elaborated type specifier using 'enum'
36743686template <typename Derived, typename Alloc>
36753687Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
3676 StringView ElabSpef;
3688 std::string_view ElabSpef;
36773689 if (consumeIf("Ts"))
36783690 ElabSpef = "struct";
36793691 else if (consumeIf("Tu"))
......@@ -3697,17 +3709,18 @@ Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
36973709template <typename Derived, typename Alloc>
36983710Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
36993711 if (consumeIf('U')) {
3700 StringView Qual = parseBareSourceName();
3712 std::string_view Qual = parseBareSourceName();
37013713 if (Qual.empty())
37023714 return nullptr;
37033715
37043716 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3705 if (Qual.startsWith("objcproto")) {
3706 StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto"));
3707 StringView Proto;
3717 if (starts_with(Qual, "objcproto")) {
3718 constexpr size_t Len = sizeof("objcproto") - 1;
3719 std::string_view ProtoSourceName(Qual.data() + Len, Qual.size() - Len);
3720 std::string_view Proto;
37083721 {
3709 ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.begin()),
3710 SaveLast(Last, ProtoSourceName.end());
3722 ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.data()),
3723 SaveLast(Last, &*ProtoSourceName.rbegin() + 1);
37113724 Proto = parseBareSourceName();
37123725 }
37133726 if (Proto.empty())
......@@ -3875,7 +3888,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
38753888 // <builtin-type> ::= u <source-name> # vendor extended type
38763889 case 'u': {
38773890 ++First;
3878 StringView Res = parseBareSourceName();
3891 std::string_view Res = parseBareSourceName();
38793892 if (Res.empty())
38803893 return nullptr;
38813894 // Typically, <builtin-type>s are not considered substitution candidates,
......@@ -4123,8 +4136,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
41234136}
41244137
41254138template <typename Derived, typename Alloc>
4126Node *AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(StringView Kind,
4127 Node::Prec Prec) {
4139Node *
4140AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(std::string_view Kind,
4141 Node::Prec Prec) {
41284142 Node *E = getDerived().parseExpr();
41294143 if (E == nullptr)
41304144 return nullptr;
......@@ -4132,8 +4146,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(StringView Kind,
41324146}
41334147
41344148template <typename Derived, typename Alloc>
4135Node *AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(StringView Kind,
4136 Node::Prec Prec) {
4149Node *
4150AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(std::string_view Kind,
4151 Node::Prec Prec) {
41374152 Node *LHS = getDerived().parseExpr();
41384153 if (LHS == nullptr)
41394154 return nullptr;
......@@ -4144,9 +4159,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(StringView Kind,
41444159}
41454160
41464161template <typename Derived, typename Alloc>
4147Node *
4148AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(StringView Lit) {
4149 StringView Tmp = parseNumber(true);
4162Node *AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(
4163 std::string_view Lit) {
4164 std::string_view Tmp = parseNumber(true);
41504165 if (!Tmp.empty() && consumeIf('E'))
41514166 return make<IntegerLiteral>(Lit, Tmp);
41524167 return nullptr;
......@@ -4176,7 +4191,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
41764191 return make<NameType>("this");
41774192 if (consumeIf("fp")) {
41784193 parseCVQualifiers();
4179 StringView Num = parseNumber();
4194 std::string_view Num = parseNumber();
41804195 if (!consumeIf('_'))
41814196 return nullptr;
41824197 return make<FunctionParam>(Num);
......@@ -4187,7 +4202,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
41874202 if (!consumeIf('p'))
41884203 return nullptr;
41894204 parseCVQualifiers();
4190 StringView Num = parseNumber();
4205 std::string_view Num = parseNumber();
41914206 if (!consumeIf('_'))
41924207 return nullptr;
41934208 return make<FunctionParam>(Num);
......@@ -4341,7 +4356,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
43414356 Node *T = getDerived().parseType();
43424357 if (T == nullptr)
43434358 return nullptr;
4344 StringView N = parseNumber(/*AllowNegative=*/true);
4359 std::string_view N = parseNumber(/*AllowNegative=*/true);
43454360 if (N.empty())
43464361 return nullptr;
43474362 if (!consumeIf('E'))
......@@ -4464,7 +4479,7 @@ AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr(
44644479 Node *Expr = getDerived().parseExpr();
44654480 if (!Expr)
44664481 return nullptr;
4467 StringView Offset = getDerived().parseNumber(true);
4482 std::string_view Offset = getDerived().parseNumber(true);
44684483 if (!consumeIf('E'))
44694484 return nullptr;
44704485 return make<PointerToMemberConversionExpr>(Ty, Expr, Offset, Prec);
......@@ -4482,7 +4497,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
44824497 Node *Expr = getDerived().parseExpr();
44834498 if (!Expr)
44844499 return nullptr;
4485 StringView Offset = getDerived().parseNumber(true);
4500 std::string_view Offset = getDerived().parseNumber(true);
44864501 size_t SelectorsBegin = Names.size();
44874502 while (consumeIf('_')) {
44884503 Node *Selector = make<NameType>(parseNumber());
......@@ -5141,7 +5156,7 @@ Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() {
51415156 const size_t N = FloatData<Float>::mangled_size;
51425157 if (numLeft() <= N)
51435158 return nullptr;
5144 StringView Data(First, First + N);
5159 std::string_view Data(First, N);
51455160 for (char C : Data)
51465161 if (!std::isxdigit(C))
51475162 return nullptr;
......@@ -5461,7 +5476,8 @@ Node *AbstractManglingParser<Derived, Alloc>::parse() {
54615476 if (Encoding == nullptr)
54625477 return nullptr;
54635478 if (look() == '.') {
5464 Encoding = make<DotSuffix>(Encoding, StringView(First, Last));
5479 Encoding =
5480 make<DotSuffix>(Encoding, std::string_view(First, Last - First));
54655481 First = Last;
54665482 }
54675483 if (numLeft() != 0)
......@@ -5497,4 +5513,8 @@ struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
54975513
54985514DEMANGLE_NAMESPACE_END
54995515
5516#ifdef _LIBCXXABI_COMPILER_CLANG
5517#pragma clang diagnostic pop
5518#endif
5519
55005520#endif // DEMANGLE_ITANIUMDEMANGLE_H
lib/libcxxabi/src/demangle/StringView.h deleted-122
......@@ -1,122 +0,0 @@
1//===--- StringView.h -------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// FIXME: Use std::string_view instead when we support C++17.
10// There are two copies of this file in the source tree. The one under
11// libcxxabi is the original and the one under llvm is the copy. Use
12// cp-to-llvm.sh to update the copy. See README.txt for more details.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef DEMANGLE_STRINGVIEW_H
17#define DEMANGLE_STRINGVIEW_H
18
19#include "DemangleConfig.h"
20#include <cassert>
21#include <cstring>
22
23DEMANGLE_NAMESPACE_BEGIN
24
25class StringView {
26 const char *First;
27 const char *Last;
28
29public:
30 static const size_t npos = ~size_t(0);
31
32 template <size_t N>
33 StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
34 StringView(const char *First_, const char *Last_)
35 : First(First_), Last(Last_) {}
36 StringView(const char *First_, size_t Len)
37 : First(First_), Last(First_ + Len) {}
38 StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
39 StringView() : First(nullptr), Last(nullptr) {}
40
41 StringView substr(size_t Pos, size_t Len = npos) const {
42 assert(Pos <= size());
43 if (Len > size() - Pos)
44 Len = size() - Pos;
45 return StringView(begin() + Pos, Len);
46 }
47
48 size_t find(char C, size_t From = 0) const {
49 // Avoid calling memchr with nullptr.
50 if (From < size()) {
51 // Just forward to memchr, which is faster than a hand-rolled loop.
52 if (const void *P = ::memchr(First + From, C, size() - From))
53 return size_t(static_cast<const char *>(P) - First);
54 }
55 return npos;
56 }
57
58 StringView dropFront(size_t N = 1) const {
59 if (N >= size())
60 N = size();
61 return StringView(First + N, Last);
62 }
63
64 StringView dropBack(size_t N = 1) const {
65 if (N >= size())
66 N = size();
67 return StringView(First, Last - N);
68 }
69
70 char front() const {
71 assert(!empty());
72 return *begin();
73 }
74
75 char back() const {
76 assert(!empty());
77 return *(end() - 1);
78 }
79
80 char popFront() {
81 assert(!empty());
82 return *First++;
83 }
84
85 bool consumeFront(char C) {
86 if (!startsWith(C))
87 return false;
88 *this = dropFront(1);
89 return true;
90 }
91
92 bool consumeFront(StringView S) {
93 if (!startsWith(S))
94 return false;
95 *this = dropFront(S.size());
96 return true;
97 }
98
99 bool startsWith(char C) const { return !empty() && *begin() == C; }
100
101 bool startsWith(StringView Str) const {
102 if (Str.size() > size())
103 return false;
104 return std::strncmp(Str.begin(), begin(), Str.size()) == 0;
105 }
106
107 const char &operator[](size_t Idx) const { return *(begin() + Idx); }
108
109 const char *begin() const { return First; }
110 const char *end() const { return Last; }
111 size_t size() const { return static_cast<size_t>(Last - First); }
112 bool empty() const { return First == Last; }
113};
114
115inline bool operator==(const StringView &LHS, const StringView &RHS) {
116 return LHS.size() == RHS.size() &&
117 std::strncmp(LHS.begin(), RHS.begin(), LHS.size()) == 0;
118}
119
120DEMANGLE_NAMESPACE_END
121
122#endif
lib/libcxxabi/src/demangle/StringViewExtras.h created+38
......@@ -0,0 +1,38 @@
1//===--- StringViewExtras.h -------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// There are two copies of this file in the source tree. The one under
10// libcxxabi is the original and the one under llvm is the copy. Use
11// cp-to-llvm.sh to update the copy. See README.txt for more details.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef DEMANGLE_STRINGVIEW_H
16#define DEMANGLE_STRINGVIEW_H
17
18#include "DemangleConfig.h"
19
20#include <string_view>
21
22DEMANGLE_NAMESPACE_BEGIN
23
24inline bool starts_with(std::string_view self, char C) noexcept {
25 return !self.empty() && *self.begin() == C;
26}
27
28inline bool starts_with(std::string_view haystack,
29 std::string_view needle) noexcept {
30 if (needle.size() > haystack.size())
31 return false;
32 haystack.remove_suffix(haystack.size() - needle.size());
33 return haystack == needle;
34}
35
36DEMANGLE_NAMESPACE_END
37
38#endif
lib/libcxxabi/src/demangle/Utility.h+14-8
......@@ -16,13 +16,16 @@
1616#ifndef DEMANGLE_UTILITY_H
1717#define DEMANGLE_UTILITY_H
1818
19#include "StringView.h"
19#include "DemangleConfig.h"
20
2021#include <array>
22#include <cassert>
2123#include <cstdint>
2224#include <cstdlib>
2325#include <cstring>
2426#include <exception>
2527#include <limits>
28#include <string_view>
2629
2730DEMANGLE_NAMESPACE_BEGIN
2831
......@@ -64,7 +67,8 @@ class OutputBuffer {
6467 if (isNeg)
6568 *--TempPtr = '-';
6669
67 return operator+=(StringView(TempPtr, Temp.data() + Temp.size()));
70 return operator+=(
71 std::string_view(TempPtr, Temp.data() + Temp.size() - TempPtr));
6872 }
6973
7074public:
......@@ -77,7 +81,9 @@ public:
7781 OutputBuffer(const OutputBuffer &) = delete;
7882 OutputBuffer &operator=(const OutputBuffer &) = delete;
7983
80 operator StringView() const { return StringView(Buffer, CurrentPosition); }
84 operator std::string_view() const {
85 return std::string_view(Buffer, CurrentPosition);
86 }
8187
8288 /// If a ParameterPackExpansion (or similar type) is encountered, the offset
8389 /// into the pack that we're currently printing.
......@@ -99,10 +105,10 @@ public:
99105 *this += Close;
100106 }
101107
102 OutputBuffer &operator+=(StringView R) {
108 OutputBuffer &operator+=(std::string_view R) {
103109 if (size_t Size = R.size()) {
104110 grow(Size);
105 std::memcpy(Buffer + CurrentPosition, R.begin(), Size);
111 std::memcpy(Buffer + CurrentPosition, &*R.begin(), Size);
106112 CurrentPosition += Size;
107113 }
108114 return *this;
......@@ -114,18 +120,18 @@ public:
114120 return *this;
115121 }
116122
117 OutputBuffer &prepend(StringView R) {
123 OutputBuffer &prepend(std::string_view R) {
118124 size_t Size = R.size();
119125
120126 grow(Size);
121127 std::memmove(Buffer + Size, Buffer, CurrentPosition);
122 std::memcpy(Buffer, R.begin(), Size);
128 std::memcpy(Buffer, &*R.begin(), Size);
123129 CurrentPosition += Size;
124130
125131 return *this;
126132 }
127133
128 OutputBuffer &operator<<(StringView R) { return (*this += R); }
134 OutputBuffer &operator<<(std::string_view R) { return (*this += R); }
129135
130136 OutputBuffer &operator<<(char C) { return (*this += C); }
131137
lib/libcxxabi/src/fallback_malloc.cpp+1-1
......@@ -15,10 +15,10 @@
1515#endif
1616#endif
1717
18#include <__memory/aligned_alloc.h>
1819#include <assert.h>
1920#include <stdlib.h> // for malloc, calloc, free
2021#include <string.h> // for memset
21#include <new> // for std::__libcpp_aligned_{alloc,free}
2222
2323// A small, simple heap manager based (loosely) on
2424// the startup heap manager from FreeBSD, optimized for space.
lib/libcxxabi/src/private_typeinfo.cpp+124-62
......@@ -41,6 +41,7 @@
4141// Defining _LIBCXXABI_FORGIVING_DYNAMIC_CAST does not help since can_catch() calls
4242// is_equal() with use_strcmp=false so the string names are not compared.
4343
44#include <cstdint>
4445#include <string.h>
4546
4647#ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
......@@ -656,77 +657,138 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type,
656657 // Find out if we can use a giant short cut in the search
657658 if (is_equal(dynamic_type, dst_type, false))
658659 {
659 // Using giant short cut. Add that information to info.
660 info.number_of_dst_type = 1;
661 // Do the search
662 dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false);
663#ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
664 // The following if should always be false because we should definitely
665 // find (static_ptr, static_type), either on a public or private path
666 if (info.path_dst_ptr_to_static_ptr == unknown)
660 // We're downcasting from src_type to the complete object's dynamic
661 // type. This is a really hot path that can be further optimized
662 // with the `src2dst_offset` hint.
663 // In such a case, dynamic_ptr already gives the casting result if the
664 // casting ever succeeds. All we have to do now is to check
665 // static_ptr points to a public base sub-object of dynamic_ptr.
666
667 if (src2dst_offset >= 0)
667668 {
668 // We get here only if there is some kind of visibility problem
669 // in client code.
670 static_assert(std::atomic<size_t>::is_always_lock_free, "");
671 static std::atomic<size_t> error_count(0);
672 size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed);
673 if ((error_count_snapshot & (error_count_snapshot-1)) == 0)
674 syslog(LOG_ERR, "dynamic_cast error 1: Both of the following type_info's "
675 "should have public visibility. At least one of them is hidden. %s"
676 ", %s.\n", static_type->name(), dynamic_type->name());
677 // Redo the search comparing type_info's using strcmp
678 info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
679 info.number_of_dst_type = 1;
680 dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true);
669 // The static type is a unique public non-virtual base type of
670 // dst_type at offset `src2dst_offset` from the origin of dst.
671 // Note that there might be other non-public static_type bases. The
672 // hint only guarantees that the public base is non-virtual and
673 // unique. So we have to check whether static_ptr points to that
674 // unique public base sub-object.
675 if (offset_to_derived == -src2dst_offset)
676 dst_ptr = dynamic_ptr;
677 }
678 else if (src2dst_offset == -2)
679 {
680 // static_type is not a public base of dst_type.
681 dst_ptr = nullptr;
681682 }
683 else
684 {
685 // If src2dst_offset == -3, then:
686 // src_type is a multiple public base type but never a virtual
687 // base type. We can't conclude that static_ptr points to those
688 // public base sub-objects because there might be other non-
689 // public static_type bases. The search is inevitable.
690
691 // Fallback to the slow path to check that static_type is a public
692 // base type of dynamic_type.
693 // Using giant short cut. Add that information to info.
694 info.number_of_dst_type = 1;
695 // Do the search
696 dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false);
697#ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
698 // The following if should always be false because we should
699 // definitely find (static_ptr, static_type), either on a public
700 // or private path
701 if (info.path_dst_ptr_to_static_ptr == unknown)
702 {
703 // We get here only if there is some kind of visibility problem
704 // in client code.
705 static_assert(std::atomic<size_t>::is_always_lock_free, "");
706 static std::atomic<size_t> error_count(0);
707 size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed);
708 if ((error_count_snapshot & (error_count_snapshot-1)) == 0)
709 syslog(LOG_ERR, "dynamic_cast error 1: Both of the following type_info's "
710 "should have public visibility. At least one of them is hidden. %s"
711 ", %s.\n", static_type->name(), dynamic_type->name());
712 // Redo the search comparing type_info's using strcmp
713 info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
714 info.number_of_dst_type = 1;
715 dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true);
716 }
682717#endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST
683 // Query the search.
684 if (info.path_dst_ptr_to_static_ptr == public_path)
685 dst_ptr = dynamic_ptr;
718 // Query the search.
719 if (info.path_dst_ptr_to_static_ptr == public_path)
720 dst_ptr = dynamic_ptr;
721 }
686722 }
687723 else
688724 {
689 // Not using giant short cut. Do the search
690 dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false);
691 #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
692 // The following if should always be false because we should definitely
693 // find (static_ptr, static_type), either on a public or private path
694 if (info.path_dst_ptr_to_static_ptr == unknown &&
695 info.path_dynamic_ptr_to_static_ptr == unknown)
725 if (src2dst_offset >= 0)
696726 {
697 static_assert(std::atomic<size_t>::is_always_lock_free, "");
698 static std::atomic<size_t> error_count(0);
699 size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed);
700 if ((error_count_snapshot & (error_count_snapshot-1)) == 0)
701 syslog(LOG_ERR, "dynamic_cast error 2: One or more of the following type_info's "
702 "has hidden visibility or is defined in more than one translation "
703 "unit. They should all have public visibility. "
704 "%s, %s, %s.\n", static_type->name(), dynamic_type->name(),
705 dst_type->name());
706 // Redo the search comparing type_info's using strcmp
707 info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
708 dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true);
727 // Optimize toward downcasting: dst_type has one unique public
728 // static_type bases. Let's first try to do a downcast before
729 // falling back to the slow path. The downcast succeeds if there
730 // is at least one path regardless of visibility from
731 // dynamic_type to dst_type.
732 const void* dst_ptr_to_static = reinterpret_cast<const char*>(static_ptr) - src2dst_offset;
733 if (reinterpret_cast<std::intptr_t>(dst_ptr_to_static) >= reinterpret_cast<std::intptr_t>(dynamic_ptr))
734 {
735 // Try to search a path from dynamic_type to dst_type.
736 __dynamic_cast_info dynamic_to_dst_info = {dynamic_type, dst_ptr_to_static, dst_type, src2dst_offset};
737 dynamic_to_dst_info.number_of_dst_type = 1;
738 dynamic_type->search_above_dst(&dynamic_to_dst_info, dynamic_ptr, dynamic_ptr, public_path, false);
739 if (dynamic_to_dst_info.path_dst_ptr_to_static_ptr != unknown) {
740 // We have found at least one path from dynamic_ptr to
741 // dst_ptr. The downcast can succeed.
742 dst_ptr = dst_ptr_to_static;
743 }
744 }
709745 }
710#endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST
711 // Query the search.
712 switch (info.number_to_static_ptr)
746
747 if (!dst_ptr)
713748 {
714 case 0:
715 if (info.number_to_dst_ptr == 1 &&
716 info.path_dynamic_ptr_to_static_ptr == public_path &&
717 info.path_dynamic_ptr_to_dst_ptr == public_path)
718 dst_ptr = info.dst_ptr_not_leading_to_static_ptr;
719 break;
720 case 1:
721 if (info.path_dst_ptr_to_static_ptr == public_path ||
722 (
723 info.number_to_dst_ptr == 0 &&
724 info.path_dynamic_ptr_to_static_ptr == public_path &&
725 info.path_dynamic_ptr_to_dst_ptr == public_path
726 )
727 )
728 dst_ptr = info.dst_ptr_leading_to_static_ptr;
729 break;
749 // Not using giant short cut. Do the search
750 dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false);
751#ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
752 // The following if should always be false because we should
753 // definitely find (static_ptr, static_type), either on a public
754 // or private path
755 if (info.path_dst_ptr_to_static_ptr == unknown &&
756 info.path_dynamic_ptr_to_static_ptr == unknown)
757 {
758 static_assert(std::atomic<size_t>::is_always_lock_free, "");
759 static std::atomic<size_t> error_count(0);
760 size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed);
761 if ((error_count_snapshot & (error_count_snapshot-1)) == 0)
762 syslog(LOG_ERR, "dynamic_cast error 2: One or more of the following type_info's "
763 "has hidden visibility or is defined in more than one translation "
764 "unit. They should all have public visibility. "
765 "%s, %s, %s.\n", static_type->name(), dynamic_type->name(),
766 dst_type->name());
767 // Redo the search comparing type_info's using strcmp
768 info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
769 dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true);
770 }
771#endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST
772 // Query the search.
773 switch (info.number_to_static_ptr)
774 {
775 case 0:
776 if (info.number_to_dst_ptr == 1 &&
777 info.path_dynamic_ptr_to_static_ptr == public_path &&
778 info.path_dynamic_ptr_to_dst_ptr == public_path)
779 dst_ptr = info.dst_ptr_not_leading_to_static_ptr;
780 break;
781 case 1:
782 if (info.path_dst_ptr_to_static_ptr == public_path ||
783 (
784 info.number_to_dst_ptr == 0 &&
785 info.path_dynamic_ptr_to_static_ptr == public_path &&
786 info.path_dynamic_ptr_to_dst_ptr == public_path
787 )
788 )
789 dst_ptr = info.dst_ptr_leading_to_static_ptr;
790 break;
791 }
730792 }
731793 }
732794 return const_cast<void*>(dst_ptr);
lib/libcxxabi/src/stdlib_new_delete.cpp+57-46
......@@ -4,30 +4,40 @@
44// See https://llvm.org/LICENSE.txt for license information.
55// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66//
7//
8// This file implements the new and delete operators.
97//===----------------------------------------------------------------------===//
108
119#include "__cxxabi_config.h"
12#include <new>
10#include <__memory/aligned_alloc.h>
1311#include <cstdlib>
12#include <new>
13
14// Perform a few sanity checks on libc++ and libc++abi macros to ensure that
15// the code below can be an exact copy of the code in libcxx/src/new.cpp.
16#if !defined(_THROW_BAD_ALLOC)
17# error The _THROW_BAD_ALLOC macro should be already defined by libc++
18#endif
19
20#ifndef _LIBCPP_WEAK
21# error The _LIBCPP_WEAK macro should be already defined by libc++
22#endif
1423
15#if !defined(_THROW_BAD_ALLOC) || !defined(_LIBCXXABI_WEAK)
16#error The _THROW_BAD_ALLOC and _LIBCXXABI_WEAK libc++ macros must \
17 already be defined by libc++.
24#if defined(_LIBCXXABI_NO_EXCEPTIONS) != defined(_LIBCPP_HAS_NO_EXCEPTIONS)
25# error libc++ and libc++abi seem to disagree on whether exceptions are enabled
1826#endif
27
28// ------------------ BEGIN COPY ------------------
1929// Implement all new and delete operators as weak definitions
2030// in this shared library, so that they can be overridden by programs
2131// that define non-weak copies of the functions.
2232
23_LIBCXXABI_WEAK
33_LIBCPP_WEAK
2434void *
2535operator new(std::size_t size) _THROW_BAD_ALLOC
2636{
2737 if (size == 0)
2838 size = 1;
2939 void* p;
30 while ((p = ::malloc(size)) == nullptr)
40 while ((p = std::malloc(size)) == nullptr)
3141 {
3242 // If malloc fails and there is a new_handler,
3343 // call it to try free up memory.
......@@ -35,7 +45,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
3545 if (nh)
3646 nh();
3747 else
38#ifndef _LIBCXXABI_NO_EXCEPTIONS
48#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
3949 throw std::bad_alloc();
4050#else
4151 break;
......@@ -44,87 +54,87 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
4454 return p;
4555}
4656
47_LIBCXXABI_WEAK
57_LIBCPP_WEAK
4858void*
4959operator new(size_t size, const std::nothrow_t&) noexcept
5060{
5161 void* p = nullptr;
52#ifndef _LIBCXXABI_NO_EXCEPTIONS
62#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
5363 try
5464 {
55#endif // _LIBCXXABI_NO_EXCEPTIONS
65#endif // _LIBCPP_HAS_NO_EXCEPTIONS
5666 p = ::operator new(size);
57#ifndef _LIBCXXABI_NO_EXCEPTIONS
67#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
5868 }
5969 catch (...)
6070 {
6171 }
62#endif // _LIBCXXABI_NO_EXCEPTIONS
72#endif // _LIBCPP_HAS_NO_EXCEPTIONS
6373 return p;
6474}
6575
66_LIBCXXABI_WEAK
76_LIBCPP_WEAK
6777void*
6878operator new[](size_t size) _THROW_BAD_ALLOC
6979{
7080 return ::operator new(size);
7181}
7282
73_LIBCXXABI_WEAK
83_LIBCPP_WEAK
7484void*
7585operator new[](size_t size, const std::nothrow_t&) noexcept
7686{
7787 void* p = nullptr;
78#ifndef _LIBCXXABI_NO_EXCEPTIONS
88#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
7989 try
8090 {
81#endif // _LIBCXXABI_NO_EXCEPTIONS
91#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8292 p = ::operator new[](size);
83#ifndef _LIBCXXABI_NO_EXCEPTIONS
93#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
8494 }
8595 catch (...)
8696 {
8797 }
88#endif // _LIBCXXABI_NO_EXCEPTIONS
98#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8999 return p;
90100}
91101
92_LIBCXXABI_WEAK
102_LIBCPP_WEAK
93103void
94104operator delete(void* ptr) noexcept
95105{
96 ::free(ptr);
106 std::free(ptr);
97107}
98108
99_LIBCXXABI_WEAK
109_LIBCPP_WEAK
100110void
101111operator delete(void* ptr, const std::nothrow_t&) noexcept
102112{
103113 ::operator delete(ptr);
104114}
105115
106_LIBCXXABI_WEAK
116_LIBCPP_WEAK
107117void
108118operator delete(void* ptr, size_t) noexcept
109119{
110120 ::operator delete(ptr);
111121}
112122
113_LIBCXXABI_WEAK
123_LIBCPP_WEAK
114124void
115125operator delete[] (void* ptr) noexcept
116126{
117127 ::operator delete(ptr);
118128}
119129
120_LIBCXXABI_WEAK
130_LIBCPP_WEAK
121131void
122132operator delete[] (void* ptr, const std::nothrow_t&) noexcept
123133{
124134 ::operator delete[](ptr);
125135}
126136
127_LIBCXXABI_WEAK
137_LIBCPP_WEAK
128138void
129139operator delete[] (void* ptr, size_t) noexcept
130140{
......@@ -133,7 +143,7 @@ operator delete[] (void* ptr, size_t) noexcept
133143
134144#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
135145
136_LIBCXXABI_WEAK
146_LIBCPP_WEAK
137147void *
138148operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
139149{
......@@ -155,7 +165,7 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
155165 if (nh)
156166 nh();
157167 else {
158#ifndef _LIBCXXABI_NO_EXCEPTIONS
168#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
159169 throw std::bad_alloc();
160170#else
161171 break;
......@@ -165,87 +175,87 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
165175 return p;
166176}
167177
168_LIBCXXABI_WEAK
178_LIBCPP_WEAK
169179void*
170180operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
171181{
172182 void* p = nullptr;
173#ifndef _LIBCXXABI_NO_EXCEPTIONS
183#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
174184 try
175185 {
176#endif // _LIBCXXABI_NO_EXCEPTIONS
186#endif // _LIBCPP_HAS_NO_EXCEPTIONS
177187 p = ::operator new(size, alignment);
178#ifndef _LIBCXXABI_NO_EXCEPTIONS
188#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
179189 }
180190 catch (...)
181191 {
182192 }
183#endif // _LIBCXXABI_NO_EXCEPTIONS
193#endif // _LIBCPP_HAS_NO_EXCEPTIONS
184194 return p;
185195}
186196
187_LIBCXXABI_WEAK
197_LIBCPP_WEAK
188198void*
189199operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
190200{
191201 return ::operator new(size, alignment);
192202}
193203
194_LIBCXXABI_WEAK
204_LIBCPP_WEAK
195205void*
196206operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
197207{
198208 void* p = nullptr;
199#ifndef _LIBCXXABI_NO_EXCEPTIONS
209#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
200210 try
201211 {
202#endif // _LIBCXXABI_NO_EXCEPTIONS
212#endif // _LIBCPP_HAS_NO_EXCEPTIONS
203213 p = ::operator new[](size, alignment);
204#ifndef _LIBCXXABI_NO_EXCEPTIONS
214#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
205215 }
206216 catch (...)
207217 {
208218 }
209#endif // _LIBCXXABI_NO_EXCEPTIONS
219#endif // _LIBCPP_HAS_NO_EXCEPTIONS
210220 return p;
211221}
212222
213_LIBCXXABI_WEAK
223_LIBCPP_WEAK
214224void
215225operator delete(void* ptr, std::align_val_t) noexcept
216226{
217227 std::__libcpp_aligned_free(ptr);
218228}
219229
220_LIBCXXABI_WEAK
230_LIBCPP_WEAK
221231void
222232operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
223233{
224234 ::operator delete(ptr, alignment);
225235}
226236
227_LIBCXXABI_WEAK
237_LIBCPP_WEAK
228238void
229239operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept
230240{
231241 ::operator delete(ptr, alignment);
232242}
233243
234_LIBCXXABI_WEAK
244_LIBCPP_WEAK
235245void
236246operator delete[] (void* ptr, std::align_val_t alignment) noexcept
237247{
238248 ::operator delete(ptr, alignment);
239249}
240250
241_LIBCXXABI_WEAK
251_LIBCPP_WEAK
242252void
243253operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
244254{
245255 ::operator delete[](ptr, alignment);
246256}
247257
248_LIBCXXABI_WEAK
258_LIBCPP_WEAK
249259void
250260operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept
251261{
......@@ -253,3 +263,4 @@ operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept
253263}
254264
255265#endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
266// ------------------ END COPY ------------------
lib/libunwind/include/__libunwind_config.h+2-2
......@@ -196,9 +196,9 @@
196196# define _LIBUNWIND_TARGET_RISCV 1
197197# define _LIBUNWIND_TARGET_VE 1
198198# define _LIBUNWIND_TARGET_S390X 1
199#define _LIBUNWIND_TARGET_LOONGARCH 1
199 #define _LIBUNWIND_TARGET_LOONGARCH 1
200200# define _LIBUNWIND_CONTEXT_SIZE 167
201# define _LIBUNWIND_CURSOR_SIZE 179
201# define _LIBUNWIND_CURSOR_SIZE 204
202202# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
203203#endif // _LIBUNWIND_IS_NATIVE_ONLY
204204
lib/libunwind/include/unwind.h+2-2
......@@ -56,9 +56,9 @@ typedef enum {
5656typedef struct _Unwind_Context _Unwind_Context; // opaque
5757
5858#if defined(_LIBUNWIND_ARM_EHABI)
59#include "unwind_arm_ehabi.h"
59#include <unwind_arm_ehabi.h>
6060#else
61#include "unwind_itanium.h"
61#include <unwind_itanium.h>
6262#endif
6363
6464typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
lib/libunwind/src/AddressSpace.hpp+20
......@@ -66,6 +66,10 @@ char *getFuncNameFromTBTable(uintptr_t pc, uint16_t &NameLen,
6666 // In 10.7.0 or later, libSystem.dylib implements this function.
6767 extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *);
6868
69namespace libunwind {
70 bool findDynamicUnwindSections(void *, unw_dynamic_unwind_sections *);
71}
72
6973#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
7074
7175// When statically linked on bare-metal, the symbols for the EH table are looked
......@@ -497,6 +501,22 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
497501 info.compact_unwind_section_length = (size_t)dyldInfo.compact_unwind_section_length;
498502 return true;
499503 }
504
505 unw_dynamic_unwind_sections dynamicUnwindSectionInfo;
506 if (findDynamicUnwindSections((void *)targetAddr,
507 &dynamicUnwindSectionInfo)) {
508 info.dso_base = dynamicUnwindSectionInfo.dso_base;
509#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
510 info.dwarf_section = (uintptr_t)dynamicUnwindSectionInfo.dwarf_section;
511 info.dwarf_section_length = dynamicUnwindSectionInfo.dwarf_section_length;
512#endif
513 info.compact_unwind_section =
514 (uintptr_t)dynamicUnwindSectionInfo.compact_unwind_section;
515 info.compact_unwind_section_length =
516 dynamicUnwindSectionInfo.compact_unwind_section_length;
517 return true;
518 }
519
500520#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
501521 info.dso_base = 0;
502522 // Bare metal is statically linked, so no need to ask the dynamic loader
lib/libunwind/src/DwarfInstructions.hpp+2-1
......@@ -224,7 +224,8 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
224224 p &= ~0xfULL;
225225 // CFA is the bottom of the current stack frame.
226226 for (; p < cfa; p += 16) {
227 __asm__ __volatile__(".arch_extension memtag\n"
227 __asm__ __volatile__(".arch armv8.5-a\n"
228 ".arch_extension memtag\n"
228229 "stg %[Ptr], [%[Ptr]]\n"
229230 :
230231 : [Ptr] "r"(p)
lib/libunwind/src/Unwind-EHABI.cpp+6-3
......@@ -709,7 +709,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
709709 // Update info about this frame.
710710 unw_proc_info_t frameInfo;
711711 if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
712 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step "
712 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_get_proc_info "
713713 "failed => _URC_END_OF_STACK",
714714 (void *)exception_object);
715715 return _URC_FATAL_PHASE2_ERROR;
......@@ -885,8 +885,11 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
885885 return result;
886886}
887887
888static uint64_t ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation,
889 void* valuep) {
888// Only used in _LIBUNWIND_TRACE_API, which is a no-op when assertions are
889// disabled.
890[[gnu::unused]] static uint64_t
891ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation,
892 const void *valuep) {
890893 uint64_t value = 0;
891894 switch (representation) {
892895 case _UVRSD_UINT32:
lib/libunwind/src/Unwind-seh.cpp+18-1
......@@ -212,11 +212,20 @@ __libunwind_seh_personality(int version, _Unwind_Action state,
212212 ms_exc.ExceptionInformation[2] = state;
213213 DISPATCHER_CONTEXT *disp_ctx =
214214 __unw_seh_get_disp_ctx((unw_cursor_t *)context);
215 _LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() calling "
216 "LanguageHandler %p(%p, %p, %p, %p)",
217 (void *)disp_ctx->LanguageHandler, (void *)&ms_exc,
218 (void *)disp_ctx->EstablisherFrame,
219 (void *)disp_ctx->ContextRecord, (void *)disp_ctx);
215220 EXCEPTION_DISPOSITION ms_act = disp_ctx->LanguageHandler(&ms_exc,
216221 (PVOID)disp_ctx->EstablisherFrame,
217222 disp_ctx->ContextRecord,
218223 disp_ctx);
224 _LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() LanguageHandler "
225 "returned %d",
226 (int)ms_act);
219227 switch (ms_act) {
228 case ExceptionContinueExecution: return _URC_END_OF_STACK;
220229 case ExceptionContinueSearch: return _URC_CONTINUE_UNWIND;
221230 case 4 /*ExceptionExecuteHandler*/:
222231 return phase2 ? _URC_INSTALL_CONTEXT : _URC_HANDLER_FOUND;
......@@ -238,7 +247,7 @@ unwind_phase2_forced(unw_context_t *uc,
238247 // Update info about this frame.
239248 unw_proc_info_t frameInfo;
240249 if (__unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
241 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step "
250 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_get_proc_info "
242251 "failed => _URC_END_OF_STACK",
243252 (void *)exception_object);
244253 return _URC_FATAL_PHASE2_ERROR;
......@@ -304,6 +313,12 @@ unwind_phase2_forced(unw_context_t *uc,
304313 // We may get control back if landing pad calls _Unwind_Resume().
305314 __unw_resume(&cursor2);
306315 break;
316 case _URC_END_OF_STACK:
317 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
318 "personality returned "
319 "_URC_END_OF_STACK",
320 (void *)exception_object);
321 break;
307322 default:
308323 // Personality routine returned an unknown result code.
309324 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
......@@ -312,6 +327,8 @@ unwind_phase2_forced(unw_context_t *uc,
312327 (void *)exception_object, personalityResult);
313328 return _URC_FATAL_PHASE2_ERROR;
314329 }
330 if (personalityResult == _URC_END_OF_STACK)
331 break;
315332 }
316333 }
317334
lib/libunwind/src/UnwindCursor.hpp+77-3
......@@ -31,7 +31,8 @@
3131#endif
3232
3333#if defined(_LIBUNWIND_TARGET_LINUX) && \
34 (defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_S390X))
34 (defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_RISCV) || \
35 defined(_LIBUNWIND_TARGET_S390X))
3536#include <sys/syscall.h>
3637#include <sys/uio.h>
3738#include <unistd.h>
......@@ -506,7 +507,14 @@ public:
506507#endif
507508
508509 DISPATCHER_CONTEXT *getDispatcherContext() { return &_dispContext; }
509 void setDispatcherContext(DISPATCHER_CONTEXT *disp) { _dispContext = *disp; }
510 void setDispatcherContext(DISPATCHER_CONTEXT *disp) {
511 _dispContext = *disp;
512 _info.lsda = reinterpret_cast<unw_word_t>(_dispContext.HandlerData);
513 if (_dispContext.LanguageHandler) {
514 _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
515 } else
516 _info.handler = 0;
517 }
510518
511519 // libunwind does not and should not depend on C++ library which means that we
512520 // need our own definition of inline placement new.
......@@ -568,10 +576,12 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
568576 "UnwindCursor<> requires more alignment than unw_cursor_t");
569577 memset(&_info, 0, sizeof(_info));
570578 memset(&_histTable, 0, sizeof(_histTable));
579 memset(&_dispContext, 0, sizeof(_dispContext));
571580 _dispContext.ContextRecord = &_msContext;
572581 _dispContext.HistoryTable = &_histTable;
573582 // Initialize MS context from ours.
574583 R r(context);
584 RtlCaptureContext(&_msContext);
575585 _msContext.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_FLOATING_POINT;
576586#if defined(_LIBUNWIND_TARGET_X86_64)
577587 _msContext.Rax = r.getRegister(UNW_X86_64_RAX);
......@@ -669,6 +679,7 @@ UnwindCursor<A, R>::UnwindCursor(CONTEXT *context, A &as)
669679 "UnwindCursor<> does not fit in unw_cursor_t");
670680 memset(&_info, 0, sizeof(_info));
671681 memset(&_histTable, 0, sizeof(_histTable));
682 memset(&_dispContext, 0, sizeof(_dispContext));
672683 _dispContext.ContextRecord = &_msContext;
673684 _dispContext.HistoryTable = &_histTable;
674685 _msContext = *context;
......@@ -679,7 +690,7 @@ template <typename A, typename R>
679690bool UnwindCursor<A, R>::validReg(int regNum) {
680691 if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) return true;
681692#if defined(_LIBUNWIND_TARGET_X86_64)
682 if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_R15) return true;
693 if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_RIP) return true;
683694#elif defined(_LIBUNWIND_TARGET_ARM)
684695 if ((regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) ||
685696 regNum == UNW_ARM_RA_AUTH_CODE)
......@@ -694,6 +705,7 @@ template <typename A, typename R>
694705unw_word_t UnwindCursor<A, R>::getReg(int regNum) {
695706 switch (regNum) {
696707#if defined(_LIBUNWIND_TARGET_X86_64)
708 case UNW_X86_64_RIP:
697709 case UNW_REG_IP: return _msContext.Rip;
698710 case UNW_X86_64_RAX: return _msContext.Rax;
699711 case UNW_X86_64_RDX: return _msContext.Rdx;
......@@ -744,6 +756,7 @@ template <typename A, typename R>
744756void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) {
745757 switch (regNum) {
746758#if defined(_LIBUNWIND_TARGET_X86_64)
759 case UNW_X86_64_RIP:
747760 case UNW_REG_IP: _msContext.Rip = value; break;
748761 case UNW_X86_64_RAX: _msContext.Rax = value; break;
749762 case UNW_X86_64_RDX: _msContext.Rdx = value; break;
......@@ -981,6 +994,10 @@ private:
981994 bool setInfoForSigReturn(Registers_arm64 &);
982995 int stepThroughSigReturn(Registers_arm64 &);
983996#endif
997#if defined(_LIBUNWIND_TARGET_RISCV)
998 bool setInfoForSigReturn(Registers_riscv &);
999 int stepThroughSigReturn(Registers_riscv &);
1000#endif
9841001#if defined(_LIBUNWIND_TARGET_S390X)
9851002 bool setInfoForSigReturn(Registers_s390x &);
9861003 int stepThroughSigReturn(Registers_s390x &);
......@@ -1978,6 +1995,9 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
19781995 uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1;
19791996 const uint32_t *handler = reinterpret_cast<uint32_t *>(&xdata->UnwindCodes[lastcode]);
19801997 _info.lsda = reinterpret_cast<unw_word_t>(handler+1);
1998 _dispContext.HandlerData = reinterpret_cast<void *>(_info.lsda);
1999 _dispContext.LanguageHandler =
2000 reinterpret_cast<EXCEPTION_ROUTINE *>(base + *handler);
19812001 if (*handler) {
19822002 _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
19832003 } else
......@@ -2705,6 +2725,60 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
27052725#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
27062726 // defined(_LIBUNWIND_TARGET_AARCH64)
27072727
2728#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \
2729 defined(_LIBUNWIND_TARGET_RISCV)
2730template <typename A, typename R>
2731bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_riscv &) {
2732 const pint_t pc = static_cast<pint_t>(getReg(UNW_REG_IP));
2733 uint32_t instructions[2];
2734 struct iovec local_iov = {&instructions, sizeof instructions};
2735 struct iovec remote_iov = {reinterpret_cast<void *>(pc), sizeof instructions};
2736 long bytesRead =
2737 syscall(SYS_process_vm_readv, getpid(), &local_iov, 1, &remote_iov, 1, 0);
2738 // Look for the two instructions used in the sigreturn trampoline
2739 // __vdso_rt_sigreturn:
2740 //
2741 // 0x08b00893 li a7,0x8b
2742 // 0x00000073 ecall
2743 if (bytesRead != sizeof instructions || instructions[0] != 0x08b00893 ||
2744 instructions[1] != 0x00000073)
2745 return false;
2746
2747 _info = {};
2748 _info.start_ip = pc;
2749 _info.end_ip = pc + 4;
2750 _isSigReturn = true;
2751 return true;
2752}
2753
2754template <typename A, typename R>
2755int UnwindCursor<A, R>::stepThroughSigReturn(Registers_riscv &) {
2756 // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
2757 // - 128-byte siginfo struct
2758 // - ucontext_t struct:
2759 // - 8-byte long (__uc_flags)
2760 // - 8-byte pointer (*uc_link)
2761 // - 24-byte uc_stack
2762 // - 8-byte uc_sigmask
2763 // - 120-byte of padding to allow sigset_t to be expanded in the future
2764 // - 8 bytes of padding because sigcontext has 16-byte alignment
2765 // - struct sigcontext uc_mcontext
2766 // [1]
2767 // https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/signal.c
2768 const pint_t kOffsetSpToSigcontext = 128 + 8 + 8 + 24 + 8 + 128;
2769
2770 const pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext;
2771 _registers.setIP(_addressSpace.get64(sigctx));
2772 for (int i = UNW_RISCV_X1; i <= UNW_RISCV_X31; ++i) {
2773 uint64_t value = _addressSpace.get64(sigctx + static_cast<pint_t>(i * 8));
2774 _registers.setRegister(i, value);
2775 }
2776 _isSignalFrame = true;
2777 return UNW_STEP_SUCCESS;
2778}
2779#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
2780 // defined(_LIBUNWIND_TARGET_RISCV)
2781
27082782#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \
27092783 defined(_LIBUNWIND_TARGET_S390X)
27102784template <typename A, typename R>
lib/libunwind/src/UnwindLevel1-gcc-ext.c+1-1
......@@ -167,7 +167,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) {
167167 }
168168
169169 // Update the pr_cache in the mock exception object.
170 const uint32_t* unwindInfo = (uint32_t *) frameInfo.unwind_info;
170 uint32_t *unwindInfo = (uint32_t *)frameInfo.unwind_info;
171171 ex.pr_cache.fnstart = frameInfo.start_ip;
172172 ex.pr_cache.ehtp = (_Unwind_EHT_Header *) unwindInfo;
173173 ex.pr_cache.additional= frameInfo.flags;
lib/libunwind/src/UnwindLevel1.c+1-1
......@@ -321,7 +321,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
321321 unw_proc_info_t frameInfo;
322322 if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
323323 _LIBUNWIND_TRACE_UNWINDING(
324 "unwind_phase2_forced(ex_obj=%p): __unw_step_stage2 "
324 "unwind_phase2_forced(ex_obj=%p): __unw_get_proc_info "
325325 "failed => _URC_END_OF_STACK",
326326 (void *)exception_object);
327327 return _URC_FATAL_PHASE2_ERROR;
lib/libunwind/src/UnwindRegistersRestore.S+20-2
......@@ -194,9 +194,20 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
194194 addi 4, 3, PPC64_OFFS_FP
195195
196196// load VS register
197#ifdef __LITTLE_ENDIAN__
198// For little-endian targets, we need a swap since lxvd2x will load the register
199// in the incorrect doubleword order.
200// FIXME: when supporting targets older than Power9 on LE is no longer required,
201// this can be changed to simply `lxv n, (16 * n)(4)`.
197202#define PPC64_LVS(n) \
198203 lxvd2x n, 0, 4 ;\
204 xxswapd n, n ;\
199205 addi 4, 4, 16
206#else
207#define PPC64_LVS(n) \
208 lxvd2x n, 0, 4 ;\
209 addi 4, 4, 16
210#endif
200211
201212 // restore the first 32 VS regs (and also all floating point regs)
202213 PPC64_LVS(0)
......@@ -232,9 +243,16 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
232243 PPC64_LVS(30)
233244 PPC64_LVS(31)
234245
246#ifdef __LITTLE_ENDIAN__
247#define PPC64_CLVS_RESTORE(n) \
248 addi 4, 3, PPC64_OFFS_FP + n * 16 ;\
249 lxvd2x n, 0, 4 ;\
250 xxswapd n, n
251#else
235252#define PPC64_CLVS_RESTORE(n) \
236253 addi 4, 3, PPC64_OFFS_FP + n * 16 ;\
237254 lxvd2x n, 0, 4
255#endif
238256
239257#if !defined(_AIX)
240258 // use VRSAVE to conditionally restore the remaining VS regs, that are
......@@ -1203,8 +1221,8 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind19Registers_loongarch6jumptoEv)
12031221 ld.d $r\i, $a0, (8 * \i)
12041222 .endr
12051223
1206 ld.d $r4, $a0, (8 * 4) // restore $a0 last
1207 ld.d $r1, $a0, (8 * 32) // load new pc into $ra
1224 ld.d $ra, $a0, (8 * 32) // load new pc into $ra
1225 ld.d $a0, $a0, (8 * 4) // restore $a0 last
12081226
12091227 jr $ra
12101228
lib/libunwind/src/UnwindRegistersSave.S+11
......@@ -351,9 +351,20 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
351351 addi 4, 3, PPC64_OFFS_FP
352352
353353// store VS register
354#ifdef __LITTLE_ENDIAN__
355// For little-endian targets, we need a swap since stxvd2x will store the
356// register in the incorrect doubleword order.
357// FIXME: when supporting targets older than Power9 on LE is no longer required
358// this can be changed to simply `stxv n, 16 * n(4)`.
354359#define PPC64_STVS(n) \
360 xxswapd n, n ;\
355361 stxvd2x n, 0, 4 ;\
356362 addi 4, 4, 16
363#else
364#define PPC64_STVS(n) \
365 stxvd2x n, 0, 4 ;\
366 addi 4, 4, 16
367#endif
357368
358369 PPC64_STVS(0)
359370 PPC64_STVS(1)
lib/libunwind/src/Unwind_AppleExtras.cpp deleted-113
......@@ -1,113 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//
8//===----------------------------------------------------------------------===//
9
10#include "config.h"
11
12
13// static linker symbols to prevent wrong two level namespace for _Unwind symbols
14#if defined(__arm__)
15 #define NOT_HERE_BEFORE_5_0(sym) \
16 extern const char sym##_tmp30 __asm("$ld$hide$os3.0$_" #sym ); \
17 __attribute__((visibility("default"))) const char sym##_tmp30 = 0; \
18 extern const char sym##_tmp31 __asm("$ld$hide$os3.1$_" #sym ); \
19 __attribute__((visibility("default"))) const char sym##_tmp31 = 0; \
20 extern const char sym##_tmp32 __asm("$ld$hide$os3.2$_" #sym );\
21 __attribute__((visibility("default"))) const char sym##_tmp32 = 0; \
22 extern const char sym##_tmp40 __asm("$ld$hide$os4.0$_" #sym ); \
23 __attribute__((visibility("default"))) const char sym##_tmp40 = 0; \
24 extern const char sym##_tmp41 __asm("$ld$hide$os4.1$_" #sym ); \
25 __attribute__((visibility("default"))) const char sym##_tmp41 = 0; \
26 extern const char sym##_tmp42 __asm("$ld$hide$os4.2$_" #sym ); \
27 __attribute__((visibility("default"))) const char sym##_tmp42 = 0; \
28 extern const char sym##_tmp43 __asm("$ld$hide$os4.3$_" #sym ); \
29 __attribute__((visibility("default"))) const char sym##_tmp43 = 0;
30#elif defined(__aarch64__)
31 #define NOT_HERE_BEFORE_10_6(sym)
32 #define NEVER_HERE(sym)
33#else
34 #define NOT_HERE_BEFORE_10_6(sym) \
35 extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
36 __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
37 extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
38 __attribute__((visibility("default"))) const char sym##_tmp5 = 0;
39 #define NEVER_HERE(sym) \
40 extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
41 __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
42 extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
43 __attribute__((visibility("default"))) const char sym##_tmp5 = 0; \
44 extern const char sym##_tmp6 __asm("$ld$hide$os10.6$_" #sym ); \
45 __attribute__((visibility("default"))) const char sym##_tmp6 = 0;
46#endif
47
48
49#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
50
51//
52// symbols in libSystem.dylib in 10.6 and later, but are in libgcc_s.dylib in
53// earlier versions
54//
55NOT_HERE_BEFORE_10_6(_Unwind_DeleteException)
56NOT_HERE_BEFORE_10_6(_Unwind_Find_FDE)
57NOT_HERE_BEFORE_10_6(_Unwind_ForcedUnwind)
58NOT_HERE_BEFORE_10_6(_Unwind_GetGR)
59NOT_HERE_BEFORE_10_6(_Unwind_GetIP)
60NOT_HERE_BEFORE_10_6(_Unwind_GetLanguageSpecificData)
61NOT_HERE_BEFORE_10_6(_Unwind_GetRegionStart)
62NOT_HERE_BEFORE_10_6(_Unwind_RaiseException)
63NOT_HERE_BEFORE_10_6(_Unwind_Resume)
64NOT_HERE_BEFORE_10_6(_Unwind_SetGR)
65NOT_HERE_BEFORE_10_6(_Unwind_SetIP)
66NOT_HERE_BEFORE_10_6(_Unwind_Backtrace)
67NOT_HERE_BEFORE_10_6(_Unwind_FindEnclosingFunction)
68NOT_HERE_BEFORE_10_6(_Unwind_GetCFA)
69NOT_HERE_BEFORE_10_6(_Unwind_GetDataRelBase)
70NOT_HERE_BEFORE_10_6(_Unwind_GetTextRelBase)
71NOT_HERE_BEFORE_10_6(_Unwind_Resume_or_Rethrow)
72NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo)
73NOT_HERE_BEFORE_10_6(__register_frame)
74NOT_HERE_BEFORE_10_6(__deregister_frame)
75
76//
77// symbols in libSystem.dylib for compatibility, but we don't want any new code
78// using them
79//
80NEVER_HERE(__register_frame_info_bases)
81NEVER_HERE(__register_frame_info)
82NEVER_HERE(__register_frame_info_table_bases)
83NEVER_HERE(__register_frame_info_table)
84NEVER_HERE(__register_frame_table)
85NEVER_HERE(__deregister_frame_info)
86NEVER_HERE(__deregister_frame_info_bases)
87
88#endif // defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
89
90
91
92
93#if defined(_LIBUNWIND_BUILD_SJLJ_APIS)
94//
95// symbols in libSystem.dylib in iOS 5.0 and later, but are in libgcc_s.dylib in
96// earlier versions
97//
98NOT_HERE_BEFORE_5_0(_Unwind_GetLanguageSpecificData)
99NOT_HERE_BEFORE_5_0(_Unwind_GetRegionStart)
100NOT_HERE_BEFORE_5_0(_Unwind_GetIP)
101NOT_HERE_BEFORE_5_0(_Unwind_SetGR)
102NOT_HERE_BEFORE_5_0(_Unwind_SetIP)
103NOT_HERE_BEFORE_5_0(_Unwind_DeleteException)
104NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Register)
105NOT_HERE_BEFORE_5_0(_Unwind_GetGR)
106NOT_HERE_BEFORE_5_0(_Unwind_GetIPInfo)
107NOT_HERE_BEFORE_5_0(_Unwind_GetCFA)
108NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume)
109NOT_HERE_BEFORE_5_0(_Unwind_SjLj_RaiseException)
110NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow)
111NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister)
112
113#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS)
lib/libunwind/src/config.h+8-4
......@@ -162,10 +162,14 @@
162162#define _LIBUNWIND_LOG0(msg)
163163#define _LIBUNWIND_LOG(msg, ...)
164164#else
165#define _LIBUNWIND_LOG0(msg) \
166 fprintf(stderr, "libunwind: " msg "\n")
167#define _LIBUNWIND_LOG(msg, ...) \
168 fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__)
165#define _LIBUNWIND_LOG0(msg) do { \
166 fprintf(stderr, "libunwind: " msg "\n"); \
167 fflush(stderr); \
168 } while (0)
169#define _LIBUNWIND_LOG(msg, ...) do { \
170 fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__); \
171 fflush(stderr); \
172 } while (0)
169173#endif
170174
171175#if defined(NDEBUG)
lib/libunwind/src/libunwind.cpp+80
......@@ -349,7 +349,87 @@ void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start) {
349349#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
350350#endif // !defined(__USING_SJLJ_EXCEPTIONS__)
351351
352#ifdef __APPLE__
352353
354namespace libunwind {
355
356static constexpr size_t MAX_DYNAMIC_UNWIND_SECTIONS_FINDERS = 8;
357
358static RWMutex findDynamicUnwindSectionsLock;
359static size_t numDynamicUnwindSectionsFinders = 0;
360static unw_find_dynamic_unwind_sections
361 dynamicUnwindSectionsFinders[MAX_DYNAMIC_UNWIND_SECTIONS_FINDERS] = {0};
362
363bool findDynamicUnwindSections(void *addr, unw_dynamic_unwind_sections *info) {
364 bool found = false;
365 findDynamicUnwindSectionsLock.lock_shared();
366 for (size_t i = 0; i != numDynamicUnwindSectionsFinders; ++i) {
367 if (dynamicUnwindSectionsFinders[i]((unw_word_t)addr, info)) {
368 found = true;
369 break;
370 }
371 }
372 findDynamicUnwindSectionsLock.unlock_shared();
373 return found;
374}
375
376} // namespace libunwind
377
378int __unw_add_find_dynamic_unwind_sections(
379 unw_find_dynamic_unwind_sections find_dynamic_unwind_sections) {
380 findDynamicUnwindSectionsLock.lock();
381
382 // Check that we have enough space...
383 if (numDynamicUnwindSectionsFinders == MAX_DYNAMIC_UNWIND_SECTIONS_FINDERS) {
384 findDynamicUnwindSectionsLock.unlock();
385 return UNW_ENOMEM;
386 }
387
388 // Check for value already present...
389 for (size_t i = 0; i != numDynamicUnwindSectionsFinders; ++i) {
390 if (dynamicUnwindSectionsFinders[i] == find_dynamic_unwind_sections) {
391 findDynamicUnwindSectionsLock.unlock();
392 return UNW_EINVAL;
393 }
394 }
395
396 // Success -- add callback entry.
397 dynamicUnwindSectionsFinders[numDynamicUnwindSectionsFinders++] =
398 find_dynamic_unwind_sections;
399 findDynamicUnwindSectionsLock.unlock();
400
401 return UNW_ESUCCESS;
402}
403
404int __unw_remove_find_dynamic_unwind_sections(
405 unw_find_dynamic_unwind_sections find_dynamic_unwind_sections) {
406 findDynamicUnwindSectionsLock.lock();
407
408 // Find index to remove.
409 size_t finderIdx = numDynamicUnwindSectionsFinders;
410 for (size_t i = 0; i != numDynamicUnwindSectionsFinders; ++i) {
411 if (dynamicUnwindSectionsFinders[i] == find_dynamic_unwind_sections) {
412 finderIdx = i;
413 break;
414 }
415 }
416
417 // If no such registration is present then error out.
418 if (finderIdx == numDynamicUnwindSectionsFinders) {
419 findDynamicUnwindSectionsLock.unlock();
420 return UNW_EINVAL;
421 }
422
423 // Remove entry.
424 for (size_t i = finderIdx; i != numDynamicUnwindSectionsFinders - 1; ++i)
425 dynamicUnwindSectionsFinders[i] = dynamicUnwindSectionsFinders[i + 1];
426 dynamicUnwindSectionsFinders[--numDynamicUnwindSectionsFinders] = nullptr;
427
428 findDynamicUnwindSectionsLock.unlock();
429 return UNW_ESUCCESS;
430}
431
432#endif // __APPLE__
353433
354434// Add logging hooks in Debug builds only
355435#ifndef NDEBUG
lib/libunwind/src/libunwind_ext.h+65
......@@ -58,6 +58,71 @@ extern void __unw_remove_dynamic_fde(unw_word_t fde);
5858extern void __unw_add_dynamic_eh_frame_section(unw_word_t eh_frame_start);
5959extern void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start);
6060
61#ifdef __APPLE__
62
63// Holds a description of the object-format-header (if any) and unwind info
64// sections for a given address:
65//
66// * dso_base should point to a header for the JIT'd object containing the
67// given address. The header's type should match the format type that
68// libunwind was compiled for (so a mach_header or mach_header_64 on Darwin).
69// A value of zero indicates that no such header exists.
70//
71// * dwarf_section and dwarf_section_length hold the address range of a DWARF
72// eh-frame section associated with the given address, if any. If the
73// dwarf_section_length field is zero it indicates that no such section
74// exists (and in this case dwarf_section should also be set to zero).
75//
76// * compact_unwind_section and compact_unwind_section_length hold the address
77// range of a compact-unwind info section associated with the given address,
78// if any. If the compact_unwind_section_length field is zero it indicates
79// that no such section exists (and in this case compact_unwind_section
80// should also be set to zero).
81//
82// See the unw_find_dynamic_unwind_sections type below for more details.
83struct unw_dynamic_unwind_sections {
84 unw_word_t dso_base;
85 unw_word_t dwarf_section;
86 size_t dwarf_section_length;
87 unw_word_t compact_unwind_section;
88 size_t compact_unwind_section_length;
89};
90
91// Typedef for unwind-info lookup callbacks. Functions of this type can be
92// registered and deregistered using __unw_add_find_dynamic_unwind_sections
93// and __unw_remove_find_dynamic_unwind_sections respectively.
94//
95// An unwind-info lookup callback should return 1 to indicate that it found
96// unwind-info for the given address, or 0 to indicate that it did not find
97// unwind-info for the given address. If found, the callback should populate
98// some or all of the fields of the info argument (which is guaranteed to be
99// non-null with all fields zero-initialized):
100typedef int (*unw_find_dynamic_unwind_sections)(
101 unw_word_t addr, struct unw_dynamic_unwind_sections *info);
102
103// Register a dynamic unwind-info lookup callback. If libunwind does not find
104// unwind info for a given frame in the executable program or normal dynamic
105// shared objects then it will call all registered dynamic lookup functions
106// in registration order until either one of them returns true, or the end
107// of the list is reached. This lookup will happen before libunwind searches
108// any eh-frames registered via __register_frame or
109// __unw_add_dynamic_eh_frame_section.
110//
111// Returns UNW_ESUCCESS for successful registrations. If the given callback
112// has already been registered then UNW_EINVAL will be returned. If all
113// available callback entries are in use then UNW_ENOMEM will be returned.
114extern int __unw_add_find_dynamic_unwind_sections(
115 unw_find_dynamic_unwind_sections find_dynamic_unwind_sections);
116
117// Deregister a dynacim unwind-info lookup callback.
118//
119// Returns UNW_ESUCCESS for successful deregistrations. If the given callback
120// has already been registered then UNW_EINVAL will be returned.
121extern int __unw_remove_find_dynamic_unwind_sections(
122 unw_find_dynamic_unwind_sections find_dynamic_unwind_sections);
123
124#endif
125
61126#if defined(_LIBUNWIND_ARM_EHABI)
62127extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*);
63128extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context,
lib/std/mem.zig+5
......@@ -4490,6 +4490,11 @@ test "read/write(Var)PackedInt" {
44904490 else => {},
44914491 }
44924492
4493 if (builtin.cpu.arch == .powerpc) {
4494 // https://github.com/ziglang/zig/issues/16951
4495 return error.SkipZigTest;
4496 }
4497
44934498 const foreign_endian: Endian = if (native_endian == .Big) .Little else .Big;
44944499 const expect = std.testing.expect;
44954500 var prng = std.rand.DefaultPrng.init(1234);
lib/std/start.zig+10-1
......@@ -240,6 +240,14 @@ fn _start() callconv(.Naked) noreturn {
240240 : [tos] "={rax}" (-> *std.os.plan9.Tos),
241241 );
242242 }
243 switch (native_arch) {
244 // https://github.com/ziglang/zig/issues/16799
245 .riscv64 => @export(argc_argv_ptr, .{
246 .name = "__zig_argc_argv_ptr",
247 .visibility = .hidden,
248 }),
249 else => {},
250 }
243251 asm volatile (switch (native_arch) {
244252 .x86_64 =>
245253 \\ xorl %%ebp, %%ebp
......@@ -270,7 +278,8 @@ fn _start() callconv(.Naked) noreturn {
270278 .riscv64 =>
271279 \\ li s0, 0
272280 \\ li ra, 0
273 \\ sd sp, %[argc_argv_ptr]
281 \\ lui a0, %hi(__zig_argc_argv_ptr)
282 \\ sd sp, %lo(__zig_argc_argv_ptr)(a0)
274283 \\ andi sp, sp, -16
275284 \\ tail %[posixCallMainAndExit]@plt
276285 ,
lib/std/target.zig+20-15
......@@ -28,6 +28,7 @@ pub const Target = struct {
2828 netbsd,
2929 openbsd,
3030 solaris,
31 uefi,
3132 windows,
3233 zos,
3334 haiku,
......@@ -52,7 +53,7 @@ pub const Target = struct {
5253 wasi,
5354 emscripten,
5455 shadermodel,
55 uefi,
56 liteos,
5657 opencl,
5758 glsl450,
5859 vulkan,
......@@ -259,6 +260,7 @@ pub const Target = struct {
259260 .emscripten,
260261 .driverkit,
261262 .shadermodel,
263 .liteos,
262264 .uefi,
263265 .opencl, // TODO: OpenCL versions
264266 .glsl450, // TODO: GLSL versions
......@@ -395,7 +397,7 @@ pub const Target = struct {
395397 /// On Darwin, we always link libSystem which contains libc.
396398 /// Similarly on FreeBSD and NetBSD we always link system libc
397399 /// since this is the stable syscall interface.
398 pub inline fn requiresLibC(os: Os) bool {
400 pub fn requiresLibC(os: Os) bool {
399401 return switch (os.tag) {
400402 .freebsd,
401403 .netbsd,
......@@ -437,6 +439,7 @@ pub const Target = struct {
437439 .emscripten,
438440 .driverkit,
439441 .shadermodel,
442 .liteos,
440443 .uefi,
441444 .opencl,
442445 .glsl450,
......@@ -565,6 +568,7 @@ pub const Target = struct {
565568 .watchos,
566569 .driverkit,
567570 .shadermodel,
571 .liteos, // TODO: audit this
568572 => return .none,
569573 }
570574 }
......@@ -975,7 +979,7 @@ pub const Target = struct {
975979 return error.UnknownCpuModel;
976980 }
977981
978 pub inline fn toElfMachine(arch: Arch) std.elf.EM {
982 pub fn toElfMachine(arch: Arch) std.elf.EM {
979983 return switch (arch) {
980984 .avr => .AVR,
981985 .msp430 => .MSP430,
......@@ -1040,7 +1044,7 @@ pub const Target = struct {
10401044 };
10411045 }
10421046
1043 pub inline fn toCoffMachine(arch: Arch) std.coff.MachineType {
1047 pub fn toCoffMachine(arch: Arch) std.coff.MachineType {
10441048 return switch (arch) {
10451049 .avr => .Unknown,
10461050 .msp430 => .Unknown,
......@@ -1105,7 +1109,7 @@ pub const Target = struct {
11051109 };
11061110 }
11071111
1108 pub inline fn endian(arch: Arch) std.builtin.Endian {
1112 pub fn endian(arch: Arch) std.builtin.Endian {
11091113 return switch (arch) {
11101114 .avr,
11111115 .arm,
......@@ -1176,7 +1180,7 @@ pub const Target = struct {
11761180 }
11771181
11781182 /// Returns whether this architecture supports the address space
1179 pub inline fn supportsAddressSpace(arch: Arch, address_space: std.builtin.AddressSpace) bool {
1183 pub fn supportsAddressSpace(arch: Arch, address_space: std.builtin.AddressSpace) bool {
11801184 const is_nvptx = arch == .nvptx or arch == .nvptx64;
11811185 const is_spirv = arch == .spirv32 or arch == .spirv64;
11821186 const is_gpu = is_nvptx or is_spirv or arch == .amdgcn;
......@@ -1469,7 +1473,6 @@ pub const Target = struct {
14691473 pub const FloatAbi = enum {
14701474 hard,
14711475 soft,
1472 soft_fp,
14731476 };
14741477
14751478 pub inline fn getFloatAbi(self: Target) FloatAbi {
......@@ -1714,6 +1717,7 @@ pub const Target = struct {
17141717 .hurd,
17151718 .driverkit,
17161719 .shadermodel,
1720 .liteos,
17171721 => return result,
17181722 }
17191723 }
......@@ -1742,7 +1746,7 @@ pub const Target = struct {
17421746 };
17431747 }
17441748
1745 pub inline fn maxIntAlignment(target: Target) u16 {
1749 pub fn maxIntAlignment(target: Target) u16 {
17461750 return switch (target.cpu.arch) {
17471751 .avr => 1,
17481752 .msp430 => 2,
......@@ -1832,7 +1836,7 @@ pub const Target = struct {
18321836 };
18331837 }
18341838
1835 pub inline fn ptrBitWidth(target: Target) u16 {
1839 pub fn ptrBitWidth(target: Target) u16 {
18361840 switch (target.abi) {
18371841 .gnux32, .muslx32, .gnuabin32, .gnuilp32 => return 32,
18381842 .gnuabi64 => return 64,
......@@ -1909,7 +1913,7 @@ pub const Target = struct {
19091913 }
19101914 }
19111915
1912 pub inline fn stackAlignment(target: Target) u16 {
1916 pub fn stackAlignment(target: Target) u16 {
19131917 return switch (target.cpu.arch) {
19141918 .m68k => 2,
19151919 .amdgcn => 4,
......@@ -1954,7 +1958,7 @@ pub const Target = struct {
19541958 /// Default signedness of `char` for the native C compiler for this target
19551959 /// Note that char signedness is implementation-defined and many compilers provide
19561960 /// an option to override the default signedness e.g. GCC's -funsigned-char / -fsigned-char
1957 pub inline fn charSignedness(target: Target) std.builtin.Signedness {
1961 pub fn charSignedness(target: Target) std.builtin.Signedness {
19581962 switch (target.cpu.arch) {
19591963 .aarch64,
19601964 .aarch64_32,
......@@ -1993,7 +1997,7 @@ pub const Target = struct {
19931997 longdouble,
19941998 };
19951999
1996 pub inline fn c_type_byte_size(t: Target, c_type: CType) u16 {
2000 pub fn c_type_byte_size(t: Target, c_type: CType) u16 {
19972001 return switch (c_type) {
19982002 .char,
19992003 .short,
......@@ -2019,7 +2023,7 @@ pub const Target = struct {
20192023 };
20202024 }
20212025
2022 pub inline fn c_type_bit_size(target: Target, c_type: CType) u16 {
2026 pub fn c_type_bit_size(target: Target, c_type: CType) u16 {
20232027 switch (target.os.tag) {
20242028 .freestanding, .other => switch (target.cpu.arch) {
20252029 .msp430 => switch (c_type) {
......@@ -2329,11 +2333,12 @@ pub const Target = struct {
23292333 .vulkan,
23302334 .driverkit,
23312335 .shadermodel,
2336 .liteos,
23322337 => @panic("TODO specify the C integer and float type sizes for this OS"),
23332338 }
23342339 }
23352340
2336 pub inline fn c_type_alignment(target: Target, c_type: CType) u16 {
2341 pub fn c_type_alignment(target: Target, c_type: CType) u16 {
23372342 // Overrides for unusual alignments
23382343 switch (target.cpu.arch) {
23392344 .avr => return 1,
......@@ -2440,7 +2445,7 @@ pub const Target = struct {
24402445 );
24412446 }
24422447
2443 pub inline fn c_type_preferred_alignment(target: Target, c_type: CType) u16 {
2448 pub fn c_type_preferred_alignment(target: Target, c_type: CType) u16 {
24442449 // Overrides for unusual alignments
24452450 switch (target.cpu.arch) {
24462451 .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
lib/std/target/aarch64.zig+53
......@@ -37,6 +37,7 @@ pub const Feature = enum {
3737 ccdp,
3838 ccidx,
3939 ccpp,
40 chk,
4041 clrbhb,
4142 cmp_bcc_fusion,
4243 complxnum,
......@@ -68,12 +69,14 @@ pub const Feature = enum {
6869 fptoint,
6970 fullfp16,
7071 fuse_address,
72 fuse_addsub_2reg_const1,
7173 fuse_adrp_add,
7274 fuse_aes,
7375 fuse_arith_logic,
7476 fuse_crypto_eor,
7577 fuse_csel,
7678 fuse_literals,
79 gcs,
7780 harden_sls_blr,
7881 harden_sls_nocomdat,
7982 harden_sls_retbr,
......@@ -96,6 +99,7 @@ pub const Feature = enum {
9699 nmi,
97100 no_bti_at_return_twice,
98101 no_neg_immediates,
102 no_sve_fp_ld1r,
99103 no_zcz_fp,
100104 nv,
101105 outline_atomics,
......@@ -173,6 +177,7 @@ pub const Feature = enum {
173177 tpidr_el1,
174178 tpidr_el2,
175179 tpidr_el3,
180 tpidrro_el0,
176181 tracev8_4,
177182 trbe,
178183 uaops,
......@@ -233,6 +238,7 @@ pub const all_features = blk: {
233238 .fuse_adrp_add,
234239 .fuse_aes,
235240 .fuse_literals,
241 .predictable_select_expensive,
236242 }),
237243 };
238244 result[@intFromEnum(Feature.a710)] = .{
......@@ -244,6 +250,7 @@ pub const all_features = blk: {
244250 .fuse_adrp_add,
245251 .fuse_aes,
246252 .lsl_fast,
253 .predictable_select_expensive,
247254 .use_postra_scheduler,
248255 }),
249256 };
......@@ -255,6 +262,7 @@ pub const all_features = blk: {
255262 .fuse_adrp_add,
256263 .fuse_aes,
257264 .lsl_fast,
265 .predictable_select_expensive,
258266 }),
259267 };
260268 result[@intFromEnum(Feature.a78)] = .{
......@@ -266,6 +274,7 @@ pub const all_features = blk: {
266274 .fuse_adrp_add,
267275 .fuse_aes,
268276 .lsl_fast,
277 .predictable_select_expensive,
269278 .use_postra_scheduler,
270279 }),
271280 };
......@@ -278,6 +287,7 @@ pub const all_features = blk: {
278287 .fuse_adrp_add,
279288 .fuse_aes,
280289 .lsl_fast,
290 .predictable_select_expensive,
281291 .use_postra_scheduler,
282292 }),
283293 };
......@@ -415,6 +425,11 @@ pub const all_features = blk: {
415425 .description = "Enable v8.2 data Cache Clean to Point of Persistence (FEAT_DPB)",
416426 .dependencies = featureSet(&[_]Feature{}),
417427 };
428 result[@intFromEnum(Feature.chk)] = .{
429 .llvm_name = "chk",
430 .description = "Enable Armv8.0-A Check Feature Status Extension (FEAT_CHK)",
431 .dependencies = featureSet(&[_]Feature{}),
432 };
418433 result[@intFromEnum(Feature.clrbhb)] = .{
419434 .llvm_name = "clrbhb",
420435 .description = "Enable Clear BHB instruction (FEAT_CLRBHB)",
......@@ -591,6 +606,11 @@ pub const all_features = blk: {
591606 .description = "CPU fuses address generation and memory operations",
592607 .dependencies = featureSet(&[_]Feature{}),
593608 };
609 result[@intFromEnum(Feature.fuse_addsub_2reg_const1)] = .{
610 .llvm_name = "fuse-addsub-2reg-const1",
611 .description = "CPU fuses (a + b + 1) and (a - b - 1)",
612 .dependencies = featureSet(&[_]Feature{}),
613 };
594614 result[@intFromEnum(Feature.fuse_adrp_add)] = .{
595615 .llvm_name = "fuse-adrp-add",
596616 .description = "CPU fuses adrp+add operations",
......@@ -621,6 +641,13 @@ pub const all_features = blk: {
621641 .description = "CPU fuses literal generation operations",
622642 .dependencies = featureSet(&[_]Feature{}),
623643 };
644 result[@intFromEnum(Feature.gcs)] = .{
645 .llvm_name = "gcs",
646 .description = "Enable Armv9.4-A Guarded Call Stack Extension",
647 .dependencies = featureSet(&[_]Feature{
648 .chk,
649 }),
650 };
624651 result[@intFromEnum(Feature.harden_sls_blr)] = .{
625652 .llvm_name = "harden-sls-blr",
626653 .description = "Harden against straight line speculation across BLR instructions",
......@@ -741,6 +768,11 @@ pub const all_features = blk: {
741768 .description = "Convert immediates and instructions to their negated or complemented equivalent when the immediate does not fit in the encoding.",
742769 .dependencies = featureSet(&[_]Feature{}),
743770 };
771 result[@intFromEnum(Feature.no_sve_fp_ld1r)] = .{
772 .llvm_name = "no-sve-fp-ld1r",
773 .description = "Avoid using LD1RX instructions for FP",
774 .dependencies = featureSet(&[_]Feature{}),
775 };
744776 result[@intFromEnum(Feature.no_zcz_fp)] = .{
745777 .llvm_name = "no-zcz-fp",
746778 .description = "Has no zero-cycle zeroing instructions for FP registers",
......@@ -1171,6 +1203,11 @@ pub const all_features = blk: {
11711203 .description = "Permit use of TPIDR_EL3 for the TLS base",
11721204 .dependencies = featureSet(&[_]Feature{}),
11731205 };
1206 result[@intFromEnum(Feature.tpidrro_el0)] = .{
1207 .llvm_name = "tpidrro-el0",
1208 .description = "Permit use of TPIDRRO_EL0 for the TLS base",
1209 .dependencies = featureSet(&[_]Feature{}),
1210 };
11741211 result[@intFromEnum(Feature.tracev8_4)] = .{
11751212 .llvm_name = "tracev8.4",
11761213 .description = "Enable v8.4-A Trace extension (FEAT_TRF)",
......@@ -1311,6 +1348,7 @@ pub const all_features = blk: {
13111348 .llvm_name = "v8.9a",
13121349 .description = "Support ARM v8.9a instructions",
13131350 .dependencies = featureSet(&[_]Feature{
1351 .chk,
13141352 .clrbhb,
13151353 .cssc,
13161354 .prfm_slc_target,
......@@ -1974,6 +2012,7 @@ pub const cpu = struct {
19742012 .lsl_fast,
19752013 .mte,
19762014 .perfmon,
2015 .predictable_select_expensive,
19772016 .spe,
19782017 .sve2_bitperm,
19792018 .use_postra_scheduler,
......@@ -1991,6 +2030,7 @@ pub const cpu = struct {
19912030 .fuse_aes,
19922031 .fuse_literals,
19932032 .perfmon,
2033 .predictable_select_expensive,
19942034 .v8a,
19952035 }),
19962036 };
......@@ -2004,6 +2044,7 @@ pub const cpu = struct {
20042044 .fuse_adrp_add,
20052045 .fuse_aes,
20062046 .perfmon,
2047 .predictable_select_expensive,
20072048 .v8a,
20082049 }),
20092050 };
......@@ -2018,6 +2059,7 @@ pub const cpu = struct {
20182059 .fuse_adrp_add,
20192060 .fuse_aes,
20202061 .perfmon,
2062 .predictable_select_expensive,
20212063 .rcpc,
20222064 .v8_2a,
20232065 }),
......@@ -2063,6 +2105,7 @@ pub const cpu = struct {
20632105 .fuse_aes,
20642106 .lsl_fast,
20652107 .perfmon,
2108 .predictable_select_expensive,
20662109 .rcpc,
20672110 .ssbs,
20682111 .v8_2a,
......@@ -2126,6 +2169,7 @@ pub const cpu = struct {
21262169 .fuse_aes,
21272170 .lsl_fast,
21282171 .perfmon,
2172 .predictable_select_expensive,
21292173 .rcpc,
21302174 .spe,
21312175 .ssbs,
......@@ -2149,6 +2193,7 @@ pub const cpu = struct {
21492193 .lsl_fast,
21502194 .pauth,
21512195 .perfmon,
2196 .predictable_select_expensive,
21522197 .rcpc_immo,
21532198 .spe,
21542199 .ssbs,
......@@ -2171,6 +2216,7 @@ pub const cpu = struct {
21712216 .lsl_fast,
21722217 .mte,
21732218 .perfmon,
2219 .predictable_select_expensive,
21742220 .sve2_bitperm,
21752221 .use_postra_scheduler,
21762222 .v9a,
......@@ -2190,6 +2236,7 @@ pub const cpu = struct {
21902236 .lsl_fast,
21912237 .mte,
21922238 .perfmon,
2239 .predictable_select_expensive,
21932240 .spe,
21942241 .sve2_bitperm,
21952242 .use_postra_scheduler,
......@@ -2383,6 +2430,7 @@ pub const cpu = struct {
23832430 .i8mm,
23842431 .lsl_fast,
23852432 .perfmon,
2433 .predictable_select_expensive,
23862434 .rand,
23872435 .spe,
23882436 .ssbs,
......@@ -2419,6 +2467,7 @@ pub const cpu = struct {
24192467 .fuse_aes,
24202468 .lsl_fast,
24212469 .perfmon,
2470 .predictable_select_expensive,
24222471 .rcpc,
24232472 .spe,
24242473 .ssbs,
......@@ -2440,6 +2489,7 @@ pub const cpu = struct {
24402489 .lsl_fast,
24412490 .mte,
24422491 .perfmon,
2492 .predictable_select_expensive,
24432493 .sve2_bitperm,
24442494 .use_postra_scheduler,
24452495 .v8_5a,
......@@ -2458,7 +2508,9 @@ pub const cpu = struct {
24582508 .fuse_aes,
24592509 .i8mm,
24602510 .lsl_fast,
2511 .no_sve_fp_ld1r,
24612512 .perfmon,
2513 .predictable_select_expensive,
24622514 .rand,
24632515 .spe,
24642516 .ssbs,
......@@ -2480,6 +2532,7 @@ pub const cpu = struct {
24802532 .lsl_fast,
24812533 .mte,
24822534 .perfmon,
2535 .predictable_select_expensive,
24832536 .rand,
24842537 .spe,
24852538 .sve2_bitperm,
lib/std/target/amdgpu.zig+215-35
......@@ -10,14 +10,20 @@ pub const Feature = enum {
1010 add_no_carry_insts,
1111 aperture_regs,
1212 architected_flat_scratch,
13 architected_sgprs,
14 atomic_buffer_global_pk_add_f16_insts,
15 atomic_buffer_global_pk_add_f16_no_rtn_insts,
16 atomic_ds_pk_add_16_insts,
1317 atomic_fadd_no_rtn_insts,
1418 atomic_fadd_rtn_insts,
15 atomic_pk_fadd_no_rtn_insts,
19 atomic_flat_pk_add_16_insts,
20 atomic_global_pk_add_bf16_inst,
1621 auto_waitcnt_before_barrier,
1722 back_off_barrier,
1823 ci_insts,
1924 cumode,
2025 dl_insts,
26 dot10_insts,
2127 dot1_insts,
2228 dot2_insts,
2329 dot3_insts,
......@@ -46,6 +52,7 @@ pub const Feature = enum {
4652 fma_mix_insts,
4753 fmacf64_inst,
4854 fmaf,
55 force_store_sc0_sc1,
4956 fp64,
5057 fp8_insts,
5158 full_rate_64_ops,
......@@ -96,12 +103,11 @@ pub const Feature = enum {
96103 no_sdst_cmpx,
97104 nsa_clause_bug,
98105 nsa_encoding,
99 nsa_max_size_13,
100 nsa_max_size_5,
101106 nsa_to_vmem_bug,
102107 offset_3f_bug,
103108 packed_fp32_ops,
104109 packed_tid,
110 partial_nsa_encoding,
105111 pk_fmac_f16_inst,
106112 promote_alloca,
107113 prt_strict_null,
......@@ -187,6 +193,30 @@ pub const all_features = blk: {
187193 .description = "Flat Scratch register is a readonly SPI initialized architected register",
188194 .dependencies = featureSet(&[_]Feature{}),
189195 };
196 result[@intFromEnum(Feature.architected_sgprs)] = .{
197 .llvm_name = "architected-sgprs",
198 .description = "Enable the architected SGPRs",
199 .dependencies = featureSet(&[_]Feature{}),
200 };
201 result[@intFromEnum(Feature.atomic_buffer_global_pk_add_f16_insts)] = .{
202 .llvm_name = "atomic-buffer-global-pk-add-f16-insts",
203 .description = "Has buffer_atomic_pk_add_f16 and global_atomic_pk_add_f16 instructions that can return original value",
204 .dependencies = featureSet(&[_]Feature{
205 .flat_global_insts,
206 }),
207 };
208 result[@intFromEnum(Feature.atomic_buffer_global_pk_add_f16_no_rtn_insts)] = .{
209 .llvm_name = "atomic-buffer-global-pk-add-f16-no-rtn-insts",
210 .description = "Has buffer_atomic_pk_add_f16 and global_atomic_pk_add_f16 instructions that don't return original value",
211 .dependencies = featureSet(&[_]Feature{
212 .flat_global_insts,
213 }),
214 };
215 result[@intFromEnum(Feature.atomic_ds_pk_add_16_insts)] = .{
216 .llvm_name = "atomic-ds-pk-add-16-insts",
217 .description = "Has ds_pk_add_bf16, ds_pk_add_f16, ds_pk_add_rtn_bf16, ds_pk_add_rtn_f16 instructions",
218 .dependencies = featureSet(&[_]Feature{}),
219 };
190220 result[@intFromEnum(Feature.atomic_fadd_no_rtn_insts)] = .{
191221 .llvm_name = "atomic-fadd-no-rtn-insts",
192222 .description = "Has buffer_atomic_add_f32 and global_atomic_add_f32 instructions that don't return original value",
......@@ -201,9 +231,14 @@ pub const all_features = blk: {
201231 .flat_global_insts,
202232 }),
203233 };
204 result[@intFromEnum(Feature.atomic_pk_fadd_no_rtn_insts)] = .{
205 .llvm_name = "atomic-pk-fadd-no-rtn-insts",
206 .description = "Has buffer_atomic_pk_add_f16 and global_atomic_pk_add_f16 instructions that don't return original value",
234 result[@intFromEnum(Feature.atomic_flat_pk_add_16_insts)] = .{
235 .llvm_name = "atomic-flat-pk-add-16-insts",
236 .description = "Has flat_atomic_pk_add_f16 and flat_atomic_pk_add_bf16 instructions",
237 .dependencies = featureSet(&[_]Feature{}),
238 };
239 result[@intFromEnum(Feature.atomic_global_pk_add_bf16_inst)] = .{
240 .llvm_name = "atomic-global-pk-add-bf16-inst",
241 .description = "Has global_atomic_pk_add_bf16 instruction",
207242 .dependencies = featureSet(&[_]Feature{
208243 .flat_global_insts,
209244 }),
......@@ -233,6 +268,11 @@ pub const all_features = blk: {
233268 .description = "Has v_fmac_f32 and v_xnor_b32 instructions",
234269 .dependencies = featureSet(&[_]Feature{}),
235270 };
271 result[@intFromEnum(Feature.dot10_insts)] = .{
272 .llvm_name = "dot10-insts",
273 .description = "Has v_dot2_f32_f16 instruction",
274 .dependencies = featureSet(&[_]Feature{}),
275 };
236276 result[@intFromEnum(Feature.dot1_insts)] = .{
237277 .llvm_name = "dot1-insts",
238278 .description = "Has v_dot4_i32_i8 and v_dot8_i32_i4 instructions",
......@@ -265,7 +305,7 @@ pub const all_features = blk: {
265305 };
266306 result[@intFromEnum(Feature.dot7_insts)] = .{
267307 .llvm_name = "dot7-insts",
268 .description = "Has v_dot2_f32_f16, v_dot4_u32_u8, v_dot8_u32_u4 instructions",
308 .description = "Has v_dot4_u32_u8, v_dot8_u32_u4 instructions",
269309 .dependencies = featureSet(&[_]Feature{}),
270310 };
271311 result[@intFromEnum(Feature.dot8_insts)] = .{
......@@ -373,6 +413,11 @@ pub const all_features = blk: {
373413 .description = "Enable single precision FMA (not as fast as mul+add, but fused)",
374414 .dependencies = featureSet(&[_]Feature{}),
375415 };
416 result[@intFromEnum(Feature.force_store_sc0_sc1)] = .{
417 .llvm_name = "force-store-sc0-sc1",
418 .description = "Has SC0 and SC1 on stores",
419 .dependencies = featureSet(&[_]Feature{}),
420 };
376421 result[@intFromEnum(Feature.fp64)] = .{
377422 .llvm_name = "fp64",
378423 .description = "Enable double precision operations",
......@@ -742,16 +787,6 @@ pub const all_features = blk: {
742787 .description = "Support NSA encoding for image instructions",
743788 .dependencies = featureSet(&[_]Feature{}),
744789 };
745 result[@intFromEnum(Feature.nsa_max_size_13)] = .{
746 .llvm_name = "nsa-max-size-13",
747 .description = "The maximum non-sequential address size in VGPRs.",
748 .dependencies = featureSet(&[_]Feature{}),
749 };
750 result[@intFromEnum(Feature.nsa_max_size_5)] = .{
751 .llvm_name = "nsa-max-size-5",
752 .description = "The maximum non-sequential address size in VGPRs.",
753 .dependencies = featureSet(&[_]Feature{}),
754 };
755790 result[@intFromEnum(Feature.nsa_to_vmem_bug)] = .{
756791 .llvm_name = "nsa-to-vmem-bug",
757792 .description = "MIMG-NSA followed by VMEM fail if EXEC_LO or EXEC_HI equals zero",
......@@ -772,6 +807,11 @@ pub const all_features = blk: {
772807 .description = "Workitem IDs are packed into v0 at kernel launch",
773808 .dependencies = featureSet(&[_]Feature{}),
774809 };
810 result[@intFromEnum(Feature.partial_nsa_encoding)] = .{
811 .llvm_name = "partial-nsa-encoding",
812 .description = "Support partial NSA encoding for image instructions",
813 .dependencies = featureSet(&[_]Feature{}),
814 };
775815 result[@intFromEnum(Feature.pk_fmac_f16_inst)] = .{
776816 .llvm_name = "pk-fmac-f16-inst",
777817 .description = "Has v_pk_fmac_f16 instruction",
......@@ -1146,7 +1186,6 @@ pub const cpu = struct {
11461186 .negative_unaligned_scratch_offset_bug,
11471187 .nsa_clause_bug,
11481188 .nsa_encoding,
1149 .nsa_max_size_5,
11501189 .nsa_to_vmem_bug,
11511190 .offset_3f_bug,
11521191 .scalar_atomics,
......@@ -1166,6 +1205,7 @@ pub const cpu = struct {
11661205 .features = featureSet(&[_]Feature{
11671206 .back_off_barrier,
11681207 .dl_insts,
1208 .dot10_insts,
11691209 .dot1_insts,
11701210 .dot2_insts,
11711211 .dot5_insts,
......@@ -1183,7 +1223,6 @@ pub const cpu = struct {
11831223 .negative_unaligned_scratch_offset_bug,
11841224 .nsa_clause_bug,
11851225 .nsa_encoding,
1186 .nsa_max_size_5,
11871226 .nsa_to_vmem_bug,
11881227 .offset_3f_bug,
11891228 .scalar_atomics,
......@@ -1203,6 +1242,7 @@ pub const cpu = struct {
12031242 .features = featureSet(&[_]Feature{
12041243 .back_off_barrier,
12051244 .dl_insts,
1245 .dot10_insts,
12061246 .dot1_insts,
12071247 .dot2_insts,
12081248 .dot5_insts,
......@@ -1220,7 +1260,6 @@ pub const cpu = struct {
12201260 .negative_unaligned_scratch_offset_bug,
12211261 .nsa_clause_bug,
12221262 .nsa_encoding,
1223 .nsa_max_size_5,
12241263 .nsa_to_vmem_bug,
12251264 .offset_3f_bug,
12261265 .scalar_atomics,
......@@ -1253,7 +1292,6 @@ pub const cpu = struct {
12531292 .negative_unaligned_scratch_offset_bug,
12541293 .nsa_clause_bug,
12551294 .nsa_encoding,
1256 .nsa_max_size_5,
12571295 .nsa_to_vmem_bug,
12581296 .offset_3f_bug,
12591297 .scalar_atomics,
......@@ -1273,6 +1311,7 @@ pub const cpu = struct {
12731311 .features = featureSet(&[_]Feature{
12741312 .back_off_barrier,
12751313 .dl_insts,
1314 .dot10_insts,
12761315 .dot1_insts,
12771316 .dot2_insts,
12781317 .dot5_insts,
......@@ -1284,7 +1323,6 @@ pub const cpu = struct {
12841323 .gfx10_b_encoding,
12851324 .ldsbankcount32,
12861325 .nsa_encoding,
1287 .nsa_max_size_13,
12881326 .shader_cycles_register,
12891327 .wavefrontsize32,
12901328 }),
......@@ -1295,6 +1333,7 @@ pub const cpu = struct {
12951333 .features = featureSet(&[_]Feature{
12961334 .back_off_barrier,
12971335 .dl_insts,
1336 .dot10_insts,
12981337 .dot1_insts,
12991338 .dot2_insts,
13001339 .dot5_insts,
......@@ -1306,7 +1345,6 @@ pub const cpu = struct {
13061345 .gfx10_b_encoding,
13071346 .ldsbankcount32,
13081347 .nsa_encoding,
1309 .nsa_max_size_13,
13101348 .shader_cycles_register,
13111349 .wavefrontsize32,
13121350 }),
......@@ -1317,6 +1355,7 @@ pub const cpu = struct {
13171355 .features = featureSet(&[_]Feature{
13181356 .back_off_barrier,
13191357 .dl_insts,
1358 .dot10_insts,
13201359 .dot1_insts,
13211360 .dot2_insts,
13221361 .dot5_insts,
......@@ -1328,7 +1367,6 @@ pub const cpu = struct {
13281367 .gfx10_b_encoding,
13291368 .ldsbankcount32,
13301369 .nsa_encoding,
1331 .nsa_max_size_13,
13321370 .shader_cycles_register,
13331371 .wavefrontsize32,
13341372 }),
......@@ -1339,6 +1377,7 @@ pub const cpu = struct {
13391377 .features = featureSet(&[_]Feature{
13401378 .back_off_barrier,
13411379 .dl_insts,
1380 .dot10_insts,
13421381 .dot1_insts,
13431382 .dot2_insts,
13441383 .dot5_insts,
......@@ -1350,7 +1389,6 @@ pub const cpu = struct {
13501389 .gfx10_b_encoding,
13511390 .ldsbankcount32,
13521391 .nsa_encoding,
1353 .nsa_max_size_13,
13541392 .shader_cycles_register,
13551393 .wavefrontsize32,
13561394 }),
......@@ -1361,6 +1399,7 @@ pub const cpu = struct {
13611399 .features = featureSet(&[_]Feature{
13621400 .back_off_barrier,
13631401 .dl_insts,
1402 .dot10_insts,
13641403 .dot1_insts,
13651404 .dot2_insts,
13661405 .dot5_insts,
......@@ -1372,7 +1411,6 @@ pub const cpu = struct {
13721411 .gfx10_b_encoding,
13731412 .ldsbankcount32,
13741413 .nsa_encoding,
1375 .nsa_max_size_13,
13761414 .shader_cycles_register,
13771415 .wavefrontsize32,
13781416 }),
......@@ -1383,6 +1421,7 @@ pub const cpu = struct {
13831421 .features = featureSet(&[_]Feature{
13841422 .back_off_barrier,
13851423 .dl_insts,
1424 .dot10_insts,
13861425 .dot1_insts,
13871426 .dot2_insts,
13881427 .dot5_insts,
......@@ -1394,7 +1433,6 @@ pub const cpu = struct {
13941433 .gfx10_b_encoding,
13951434 .ldsbankcount32,
13961435 .nsa_encoding,
1397 .nsa_max_size_13,
13981436 .shader_cycles_register,
13991437 .wavefrontsize32,
14001438 }),
......@@ -1405,6 +1443,7 @@ pub const cpu = struct {
14051443 .features = featureSet(&[_]Feature{
14061444 .back_off_barrier,
14071445 .dl_insts,
1446 .dot10_insts,
14081447 .dot1_insts,
14091448 .dot2_insts,
14101449 .dot5_insts,
......@@ -1416,7 +1455,6 @@ pub const cpu = struct {
14161455 .gfx10_b_encoding,
14171456 .ldsbankcount32,
14181457 .nsa_encoding,
1419 .nsa_max_size_13,
14201458 .shader_cycles_register,
14211459 .wavefrontsize32,
14221460 }),
......@@ -1429,6 +1467,7 @@ pub const cpu = struct {
14291467 .atomic_fadd_no_rtn_insts,
14301468 .atomic_fadd_rtn_insts,
14311469 .dl_insts,
1470 .dot10_insts,
14321471 .dot5_insts,
14331472 .dot7_insts,
14341473 .dot8_insts,
......@@ -1440,8 +1479,8 @@ pub const cpu = struct {
14401479 .ldsbankcount32,
14411480 .mad_intra_fwd_bug,
14421481 .nsa_encoding,
1443 .nsa_max_size_5,
14441482 .packed_tid,
1483 .partial_nsa_encoding,
14451484 .shader_cycles_register,
14461485 .user_sgpr_init16_bug,
14471486 .valu_trans_use_hazard,
......@@ -1457,6 +1496,7 @@ pub const cpu = struct {
14571496 .atomic_fadd_no_rtn_insts,
14581497 .atomic_fadd_rtn_insts,
14591498 .dl_insts,
1499 .dot10_insts,
14601500 .dot5_insts,
14611501 .dot7_insts,
14621502 .dot8_insts,
......@@ -1468,8 +1508,8 @@ pub const cpu = struct {
14681508 .ldsbankcount32,
14691509 .mad_intra_fwd_bug,
14701510 .nsa_encoding,
1471 .nsa_max_size_5,
14721511 .packed_tid,
1512 .partial_nsa_encoding,
14731513 .shader_cycles_register,
14741514 .valu_trans_use_hazard,
14751515 .vcmpx_permlane_hazard,
......@@ -1484,6 +1524,7 @@ pub const cpu = struct {
14841524 .atomic_fadd_no_rtn_insts,
14851525 .atomic_fadd_rtn_insts,
14861526 .dl_insts,
1527 .dot10_insts,
14871528 .dot5_insts,
14881529 .dot7_insts,
14891530 .dot8_insts,
......@@ -1494,8 +1535,8 @@ pub const cpu = struct {
14941535 .ldsbankcount32,
14951536 .mad_intra_fwd_bug,
14961537 .nsa_encoding,
1497 .nsa_max_size_5,
14981538 .packed_tid,
1539 .partial_nsa_encoding,
14991540 .shader_cycles_register,
15001541 .user_sgpr_init16_bug,
15011542 .valu_trans_use_hazard,
......@@ -1511,6 +1552,7 @@ pub const cpu = struct {
15111552 .atomic_fadd_no_rtn_insts,
15121553 .atomic_fadd_rtn_insts,
15131554 .dl_insts,
1555 .dot10_insts,
15141556 .dot5_insts,
15151557 .dot7_insts,
15161558 .dot8_insts,
......@@ -1521,14 +1563,67 @@ pub const cpu = struct {
15211563 .ldsbankcount32,
15221564 .mad_intra_fwd_bug,
15231565 .nsa_encoding,
1524 .nsa_max_size_5,
15251566 .packed_tid,
1567 .partial_nsa_encoding,
15261568 .shader_cycles_register,
15271569 .valu_trans_use_hazard,
15281570 .vcmpx_permlane_hazard,
15291571 .wavefrontsize32,
15301572 }),
15311573 };
1574 pub const gfx1150 = CpuModel{
1575 .name = "gfx1150",
1576 .llvm_name = "gfx1150",
1577 .features = featureSet(&[_]Feature{
1578 .architected_flat_scratch,
1579 .atomic_fadd_no_rtn_insts,
1580 .atomic_fadd_rtn_insts,
1581 .dl_insts,
1582 .dot10_insts,
1583 .dot5_insts,
1584 .dot7_insts,
1585 .dot8_insts,
1586 .dot9_insts,
1587 .flat_atomic_fadd_f32_inst,
1588 .gfx11,
1589 .image_insts,
1590 .ldsbankcount32,
1591 .mad_intra_fwd_bug,
1592 .nsa_encoding,
1593 .packed_tid,
1594 .partial_nsa_encoding,
1595 .shader_cycles_register,
1596 .vcmpx_permlane_hazard,
1597 .wavefrontsize32,
1598 }),
1599 };
1600 pub const gfx1151 = CpuModel{
1601 .name = "gfx1151",
1602 .llvm_name = "gfx1151",
1603 .features = featureSet(&[_]Feature{
1604 .architected_flat_scratch,
1605 .atomic_fadd_no_rtn_insts,
1606 .atomic_fadd_rtn_insts,
1607 .dl_insts,
1608 .dot10_insts,
1609 .dot5_insts,
1610 .dot7_insts,
1611 .dot8_insts,
1612 .dot9_insts,
1613 .flat_atomic_fadd_f32_inst,
1614 .gfx11,
1615 .gfx11_full_vgprs,
1616 .image_insts,
1617 .ldsbankcount32,
1618 .mad_intra_fwd_bug,
1619 .nsa_encoding,
1620 .packed_tid,
1621 .partial_nsa_encoding,
1622 .shader_cycles_register,
1623 .vcmpx_permlane_hazard,
1624 .wavefrontsize32,
1625 }),
1626 };
15321627 pub const gfx600 = CpuModel{
15331628 .name = "gfx600",
15341629 .llvm_name = "gfx600",
......@@ -1702,6 +1797,7 @@ pub const cpu = struct {
17021797 .llvm_name = "gfx906",
17031798 .features = featureSet(&[_]Feature{
17041799 .dl_insts,
1800 .dot10_insts,
17051801 .dot1_insts,
17061802 .dot2_insts,
17071803 .dot7_insts,
......@@ -1721,9 +1817,10 @@ pub const cpu = struct {
17211817 .name = "gfx908",
17221818 .llvm_name = "gfx908",
17231819 .features = featureSet(&[_]Feature{
1820 .atomic_buffer_global_pk_add_f16_no_rtn_insts,
17241821 .atomic_fadd_no_rtn_insts,
1725 .atomic_pk_fadd_no_rtn_insts,
17261822 .dl_insts,
1823 .dot10_insts,
17271824 .dot1_insts,
17281825 .dot2_insts,
17291826 .dot3_insts,
......@@ -1764,11 +1861,12 @@ pub const cpu = struct {
17641861 .name = "gfx90a",
17651862 .llvm_name = "gfx90a",
17661863 .features = featureSet(&[_]Feature{
1864 .atomic_buffer_global_pk_add_f16_insts,
17671865 .atomic_fadd_no_rtn_insts,
17681866 .atomic_fadd_rtn_insts,
1769 .atomic_pk_fadd_no_rtn_insts,
17701867 .back_off_barrier,
17711868 .dl_insts,
1869 .dot10_insts,
17721870 .dot1_insts,
17731871 .dot2_insts,
17741872 .dot3_insts,
......@@ -1811,11 +1909,93 @@ pub const cpu = struct {
18111909 .llvm_name = "gfx940",
18121910 .features = featureSet(&[_]Feature{
18131911 .architected_flat_scratch,
1912 .atomic_buffer_global_pk_add_f16_insts,
1913 .atomic_ds_pk_add_16_insts,
1914 .atomic_fadd_no_rtn_insts,
1915 .atomic_fadd_rtn_insts,
1916 .atomic_flat_pk_add_16_insts,
1917 .atomic_global_pk_add_bf16_inst,
1918 .back_off_barrier,
1919 .dl_insts,
1920 .dot10_insts,
1921 .dot1_insts,
1922 .dot2_insts,
1923 .dot3_insts,
1924 .dot4_insts,
1925 .dot5_insts,
1926 .dot6_insts,
1927 .dot7_insts,
1928 .dpp_64bit,
1929 .flat_atomic_fadd_f32_inst,
1930 .fma_mix_insts,
1931 .fmacf64_inst,
1932 .force_store_sc0_sc1,
1933 .fp8_insts,
1934 .full_rate_64_ops,
1935 .gfx9,
1936 .gfx90a_insts,
1937 .gfx940_insts,
1938 .ldsbankcount32,
1939 .mai_insts,
1940 .packed_fp32_ops,
1941 .packed_tid,
1942 .pk_fmac_f16_inst,
1943 .sramecc_support,
1944 }),
1945 };
1946 pub const gfx941 = CpuModel{
1947 .name = "gfx941",
1948 .llvm_name = "gfx941",
1949 .features = featureSet(&[_]Feature{
1950 .architected_flat_scratch,
1951 .atomic_buffer_global_pk_add_f16_insts,
1952 .atomic_ds_pk_add_16_insts,
1953 .atomic_fadd_no_rtn_insts,
1954 .atomic_fadd_rtn_insts,
1955 .atomic_flat_pk_add_16_insts,
1956 .atomic_global_pk_add_bf16_inst,
1957 .back_off_barrier,
1958 .dl_insts,
1959 .dot10_insts,
1960 .dot1_insts,
1961 .dot2_insts,
1962 .dot3_insts,
1963 .dot4_insts,
1964 .dot5_insts,
1965 .dot6_insts,
1966 .dot7_insts,
1967 .dpp_64bit,
1968 .flat_atomic_fadd_f32_inst,
1969 .fma_mix_insts,
1970 .fmacf64_inst,
1971 .force_store_sc0_sc1,
1972 .fp8_insts,
1973 .full_rate_64_ops,
1974 .gfx9,
1975 .gfx90a_insts,
1976 .gfx940_insts,
1977 .ldsbankcount32,
1978 .mai_insts,
1979 .packed_fp32_ops,
1980 .packed_tid,
1981 .pk_fmac_f16_inst,
1982 .sramecc_support,
1983 }),
1984 };
1985 pub const gfx942 = CpuModel{
1986 .name = "gfx942",
1987 .llvm_name = "gfx942",
1988 .features = featureSet(&[_]Feature{
1989 .architected_flat_scratch,
1990 .atomic_buffer_global_pk_add_f16_insts,
1991 .atomic_ds_pk_add_16_insts,
18141992 .atomic_fadd_no_rtn_insts,
18151993 .atomic_fadd_rtn_insts,
1816 .atomic_pk_fadd_no_rtn_insts,
1994 .atomic_flat_pk_add_16_insts,
1995 .atomic_global_pk_add_bf16_inst,
18171996 .back_off_barrier,
18181997 .dl_insts,
1998 .dot10_insts,
18191999 .dot1_insts,
18202000 .dot2_insts,
18212001 .dot3_insts,
lib/std/target/arm.zig+16-4
......@@ -122,7 +122,9 @@ pub const Feature = enum {
122122 r4,
123123 ras,
124124 rclass,
125 read_tp_hard,
125 read_tp_tpidrprw,
126 read_tp_tpidruro,
127 read_tp_tpidrurw,
126128 reserve_r9,
127129 ret_addr_stack,
128130 sb,
......@@ -949,9 +951,19 @@ pub const all_features = blk: {
949951 .description = "Is realtime profile ('R' series)",
950952 .dependencies = featureSet(&[_]Feature{}),
951953 };
952 result[@intFromEnum(Feature.read_tp_hard)] = .{
953 .llvm_name = "read-tp-hard",
954 .description = "Reading thread pointer from register",
954 result[@intFromEnum(Feature.read_tp_tpidrprw)] = .{
955 .llvm_name = "read-tp-tpidrprw",
956 .description = "Reading thread pointer from TPIDRPRW register",
957 .dependencies = featureSet(&[_]Feature{}),
958 };
959 result[@intFromEnum(Feature.read_tp_tpidruro)] = .{
960 .llvm_name = "read-tp-tpidruro",
961 .description = "Reading thread pointer from TPIDRURO register",
962 .dependencies = featureSet(&[_]Feature{}),
963 };
964 result[@intFromEnum(Feature.read_tp_tpidrurw)] = .{
965 .llvm_name = "read-tp-tpidrurw",
966 .description = "Reading thread pointer from TPIDRURW register",
955967 .dependencies = featureSet(&[_]Feature{}),
956968 };
957969 result[@intFromEnum(Feature.reserve_r9)] = .{
lib/std/target/avr.zig+8-9
......@@ -25,12 +25,12 @@ pub const Feature = enum {
2525 elpmx,
2626 ijmpcall,
2727 jmpcall,
28 lowbytefirst,
2829 lpm,
2930 lpmx,
3031 memmappedregs,
3132 movw,
3233 mul,
33 progmem,
3434 rmw,
3535 smallstack,
3636 special,
......@@ -69,7 +69,6 @@ pub const all_features = blk: {
6969 .avr0,
7070 .lpm,
7171 .memmappedregs,
72 .progmem,
7372 }),
7473 };
7574 result[@intFromEnum(Feature.avr2)] = .{
......@@ -207,6 +206,11 @@ pub const all_features = blk: {
207206 .description = "The device supports the `JMP` and `CALL` instructions",
208207 .dependencies = featureSet(&[_]Feature{}),
209208 };
209 result[@intFromEnum(Feature.lowbytefirst)] = .{
210 .llvm_name = "lowbytefirst",
211 .description = "Do the low byte first when writing a 16-bit port or storing a 16-bit word",
212 .dependencies = featureSet(&[_]Feature{}),
213 };
210214 result[@intFromEnum(Feature.lpm)] = .{
211215 .llvm_name = "lpm",
212216 .description = "The device supports the `LPM` instruction",
......@@ -232,11 +236,6 @@ pub const all_features = blk: {
232236 .description = "The device supports the multiplication instructions",
233237 .dependencies = featureSet(&[_]Feature{}),
234238 };
235 result[@intFromEnum(Feature.progmem)] = .{
236 .llvm_name = "progmem",
237 .description = "The device has a separate flash namespace",
238 .dependencies = featureSet(&[_]Feature{}),
239 };
240239 result[@intFromEnum(Feature.rmw)] = .{
241240 .llvm_name = "rmw",
242241 .description = "The device supports the read-write-modify instructions: XCH, LAS, LAC, LAT",
......@@ -303,11 +302,11 @@ pub const all_features = blk: {
303302 .elpmx,
304303 .ijmpcall,
305304 .jmpcall,
305 .lowbytefirst,
306306 .lpm,
307307 .lpmx,
308308 .movw,
309309 .mul,
310 .progmem,
311310 .spm,
312311 .spmx,
313312 .sram,
......@@ -322,11 +321,11 @@ pub const all_features = blk: {
322321 .@"break",
323322 .ijmpcall,
324323 .jmpcall,
324 .lowbytefirst,
325325 .lpm,
326326 .lpmx,
327327 .movw,
328328 .mul,
329 .progmem,
330329 .sram,
331330 }),
332331 };
lib/std/target/bpf.zig+3-1
......@@ -66,6 +66,8 @@ pub const cpu = struct {
6666 pub const v3 = CpuModel{
6767 .name = "v3",
6868 .llvm_name = "v3",
69 .features = featureSet(&[_]Feature{}),
69 .features = featureSet(&[_]Feature{
70 .alu32,
71 }),
7072 };
7173};
lib/std/target/csky.zig+9-9
......@@ -214,7 +214,7 @@ pub const all_features = blk: {
214214 };
215215 result[@intFromEnum(Feature.dsp_silan)] = .{
216216 .llvm_name = "dsp_silan",
217 .description = "Enable DSP Silan instructions",
217 .description = "Enable DSP Silan instrutions",
218218 .dependencies = featureSet(&[_]Feature{}),
219219 };
220220 result[@intFromEnum(Feature.dspe60)] = .{
......@@ -224,7 +224,7 @@ pub const all_features = blk: {
224224 };
225225 result[@intFromEnum(Feature.dspv2)] = .{
226226 .llvm_name = "dspv2",
227 .description = "Enable DSP V2.0 instructions",
227 .description = "Enable DSP V2.0 instrutions",
228228 .dependencies = featureSet(&[_]Feature{}),
229229 };
230230 result[@intFromEnum(Feature.e1)] = .{
......@@ -243,7 +243,7 @@ pub const all_features = blk: {
243243 };
244244 result[@intFromEnum(Feature.edsp)] = .{
245245 .llvm_name = "edsp",
246 .description = "Enable DSP instructions",
246 .description = "Enable DSP instrutions",
247247 .dependencies = featureSet(&[_]Feature{}),
248248 };
249249 result[@intFromEnum(Feature.elrw)] = .{
......@@ -298,12 +298,12 @@ pub const all_features = blk: {
298298 };
299299 result[@intFromEnum(Feature.fpuv3_hf)] = .{
300300 .llvm_name = "fpuv3_hf",
301 .description = "Enable FPUv3 harf precision operate instructions",
301 .description = "Enable FPUv3 half precision operate instructions",
302302 .dependencies = featureSet(&[_]Feature{}),
303303 };
304304 result[@intFromEnum(Feature.fpuv3_hi)] = .{
305305 .llvm_name = "fpuv3_hi",
306 .description = "Enable FPUv3 harf word converting instructions",
306 .description = "Enable FPUv3 half word converting instructions",
307307 .dependencies = featureSet(&[_]Feature{}),
308308 };
309309 result[@intFromEnum(Feature.fpuv3_sf)] = .{
......@@ -333,12 +333,12 @@ pub const all_features = blk: {
333333 };
334334 result[@intFromEnum(Feature.hwdiv)] = .{
335335 .llvm_name = "hwdiv",
336 .description = "Enable divide instructions",
336 .description = "Enable divide instrutions",
337337 .dependencies = featureSet(&[_]Feature{}),
338338 };
339339 result[@intFromEnum(Feature.istack)] = .{
340340 .llvm_name = "istack",
341 .description = "Enable interrupt attribute",
341 .description = "Enable interrput attribute",
342342 .dependencies = featureSet(&[_]Feature{}),
343343 };
344344 result[@intFromEnum(Feature.java)] = .{
......@@ -362,7 +362,7 @@ pub const all_features = blk: {
362362 };
363363 result[@intFromEnum(Feature.multiple_stld)] = .{
364364 .llvm_name = "multiple_stld",
365 .description = "Enable multiple load/store instructions",
365 .description = "Enable multiple load/store instrutions",
366366 .dependencies = featureSet(&[_]Feature{}),
367367 };
368368 result[@intFromEnum(Feature.nvic)] = .{
......@@ -372,7 +372,7 @@ pub const all_features = blk: {
372372 };
373373 result[@intFromEnum(Feature.pushpop)] = .{
374374 .llvm_name = "pushpop",
375 .description = "Enable push/pop instructions",
375 .description = "Enable push/pop instrutions",
376376 .dependencies = featureSet(&[_]Feature{}),
377377 };
378378 result[@intFromEnum(Feature.smart)] = .{
lib/std/target/loongarch.zig+17
......@@ -16,6 +16,7 @@ pub const Feature = enum {
1616 lbt,
1717 lsx,
1818 lvz,
19 ual,
1920};
2021
2122pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
......@@ -88,6 +89,11 @@ pub const all_features = blk: {
8889 .description = "'LVZ' (Loongson Virtualization Extension)",
8990 .dependencies = featureSet(&[_]Feature{}),
9091 };
92 result[@intFromEnum(Feature.ual)] = .{
93 .llvm_name = "ual",
94 .description = "Allow memory accesses to be unaligned",
95 .dependencies = featureSet(&[_]Feature{}),
96 };
9197 const ti = @typeInfo(Feature);
9298 for (&result, 0..) |*elem, i| {
9399 elem.index = i;
......@@ -114,6 +120,7 @@ pub const cpu = struct {
114120 .llvm_name = "generic-la64",
115121 .features = featureSet(&[_]Feature{
116122 .@"64bit",
123 .ual,
117124 }),
118125 };
119126 pub const la464 = CpuModel{
......@@ -124,6 +131,16 @@ pub const cpu = struct {
124131 .lasx,
125132 .lbt,
126133 .lvz,
134 .ual,
135 }),
136 };
137 pub const loongarch64 = CpuModel{
138 .name = "loongarch64",
139 .llvm_name = "loongarch64",
140 .features = featureSet(&[_]Feature{
141 .@"64bit",
142 .d,
143 .ual,
127144 }),
128145 };
129146};
lib/std/target/m68k.zig+15
......@@ -11,6 +11,8 @@ pub const Feature = enum {
1111 isa_68030,
1212 isa_68040,
1313 isa_68060,
14 isa_68881,
15 isa_68882,
1416 reserve_a0,
1517 reserve_a1,
1618 reserve_a2,
......@@ -68,6 +70,7 @@ pub const all_features = blk: {
6870 .description = "Is M68040 ISA supported",
6971 .dependencies = featureSet(&[_]Feature{
7072 .isa_68030,
73 .isa_68882,
7174 }),
7275 };
7376 result[@intFromEnum(Feature.isa_68060)] = .{
......@@ -77,6 +80,18 @@ pub const all_features = blk: {
7780 .isa_68040,
7881 }),
7982 };
83 result[@intFromEnum(Feature.isa_68881)] = .{
84 .llvm_name = "isa-68881",
85 .description = "Is M68881 (FPU) ISA supported",
86 .dependencies = featureSet(&[_]Feature{}),
87 };
88 result[@intFromEnum(Feature.isa_68882)] = .{
89 .llvm_name = "isa-68882",
90 .description = "Is M68882 (FPU) ISA supported",
91 .dependencies = featureSet(&[_]Feature{
92 .isa_68881,
93 }),
94 };
8095 result[@intFromEnum(Feature.reserve_a0)] = .{
8196 .llvm_name = "reserve-a0",
8297 .description = "Reserve A0 register",
lib/std/target/nvptx.zig+52-40
......@@ -25,6 +25,8 @@ pub const Feature = enum {
2525 ptx76,
2626 ptx77,
2727 ptx78,
28 ptx80,
29 ptx81,
2830 sm_20,
2931 sm_21,
3032 sm_30,
......@@ -58,202 +60,212 @@ pub const all_features = blk: {
5860 var result: [len]CpuFeature = undefined;
5961 result[@intFromEnum(Feature.ptx32)] = .{
6062 .llvm_name = "ptx32",
61 .description = "Use PTX version 3.2",
63 .description = "Use PTX version 32",
6264 .dependencies = featureSet(&[_]Feature{}),
6365 };
6466 result[@intFromEnum(Feature.ptx40)] = .{
6567 .llvm_name = "ptx40",
66 .description = "Use PTX version 4.0",
68 .description = "Use PTX version 40",
6769 .dependencies = featureSet(&[_]Feature{}),
6870 };
6971 result[@intFromEnum(Feature.ptx41)] = .{
7072 .llvm_name = "ptx41",
71 .description = "Use PTX version 4.1",
73 .description = "Use PTX version 41",
7274 .dependencies = featureSet(&[_]Feature{}),
7375 };
7476 result[@intFromEnum(Feature.ptx42)] = .{
7577 .llvm_name = "ptx42",
76 .description = "Use PTX version 4.2",
78 .description = "Use PTX version 42",
7779 .dependencies = featureSet(&[_]Feature{}),
7880 };
7981 result[@intFromEnum(Feature.ptx43)] = .{
8082 .llvm_name = "ptx43",
81 .description = "Use PTX version 4.3",
83 .description = "Use PTX version 43",
8284 .dependencies = featureSet(&[_]Feature{}),
8385 };
8486 result[@intFromEnum(Feature.ptx50)] = .{
8587 .llvm_name = "ptx50",
86 .description = "Use PTX version 5.0",
88 .description = "Use PTX version 50",
8789 .dependencies = featureSet(&[_]Feature{}),
8890 };
8991 result[@intFromEnum(Feature.ptx60)] = .{
9092 .llvm_name = "ptx60",
91 .description = "Use PTX version 6.0",
93 .description = "Use PTX version 60",
9294 .dependencies = featureSet(&[_]Feature{}),
9395 };
9496 result[@intFromEnum(Feature.ptx61)] = .{
9597 .llvm_name = "ptx61",
96 .description = "Use PTX version 6.1",
98 .description = "Use PTX version 61",
9799 .dependencies = featureSet(&[_]Feature{}),
98100 };
99101 result[@intFromEnum(Feature.ptx63)] = .{
100102 .llvm_name = "ptx63",
101 .description = "Use PTX version 6.3",
103 .description = "Use PTX version 63",
102104 .dependencies = featureSet(&[_]Feature{}),
103105 };
104106 result[@intFromEnum(Feature.ptx64)] = .{
105107 .llvm_name = "ptx64",
106 .description = "Use PTX version 6.4",
108 .description = "Use PTX version 64",
107109 .dependencies = featureSet(&[_]Feature{}),
108110 };
109111 result[@intFromEnum(Feature.ptx65)] = .{
110112 .llvm_name = "ptx65",
111 .description = "Use PTX version 6.5",
113 .description = "Use PTX version 65",
112114 .dependencies = featureSet(&[_]Feature{}),
113115 };
114116 result[@intFromEnum(Feature.ptx70)] = .{
115117 .llvm_name = "ptx70",
116 .description = "Use PTX version 7.0",
118 .description = "Use PTX version 70",
117119 .dependencies = featureSet(&[_]Feature{}),
118120 };
119121 result[@intFromEnum(Feature.ptx71)] = .{
120122 .llvm_name = "ptx71",
121 .description = "Use PTX version 7.1",
123 .description = "Use PTX version 71",
122124 .dependencies = featureSet(&[_]Feature{}),
123125 };
124126 result[@intFromEnum(Feature.ptx72)] = .{
125127 .llvm_name = "ptx72",
126 .description = "Use PTX version 7.2",
128 .description = "Use PTX version 72",
127129 .dependencies = featureSet(&[_]Feature{}),
128130 };
129131 result[@intFromEnum(Feature.ptx73)] = .{
130132 .llvm_name = "ptx73",
131 .description = "Use PTX version 7.3",
133 .description = "Use PTX version 73",
132134 .dependencies = featureSet(&[_]Feature{}),
133135 };
134136 result[@intFromEnum(Feature.ptx74)] = .{
135137 .llvm_name = "ptx74",
136 .description = "Use PTX version 7.4",
138 .description = "Use PTX version 74",
137139 .dependencies = featureSet(&[_]Feature{}),
138140 };
139141 result[@intFromEnum(Feature.ptx75)] = .{
140142 .llvm_name = "ptx75",
141 .description = "Use PTX version 7.5",
143 .description = "Use PTX version 75",
142144 .dependencies = featureSet(&[_]Feature{}),
143145 };
144146 result[@intFromEnum(Feature.ptx76)] = .{
145147 .llvm_name = "ptx76",
146 .description = "Use PTX version 7.6",
148 .description = "Use PTX version 76",
147149 .dependencies = featureSet(&[_]Feature{}),
148150 };
149151 result[@intFromEnum(Feature.ptx77)] = .{
150152 .llvm_name = "ptx77",
151 .description = "Use PTX version 7.7",
153 .description = "Use PTX version 77",
152154 .dependencies = featureSet(&[_]Feature{}),
153155 };
154156 result[@intFromEnum(Feature.ptx78)] = .{
155157 .llvm_name = "ptx78",
156 .description = "Use PTX version 7.8",
158 .description = "Use PTX version 78",
159 .dependencies = featureSet(&[_]Feature{}),
160 };
161 result[@intFromEnum(Feature.ptx80)] = .{
162 .llvm_name = "ptx80",
163 .description = "Use PTX version 80",
164 .dependencies = featureSet(&[_]Feature{}),
165 };
166 result[@intFromEnum(Feature.ptx81)] = .{
167 .llvm_name = "ptx81",
168 .description = "Use PTX version 81",
157169 .dependencies = featureSet(&[_]Feature{}),
158170 };
159171 result[@intFromEnum(Feature.sm_20)] = .{
160172 .llvm_name = "sm_20",
161 .description = "Target SM 2.0",
173 .description = "Target SM 20",
162174 .dependencies = featureSet(&[_]Feature{}),
163175 };
164176 result[@intFromEnum(Feature.sm_21)] = .{
165177 .llvm_name = "sm_21",
166 .description = "Target SM 2.1",
178 .description = "Target SM 21",
167179 .dependencies = featureSet(&[_]Feature{}),
168180 };
169181 result[@intFromEnum(Feature.sm_30)] = .{
170182 .llvm_name = "sm_30",
171 .description = "Target SM 3.0",
183 .description = "Target SM 30",
172184 .dependencies = featureSet(&[_]Feature{}),
173185 };
174186 result[@intFromEnum(Feature.sm_32)] = .{
175187 .llvm_name = "sm_32",
176 .description = "Target SM 3.2",
188 .description = "Target SM 32",
177189 .dependencies = featureSet(&[_]Feature{}),
178190 };
179191 result[@intFromEnum(Feature.sm_35)] = .{
180192 .llvm_name = "sm_35",
181 .description = "Target SM 3.5",
193 .description = "Target SM 35",
182194 .dependencies = featureSet(&[_]Feature{}),
183195 };
184196 result[@intFromEnum(Feature.sm_37)] = .{
185197 .llvm_name = "sm_37",
186 .description = "Target SM 3.7",
198 .description = "Target SM 37",
187199 .dependencies = featureSet(&[_]Feature{}),
188200 };
189201 result[@intFromEnum(Feature.sm_50)] = .{
190202 .llvm_name = "sm_50",
191 .description = "Target SM 5.0",
203 .description = "Target SM 50",
192204 .dependencies = featureSet(&[_]Feature{}),
193205 };
194206 result[@intFromEnum(Feature.sm_52)] = .{
195207 .llvm_name = "sm_52",
196 .description = "Target SM 5.2",
208 .description = "Target SM 52",
197209 .dependencies = featureSet(&[_]Feature{}),
198210 };
199211 result[@intFromEnum(Feature.sm_53)] = .{
200212 .llvm_name = "sm_53",
201 .description = "Target SM 5.3",
213 .description = "Target SM 53",
202214 .dependencies = featureSet(&[_]Feature{}),
203215 };
204216 result[@intFromEnum(Feature.sm_60)] = .{
205217 .llvm_name = "sm_60",
206 .description = "Target SM 6.0",
218 .description = "Target SM 60",
207219 .dependencies = featureSet(&[_]Feature{}),
208220 };
209221 result[@intFromEnum(Feature.sm_61)] = .{
210222 .llvm_name = "sm_61",
211 .description = "Target SM 6.1",
223 .description = "Target SM 61",
212224 .dependencies = featureSet(&[_]Feature{}),
213225 };
214226 result[@intFromEnum(Feature.sm_62)] = .{
215227 .llvm_name = "sm_62",
216 .description = "Target SM 6.2",
228 .description = "Target SM 62",
217229 .dependencies = featureSet(&[_]Feature{}),
218230 };
219231 result[@intFromEnum(Feature.sm_70)] = .{
220232 .llvm_name = "sm_70",
221 .description = "Target SM 7.0",
233 .description = "Target SM 70",
222234 .dependencies = featureSet(&[_]Feature{}),
223235 };
224236 result[@intFromEnum(Feature.sm_72)] = .{
225237 .llvm_name = "sm_72",
226 .description = "Target SM 7.2",
238 .description = "Target SM 72",
227239 .dependencies = featureSet(&[_]Feature{}),
228240 };
229241 result[@intFromEnum(Feature.sm_75)] = .{
230242 .llvm_name = "sm_75",
231 .description = "Target SM 7.5",
243 .description = "Target SM 75",
232244 .dependencies = featureSet(&[_]Feature{}),
233245 };
234246 result[@intFromEnum(Feature.sm_80)] = .{
235247 .llvm_name = "sm_80",
236 .description = "Target SM 8.0",
248 .description = "Target SM 80",
237249 .dependencies = featureSet(&[_]Feature{}),
238250 };
239251 result[@intFromEnum(Feature.sm_86)] = .{
240252 .llvm_name = "sm_86",
241 .description = "Target SM 8.6",
253 .description = "Target SM 86",
242254 .dependencies = featureSet(&[_]Feature{}),
243255 };
244256 result[@intFromEnum(Feature.sm_87)] = .{
245257 .llvm_name = "sm_87",
246 .description = "Target SM 8.7",
258 .description = "Target SM 87",
247259 .dependencies = featureSet(&[_]Feature{}),
248260 };
249261 result[@intFromEnum(Feature.sm_89)] = .{
250262 .llvm_name = "sm_89",
251 .description = "Target SM 8.9",
263 .description = "Target SM 89",
252264 .dependencies = featureSet(&[_]Feature{}),
253265 };
254266 result[@intFromEnum(Feature.sm_90)] = .{
255267 .llvm_name = "sm_90",
256 .description = "Target SM 9.0",
268 .description = "Target SM 90",
257269 .dependencies = featureSet(&[_]Feature{}),
258270 };
259271 const ti = @typeInfo(Feature);
lib/std/target/riscv.zig+401-26
......@@ -10,14 +10,33 @@ pub const Feature = enum {
1010 a,
1111 c,
1212 d,
13 dlen_factor_2,
1314 e,
14 experimental_zawrs,
15 experimental_zca,
16 experimental_zcd,
17 experimental_zcf,
15 experimental_smaia,
16 experimental_ssaia,
17 experimental_zacas,
18 experimental_zfa,
19 experimental_zfbfmin,
20 experimental_zicond,
1821 experimental_zihintntl,
1922 experimental_ztso,
20 experimental_zvfh,
23 experimental_zvbb,
24 experimental_zvbc,
25 experimental_zvfbfmin,
26 experimental_zvfbfwma,
27 experimental_zvkg,
28 experimental_zvkn,
29 experimental_zvknc,
30 experimental_zvkned,
31 experimental_zvkng,
32 experimental_zvknha,
33 experimental_zvknhb,
34 experimental_zvks,
35 experimental_zvksc,
36 experimental_zvksed,
37 experimental_zvksg,
38 experimental_zvksh,
39 experimental_zvkt,
2140 f,
2241 forced_atomics,
2342 h,
......@@ -59,15 +78,32 @@ pub const Feature = enum {
5978 reserve_x8,
6079 reserve_x9,
6180 save_restore,
81 seq_cst_trailing_fence,
6282 short_forward_branch_opt,
6383 svinval,
6484 svnapot,
6585 svpbmt,
6686 tagged_globals,
6787 unaligned_scalar_mem,
88 unaligned_vector_mem,
6889 v,
90 xcvbitmanip,
91 xcvmac,
92 xsfcie,
93 xsfvcp,
94 xtheadba,
95 xtheadbb,
96 xtheadbs,
97 xtheadcmo,
98 xtheadcondmov,
99 xtheadfmemidx,
100 xtheadmac,
101 xtheadmemidx,
102 xtheadmempair,
103 xtheadsync,
69104 xtheadvdot,
70105 xventanacondops,
106 zawrs,
71107 zba,
72108 zbb,
73109 zbc,
......@@ -75,6 +111,13 @@ pub const Feature = enum {
75111 zbkc,
76112 zbkx,
77113 zbs,
114 zca,
115 zcb,
116 zcd,
117 zce,
118 zcf,
119 zcmp,
120 zcmt,
78121 zdinx,
79122 zfh,
80123 zfhmin,
......@@ -84,7 +127,11 @@ pub const Feature = enum {
84127 zicbom,
85128 zicbop,
86129 zicboz,
130 zicntr,
131 zicsr,
132 zifencei,
87133 zihintpause,
134 zihpm,
88135 zk,
89136 zkn,
90137 zknd,
......@@ -101,6 +148,7 @@ pub const Feature = enum {
101148 zve64d,
102149 zve64f,
103150 zve64x,
151 zvfh,
104152 zvl1024b,
105153 zvl128b,
106154 zvl16384b,
......@@ -151,34 +199,53 @@ pub const all_features = blk: {
151199 .f,
152200 }),
153201 };
202 result[@intFromEnum(Feature.dlen_factor_2)] = .{
203 .llvm_name = "dlen-factor-2",
204 .description = "Vector unit DLEN(data path width) is half of VLEN",
205 .dependencies = featureSet(&[_]Feature{}),
206 };
154207 result[@intFromEnum(Feature.e)] = .{
155208 .llvm_name = "e",
156 .description = "Implements RV32E (provides 16 rather than 32 GPRs)",
209 .description = "Implements RV{32,64}E (provides 16 rather than 32 GPRs)",
157210 .dependencies = featureSet(&[_]Feature{}),
158211 };
159 result[@intFromEnum(Feature.experimental_zawrs)] = .{
160 .llvm_name = "experimental-zawrs",
161 .description = "'Zawrs' (Wait on Reservation Set)",
212 result[@intFromEnum(Feature.experimental_smaia)] = .{
213 .llvm_name = "experimental-smaia",
214 .description = "'Smaia' (Smaia encompasses all added CSRs and all modifications to interrupt response behavior that the AIA specifies for a hart, over all privilege levels.)",
162215 .dependencies = featureSet(&[_]Feature{}),
163216 };
164 result[@intFromEnum(Feature.experimental_zca)] = .{
165 .llvm_name = "experimental-zca",
166 .description = "'Zca' (part of the C extension, excluding compressed floating point loads/stores)",
217 result[@intFromEnum(Feature.experimental_ssaia)] = .{
218 .llvm_name = "experimental-ssaia",
219 .description = "'Ssaia' (Ssaia is essentially the same as Smaia except excluding the machine-level CSRs and behavior not directly visible to supervisor level.)",
167220 .dependencies = featureSet(&[_]Feature{}),
168221 };
169 result[@intFromEnum(Feature.experimental_zcd)] = .{
170 .llvm_name = "experimental-zcd",
171 .description = "'Zcd' (Compressed Double-Precision Floating-Point Instructions)",
222 result[@intFromEnum(Feature.experimental_zacas)] = .{
223 .llvm_name = "experimental-zacas",
224 .description = "'Zacas' (Atomic Compare-And-Swap Instructions)",
172225 .dependencies = featureSet(&[_]Feature{}),
173226 };
174 result[@intFromEnum(Feature.experimental_zcf)] = .{
175 .llvm_name = "experimental-zcf",
176 .description = "'Zcf' (Compressed Single-Precision Floating-Point Instructions)",
227 result[@intFromEnum(Feature.experimental_zfa)] = .{
228 .llvm_name = "experimental-zfa",
229 .description = "'Zfa' (Additional Floating-Point)",
230 .dependencies = featureSet(&[_]Feature{
231 .f,
232 }),
233 };
234 result[@intFromEnum(Feature.experimental_zfbfmin)] = .{
235 .llvm_name = "experimental-zfbfmin",
236 .description = "'Zfbfmin' (Scalar BF16 Converts)",
237 .dependencies = featureSet(&[_]Feature{
238 .f,
239 }),
240 };
241 result[@intFromEnum(Feature.experimental_zicond)] = .{
242 .llvm_name = "experimental-zicond",
243 .description = "'Zicond' (Integer Conditional Operations)",
177244 .dependencies = featureSet(&[_]Feature{}),
178245 };
179246 result[@intFromEnum(Feature.experimental_zihintntl)] = .{
180247 .llvm_name = "experimental-zihintntl",
181 .description = "'zihintntl' (Non-Temporal Locality Hints)",
248 .description = "'Zihintntl' (Non-Temporal Locality Hints)",
182249 .dependencies = featureSet(&[_]Feature{}),
183250 };
184251 result[@intFromEnum(Feature.experimental_ztso)] = .{
......@@ -186,17 +253,103 @@ pub const all_features = blk: {
186253 .description = "'Ztso' (Memory Model - Total Store Order)",
187254 .dependencies = featureSet(&[_]Feature{}),
188255 };
189 result[@intFromEnum(Feature.experimental_zvfh)] = .{
190 .llvm_name = "experimental-zvfh",
191 .description = "'Zvfh' (Vector Half-Precision Floating-Point)",
256 result[@intFromEnum(Feature.experimental_zvbb)] = .{
257 .llvm_name = "experimental-zvbb",
258 .description = "'Zvbb' (Vector Bit-manipulation used in Cryptography)",
259 .dependencies = featureSet(&[_]Feature{}),
260 };
261 result[@intFromEnum(Feature.experimental_zvbc)] = .{
262 .llvm_name = "experimental-zvbc",
263 .description = "'Zvbc' (Vector Carryless Multiplication)",
264 .dependencies = featureSet(&[_]Feature{}),
265 };
266 result[@intFromEnum(Feature.experimental_zvfbfmin)] = .{
267 .llvm_name = "experimental-zvfbfmin",
268 .description = "'Zvbfmin' (Vector BF16 Converts)",
192269 .dependencies = featureSet(&[_]Feature{
193270 .zve32f,
194271 }),
195272 };
273 result[@intFromEnum(Feature.experimental_zvfbfwma)] = .{
274 .llvm_name = "experimental-zvfbfwma",
275 .description = "'Zvfbfwma' (Vector BF16 widening mul-add)",
276 .dependencies = featureSet(&[_]Feature{
277 .zve32f,
278 }),
279 };
280 result[@intFromEnum(Feature.experimental_zvkg)] = .{
281 .llvm_name = "experimental-zvkg",
282 .description = "'Zvkg' (Vector GCM instructions for Cryptography)",
283 .dependencies = featureSet(&[_]Feature{}),
284 };
285 result[@intFromEnum(Feature.experimental_zvkn)] = .{
286 .llvm_name = "experimental-zvkn",
287 .description = "This extension is shorthand for the following set of other extensions: Zvkned, Zvknhb, Zvbb, Zvbc, and Zvkt.",
288 .dependencies = featureSet(&[_]Feature{}),
289 };
290 result[@intFromEnum(Feature.experimental_zvknc)] = .{
291 .llvm_name = "experimental-zvknc",
292 .description = "This extension is shorthand for the following set of other extensions: Zvkn and Zvbc.",
293 .dependencies = featureSet(&[_]Feature{}),
294 };
295 result[@intFromEnum(Feature.experimental_zvkned)] = .{
296 .llvm_name = "experimental-zvkned",
297 .description = "'Zvkned' (Vector AES Encryption & Decryption (Single Round))",
298 .dependencies = featureSet(&[_]Feature{}),
299 };
300 result[@intFromEnum(Feature.experimental_zvkng)] = .{
301 .llvm_name = "experimental-zvkng",
302 .description = "This extension is shorthand for the following set of other extensions: Zvkn and Zvkg.",
303 .dependencies = featureSet(&[_]Feature{}),
304 };
305 result[@intFromEnum(Feature.experimental_zvknha)] = .{
306 .llvm_name = "experimental-zvknha",
307 .description = "'Zvknha' (Vector SHA-2 (SHA-256 only))",
308 .dependencies = featureSet(&[_]Feature{}),
309 };
310 result[@intFromEnum(Feature.experimental_zvknhb)] = .{
311 .llvm_name = "experimental-zvknhb",
312 .description = "'Zvknhb' (Vector SHA-2 (SHA-256 and SHA-512))",
313 .dependencies = featureSet(&[_]Feature{
314 .experimental_zvknha,
315 }),
316 };
317 result[@intFromEnum(Feature.experimental_zvks)] = .{
318 .llvm_name = "experimental-zvks",
319 .description = "This extension is shorthand for the following set of other extensions: Zvksed, Zvksh, Zvbb, Zvbc, and Zvkt.",
320 .dependencies = featureSet(&[_]Feature{}),
321 };
322 result[@intFromEnum(Feature.experimental_zvksc)] = .{
323 .llvm_name = "experimental-zvksc",
324 .description = "This extension is shorthand for the following set of other extensions: Zvks and Zvbc.",
325 .dependencies = featureSet(&[_]Feature{}),
326 };
327 result[@intFromEnum(Feature.experimental_zvksed)] = .{
328 .llvm_name = "experimental-zvksed",
329 .description = "'Zvksed' (SM4 Block Cipher Instructions)",
330 .dependencies = featureSet(&[_]Feature{}),
331 };
332 result[@intFromEnum(Feature.experimental_zvksg)] = .{
333 .llvm_name = "experimental-zvksg",
334 .description = "This extension is shorthand for the following set of other extensions: Zvks and Zvkg.",
335 .dependencies = featureSet(&[_]Feature{}),
336 };
337 result[@intFromEnum(Feature.experimental_zvksh)] = .{
338 .llvm_name = "experimental-zvksh",
339 .description = "'Zvksh' (SM3 Hash Function Instructions)",
340 .dependencies = featureSet(&[_]Feature{}),
341 };
342 result[@intFromEnum(Feature.experimental_zvkt)] = .{
343 .llvm_name = "experimental-zvkt",
344 .description = "'Zvkt' (Vector Data-Independent Execution Latency)",
345 .dependencies = featureSet(&[_]Feature{}),
346 };
196347 result[@intFromEnum(Feature.f)] = .{
197348 .llvm_name = "f",
198349 .description = "'F' (Single-Precision Floating-Point)",
199 .dependencies = featureSet(&[_]Feature{}),
350 .dependencies = featureSet(&[_]Feature{
351 .zicsr,
352 }),
200353 };
201354 result[@intFromEnum(Feature.forced_atomics)] = .{
202355 .llvm_name = "forced-atomics",
......@@ -398,6 +551,11 @@ pub const all_features = blk: {
398551 .description = "Enable save/restore.",
399552 .dependencies = featureSet(&[_]Feature{}),
400553 };
554 result[@intFromEnum(Feature.seq_cst_trailing_fence)] = .{
555 .llvm_name = "seq-cst-trailing-fence",
556 .description = "Enable trailing fence for seq-cst store.",
557 .dependencies = featureSet(&[_]Feature{}),
558 };
401559 result[@intFromEnum(Feature.short_forward_branch_opt)] = .{
402560 .llvm_name = "short-forward-branch-opt",
403561 .description = "Enable short forward branch optimization",
......@@ -428,15 +586,93 @@ pub const all_features = blk: {
428586 .description = "Has reasonably performant unaligned scalar loads and stores",
429587 .dependencies = featureSet(&[_]Feature{}),
430588 };
589 result[@intFromEnum(Feature.unaligned_vector_mem)] = .{
590 .llvm_name = "unaligned-vector-mem",
591 .description = "Has reasonably performant unaligned vector loads and stores",
592 .dependencies = featureSet(&[_]Feature{}),
593 };
431594 result[@intFromEnum(Feature.v)] = .{
432595 .llvm_name = "v",
433596 .description = "'V' (Vector Extension for Application Processors)",
434597 .dependencies = featureSet(&[_]Feature{
435 .d,
436598 .zve64d,
437599 .zvl128b,
438600 }),
439601 };
602 result[@intFromEnum(Feature.xcvbitmanip)] = .{
603 .llvm_name = "xcvbitmanip",
604 .description = "'XCVbitmanip' (CORE-V Bit Manipulation)",
605 .dependencies = featureSet(&[_]Feature{}),
606 };
607 result[@intFromEnum(Feature.xcvmac)] = .{
608 .llvm_name = "xcvmac",
609 .description = "'XCVmac' (CORE-V Multiply-Accumulate)",
610 .dependencies = featureSet(&[_]Feature{}),
611 };
612 result[@intFromEnum(Feature.xsfcie)] = .{
613 .llvm_name = "xsfcie",
614 .description = "'XSfcie' (SiFive Custom Instruction Extension SCIE.)",
615 .dependencies = featureSet(&[_]Feature{}),
616 };
617 result[@intFromEnum(Feature.xsfvcp)] = .{
618 .llvm_name = "xsfvcp",
619 .description = "'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions)",
620 .dependencies = featureSet(&[_]Feature{
621 .zve32x,
622 }),
623 };
624 result[@intFromEnum(Feature.xtheadba)] = .{
625 .llvm_name = "xtheadba",
626 .description = "'xtheadba' (T-Head address calculation instructions)",
627 .dependencies = featureSet(&[_]Feature{}),
628 };
629 result[@intFromEnum(Feature.xtheadbb)] = .{
630 .llvm_name = "xtheadbb",
631 .description = "'xtheadbb' (T-Head basic bit-manipulation instructions)",
632 .dependencies = featureSet(&[_]Feature{}),
633 };
634 result[@intFromEnum(Feature.xtheadbs)] = .{
635 .llvm_name = "xtheadbs",
636 .description = "'xtheadbs' (T-Head single-bit instructions)",
637 .dependencies = featureSet(&[_]Feature{}),
638 };
639 result[@intFromEnum(Feature.xtheadcmo)] = .{
640 .llvm_name = "xtheadcmo",
641 .description = "'xtheadcmo' (T-Head cache management instructions)",
642 .dependencies = featureSet(&[_]Feature{}),
643 };
644 result[@intFromEnum(Feature.xtheadcondmov)] = .{
645 .llvm_name = "xtheadcondmov",
646 .description = "'xtheadcondmov' (T-Head conditional move instructions)",
647 .dependencies = featureSet(&[_]Feature{}),
648 };
649 result[@intFromEnum(Feature.xtheadfmemidx)] = .{
650 .llvm_name = "xtheadfmemidx",
651 .description = "'xtheadfmemidx' (T-Head FP Indexed Memory Operations)",
652 .dependencies = featureSet(&[_]Feature{
653 .f,
654 }),
655 };
656 result[@intFromEnum(Feature.xtheadmac)] = .{
657 .llvm_name = "xtheadmac",
658 .description = "'xtheadmac' (T-Head Multiply-Accumulate Instructions)",
659 .dependencies = featureSet(&[_]Feature{}),
660 };
661 result[@intFromEnum(Feature.xtheadmemidx)] = .{
662 .llvm_name = "xtheadmemidx",
663 .description = "'xtheadmemidx' (T-Head Indexed Memory Operations)",
664 .dependencies = featureSet(&[_]Feature{}),
665 };
666 result[@intFromEnum(Feature.xtheadmempair)] = .{
667 .llvm_name = "xtheadmempair",
668 .description = "'xtheadmempair' (T-Head two-GPR Memory Operations)",
669 .dependencies = featureSet(&[_]Feature{}),
670 };
671 result[@intFromEnum(Feature.xtheadsync)] = .{
672 .llvm_name = "xtheadsync",
673 .description = "'xtheadsync' (T-Head multicore synchronization instructions)",
674 .dependencies = featureSet(&[_]Feature{}),
675 };
440676 result[@intFromEnum(Feature.xtheadvdot)] = .{
441677 .llvm_name = "xtheadvdot",
442678 .description = "'xtheadvdot' (T-Head Vector Extensions for Dot)",
......@@ -449,6 +685,11 @@ pub const all_features = blk: {
449685 .description = "'XVentanaCondOps' (Ventana Conditional Ops)",
450686 .dependencies = featureSet(&[_]Feature{}),
451687 };
688 result[@intFromEnum(Feature.zawrs)] = .{
689 .llvm_name = "zawrs",
690 .description = "'Zawrs' (Wait on Reservation Set)",
691 .dependencies = featureSet(&[_]Feature{}),
692 };
452693 result[@intFromEnum(Feature.zba)] = .{
453694 .llvm_name = "zba",
454695 .description = "'Zba' (Address Generation Instructions)",
......@@ -484,6 +725,56 @@ pub const all_features = blk: {
484725 .description = "'Zbs' (Single-Bit Instructions)",
485726 .dependencies = featureSet(&[_]Feature{}),
486727 };
728 result[@intFromEnum(Feature.zca)] = .{
729 .llvm_name = "zca",
730 .description = "'Zca' (part of the C extension, excluding compressed floating point loads/stores)",
731 .dependencies = featureSet(&[_]Feature{}),
732 };
733 result[@intFromEnum(Feature.zcb)] = .{
734 .llvm_name = "zcb",
735 .description = "'Zcb' (Compressed basic bit manipulation instructions)",
736 .dependencies = featureSet(&[_]Feature{
737 .zca,
738 }),
739 };
740 result[@intFromEnum(Feature.zcd)] = .{
741 .llvm_name = "zcd",
742 .description = "'Zcd' (Compressed Double-Precision Floating-Point Instructions)",
743 .dependencies = featureSet(&[_]Feature{
744 .zca,
745 }),
746 };
747 result[@intFromEnum(Feature.zce)] = .{
748 .llvm_name = "zce",
749 .description = "'Zce' (Compressed extensions for microcontrollers)",
750 .dependencies = featureSet(&[_]Feature{
751 .zcb,
752 .zcmp,
753 .zcmt,
754 }),
755 };
756 result[@intFromEnum(Feature.zcf)] = .{
757 .llvm_name = "zcf",
758 .description = "'Zcf' (Compressed Single-Precision Floating-Point Instructions)",
759 .dependencies = featureSet(&[_]Feature{
760 .zca,
761 }),
762 };
763 result[@intFromEnum(Feature.zcmp)] = .{
764 .llvm_name = "zcmp",
765 .description = "'Zcmp' (sequenced instuctions for code-size reduction)",
766 .dependencies = featureSet(&[_]Feature{
767 .zca,
768 }),
769 };
770 result[@intFromEnum(Feature.zcmt)] = .{
771 .llvm_name = "zcmt",
772 .description = "'Zcmt' (table jump instuctions for code-size reduction)",
773 .dependencies = featureSet(&[_]Feature{
774 .zca,
775 .zicsr,
776 }),
777 };
487778 result[@intFromEnum(Feature.zdinx)] = .{
488779 .llvm_name = "zdinx",
489780 .description = "'Zdinx' (Double in Integer)",
......@@ -508,7 +799,9 @@ pub const all_features = blk: {
508799 result[@intFromEnum(Feature.zfinx)] = .{
509800 .llvm_name = "zfinx",
510801 .description = "'Zfinx' (Float in Integer)",
511 .dependencies = featureSet(&[_]Feature{}),
802 .dependencies = featureSet(&[_]Feature{
803 .zicsr,
804 }),
512805 };
513806 result[@intFromEnum(Feature.zhinx)] = .{
514807 .llvm_name = "zhinx",
......@@ -539,11 +832,35 @@ pub const all_features = blk: {
539832 .description = "'Zicboz' (Cache-Block Zero Instructions)",
540833 .dependencies = featureSet(&[_]Feature{}),
541834 };
835 result[@intFromEnum(Feature.zicntr)] = .{
836 .llvm_name = "zicntr",
837 .description = "'Zicntr' (Base Counters and Timers)",
838 .dependencies = featureSet(&[_]Feature{
839 .zicsr,
840 }),
841 };
842 result[@intFromEnum(Feature.zicsr)] = .{
843 .llvm_name = "zicsr",
844 .description = "'zicsr' (CSRs)",
845 .dependencies = featureSet(&[_]Feature{}),
846 };
847 result[@intFromEnum(Feature.zifencei)] = .{
848 .llvm_name = "zifencei",
849 .description = "'Zifencei' (fence.i)",
850 .dependencies = featureSet(&[_]Feature{}),
851 };
542852 result[@intFromEnum(Feature.zihintpause)] = .{
543853 .llvm_name = "zihintpause",
544 .description = "'zihintpause' (Pause Hint)",
854 .description = "'Zihintpause' (Pause Hint)",
545855 .dependencies = featureSet(&[_]Feature{}),
546856 };
857 result[@intFromEnum(Feature.zihpm)] = .{
858 .llvm_name = "zihpm",
859 .description = "'Zihpm' (Hardware Performance Counters)",
860 .dependencies = featureSet(&[_]Feature{
861 .zicsr,
862 }),
863 };
547864 result[@intFromEnum(Feature.zk)] = .{
548865 .llvm_name = "zk",
549866 .description = "'Zk' (Standard scalar cryptography extension)",
......@@ -620,6 +937,7 @@ pub const all_features = blk: {
620937 .llvm_name = "zve32f",
621938 .description = "'Zve32f' (Vector Extensions for Embedded Processors with maximal 32 EEW and F extension)",
622939 .dependencies = featureSet(&[_]Feature{
940 .f,
623941 .zve32x,
624942 }),
625943 };
......@@ -627,6 +945,7 @@ pub const all_features = blk: {
627945 .llvm_name = "zve32x",
628946 .description = "'Zve32x' (Vector Extensions for Embedded Processors with maximal 32 EEW)",
629947 .dependencies = featureSet(&[_]Feature{
948 .zicsr,
630949 .zvl32b,
631950 }),
632951 };
......@@ -634,6 +953,7 @@ pub const all_features = blk: {
634953 .llvm_name = "zve64d",
635954 .description = "'Zve64d' (Vector Extensions for Embedded Processors with maximal 64 EEW, F and D extension)",
636955 .dependencies = featureSet(&[_]Feature{
956 .d,
637957 .zve64f,
638958 }),
639959 };
......@@ -653,6 +973,14 @@ pub const all_features = blk: {
653973 .zvl64b,
654974 }),
655975 };
976 result[@intFromEnum(Feature.zvfh)] = .{
977 .llvm_name = "zvfh",
978 .description = "'Zvfh' (Vector Half-Precision Floating-Point)",
979 .dependencies = featureSet(&[_]Feature{
980 .zfhmin,
981 .zve32f,
982 }),
983 };
656984 result[@intFromEnum(Feature.zvl1024b)] = .{
657985 .llvm_name = "zvl1024b",
658986 .description = "'Zvl' (Minimum Vector Length) 1024",
......@@ -795,6 +1123,8 @@ pub const cpu = struct {
7951123 .llvm_name = "rocket-rv32",
7961124 .features = featureSet(&[_]Feature{
7971125 .@"32bit",
1126 .zicsr,
1127 .zifencei,
7981128 }),
7991129 };
8001130 pub const rocket_rv64 = CpuModel{
......@@ -802,6 +1132,8 @@ pub const cpu = struct {
8021132 .llvm_name = "rocket-rv64",
8031133 .features = featureSet(&[_]Feature{
8041134 .@"64bit",
1135 .zicsr,
1136 .zifencei,
8051137 }),
8061138 };
8071139 pub const sifive_7_series = CpuModel{
......@@ -819,6 +1151,8 @@ pub const cpu = struct {
8191151 .@"32bit",
8201152 .c,
8211153 .m,
1154 .zicsr,
1155 .zifencei,
8221156 }),
8231157 };
8241158 pub const sifive_e21 = CpuModel{
......@@ -829,6 +1163,8 @@ pub const cpu = struct {
8291163 .a,
8301164 .c,
8311165 .m,
1166 .zicsr,
1167 .zifencei,
8321168 }),
8331169 };
8341170 pub const sifive_e24 = CpuModel{
......@@ -840,6 +1176,7 @@ pub const cpu = struct {
8401176 .c,
8411177 .f,
8421178 .m,
1179 .zifencei,
8431180 }),
8441181 };
8451182 pub const sifive_e31 = CpuModel{
......@@ -850,6 +1187,8 @@ pub const cpu = struct {
8501187 .a,
8511188 .c,
8521189 .m,
1190 .zicsr,
1191 .zifencei,
8531192 }),
8541193 };
8551194 pub const sifive_e34 = CpuModel{
......@@ -861,6 +1200,7 @@ pub const cpu = struct {
8611200 .c,
8621201 .f,
8631202 .m,
1203 .zifencei,
8641204 }),
8651205 };
8661206 pub const sifive_e76 = CpuModel{
......@@ -874,6 +1214,7 @@ pub const cpu = struct {
8741214 .m,
8751215 .no_default_unroll,
8761216 .short_forward_branch_opt,
1217 .zifencei,
8771218 }),
8781219 };
8791220 pub const sifive_s21 = CpuModel{
......@@ -884,6 +1225,8 @@ pub const cpu = struct {
8841225 .a,
8851226 .c,
8861227 .m,
1228 .zicsr,
1229 .zifencei,
8871230 }),
8881231 };
8891232 pub const sifive_s51 = CpuModel{
......@@ -894,6 +1237,8 @@ pub const cpu = struct {
8941237 .a,
8951238 .c,
8961239 .m,
1240 .zicsr,
1241 .zifencei,
8971242 }),
8981243 };
8991244 pub const sifive_s54 = CpuModel{
......@@ -905,6 +1250,7 @@ pub const cpu = struct {
9051250 .c,
9061251 .d,
9071252 .m,
1253 .zifencei,
9081254 }),
9091255 };
9101256 pub const sifive_s76 = CpuModel{
......@@ -918,6 +1264,9 @@ pub const cpu = struct {
9181264 .m,
9191265 .no_default_unroll,
9201266 .short_forward_branch_opt,
1267 .xsfcie,
1268 .zifencei,
1269 .zihintpause,
9211270 }),
9221271 };
9231272 pub const sifive_u54 = CpuModel{
......@@ -929,6 +1278,7 @@ pub const cpu = struct {
9291278 .c,
9301279 .d,
9311280 .m,
1281 .zifencei,
9321282 }),
9331283 };
9341284 pub const sifive_u74 = CpuModel{
......@@ -942,6 +1292,27 @@ pub const cpu = struct {
9421292 .m,
9431293 .no_default_unroll,
9441294 .short_forward_branch_opt,
1295 .zifencei,
1296 }),
1297 };
1298 pub const sifive_x280 = CpuModel{
1299 .name = "sifive_x280",
1300 .llvm_name = "sifive-x280",
1301 .features = featureSet(&[_]Feature{
1302 .@"64bit",
1303 .a,
1304 .c,
1305 .dlen_factor_2,
1306 .m,
1307 .no_default_unroll,
1308 .short_forward_branch_opt,
1309 .v,
1310 .zba,
1311 .zbb,
1312 .zfh,
1313 .zifencei,
1314 .zvfh,
1315 .zvl512b,
9451316 }),
9461317 };
9471318 pub const syntacore_scr1_base = CpuModel{
......@@ -951,6 +1322,8 @@ pub const cpu = struct {
9511322 .@"32bit",
9521323 .c,
9531324 .no_default_unroll,
1325 .zicsr,
1326 .zifencei,
9541327 }),
9551328 };
9561329 pub const syntacore_scr1_max = CpuModel{
......@@ -961,6 +1334,8 @@ pub const cpu = struct {
9611334 .c,
9621335 .m,
9631336 .no_default_unroll,
1337 .zicsr,
1338 .zifencei,
9641339 }),
9651340 };
9661341};
lib/std/target/x86.zig+304-117
......@@ -14,6 +14,7 @@ pub const Feature = enum {
1414 aes,
1515 allow_light_256_bit,
1616 amx_bf16,
17 amx_complex,
1718 amx_fp16,
1819 amx_int8,
1920 amx_tile,
......@@ -38,6 +39,7 @@ pub const Feature = enum {
3839 avxifma,
3940 avxneconvert,
4041 avxvnni,
42 avxvnniint16,
4143 avxvnniint8,
4244 bmi,
4345 bmi2,
......@@ -76,6 +78,7 @@ pub const Feature = enum {
7678 fast_variable_perlane_shuffle,
7779 fast_vector_fsqrt,
7880 fast_vector_shift_masks,
81 faster_shift_than_shuffle,
7982 fma,
8083 fma4,
8184 fsgsbase,
......@@ -101,6 +104,10 @@ pub const Feature = enum {
101104 movdir64b,
102105 movdiri,
103106 mwaitx,
107 no_bypass_delay,
108 no_bypass_delay_blend,
109 no_bypass_delay_mov,
110 no_bypass_delay_shuffle,
104111 nopl,
105112 pad_short_functions,
106113 pclmul,
......@@ -110,6 +117,7 @@ pub const Feature = enum {
110117 prefer_128_bit,
111118 prefer_256_bit,
112119 prefer_mask_registers,
120 prefer_movmsk_over_vtest,
113121 prefetchi,
114122 prefetchwt1,
115123 prfchw,
......@@ -130,6 +138,7 @@ pub const Feature = enum {
130138 seses,
131139 sgx,
132140 sha,
141 sha512,
133142 shstk,
134143 slow_3ops_lea,
135144 slow_incdec,
......@@ -140,6 +149,8 @@ pub const Feature = enum {
140149 slow_two_mem_ops,
141150 slow_unaligned_mem_16,
142151 slow_unaligned_mem_32,
152 sm3,
153 sm4,
143154 soft_float,
144155 sse,
145156 sse2,
......@@ -152,6 +163,7 @@ pub const Feature = enum {
152163 tagged_globals,
153164 tbm,
154165 tsxldtrk,
166 tuning_fast_imm_vector_shift,
155167 uintr,
156168 use_glm_div_sqrt_costs,
157169 use_slm_arith_costs,
......@@ -231,6 +243,13 @@ pub const all_features = blk: {
231243 .amx_tile,
232244 }),
233245 };
246 result[@intFromEnum(Feature.amx_complex)] = .{
247 .llvm_name = "amx-complex",
248 .description = "Support AMX-COMPLEX instructions",
249 .dependencies = featureSet(&[_]Feature{
250 .amx_tile,
251 }),
252 };
234253 result[@intFromEnum(Feature.amx_fp16)] = .{
235254 .llvm_name = "amx-fp16",
236255 .description = "Support AMX amx-fp16 instructions",
......@@ -326,7 +345,7 @@ pub const all_features = blk: {
326345 };
327346 result[@intFromEnum(Feature.avx512ifma)] = .{
328347 .llvm_name = "avx512ifma",
329 .description = "Enable AVX-512 Integer Fused Multiply-Add",
348 .description = "Enable AVX-512 Integer Fused Multiple-Add",
330349 .dependencies = featureSet(&[_]Feature{
331350 .avx512f,
332351 }),
......@@ -401,6 +420,13 @@ pub const all_features = blk: {
401420 .avx2,
402421 }),
403422 };
423 result[@intFromEnum(Feature.avxvnniint16)] = .{
424 .llvm_name = "avxvnniint16",
425 .description = "Enable AVX-VNNI-INT16",
426 .dependencies = featureSet(&[_]Feature{
427 .avx2,
428 }),
429 };
404430 result[@intFromEnum(Feature.avxvnniint8)] = .{
405431 .llvm_name = "avxvnniint8",
406432 .description = "Enable AVX-VNNI-INT8",
......@@ -597,16 +623,21 @@ pub const all_features = blk: {
597623 .description = "Prefer a left/right vector logical shift pair over a shift+and pair",
598624 .dependencies = featureSet(&[_]Feature{}),
599625 };
626 result[@intFromEnum(Feature.faster_shift_than_shuffle)] = .{
627 .llvm_name = "faster-shift-than-shuffle",
628 .description = "Shifts are faster (or as fast) as shuffle",
629 .dependencies = featureSet(&[_]Feature{}),
630 };
600631 result[@intFromEnum(Feature.fma)] = .{
601632 .llvm_name = "fma",
602 .description = "Enable three-operand fused multiply-add",
633 .description = "Enable three-operand fused multiple-add",
603634 .dependencies = featureSet(&[_]Feature{
604635 .avx,
605636 }),
606637 };
607638 result[@intFromEnum(Feature.fma4)] = .{
608639 .llvm_name = "fma4",
609 .description = "Enable four-operand fused multiply-add",
640 .description = "Enable four-operand fused multiple-add",
610641 .dependencies = featureSet(&[_]Feature{
611642 .avx,
612643 .sse4a,
......@@ -731,6 +762,26 @@ pub const all_features = blk: {
731762 .description = "Enable MONITORX/MWAITX timer functionality",
732763 .dependencies = featureSet(&[_]Feature{}),
733764 };
765 result[@intFromEnum(Feature.no_bypass_delay)] = .{
766 .llvm_name = "no-bypass-delay",
767 .description = "Has no bypass delay when using the 'wrong' domain",
768 .dependencies = featureSet(&[_]Feature{}),
769 };
770 result[@intFromEnum(Feature.no_bypass_delay_blend)] = .{
771 .llvm_name = "no-bypass-delay-blend",
772 .description = "Has no bypass delay when using the 'wrong' blend type",
773 .dependencies = featureSet(&[_]Feature{}),
774 };
775 result[@intFromEnum(Feature.no_bypass_delay_mov)] = .{
776 .llvm_name = "no-bypass-delay-mov",
777 .description = "Has no bypass delay when using the 'wrong' mov type",
778 .dependencies = featureSet(&[_]Feature{}),
779 };
780 result[@intFromEnum(Feature.no_bypass_delay_shuffle)] = .{
781 .llvm_name = "no-bypass-delay-shuffle",
782 .description = "Has no bypass delay when using the 'wrong' shuffle type",
783 .dependencies = featureSet(&[_]Feature{}),
784 };
734785 result[@intFromEnum(Feature.nopl)] = .{
735786 .llvm_name = "nopl",
736787 .description = "Enable NOPL instruction (generally pentium pro+)",
......@@ -778,6 +829,11 @@ pub const all_features = blk: {
778829 .description = "Prefer AVX512 mask registers over PTEST/MOVMSK",
779830 .dependencies = featureSet(&[_]Feature{}),
780831 };
832 result[@intFromEnum(Feature.prefer_movmsk_over_vtest)] = .{
833 .llvm_name = "prefer-movmsk-over-vtest",
834 .description = "Prefer movmsk over vtest instruction",
835 .dependencies = featureSet(&[_]Feature{}),
836 };
781837 result[@intFromEnum(Feature.prefetchi)] = .{
782838 .llvm_name = "prefetchi",
783839 .description = "Prefetch instruction with T0 or T1 Hint",
......@@ -887,6 +943,13 @@ pub const all_features = blk: {
887943 .sse2,
888944 }),
889945 };
946 result[@intFromEnum(Feature.sha512)] = .{
947 .llvm_name = "sha512",
948 .description = "Support SHA512 instructions",
949 .dependencies = featureSet(&[_]Feature{
950 .avx,
951 }),
952 };
890953 result[@intFromEnum(Feature.shstk)] = .{
891954 .llvm_name = "shstk",
892955 .description = "Support CET Shadow-Stack instructions",
......@@ -937,6 +1000,20 @@ pub const all_features = blk: {
9371000 .description = "Slow unaligned 32-byte memory access",
9381001 .dependencies = featureSet(&[_]Feature{}),
9391002 };
1003 result[@intFromEnum(Feature.sm3)] = .{
1004 .llvm_name = "sm3",
1005 .description = "Support SM3 instructions",
1006 .dependencies = featureSet(&[_]Feature{
1007 .avx,
1008 }),
1009 };
1010 result[@intFromEnum(Feature.sm4)] = .{
1011 .llvm_name = "sm4",
1012 .description = "Support SM4 instructions",
1013 .dependencies = featureSet(&[_]Feature{
1014 .avx,
1015 }),
1016 };
9401017 result[@intFromEnum(Feature.soft_float)] = .{
9411018 .llvm_name = "soft-float",
9421019 .description = "Use software floating point features",
......@@ -1009,6 +1086,11 @@ pub const all_features = blk: {
10091086 .description = "Support TSXLDTRK instructions",
10101087 .dependencies = featureSet(&[_]Feature{}),
10111088 };
1089 result[@intFromEnum(Feature.tuning_fast_imm_vector_shift)] = .{
1090 .llvm_name = "tuning-fast-imm-vector-shift",
1091 .description = "Vector shifts are fast (2/cycle) as opposed to slow (1/cycle)",
1092 .dependencies = featureSet(&[_]Feature{}),
1093 };
10121094 result[@intFromEnum(Feature.uintr)] = .{
10131095 .llvm_name = "uintr",
10141096 .description = "Has UINTR Instructions",
......@@ -1148,10 +1230,14 @@ pub const cpu = struct {
11481230 .movbe,
11491231 .movdir64b,
11501232 .movdiri,
1233 .no_bypass_delay_blend,
1234 .no_bypass_delay_mov,
1235 .no_bypass_delay_shuffle,
11511236 .nopl,
11521237 .pconfig,
11531238 .pku,
11541239 .popcnt,
1240 .prefer_movmsk_over_vtest,
11551241 .prfchw,
11561242 .ptwrite,
11571243 .rdpid,
......@@ -1162,6 +1248,7 @@ pub const cpu = struct {
11621248 .sha,
11631249 .shstk,
11641250 .slow_3ops_lea,
1251 .tuning_fast_imm_vector_shift,
11651252 .vaes,
11661253 .vpclmulqdq,
11671254 .vzeroupper,
......@@ -1342,6 +1429,7 @@ pub const cpu = struct {
13421429 .lea_uses_ag,
13431430 .mmx,
13441431 .movbe,
1432 .no_bypass_delay,
13451433 .nopl,
13461434 .pad_short_functions,
13471435 .sahf,
......@@ -1352,6 +1440,46 @@ pub const cpu = struct {
13521440 .x87,
13531441 }),
13541442 };
1443 pub const atom_sse4_2_movbe = CpuModel{
1444 .name = "atom_sse4_2_movbe",
1445 .llvm_name = "atom_sse4_2_movbe",
1446 .features = featureSet(&[_]Feature{
1447 .@"64bit",
1448 .aes,
1449 .clflushopt,
1450 .cmov,
1451 .crc32,
1452 .cx16,
1453 .false_deps_popcnt,
1454 .fast_7bytenop,
1455 .fast_movbe,
1456 .fsgsbase,
1457 .fxsr,
1458 .idivq_to_divl,
1459 .mmx,
1460 .movbe,
1461 .no_bypass_delay,
1462 .nopl,
1463 .pclmul,
1464 .popcnt,
1465 .prfchw,
1466 .rdrnd,
1467 .rdseed,
1468 .sahf,
1469 .sha,
1470 .slow_incdec,
1471 .slow_lea,
1472 .slow_pmulld,
1473 .slow_two_mem_ops,
1474 .sse4_2,
1475 .use_slm_arith_costs,
1476 .vzeroupper,
1477 .x87,
1478 .xsavec,
1479 .xsaveopt,
1480 .xsaves,
1481 }),
1482 };
13551483 pub const barcelona = CpuModel{
13561484 .name = "barcelona",
13571485 .llvm_name = "barcelona",
......@@ -1529,6 +1657,7 @@ pub const cpu = struct {
15291657 .lea_uses_ag,
15301658 .mmx,
15311659 .movbe,
1660 .no_bypass_delay,
15321661 .nopl,
15331662 .pad_short_functions,
15341663 .sahf,
......@@ -1570,6 +1699,8 @@ pub const cpu = struct {
15701699 .macrofusion,
15711700 .mmx,
15721701 .movbe,
1702 .no_bypass_delay_mov,
1703 .no_bypass_delay_shuffle,
15731704 .nopl,
15741705 .pclmul,
15751706 .popcnt,
......@@ -1701,6 +1832,9 @@ pub const cpu = struct {
17011832 .macrofusion,
17021833 .mmx,
17031834 .movbe,
1835 .no_bypass_delay_blend,
1836 .no_bypass_delay_mov,
1837 .no_bypass_delay_shuffle,
17041838 .nopl,
17051839 .pclmul,
17061840 .pku,
......@@ -1712,6 +1846,7 @@ pub const cpu = struct {
17121846 .sahf,
17131847 .sha,
17141848 .slow_3ops_lea,
1849 .tuning_fast_imm_vector_shift,
17151850 .vzeroupper,
17161851 .x87,
17171852 .xsavec,
......@@ -1748,6 +1883,7 @@ pub const cpu = struct {
17481883 .fast_variable_crosslane_shuffle,
17491884 .fast_variable_perlane_shuffle,
17501885 .fast_vector_fsqrt,
1886 .faster_shift_than_shuffle,
17511887 .fsgsbase,
17521888 .fxsr,
17531889 .idivq_to_divl,
......@@ -1756,6 +1892,9 @@ pub const cpu = struct {
17561892 .macrofusion,
17571893 .mmx,
17581894 .movbe,
1895 .no_bypass_delay_blend,
1896 .no_bypass_delay_mov,
1897 .no_bypass_delay_shuffle,
17591898 .nopl,
17601899 .pclmul,
17611900 .pku,
......@@ -1766,6 +1905,7 @@ pub const cpu = struct {
17661905 .rdseed,
17671906 .sahf,
17681907 .slow_3ops_lea,
1908 .tuning_fast_imm_vector_shift,
17691909 .vzeroupper,
17701910 .x87,
17711911 .xsavec,
......@@ -1802,6 +1942,7 @@ pub const cpu = struct {
18021942 .fast_variable_crosslane_shuffle,
18031943 .fast_variable_perlane_shuffle,
18041944 .fast_vector_fsqrt,
1945 .faster_shift_than_shuffle,
18051946 .fsgsbase,
18061947 .fxsr,
18071948 .idivq_to_divl,
......@@ -1810,6 +1951,9 @@ pub const cpu = struct {
18101951 .macrofusion,
18111952 .mmx,
18121953 .movbe,
1954 .no_bypass_delay_blend,
1955 .no_bypass_delay_mov,
1956 .no_bypass_delay_shuffle,
18131957 .nopl,
18141958 .pclmul,
18151959 .pku,
......@@ -1820,6 +1964,7 @@ pub const cpu = struct {
18201964 .rdseed,
18211965 .sahf,
18221966 .slow_3ops_lea,
1967 .tuning_fast_imm_vector_shift,
18231968 .vzeroupper,
18241969 .x87,
18251970 .xsavec,
......@@ -1845,77 +1990,6 @@ pub const cpu = struct {
18451990 .x87,
18461991 }),
18471992 };
1848 pub const core_avx2 = CpuModel{
1849 .name = "core_avx2",
1850 .llvm_name = "core-avx2",
1851 .features = featureSet(&[_]Feature{
1852 .@"64bit",
1853 .allow_light_256_bit,
1854 .avx2,
1855 .bmi,
1856 .bmi2,
1857 .cmov,
1858 .crc32,
1859 .cx16,
1860 .ermsb,
1861 .f16c,
1862 .false_deps_lzcnt_tzcnt,
1863 .false_deps_popcnt,
1864 .fast_15bytenop,
1865 .fast_scalar_fsqrt,
1866 .fast_shld_rotate,
1867 .fast_variable_crosslane_shuffle,
1868 .fast_variable_perlane_shuffle,
1869 .fma,
1870 .fsgsbase,
1871 .fxsr,
1872 .idivq_to_divl,
1873 .invpcid,
1874 .lzcnt,
1875 .macrofusion,
1876 .mmx,
1877 .movbe,
1878 .nopl,
1879 .pclmul,
1880 .popcnt,
1881 .rdrnd,
1882 .sahf,
1883 .slow_3ops_lea,
1884 .vzeroupper,
1885 .x87,
1886 .xsaveopt,
1887 }),
1888 };
1889 pub const core_avx_i = CpuModel{
1890 .name = "core_avx_i",
1891 .llvm_name = "core-avx-i",
1892 .features = featureSet(&[_]Feature{
1893 .@"64bit",
1894 .cmov,
1895 .crc32,
1896 .cx16,
1897 .f16c,
1898 .false_deps_popcnt,
1899 .fast_15bytenop,
1900 .fast_scalar_fsqrt,
1901 .fast_shld_rotate,
1902 .fsgsbase,
1903 .fxsr,
1904 .idivq_to_divl,
1905 .macrofusion,
1906 .mmx,
1907 .nopl,
1908 .pclmul,
1909 .popcnt,
1910 .rdrnd,
1911 .sahf,
1912 .slow_3ops_lea,
1913 .slow_unaligned_mem_32,
1914 .vzeroupper,
1915 .x87,
1916 .xsaveopt,
1917 }),
1918 };
19191993 pub const corei7 = CpuModel{
19201994 .name = "corei7",
19211995 .llvm_name = "corei7",
......@@ -1927,6 +2001,7 @@ pub const cpu = struct {
19272001 .fxsr,
19282002 .macrofusion,
19292003 .mmx,
2004 .no_bypass_delay_mov,
19302005 .nopl,
19312006 .popcnt,
19322007 .sahf,
......@@ -1935,34 +2010,6 @@ pub const cpu = struct {
19352010 .x87,
19362011 }),
19372012 };
1938 pub const corei7_avx = CpuModel{
1939 .name = "corei7_avx",
1940 .llvm_name = "corei7-avx",
1941 .features = featureSet(&[_]Feature{
1942 .@"64bit",
1943 .avx,
1944 .cmov,
1945 .crc32,
1946 .cx16,
1947 .false_deps_popcnt,
1948 .fast_15bytenop,
1949 .fast_scalar_fsqrt,
1950 .fast_shld_rotate,
1951 .fxsr,
1952 .idivq_to_divl,
1953 .macrofusion,
1954 .mmx,
1955 .nopl,
1956 .pclmul,
1957 .popcnt,
1958 .sahf,
1959 .slow_3ops_lea,
1960 .slow_unaligned_mem_32,
1961 .vzeroupper,
1962 .x87,
1963 .xsaveopt,
1964 }),
1965 };
19662013 pub const emeraldrapids = CpuModel{
19672014 .name = "emeraldrapids",
19682015 .llvm_name = "emeraldrapids",
......@@ -2016,6 +2063,9 @@ pub const cpu = struct {
20162063 .movbe,
20172064 .movdir64b,
20182065 .movdiri,
2066 .no_bypass_delay_blend,
2067 .no_bypass_delay_mov,
2068 .no_bypass_delay_shuffle,
20192069 .nopl,
20202070 .pconfig,
20212071 .pku,
......@@ -2031,6 +2081,7 @@ pub const cpu = struct {
20312081 .sha,
20322082 .shstk,
20332083 .tsxldtrk,
2084 .tuning_fast_imm_vector_shift,
20342085 .uintr,
20352086 .vaes,
20362087 .vpclmulqdq,
......@@ -2085,6 +2136,7 @@ pub const cpu = struct {
20852136 .fxsr,
20862137 .mmx,
20872138 .movbe,
2139 .no_bypass_delay,
20882140 .nopl,
20892141 .pclmul,
20902142 .popcnt,
......@@ -2120,6 +2172,7 @@ pub const cpu = struct {
21202172 .fxsr,
21212173 .mmx,
21222174 .movbe,
2175 .no_bypass_delay,
21232176 .nopl,
21242177 .pclmul,
21252178 .popcnt,
......@@ -2161,6 +2214,7 @@ pub const cpu = struct {
21612214 .cmpccxadd,
21622215 .crc32,
21632216 .cx16,
2217 .enqcmd,
21642218 .f16c,
21652219 .fast_movbe,
21662220 .fma,
......@@ -2174,6 +2228,7 @@ pub const cpu = struct {
21742228 .movbe,
21752229 .movdir64b,
21762230 .movdiri,
2231 .no_bypass_delay,
21772232 .nopl,
21782233 .pconfig,
21792234 .pku,
......@@ -2191,6 +2246,7 @@ pub const cpu = struct {
21912246 .slow_incdec,
21922247 .slow_lea,
21932248 .slow_two_mem_ops,
2249 .uintr,
21942250 .use_glm_div_sqrt_costs,
21952251 .vaes,
21962252 .vpclmulqdq,
......@@ -2257,6 +2313,9 @@ pub const cpu = struct {
22572313 .movbe,
22582314 .movdir64b,
22592315 .movdiri,
2316 .no_bypass_delay_blend,
2317 .no_bypass_delay_mov,
2318 .no_bypass_delay_shuffle,
22602319 .nopl,
22612320 .pconfig,
22622321 .pku,
......@@ -2273,6 +2332,94 @@ pub const cpu = struct {
22732332 .sha,
22742333 .shstk,
22752334 .tsxldtrk,
2335 .tuning_fast_imm_vector_shift,
2336 .uintr,
2337 .vaes,
2338 .vpclmulqdq,
2339 .vzeroupper,
2340 .waitpkg,
2341 .wbnoinvd,
2342 .x87,
2343 .xsavec,
2344 .xsaveopt,
2345 .xsaves,
2346 }),
2347 };
2348 pub const graniterapids_d = CpuModel{
2349 .name = "graniterapids_d",
2350 .llvm_name = "graniterapids-d",
2351 .features = featureSet(&[_]Feature{
2352 .@"64bit",
2353 .adx,
2354 .allow_light_256_bit,
2355 .amx_bf16,
2356 .amx_complex,
2357 .amx_fp16,
2358 .amx_int8,
2359 .avx512bf16,
2360 .avx512bitalg,
2361 .avx512cd,
2362 .avx512fp16,
2363 .avx512ifma,
2364 .avx512vbmi,
2365 .avx512vbmi2,
2366 .avx512vnni,
2367 .avx512vpopcntdq,
2368 .avxvnni,
2369 .bmi,
2370 .bmi2,
2371 .cldemote,
2372 .clflushopt,
2373 .clwb,
2374 .cmov,
2375 .crc32,
2376 .cx16,
2377 .enqcmd,
2378 .ermsb,
2379 .false_deps_getmant,
2380 .false_deps_mulc,
2381 .false_deps_mullq,
2382 .false_deps_perm,
2383 .false_deps_range,
2384 .fast_15bytenop,
2385 .fast_gather,
2386 .fast_scalar_fsqrt,
2387 .fast_shld_rotate,
2388 .fast_variable_crosslane_shuffle,
2389 .fast_variable_perlane_shuffle,
2390 .fast_vector_fsqrt,
2391 .fsgsbase,
2392 .fsrm,
2393 .fxsr,
2394 .gfni,
2395 .idivq_to_divl,
2396 .invpcid,
2397 .lzcnt,
2398 .macrofusion,
2399 .mmx,
2400 .movbe,
2401 .movdir64b,
2402 .movdiri,
2403 .no_bypass_delay_blend,
2404 .no_bypass_delay_mov,
2405 .no_bypass_delay_shuffle,
2406 .nopl,
2407 .pconfig,
2408 .pku,
2409 .popcnt,
2410 .prefer_256_bit,
2411 .prefetchi,
2412 .prfchw,
2413 .ptwrite,
2414 .rdpid,
2415 .rdrnd,
2416 .rdseed,
2417 .sahf,
2418 .serialize,
2419 .sha,
2420 .shstk,
2421 .tsxldtrk,
2422 .tuning_fast_imm_vector_shift,
22762423 .uintr,
22772424 .vaes,
22782425 .vpclmulqdq,
......@@ -2315,6 +2462,8 @@ pub const cpu = struct {
23152462 .macrofusion,
23162463 .mmx,
23172464 .movbe,
2465 .no_bypass_delay_mov,
2466 .no_bypass_delay_shuffle,
23182467 .nopl,
23192468 .pclmul,
23202469 .popcnt,
......@@ -2405,6 +2554,9 @@ pub const cpu = struct {
24052554 .macrofusion,
24062555 .mmx,
24072556 .movbe,
2557 .no_bypass_delay_blend,
2558 .no_bypass_delay_mov,
2559 .no_bypass_delay_shuffle,
24082560 .nopl,
24092561 .pku,
24102562 .popcnt,
......@@ -2415,6 +2567,7 @@ pub const cpu = struct {
24152567 .rdseed,
24162568 .sahf,
24172569 .sha,
2570 .tuning_fast_imm_vector_shift,
24182571 .vaes,
24192572 .vpclmulqdq,
24202573 .vzeroupper,
......@@ -2465,6 +2618,9 @@ pub const cpu = struct {
24652618 .macrofusion,
24662619 .mmx,
24672620 .movbe,
2621 .no_bypass_delay_blend,
2622 .no_bypass_delay_mov,
2623 .no_bypass_delay_shuffle,
24682624 .nopl,
24692625 .pconfig,
24702626 .pku,
......@@ -2476,6 +2632,7 @@ pub const cpu = struct {
24762632 .rdseed,
24772633 .sahf,
24782634 .sha,
2635 .tuning_fast_imm_vector_shift,
24792636 .vaes,
24802637 .vpclmulqdq,
24812638 .vzeroupper,
......@@ -2504,6 +2661,7 @@ pub const cpu = struct {
25042661 .idivq_to_divl,
25052662 .macrofusion,
25062663 .mmx,
2664 .no_bypass_delay_mov,
25072665 .nopl,
25082666 .pclmul,
25092667 .popcnt,
......@@ -2717,10 +2875,14 @@ pub const cpu = struct {
27172875 .movbe,
27182876 .movdir64b,
27192877 .movdiri,
2878 .no_bypass_delay_blend,
2879 .no_bypass_delay_mov,
2880 .no_bypass_delay_shuffle,
27202881 .nopl,
27212882 .pconfig,
27222883 .pku,
27232884 .popcnt,
2885 .prefer_movmsk_over_vtest,
27242886 .prfchw,
27252887 .ptwrite,
27262888 .rdpid,
......@@ -2731,6 +2893,7 @@ pub const cpu = struct {
27312893 .sha,
27322894 .shstk,
27332895 .slow_3ops_lea,
2896 .tuning_fast_imm_vector_shift,
27342897 .vaes,
27352898 .vpclmulqdq,
27362899 .vzeroupper,
......@@ -2753,6 +2916,7 @@ pub const cpu = struct {
27532916 .fxsr,
27542917 .macrofusion,
27552918 .mmx,
2919 .no_bypass_delay_mov,
27562920 .nopl,
27572921 .popcnt,
27582922 .sahf,
......@@ -2902,21 +3066,6 @@ pub const cpu = struct {
29023066 .x87,
29033067 }),
29043068 };
2905 pub const pentium4m = CpuModel{
2906 .name = "pentium4m",
2907 .llvm_name = "pentium4m",
2908 .features = featureSet(&[_]Feature{
2909 .cmov,
2910 .cx8,
2911 .fxsr,
2912 .mmx,
2913 .nopl,
2914 .slow_unaligned_mem_16,
2915 .sse2,
2916 .vzeroupper,
2917 .x87,
2918 }),
2919 };
29203069 pub const pentium_m = CpuModel{
29213070 .name = "pentium_m",
29223071 .llvm_name = "pentium-m",
......@@ -3009,10 +3158,14 @@ pub const cpu = struct {
30093158 .movbe,
30103159 .movdir64b,
30113160 .movdiri,
3161 .no_bypass_delay_blend,
3162 .no_bypass_delay_mov,
3163 .no_bypass_delay_shuffle,
30123164 .nopl,
30133165 .pconfig,
30143166 .pku,
30153167 .popcnt,
3168 .prefer_movmsk_over_vtest,
30163169 .prfchw,
30173170 .ptwrite,
30183171 .rdpid,
......@@ -3023,6 +3176,7 @@ pub const cpu = struct {
30233176 .sha,
30243177 .shstk,
30253178 .slow_3ops_lea,
3179 .tuning_fast_imm_vector_shift,
30263180 .vaes,
30273181 .vpclmulqdq,
30283182 .vzeroupper,
......@@ -3074,6 +3228,9 @@ pub const cpu = struct {
30743228 .macrofusion,
30753229 .mmx,
30763230 .movbe,
3231 .no_bypass_delay_blend,
3232 .no_bypass_delay_mov,
3233 .no_bypass_delay_shuffle,
30773234 .nopl,
30783235 .pku,
30793236 .popcnt,
......@@ -3084,6 +3241,7 @@ pub const cpu = struct {
30843241 .rdseed,
30853242 .sahf,
30863243 .sha,
3244 .tuning_fast_imm_vector_shift,
30873245 .vaes,
30883246 .vpclmulqdq,
30893247 .vzeroupper,
......@@ -3110,6 +3268,7 @@ pub const cpu = struct {
31103268 .idivq_to_divl,
31113269 .macrofusion,
31123270 .mmx,
3271 .no_bypass_delay_mov,
31133272 .nopl,
31143273 .pclmul,
31153274 .popcnt,
......@@ -3174,6 +3333,9 @@ pub const cpu = struct {
31743333 .movbe,
31753334 .movdir64b,
31763335 .movdiri,
3336 .no_bypass_delay_blend,
3337 .no_bypass_delay_mov,
3338 .no_bypass_delay_shuffle,
31773339 .nopl,
31783340 .pconfig,
31793341 .pku,
......@@ -3189,6 +3351,7 @@ pub const cpu = struct {
31893351 .sha,
31903352 .shstk,
31913353 .tsxldtrk,
3354 .tuning_fast_imm_vector_shift,
31923355 .uintr,
31933356 .vaes,
31943357 .vpclmulqdq,
......@@ -3220,6 +3383,7 @@ pub const cpu = struct {
32203383 .cmpccxadd,
32213384 .crc32,
32223385 .cx16,
3386 .enqcmd,
32233387 .f16c,
32243388 .fast_movbe,
32253389 .fma,
......@@ -3233,6 +3397,7 @@ pub const cpu = struct {
32333397 .movbe,
32343398 .movdir64b,
32353399 .movdiri,
3400 .no_bypass_delay,
32363401 .nopl,
32373402 .pconfig,
32383403 .pku,
......@@ -3249,6 +3414,7 @@ pub const cpu = struct {
32493414 .slow_incdec,
32503415 .slow_lea,
32513416 .slow_two_mem_ops,
3417 .uintr,
32523418 .use_glm_div_sqrt_costs,
32533419 .vaes,
32543420 .vpclmulqdq,
......@@ -3276,6 +3442,7 @@ pub const cpu = struct {
32763442 .idivq_to_divl,
32773443 .mmx,
32783444 .movbe,
3445 .no_bypass_delay,
32793446 .nopl,
32803447 .pclmul,
32813448 .popcnt,
......@@ -3320,6 +3487,7 @@ pub const cpu = struct {
33203487 .fast_variable_crosslane_shuffle,
33213488 .fast_variable_perlane_shuffle,
33223489 .fast_vector_fsqrt,
3490 .faster_shift_than_shuffle,
33233491 .fsgsbase,
33243492 .fxsr,
33253493 .idivq_to_divl,
......@@ -3328,6 +3496,9 @@ pub const cpu = struct {
33283496 .macrofusion,
33293497 .mmx,
33303498 .movbe,
3499 .no_bypass_delay_blend,
3500 .no_bypass_delay_mov,
3501 .no_bypass_delay_shuffle,
33313502 .nopl,
33323503 .pclmul,
33333504 .pku,
......@@ -3338,6 +3509,7 @@ pub const cpu = struct {
33383509 .rdseed,
33393510 .sahf,
33403511 .slow_3ops_lea,
3512 .tuning_fast_imm_vector_shift,
33413513 .vzeroupper,
33423514 .x87,
33433515 .xsavec,
......@@ -3379,6 +3551,9 @@ pub const cpu = struct {
33793551 .macrofusion,
33803552 .mmx,
33813553 .movbe,
3554 .no_bypass_delay_blend,
3555 .no_bypass_delay_mov,
3556 .no_bypass_delay_shuffle,
33823557 .nopl,
33833558 .pclmul,
33843559 .popcnt,
......@@ -3422,6 +3597,7 @@ pub const cpu = struct {
34223597 .fast_variable_crosslane_shuffle,
34233598 .fast_variable_perlane_shuffle,
34243599 .fast_vector_fsqrt,
3600 .faster_shift_than_shuffle,
34253601 .fsgsbase,
34263602 .fxsr,
34273603 .idivq_to_divl,
......@@ -3430,6 +3606,9 @@ pub const cpu = struct {
34303606 .macrofusion,
34313607 .mmx,
34323608 .movbe,
3609 .no_bypass_delay_blend,
3610 .no_bypass_delay_mov,
3611 .no_bypass_delay_shuffle,
34333612 .nopl,
34343613 .pclmul,
34353614 .pku,
......@@ -3440,6 +3619,7 @@ pub const cpu = struct {
34403619 .rdseed,
34413620 .sahf,
34423621 .slow_3ops_lea,
3622 .tuning_fast_imm_vector_shift,
34433623 .vzeroupper,
34443624 .x87,
34453625 .xsavec,
......@@ -3462,6 +3642,7 @@ pub const cpu = struct {
34623642 .idivq_to_divl,
34633643 .mmx,
34643644 .movbe,
3645 .no_bypass_delay,
34653646 .nopl,
34663647 .pclmul,
34673648 .popcnt,
......@@ -3522,6 +3703,9 @@ pub const cpu = struct {
35223703 .movbe,
35233704 .movdir64b,
35243705 .movdiri,
3706 .no_bypass_delay_blend,
3707 .no_bypass_delay_mov,
3708 .no_bypass_delay_shuffle,
35253709 .nopl,
35263710 .pku,
35273711 .popcnt,
......@@ -3533,6 +3717,7 @@ pub const cpu = struct {
35333717 .sahf,
35343718 .sha,
35353719 .shstk,
3720 .tuning_fast_imm_vector_shift,
35363721 .vaes,
35373722 .vpclmulqdq,
35383723 .vzeroupper,
......@@ -3559,6 +3744,7 @@ pub const cpu = struct {
35593744 .gfni,
35603745 .mmx,
35613746 .movbe,
3747 .no_bypass_delay,
35623748 .nopl,
35633749 .pclmul,
35643750 .popcnt,
......@@ -3592,6 +3778,7 @@ pub const cpu = struct {
35923778 .fxsr,
35933779 .macrofusion,
35943780 .mmx,
3781 .no_bypass_delay_mov,
35953782 .nopl,
35963783 .pclmul,
35973784 .popcnt,
lib/std/zig/CrossTarget.zig+2
......@@ -132,6 +132,7 @@ fn updateOsVersionRange(self: *CrossTarget, os: Target.Os) void {
132132 .emscripten,
133133 .driverkit,
134134 .shadermodel,
135 .liteos,
135136 .uefi,
136137 .opencl,
137138 .glsl450,
......@@ -734,6 +735,7 @@ fn parseOs(result: *CrossTarget, diags: *ParseOptions.Diagnostics, text: []const
734735 .plan9,
735736 .driverkit,
736737 .shadermodel,
738 .liteos,
737739 .other,
738740 => return error.InvalidOperatingSystemVersion,
739741
src/Compilation.zig+12
......@@ -4318,6 +4318,9 @@ pub fn addCCArgs(
43184318 try argv.append("-D_LIBCPP_HAS_NO_THREADS");
43194319 }
43204320
4321 // See the comment in libcxx.zig for more details about this.
4322 try argv.append("-D_LIBCPP_PSTL_CPU_BACKEND_SERIAL");
4323
43214324 try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_VERSION={d}", .{
43224325 @intFromEnum(comp.libcxx_abi_version),
43234326 }));
......@@ -4454,9 +4457,18 @@ pub fn addCCArgs(
44544457 if (comp.sanitize_c and !comp.bin_file.options.tsan) {
44554458 try argv.append("-fsanitize=undefined");
44564459 try argv.append("-fsanitize-trap=undefined");
4460 // It is very common, and well-defined, for a pointer on one side of a C ABI
4461 // to have a different but compatible element type. Examples include:
4462 // `char*` vs `uint8_t*` on a system with 8-bit bytes
4463 // `const char*` vs `char*`
4464 // `char*` vs `unsigned char*`
4465 // Without this flag, Clang would invoke UBSAN when such an extern
4466 // function was called.
4467 try argv.append("-fno-sanitize=function");
44574468 } else if (comp.sanitize_c and comp.bin_file.options.tsan) {
44584469 try argv.append("-fsanitize=undefined,thread");
44594470 try argv.append("-fsanitize-trap=undefined");
4471 try argv.append("-fno-sanitize=function");
44604472 } else if (!comp.sanitize_c and comp.bin_file.options.tsan) {
44614473 try argv.append("-fsanitize=thread");
44624474 }
src/arch/riscv64/abi.zig+19-1
......@@ -5,7 +5,7 @@ const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
55const Type = @import("../../type.zig").Type;
66const Module = @import("../../Module.zig");
77
8pub const Class = enum { memory, byval, integer, double_integer };
8pub const Class = enum { memory, byval, integer, double_integer, fields };
99
1010pub fn classifyType(ty: Type, mod: *Module) Class {
1111 const target = mod.getTarget();
......@@ -19,6 +19,24 @@ pub fn classifyType(ty: Type, mod: *Module) Class {
1919 if (bit_size > max_byval_size) return .memory;
2020 return .byval;
2121 }
22
23 if (std.Target.riscv.featureSetHas(target.cpu.features, .d)) fields: {
24 var any_fp = false;
25 var field_count: usize = 0;
26 for (0..ty.structFieldCount(mod)) |field_index| {
27 const field_ty = ty.structFieldType(field_index, mod);
28 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
29 if (field_ty.isRuntimeFloat())
30 any_fp = true
31 else if (!field_ty.isAbiInt(mod))
32 break :fields;
33 field_count += 1;
34 if (field_count > 2) break :fields;
35 }
36 std.debug.assert(field_count > 0 and field_count <= 2);
37 if (any_fp) return .fields;
38 }
39
2240 // TODO this doesn't exactly match what clang produces but its better than nothing
2341 if (bit_size > max_byval_size) return .memory;
2442 if (bit_size > max_byval_size / 2) return .double_integer;
src/clang.zig+238-4
......@@ -113,7 +113,11 @@ pub const APFloatBaseSemantics = enum(c_int) {
113113 IEEEquad,
114114 PPCDoubleDouble,
115115 Float8E5M2,
116 Float8E5M2FNUZ,
116117 Float8E4M3FN,
118 Float8E4M3FNUZ,
119 Float8E4M3B11FNUZ,
120 FloatTF32,
117121 x87DoubleExtended,
118122};
119123
......@@ -1621,10 +1625,10 @@ pub const BuiltinTypeKind = enum(c_int) {
16211625 OCLIntelSubgroupAVCImeResult,
16221626 OCLIntelSubgroupAVCRefResult,
16231627 OCLIntelSubgroupAVCSicResult,
1624 OCLIntelSubgroupAVCImeResultSingleRefStreamout,
1625 OCLIntelSubgroupAVCImeResultDualRefStreamout,
1626 OCLIntelSubgroupAVCImeSingleRefStreamin,
1627 OCLIntelSubgroupAVCImeDualRefStreamin,
1628 OCLIntelSubgroupAVCImeResultSingleReferenceStreamout,
1629 OCLIntelSubgroupAVCImeResultDualReferenceStreamout,
1630 OCLIntelSubgroupAVCImeSingleReferenceStreamin,
1631 OCLIntelSubgroupAVCImeDualReferenceStreamin,
16281632 SveInt8,
16291633 SveInt16,
16301634 SveInt32,
......@@ -1674,6 +1678,9 @@ pub const BuiltinTypeKind = enum(c_int) {
16741678 SveFloat64x4,
16751679 SveBFloat16x4,
16761680 SveBool,
1681 SveBoolx2,
1682 SveBoolx4,
1683 SveCount,
16771684 VectorQuad,
16781685 VectorPair,
16791686 RvvInt8mf8,
......@@ -1742,6 +1749,233 @@ pub const BuiltinTypeKind = enum(c_int) {
17421749 RvvBool16,
17431750 RvvBool32,
17441751 RvvBool64,
1752 RvvInt8mf8x2,
1753 RvvInt8mf8x3,
1754 RvvInt8mf8x4,
1755 RvvInt8mf8x5,
1756 RvvInt8mf8x6,
1757 RvvInt8mf8x7,
1758 RvvInt8mf8x8,
1759 RvvInt8mf4x2,
1760 RvvInt8mf4x3,
1761 RvvInt8mf4x4,
1762 RvvInt8mf4x5,
1763 RvvInt8mf4x6,
1764 RvvInt8mf4x7,
1765 RvvInt8mf4x8,
1766 RvvInt8mf2x2,
1767 RvvInt8mf2x3,
1768 RvvInt8mf2x4,
1769 RvvInt8mf2x5,
1770 RvvInt8mf2x6,
1771 RvvInt8mf2x7,
1772 RvvInt8mf2x8,
1773 RvvInt8m1x2,
1774 RvvInt8m1x3,
1775 RvvInt8m1x4,
1776 RvvInt8m1x5,
1777 RvvInt8m1x6,
1778 RvvInt8m1x7,
1779 RvvInt8m1x8,
1780 RvvInt8m2x2,
1781 RvvInt8m2x3,
1782 RvvInt8m2x4,
1783 RvvInt8m4x2,
1784 RvvUint8mf8x2,
1785 RvvUint8mf8x3,
1786 RvvUint8mf8x4,
1787 RvvUint8mf8x5,
1788 RvvUint8mf8x6,
1789 RvvUint8mf8x7,
1790 RvvUint8mf8x8,
1791 RvvUint8mf4x2,
1792 RvvUint8mf4x3,
1793 RvvUint8mf4x4,
1794 RvvUint8mf4x5,
1795 RvvUint8mf4x6,
1796 RvvUint8mf4x7,
1797 RvvUint8mf4x8,
1798 RvvUint8mf2x2,
1799 RvvUint8mf2x3,
1800 RvvUint8mf2x4,
1801 RvvUint8mf2x5,
1802 RvvUint8mf2x6,
1803 RvvUint8mf2x7,
1804 RvvUint8mf2x8,
1805 RvvUint8m1x2,
1806 RvvUint8m1x3,
1807 RvvUint8m1x4,
1808 RvvUint8m1x5,
1809 RvvUint8m1x6,
1810 RvvUint8m1x7,
1811 RvvUint8m1x8,
1812 RvvUint8m2x2,
1813 RvvUint8m2x3,
1814 RvvUint8m2x4,
1815 RvvUint8m4x2,
1816 RvvInt16mf4x2,
1817 RvvInt16mf4x3,
1818 RvvInt16mf4x4,
1819 RvvInt16mf4x5,
1820 RvvInt16mf4x6,
1821 RvvInt16mf4x7,
1822 RvvInt16mf4x8,
1823 RvvInt16mf2x2,
1824 RvvInt16mf2x3,
1825 RvvInt16mf2x4,
1826 RvvInt16mf2x5,
1827 RvvInt16mf2x6,
1828 RvvInt16mf2x7,
1829 RvvInt16mf2x8,
1830 RvvInt16m1x2,
1831 RvvInt16m1x3,
1832 RvvInt16m1x4,
1833 RvvInt16m1x5,
1834 RvvInt16m1x6,
1835 RvvInt16m1x7,
1836 RvvInt16m1x8,
1837 RvvInt16m2x2,
1838 RvvInt16m2x3,
1839 RvvInt16m2x4,
1840 RvvInt16m4x2,
1841 RvvUint16mf4x2,
1842 RvvUint16mf4x3,
1843 RvvUint16mf4x4,
1844 RvvUint16mf4x5,
1845 RvvUint16mf4x6,
1846 RvvUint16mf4x7,
1847 RvvUint16mf4x8,
1848 RvvUint16mf2x2,
1849 RvvUint16mf2x3,
1850 RvvUint16mf2x4,
1851 RvvUint16mf2x5,
1852 RvvUint16mf2x6,
1853 RvvUint16mf2x7,
1854 RvvUint16mf2x8,
1855 RvvUint16m1x2,
1856 RvvUint16m1x3,
1857 RvvUint16m1x4,
1858 RvvUint16m1x5,
1859 RvvUint16m1x6,
1860 RvvUint16m1x7,
1861 RvvUint16m1x8,
1862 RvvUint16m2x2,
1863 RvvUint16m2x3,
1864 RvvUint16m2x4,
1865 RvvUint16m4x2,
1866 RvvInt32mf2x2,
1867 RvvInt32mf2x3,
1868 RvvInt32mf2x4,
1869 RvvInt32mf2x5,
1870 RvvInt32mf2x6,
1871 RvvInt32mf2x7,
1872 RvvInt32mf2x8,
1873 RvvInt32m1x2,
1874 RvvInt32m1x3,
1875 RvvInt32m1x4,
1876 RvvInt32m1x5,
1877 RvvInt32m1x6,
1878 RvvInt32m1x7,
1879 RvvInt32m1x8,
1880 RvvInt32m2x2,
1881 RvvInt32m2x3,
1882 RvvInt32m2x4,
1883 RvvInt32m4x2,
1884 RvvUint32mf2x2,
1885 RvvUint32mf2x3,
1886 RvvUint32mf2x4,
1887 RvvUint32mf2x5,
1888 RvvUint32mf2x6,
1889 RvvUint32mf2x7,
1890 RvvUint32mf2x8,
1891 RvvUint32m1x2,
1892 RvvUint32m1x3,
1893 RvvUint32m1x4,
1894 RvvUint32m1x5,
1895 RvvUint32m1x6,
1896 RvvUint32m1x7,
1897 RvvUint32m1x8,
1898 RvvUint32m2x2,
1899 RvvUint32m2x3,
1900 RvvUint32m2x4,
1901 RvvUint32m4x2,
1902 RvvInt64m1x2,
1903 RvvInt64m1x3,
1904 RvvInt64m1x4,
1905 RvvInt64m1x5,
1906 RvvInt64m1x6,
1907 RvvInt64m1x7,
1908 RvvInt64m1x8,
1909 RvvInt64m2x2,
1910 RvvInt64m2x3,
1911 RvvInt64m2x4,
1912 RvvInt64m4x2,
1913 RvvUint64m1x2,
1914 RvvUint64m1x3,
1915 RvvUint64m1x4,
1916 RvvUint64m1x5,
1917 RvvUint64m1x6,
1918 RvvUint64m1x7,
1919 RvvUint64m1x8,
1920 RvvUint64m2x2,
1921 RvvUint64m2x3,
1922 RvvUint64m2x4,
1923 RvvUint64m4x2,
1924 RvvFloat16mf4x2,
1925 RvvFloat16mf4x3,
1926 RvvFloat16mf4x4,
1927 RvvFloat16mf4x5,
1928 RvvFloat16mf4x6,
1929 RvvFloat16mf4x7,
1930 RvvFloat16mf4x8,
1931 RvvFloat16mf2x2,
1932 RvvFloat16mf2x3,
1933 RvvFloat16mf2x4,
1934 RvvFloat16mf2x5,
1935 RvvFloat16mf2x6,
1936 RvvFloat16mf2x7,
1937 RvvFloat16mf2x8,
1938 RvvFloat16m1x2,
1939 RvvFloat16m1x3,
1940 RvvFloat16m1x4,
1941 RvvFloat16m1x5,
1942 RvvFloat16m1x6,
1943 RvvFloat16m1x7,
1944 RvvFloat16m1x8,
1945 RvvFloat16m2x2,
1946 RvvFloat16m2x3,
1947 RvvFloat16m2x4,
1948 RvvFloat16m4x2,
1949 RvvFloat32mf2x2,
1950 RvvFloat32mf2x3,
1951 RvvFloat32mf2x4,
1952 RvvFloat32mf2x5,
1953 RvvFloat32mf2x6,
1954 RvvFloat32mf2x7,
1955 RvvFloat32mf2x8,
1956 RvvFloat32m1x2,
1957 RvvFloat32m1x3,
1958 RvvFloat32m1x4,
1959 RvvFloat32m1x5,
1960 RvvFloat32m1x6,
1961 RvvFloat32m1x7,
1962 RvvFloat32m1x8,
1963 RvvFloat32m2x2,
1964 RvvFloat32m2x3,
1965 RvvFloat32m2x4,
1966 RvvFloat32m4x2,
1967 RvvFloat64m1x2,
1968 RvvFloat64m1x3,
1969 RvvFloat64m1x4,
1970 RvvFloat64m1x5,
1971 RvvFloat64m1x6,
1972 RvvFloat64m1x7,
1973 RvvFloat64m1x8,
1974 RvvFloat64m2x2,
1975 RvvFloat64m2x3,
1976 RvvFloat64m2x4,
1977 RvvFloat64m4x2,
1978 WasmExternRef,
17451979 Void,
17461980 Bool,
17471981 Char_U,
src/clang_options_data.zig+325-36
......@@ -33,6 +33,7 @@ flagpd1("H"),
3333 .psl = false,
3434},
3535flagpd1("I-"),
36flagpd1("K"),
3637.{
3738 .name = "M",
3839 .syntax = .flag,
......@@ -2121,6 +2122,7 @@ flagpd1("analyzer-viz-egraph-graphviz"),
21212122flagpd1("analyzer-werror"),
21222123flagpd1("fslp-vectorize-aggressive"),
21232124flagpd1("fno-slp-vectorize-aggressive"),
2125flagpd1("fsched-interblock"),
21242126flagpd1("ftree-vectorize"),
21252127flagpd1("fno-tree-vectorize"),
21262128flagpd1("ftree-slp-vectorize"),
......@@ -2154,9 +2156,12 @@ flagpd1("nocudalib"),
21542156 .pd2 = true,
21552157 .psl = false,
21562158},
2159flagpd1("mcpu=help"),
2160flagpd1("mtune=help"),
21572161flagpd1("integrated-as"),
21582162flagpd1("no-integrated-as"),
21592163flagpd1("shared-libasan"),
2164flagpd1("fopenmp-is-device"),
21602165.{
21612166 .name = "Gs",
21622167 .syntax = .flag,
......@@ -2277,6 +2282,10 @@ flagpd1("shared-libasan"),
22772282 .pd2 = false,
22782283 .psl = true,
22792284},
2285sepd1("Xmicrosoft-visualc-tools-root"),
2286sepd1("Xmicrosoft-visualc-tools-version"),
2287sepd1("Xmicrosoft-windows-sdk-root"),
2288sepd1("Xmicrosoft-windows-sdk-version"),
22802289flagpd1("fdiagnostics-color"),
22812290flagpd1("fno-diagnostics-color"),
22822291flagpd1("frecord-gcc-switches"),
......@@ -2291,7 +2300,6 @@ flagpd1("fdefer-pop"),
22912300flagpd1("fno-defer-pop"),
22922301flagpd1("fextended-identifiers"),
22932302flagpd1("fno-extended-identifiers"),
2294flagpd1("fno-sanitize-blacklist"),
22952303.{
22962304 .name = "config",
22972305 .syntax = .separate,
......@@ -2300,15 +2308,15 @@ flagpd1("fno-sanitize-blacklist"),
23002308 .pd2 = true,
23012309 .psl = false,
23022310},
2303flagpd1("fcuda-rdc"),
2311flagpd1("fno-sanitize-blacklist"),
23042312flagpd1("fhonor-infinites"),
23052313flagpd1("fno-honor-infinites"),
2306flagpd1("fno-cuda-rdc"),
23072314flagpd1("findirect-virtual-calls"),
2315flagpd1("fcuda-rdc"),
2316flagpd1("fno-cuda-rdc"),
23082317sepd1("fnew-alignment"),
23092318flagpd1("faligned-new"),
23102319flagpd1("fno-aligned-new"),
2311flagpd1("fsched-interblock"),
23122320.{
23132321 .name = "ansi",
23142322 .syntax = .flag,
......@@ -2349,6 +2357,7 @@ sepd1("bundle_loader"),
23492357},
23502358sepd1("c-isystem"),
23512359flagpd1("canonical-prefixes"),
2360flagpd1("canonical-system-headers"),
23522361flagpd1("cc1"),
23532362flagpd1("cc1as"),
23542363flagpd1("ccc-arcmt-check"),
......@@ -2481,6 +2490,7 @@ flagpd1("dump-coverage-mapping"),
24812490flagpd1("dump-deserialized-decls"),
24822491flagpd1("dump-raw-tokens"),
24832492flagpd1("dump-tokens"),
2493sepd1("dumpdir"),
24842494flagpd1("dumpmachine"),
24852495flagpd1("dumpspecs"),
24862496flagpd1("dumpversion"),
......@@ -2488,6 +2498,14 @@ sepd1("dwarf-debug-flags"),
24882498sepd1("dwarf-debug-producer"),
24892499flagpd1("dwarf-explicit-import"),
24902500flagpd1("dwarf-ext-refs"),
2501.{
2502 .name = "Vd",
2503 .syntax = .flag,
2504 .zig_equivalent = .other,
2505 .pd1 = true,
2506 .pd2 = false,
2507 .psl = true,
2508},
24912509.{
24922510 .name = "hlsl-no-stdinc",
24932511 .syntax = .flag,
......@@ -2512,6 +2530,7 @@ flagpd1("emit-ast"),
25122530flagpd1("emit-codegen-only"),
25132531flagpd1("emit-fir"),
25142532flagpd1("emit-header-unit"),
2533flagpd1("emit-hlfir"),
25152534flagpd1("emit-html"),
25162535flagpd1("emit-interface-stubs"),
25172536.{
......@@ -2617,6 +2636,7 @@ flagpd1("fasm"),
26172636flagpd1("fasm-blocks"),
26182637flagpd1("fassociative-math"),
26192638flagpd1("fassume-sane-operator-new"),
2639flagpd1("fassume-unique-vtables"),
26202640flagpd1("fast"),
26212641flagpd1("fastcp"),
26222642flagpd1("fastf"),
......@@ -2661,7 +2681,6 @@ flagpd1("fcaller-saves"),
26612681 .pd2 = false,
26622682 .psl = false,
26632683},
2664sepd1("fcaret-diagnostics-max-lines"),
26652684flagpd1("fcf-protection"),
26662685.{
26672686 .name = "fcgl",
......@@ -2673,6 +2692,7 @@ flagpd1("fcf-protection"),
26732692},
26742693flagpd1("fchar8_t"),
26752694flagpd1("fcheck-array-temporaries"),
2695flagpd1("fcheck-new"),
26762696.{
26772697 .name = "fcolor-diagnostics",
26782698 .syntax = .flag,
......@@ -2687,12 +2707,9 @@ flagpd1("fcomplete-member-pointers"),
26872707flagpd1("fconst-strings"),
26882708flagpd1("fconstant-cfstrings"),
26892709sepd1("fconstant-string-class"),
2690sepd1("fconstexpr-backtrace-limit"),
2691sepd1("fconstexpr-depth"),
2692sepd1("fconstexpr-steps"),
26932710flagpd1("fconvergent-functions"),
26942711flagpd1("fcoro-aligned-allocation"),
2695flagpd1("fcoroutines-ts"),
2712flagpd1("fcoroutines"),
26962713flagpd1("fcoverage-mapping"),
26972714flagpd1("fcrash-diagnostics"),
26982715flagpd1("fcray-pointer"),
......@@ -2753,6 +2770,7 @@ flagpd1("fdiagnostics-parseable-fixits"),
27532770flagpd1("fdiagnostics-print-source-range-info"),
27542771sepd1("fdiagnostics-show-category"),
27552772flagpd1("fdiagnostics-show-hotness"),
2773flagpd1("fdiagnostics-show-line-numbers"),
27562774flagpd1("fdiagnostics-show-note-include-stack"),
27572775flagpd1("fdiagnostics-show-option"),
27582776flagpd1("fdiagnostics-show-template-tree"),
......@@ -2782,13 +2800,13 @@ flagpd1("feliminate-unused-debug-types"),
27822800flagpd1("fembed-bitcode"),
27832801flagpd1("fembed-bitcode-marker"),
27842802flagpd1("femit-all-decls"),
2803flagpd1("femit-compact-unwind-non-canonical"),
27852804flagpd1("femulated-tls"),
27862805flagpd1("fenable-matrix"),
27872806flagpd1("fencode-extended-block-signature"),
27882807sepd1("ferror-limit"),
27892808flagpd1("fescaping-block-tail-calls"),
27902809flagpd1("fexceptions"),
2791flagpd1("fexperimental-assignment-tracking"),
27922810flagpd1("fexperimental-isel"),
27932811flagpd1("fexperimental-library"),
27942812flagpd1("fexperimental-new-constant-interpreter"),
......@@ -2803,7 +2821,6 @@ flagpd1("ff2c"),
28032821flagpd1("ffake-address-space-map"),
28042822flagpd1("ffast-math"),
28052823flagpd1("ffat-lto-objects"),
2806flagpd1("fcheck-new"),
28072824flagpd1("ffile-reproducible"),
28082825flagpd1("fimplicit-modules-use-lock"),
28092826flagpd1("ffine-grained-bitfield-accesses"),
......@@ -2907,6 +2924,7 @@ flagpd1("fgpu-sanitize"),
29072924flagpd1("fhalf-no-semantic-interposition"),
29082925flagpd1("fheinous-gnu-extensions"),
29092926flagpd1("fhip-dump-offload-linker-script"),
2927flagpd1("fhip-emit-relocatable"),
29102928flagpd1("fhip-fp32-correctly-rounded-divide-sqrt"),
29112929flagpd1("fhip-kernel-arg-name"),
29122930flagpd1("fhip-new-launch-api"),
......@@ -2946,13 +2964,16 @@ flagpd1("fixit-recompile"),
29462964flagpd1("fixit-to-temporary"),
29472965flagpd1("fjmc"),
29482966flagpd1("fjump-tables"),
2967flagpd1("fkeep-persistent-storage-variables"),
29492968flagpd1("fkeep-static-consts"),
2950flagpd1("flang-experimental-exec"),
2969flagpd1("flang-experimental-hlfir"),
2970flagpd1("flang-experimental-polymorphism"),
29512971flagpd1("flarge-sizes"),
29522972flagpd1("flat_namespace"),
29532973flagpd1("flax-vector-conversions"),
29542974flagpd1("flimit-debug-info"),
29552975flagpd1("flogical-abbreviations"),
2976flagpd1("fversion-loops-for-stride"),
29562977.{
29572978 .name = "flto",
29582979 .syntax = .flag,
......@@ -2965,7 +2986,6 @@ flagpd1("flto=auto"),
29652986flagpd1("flto=jobserver"),
29662987flagpd1("flto-unit"),
29672988flagpd1("flto-visibility-public-std"),
2968sepd1("fmacro-backtrace-limit"),
29692989flagpd1("fmath-errno"),
29702990flagpd1("fmax-identifier-length"),
29712991flagpd1("fmemory-profile"),
......@@ -2992,7 +3012,6 @@ flagpd1("fmodules-local-submodule-visibility"),
29923012flagpd1("fmodules-search-all"),
29933013flagpd1("fmodules-strict-context-hash"),
29943014flagpd1("fmodules-strict-decluse"),
2995flagpd1("fmodules-ts"),
29963015sepd1("fmodules-user-build-path"),
29973016flagpd1("fmodules-validate-input-files-content"),
29983017flagpd1("fmodules-validate-once-per-build-session"),
......@@ -3050,6 +3069,7 @@ flagpd1("fno-asm"),
30503069flagpd1("fno-asm-blocks"),
30513070flagpd1("fno-associative-math"),
30523071flagpd1("fno-assume-sane-operator-new"),
3072flagpd1("fno-assume-unique-vtables"),
30533073flagpd1("fno-async-exceptions"),
30543074flagpd1("fno-asynchronous-unwind-tables"),
30553075flagpd1("fno-auto-profile"),
......@@ -3082,6 +3102,7 @@ flagpd1("fno-caller-saves"),
30823102},
30833103flagpd1("fno-char8_t"),
30843104flagpd1("fno-check-array-temporaries"),
3105flagpd1("fno-check-new"),
30853106.{
30863107 .name = "fno-color-diagnostics",
30873108 .syntax = .flag,
......@@ -3094,8 +3115,9 @@ flagpd1("fno-common"),
30943115flagpd1("fno-complete-member-pointers"),
30953116flagpd1("fno-const-strings"),
30963117flagpd1("fno-constant-cfstrings"),
3118flagpd1("fno-convergent-functions"),
30973119flagpd1("fno-coro-aligned-allocation"),
3098flagpd1("fno-coroutines-ts"),
3120flagpd1("fno-coroutines"),
30993121flagpd1("fno-coverage-mapping"),
31003122flagpd1("fno-crash-diagnostics"),
31013123flagpd1("fno-cray-pointer"),
......@@ -3123,6 +3145,7 @@ flagpd1("fno-devirtualize"),
31233145flagpd1("fno-devirtualize-speculatively"),
31243146flagpd1("fno-diagnostics-fixit-info"),
31253147flagpd1("fno-diagnostics-show-hotness"),
3148flagpd1("fno-diagnostics-show-line-numbers"),
31263149flagpd1("fno-diagnostics-show-note-include-stack"),
31273150flagpd1("fno-diagnostics-show-option"),
31283151flagpd1("fno-diagnostics-use-presumed-location"),
......@@ -3143,10 +3166,10 @@ flagpd1("fno-elide-constructors"),
31433166flagpd1("fno-elide-type"),
31443167flagpd1("fno-eliminate-unused-debug-symbols"),
31453168flagpd1("fno-eliminate-unused-debug-types"),
3169flagpd1("fno-emit-compact-unwind-non-canonical"),
31463170flagpd1("fno-emulated-tls"),
31473171flagpd1("fno-escaping-block-tail-calls"),
31483172flagpd1("fno-exceptions"),
3149flagpd1("fno-experimental-assignment-tracking"),
31503173flagpd1("fno-experimental-isel"),
31513174flagpd1("fno-experimental-library"),
31523175flagpd1("fno-experimental-relative-c++-abi-vtables"),
......@@ -3154,7 +3177,6 @@ flagpd1("fno-external-blas"),
31543177flagpd1("fno-f2c"),
31553178flagpd1("fno-fast-math"),
31563179flagpd1("fno-fat-lto-objects"),
3157flagpd1("fno-check-new"),
31583180flagpd1("fno-file-reproducible"),
31593181flagpd1("fno-implicit-modules-use-lock"),
31603182flagpd1("fno-fine-grained-bitfield-accesses"),
......@@ -3193,6 +3215,7 @@ flagpd1("fno-gpu-exclude-wrong-side-overloads"),
31933215flagpd1("fno-gpu-flush-denormals-to-zero"),
31943216flagpd1("fno-gpu-rdc"),
31953217flagpd1("fno-gpu-sanitize"),
3218flagpd1("fno-hip-emit-relocatable"),
31963219flagpd1("fno-hip-fp32-correctly-rounded-divide-sqrt"),
31973220flagpd1("fno-hip-kernel-arg-name"),
31983221flagpd1("fno-hip-new-launch-api"),
......@@ -3216,11 +3239,13 @@ flagpd1("fno-ipa-cp"),
32163239flagpd1("fno-ivopts"),
32173240flagpd1("fno-jmc"),
32183241flagpd1("fno-jump-tables"),
3242flagpd1("fno-keep-persistent-storage-variables"),
32193243flagpd1("fno-keep-static-consts"),
32203244flagpd1("fno-knr-functions"),
32213245flagpd1("fno-lax-vector-conversions"),
32223246flagpd1("fno-limit-debug-info"),
32233247flagpd1("fno-logical-abbreviations"),
3248flagpd1("fno-version-loops-for-stride"),
32243249.{
32253250 .name = "fno-lto",
32263251 .syntax = .flag,
......@@ -3281,7 +3306,6 @@ flagpd1("fno-openmp-assume-teams-oversubscription"),
32813306flagpd1("fno-openmp-assume-threads-oversubscription"),
32823307flagpd1("fno-openmp-cuda-mode"),
32833308flagpd1("fno-openmp-extensions"),
3284flagpd1("fno-openmp-implicit-rpath"),
32853309flagpd1("fno-openmp-new-driver"),
32863310flagpd1("fno-openmp-optimistic-collapse"),
32873311flagpd1("fno-openmp-simd"),
......@@ -3366,6 +3390,7 @@ flagpd1("fno-rtlib-add-rpath"),
33663390flagpd1("fno-rtti"),
33673391flagpd1("fno-rtti-data"),
33683392flagpd1("fno-rwpi"),
3393flagpd1("fno-safe-buffer-usage-suggestions"),
33693394flagpd1("fno-sanitize-address-globals-dead-stripping"),
33703395flagpd1("fno-sanitize-address-outline-instrumentation"),
33713396flagpd1("fno-sanitize-address-poison-custom-array-cookie"),
......@@ -3382,6 +3407,7 @@ flagpd1("fno-sanitize-memory-track-origins"),
33823407flagpd1("fno-sanitize-memory-use-after-dtor"),
33833408flagpd1("fno-sanitize-minimal-runtime"),
33843409flagpd1("fno-sanitize-recover"),
3410flagpd1("fno-sanitize-stable-abi"),
33853411flagpd1("fno-sanitize-stats"),
33863412flagpd1("fno-sanitize-thread-atomics"),
33873413flagpd1("fno-sanitize-thread-func-entry-exit"),
......@@ -3455,6 +3481,7 @@ flagpd1("fno-tree-vectorizer-verbose"),
34553481flagpd1("fno-tree-vrp"),
34563482flagpd1("fno-trigraphs"),
34573483flagpd1("fno-underscoring"),
3484flagpd1("fno-unified-lto"),
34583485flagpd1("fno-unique-basic-block-section-names"),
34593486flagpd1("fno-unique-internal-linkage-names"),
34603487flagpd1("fno-unique-section-names"),
......@@ -3501,12 +3528,12 @@ flagpd1("fno-xray-always-emit-typedevents"),
35013528flagpd1("fno-xray-function-index"),
35023529flagpd1("fno-xray-ignore-loops"),
35033530flagpd1("fno-xray-instrument"),
3531flagpd1("fno-xray-link-deps"),
35043532flagpd1("fno-zero-initialized-in-bss"),
35053533flagpd1("fno-zvector"),
35063534flagpd1("fnon-call-exceptions"),
35073535flagpd1("fnoopenmp-relocatable-target"),
35083536flagpd1("fnoopenmp-use-tls"),
3509flagpd1("fnoxray-link-deps"),
35103537flagpd1("fobjc-arc"),
35113538flagpd1("fobjc-arc-exceptions"),
35123539flagpd1("fobjc-atdefs"),
......@@ -3546,8 +3573,7 @@ flagpd1("fopenmp-cuda-mode"),
35463573flagpd1("fopenmp-enable-irbuilder"),
35473574flagpd1("fopenmp-extensions"),
35483575sepd1("fopenmp-host-ir-file-path"),
3549flagpd1("fopenmp-implicit-rpath"),
3550flagpd1("fopenmp-is-device"),
3576flagpd1("fopenmp-is-target-device"),
35513577flagpd1("fopenmp-new-driver"),
35523578flagpd1("fopenmp-offload-mandatory"),
35533579flagpd1("fopenmp-optimistic-collapse"),
......@@ -3557,7 +3583,6 @@ flagpd1("fopenmp-target-debug"),
35573583flagpd1("fopenmp-target-jit"),
35583584flagpd1("fopenmp-target-new-runtime"),
35593585flagpd1("fopenmp-use-tls"),
3560sepd1("foperator-arrow-depth"),
35613586flagpd1("foperator-names"),
35623587flagpd1("foptimize-sibling-calls"),
35633588flagpd1("force_cpusubtype_ALL"),
......@@ -3653,6 +3678,7 @@ flagpd1("frtlib-add-rpath"),
36533678flagpd1("frtti"),
36543679flagpd1("frtti-data"),
36553680flagpd1("frwpi"),
3681flagpd1("fsafe-buffer-usage-suggestions"),
36563682flagpd1("fsample-profile-use-profi"),
36573683flagpd1("fsanitize-address-globals-dead-stripping"),
36583684flagpd1("fsanitize-address-outline-instrumentation"),
......@@ -3662,6 +3688,7 @@ flagpd1("fsanitize-address-use-odr-indicator"),
36623688flagpd1("fsanitize-cfi-canonical-jump-tables"),
36633689flagpd1("fsanitize-cfi-cross-dso"),
36643690flagpd1("fsanitize-cfi-icall-generalize-pointers"),
3691flagpd1("fsanitize-cfi-icall-experimental-normalize-integers"),
36653692flagpd1("fsanitize-coverage-8bit-counters"),
36663693flagpd1("fsanitize-coverage-control-flow"),
36673694flagpd1("fsanitize-coverage-indirect-calls"),
......@@ -3686,6 +3713,7 @@ flagpd1("fsanitize-memory-track-origins"),
36863713flagpd1("fsanitize-memory-use-after-dtor"),
36873714flagpd1("fsanitize-minimal-runtime"),
36883715flagpd1("fsanitize-recover"),
3716flagpd1("fsanitize-stable-abi"),
36893717flagpd1("fsanitize-stats"),
36903718flagpd1("fsanitize-thread-atomics"),
36913719flagpd1("fsanitize-thread-func-entry-exit"),
......@@ -3717,7 +3745,6 @@ flagpd1("fsjlj-exceptions"),
37173745flagpd1("fslp-vectorize"),
37183746flagpd1("fspec-constr-count"),
37193747flagpd1("fspell-checking"),
3720sepd1("fspell-checking-limit"),
37213748flagpd1("fsplit-dwarf-inlining"),
37223749flagpd1("fsplit-lto-unit"),
37233750flagpd1("fsplit-machine-functions"),
......@@ -3773,8 +3800,6 @@ flagpd1("fsycl-is-host"),
37733800flagpd1("fsyntax-only"),
37743801flagpd1("fsystem-module"),
37753802sepd1("ftabstop"),
3776sepd1("ftemplate-backtrace-limit"),
3777sepd1("ftemplate-depth"),
37783803flagpd1("ftest-coverage"),
37793804flagpd1("fthreadsafe-statics"),
37803805flagpd1("ftime-report"),
......@@ -3792,6 +3817,7 @@ flagpd1("ftree-vrp"),
37923817flagpd1("ftrigraphs"),
37933818sepd1("function-alignment"),
37943819flagpd1("funderscoring"),
3820flagpd1("funified-lto"),
37953821flagpd1("funique-basic-block-section-names"),
37963822flagpd1("funique-internal-linkage-names"),
37973823flagpd1("funique-section-names"),
......@@ -4024,6 +4050,7 @@ sepd1("internal-isystem"),
40244050flagpd1("keep_private_externs"),
40254051sepd1("lazy_framework"),
40264052sepd1("lazy_library"),
4053flagpd1("llvm-verify-each"),
40274054sepd1("load"),
40284055flagpd1("m16"),
40294056flagpd1("m32"),
......@@ -4036,21 +4063,24 @@ flagpd1("m68020"),
40364063flagpd1("m68030"),
40374064flagpd1("m68040"),
40384065flagpd1("m68060"),
4066flagpd1("m68881"),
40394067flagpd1("m80387"),
40404068m("mseses"),
40414069flagpd1("mabi=ieeelongdouble"),
40424070flagpd1("mabi=quadword-atomics"),
4043flagpd1("mabi=vec-default"),
40444071flagpd1("mabi=vec-extabi"),
40454072flagpd1("mabicalls"),
40464073m("madx"),
40474074m("maes"),
40484075sepd1("main-file-name"),
4076flagpd1("maix32"),
4077flagpd1("maix64"),
40494078flagpd1("maix-struct-return"),
40504079flagpd1("malign-double"),
40514080m("maltivec"),
40524081flagpd1("mamdgpu-ieee"),
40534082m("mamx-bf16"),
4083flagpd1("mamx-complex"),
40544084m("mamx-fp16"),
40554085m("mamx-int8"),
40564086m("mamx-tile"),
......@@ -4079,6 +4109,7 @@ m("mavx512vpopcntdq"),
40794109m("mavxifma"),
40804110m("mavxneconvert"),
40814111m("mavxvnni"),
4112flagpd1("mavxvnniint16"),
40824113m("mavxvnniint8"),
40834114flagpd1("mbackchain"),
40844115flagpd1("mbig-endian"),
......@@ -4099,10 +4130,8 @@ flagpd1("mcmodel=medlow"),
40994130m("mcmpb"),
41004131m("mcmpccxadd"),
41014132flagpd1("mcmse"),
4102flagpd1("mcode-object-v3"),
41034133flagpd1("mconstant-cfstrings"),
41044134flagpd1("mconstructor-aliases"),
4105flagpd1("mcpu=?"),
41064135m("mcrbits"),
41074136m("mcrc"),
41084137m("mcrc32"),
......@@ -4235,6 +4264,7 @@ m("mno-aes"),
42354264m("mno-altivec"),
42364265flagpd1("mno-amdgpu-ieee"),
42374266m("mno-amx-bf16"),
4267flagpd1("mno-amx-complex"),
42384268m("mno-amx-fp16"),
42394269m("mno-amx-int8"),
42404270m("mno-amx-tile"),
......@@ -4260,6 +4290,7 @@ m("mno-avx512vpopcntdq"),
42604290m("mno-avxifma"),
42614291m("mno-avxneconvert"),
42624292m("mno-avxvnni"),
4293flagpd1("mno-avxvnniint16"),
42634294m("mno-avxvnniint8"),
42644295flagpd1("mno-backchain"),
42654296m("mno-bmi"),
......@@ -4274,7 +4305,6 @@ m("mno-clwb"),
42744305m("mno-clzero"),
42754306m("mno-cmpb"),
42764307m("mno-cmpccxadd"),
4277flagpd1("mno-code-object-v3"),
42784308flagpd1("mno-constant-cfstrings"),
42794309flagpd1("mno-constructor-aliases"),
42804310m("mno-crbits"),
......@@ -4407,10 +4437,13 @@ m("mno-serialize"),
44074437m("mno-seses"),
44084438m("mno-sgx"),
44094439m("mno-sha"),
4440flagpd1("mno-sha512"),
44104441m("mno-shstk"),
44114442m("mno-sign-ext"),
44124443m("mno-simd128"),
44134444flagpd1("mno-skip-rax-setup"),
4445flagpd1("mno-sm3"),
4446m("mno-sm4"),
44144447m("mno-soft-float"),
44154448m("mno-spe"),
44164449flagpd1("mno-speculative-load-hardening"),
......@@ -4424,6 +4457,7 @@ m("mno-sse4a"),
44244457m("mno-ssse3"),
44254458flagpd1("mno-stack-arg-probe"),
44264459flagpd1("mno-stackrealign"),
4460m("mno-strict-align"),
44274461m("mno-tail-call"),
44284462m("mno-tbm"),
44294463m("mno-tgsplit"),
......@@ -4449,6 +4483,7 @@ m("mno-wavefrontsize64"),
44494483m("mno-wbnoinvd"),
44504484m("mno-widekl"),
44514485m("mno-x87"),
4486flagpd1("mno-xcoff-roptr"),
44524487m("mno-xgot"),
44534488m("mno-xop"),
44544489m("mno-xsave"),
......@@ -4533,12 +4568,15 @@ m("msecure-plt"),
45334568m("mserialize"),
45344569m("msgx"),
45354570m("msha"),
4571flagpd1("msha512"),
45364572m("mshstk"),
45374573m("msign-ext"),
45384574flagpd1("msim"),
45394575m("msimd128"),
45404576m("msingle-float"),
45414577flagpd1("mskip-rax-setup"),
4578flagpd1("msm3"),
4579m("msm4"),
45424580sepd1("msmall-data-limit"),
45434581m("msoft-float"),
45444582flagpd1("msoft-quad-float"),
......@@ -4565,7 +4603,6 @@ flagpd1("mthumb"),
45654603flagpd1("mtls-direct-seg-refs"),
45664604sepd1("mtp"),
45674605m("mtsxldtrk"),
4568flagpd1("mtune=?"),
45694606flagpd1("muclibc"),
45704607m("muintr"),
45714608flagpd1("multi_module"),
......@@ -4602,6 +4639,7 @@ m("mwbnoinvd"),
46024639m("mwidekl"),
46034640flagpd1("mx32"),
46044641m("mx87"),
4642flagpd1("mxcoff-roptr"),
46054643m("mxgot"),
46064644m("mxop"),
46074645m("mxsave"),
......@@ -4677,7 +4715,6 @@ flagpd1("no-implicit-float"),
46774715 .pd2 = true,
46784716 .psl = false,
46794717},
4680flagpd1("no-opaque-pointers"),
46814718.{
46824719 .name = "no-pedantic",
46834720 .syntax = .flag,
......@@ -4834,7 +4871,6 @@ sepd1("object-file-name"),
48344871 .pd2 = true,
48354872 .psl = false,
48364873},
4837flagpd1("opaque-pointers"),
48384874sepd1("opt-record-file"),
48394875sepd1("opt-record-format"),
48404876sepd1("opt-record-passes"),
......@@ -4923,6 +4959,14 @@ flagpd1("print-ivar-layout"),
49234959 .pd2 = true,
49244960 .psl = false,
49254961},
4962.{
4963 .name = "print-multi-flags-experimental",
4964 .syntax = .flag,
4965 .zig_equivalent = .other,
4966 .pd1 = true,
4967 .pd2 = true,
4968 .psl = false,
4969},
49264970.{
49274971 .name = "print-multi-lib",
49284972 .syntax = .flag,
......@@ -5187,6 +5231,7 @@ flagpd1("static-libsan"),
51875231flagpd1("static-libstdc++"),
51885232flagpd1("static-openmp"),
51895233flagpd1("static-pie"),
5234flagpd1("stats-file-append"),
51905235flagpd1("sys-header-deps"),
51915236flagpd1("t"),
51925237sepd1("target-abi"),
......@@ -5236,6 +5281,214 @@ flagpd1("twolevel_namespace_hints"),
52365281sepd1("umbrella"),
52375282flagpd1("undef"),
52385283sepd1("unexported_symbols_list"),
5284.{
5285 .name = "Wextra",
5286 .syntax = .flag,
5287 .zig_equivalent = .other,
5288 .pd1 = true,
5289 .pd2 = true,
5290 .psl = false,
5291},
5292.{
5293 .name = "Waliasing",
5294 .syntax = .flag,
5295 .zig_equivalent = .other,
5296 .pd1 = true,
5297 .pd2 = true,
5298 .psl = false,
5299},
5300.{
5301 .name = "Wampersand",
5302 .syntax = .flag,
5303 .zig_equivalent = .other,
5304 .pd1 = true,
5305 .pd2 = true,
5306 .psl = false,
5307},
5308.{
5309 .name = "Warray-bounds",
5310 .syntax = .flag,
5311 .zig_equivalent = .other,
5312 .pd1 = true,
5313 .pd2 = true,
5314 .psl = false,
5315},
5316.{
5317 .name = "Wc-binding-type",
5318 .syntax = .flag,
5319 .zig_equivalent = .other,
5320 .pd1 = true,
5321 .pd2 = true,
5322 .psl = false,
5323},
5324.{
5325 .name = "Wcharacter-truncation",
5326 .syntax = .flag,
5327 .zig_equivalent = .other,
5328 .pd1 = true,
5329 .pd2 = true,
5330 .psl = false,
5331},
5332.{
5333 .name = "Wconversion",
5334 .syntax = .flag,
5335 .zig_equivalent = .other,
5336 .pd1 = true,
5337 .pd2 = true,
5338 .psl = false,
5339},
5340.{
5341 .name = "Wdo-subscript",
5342 .syntax = .flag,
5343 .zig_equivalent = .other,
5344 .pd1 = true,
5345 .pd2 = true,
5346 .psl = false,
5347},
5348.{
5349 .name = "Wfunction-elimination",
5350 .syntax = .flag,
5351 .zig_equivalent = .other,
5352 .pd1 = true,
5353 .pd2 = true,
5354 .psl = false,
5355},
5356.{
5357 .name = "Wimplicit-interface",
5358 .syntax = .flag,
5359 .zig_equivalent = .other,
5360 .pd1 = true,
5361 .pd2 = true,
5362 .psl = false,
5363},
5364.{
5365 .name = "Wimplicit-procedure",
5366 .syntax = .flag,
5367 .zig_equivalent = .other,
5368 .pd1 = true,
5369 .pd2 = true,
5370 .psl = false,
5371},
5372.{
5373 .name = "Wintrinsic-shadow",
5374 .syntax = .flag,
5375 .zig_equivalent = .other,
5376 .pd1 = true,
5377 .pd2 = true,
5378 .psl = false,
5379},
5380.{
5381 .name = "Wuse-without-only",
5382 .syntax = .flag,
5383 .zig_equivalent = .other,
5384 .pd1 = true,
5385 .pd2 = true,
5386 .psl = false,
5387},
5388.{
5389 .name = "Wintrinsics-std",
5390 .syntax = .flag,
5391 .zig_equivalent = .other,
5392 .pd1 = true,
5393 .pd2 = true,
5394 .psl = false,
5395},
5396.{
5397 .name = "Wline-truncation",
5398 .syntax = .flag,
5399 .zig_equivalent = .other,
5400 .pd1 = true,
5401 .pd2 = true,
5402 .psl = false,
5403},
5404.{
5405 .name = "Wno-align-commons",
5406 .syntax = .flag,
5407 .zig_equivalent = .other,
5408 .pd1 = true,
5409 .pd2 = true,
5410 .psl = false,
5411},
5412.{
5413 .name = "Wno-overwrite-recursive",
5414 .syntax = .flag,
5415 .zig_equivalent = .other,
5416 .pd1 = true,
5417 .pd2 = true,
5418 .psl = false,
5419},
5420.{
5421 .name = "Wno-tabs",
5422 .syntax = .flag,
5423 .zig_equivalent = .other,
5424 .pd1 = true,
5425 .pd2 = true,
5426 .psl = false,
5427},
5428.{
5429 .name = "Wreal-q-constant",
5430 .syntax = .flag,
5431 .zig_equivalent = .other,
5432 .pd1 = true,
5433 .pd2 = true,
5434 .psl = false,
5435},
5436.{
5437 .name = "Wsurprising",
5438 .syntax = .flag,
5439 .zig_equivalent = .other,
5440 .pd1 = true,
5441 .pd2 = true,
5442 .psl = false,
5443},
5444.{
5445 .name = "Wunderflow",
5446 .syntax = .flag,
5447 .zig_equivalent = .other,
5448 .pd1 = true,
5449 .pd2 = true,
5450 .psl = false,
5451},
5452.{
5453 .name = "Wunused-parameter",
5454 .syntax = .flag,
5455 .zig_equivalent = .other,
5456 .pd1 = true,
5457 .pd2 = true,
5458 .psl = false,
5459},
5460.{
5461 .name = "Wrealloc-lhs",
5462 .syntax = .flag,
5463 .zig_equivalent = .other,
5464 .pd1 = true,
5465 .pd2 = true,
5466 .psl = false,
5467},
5468.{
5469 .name = "Wrealloc-lhs-all",
5470 .syntax = .flag,
5471 .zig_equivalent = .other,
5472 .pd1 = true,
5473 .pd2 = true,
5474 .psl = false,
5475},
5476.{
5477 .name = "Wfrontend-loop-interchange",
5478 .syntax = .flag,
5479 .zig_equivalent = .other,
5480 .pd1 = true,
5481 .pd2 = true,
5482 .psl = false,
5483},
5484.{
5485 .name = "Wtarget-lifetime",
5486 .syntax = .flag,
5487 .zig_equivalent = .other,
5488 .pd1 = true,
5489 .pd2 = true,
5490 .psl = false,
5491},
52395492.{
52405493 .name = "v",
52415494 .syntax = .flag,
......@@ -5296,6 +5549,7 @@ sepd1("working-directory"),
52965549 .pd2 = false,
52975550 .psl = false,
52985551},
5552joinpd1("fexperimental-sanitize-metadata-ignorelist="),
52995553joinpd1("fsanitize-undefined-strip-path-components="),
53005554joinpd1("fopenmp-cuda-teams-reduction-recs-num="),
53015555joinpd1("fvisibility-externs-nodllstorageclass="),
......@@ -5319,6 +5573,7 @@ joinpd1("fsanitize-address-use-after-return="),
53195573 .psl = true,
53205574},
53215575joinpd1("darwin-target-variant-sdk-version="),
5576joinpd1("fexperimental-assignment-tracking="),
53225577joinpd1("ftrivial-auto-var-init-stop-after="),
53235578joinpd1("fverify-debuginfo-preserve-export="),
53245579joinpd1("fdiagnostics-misexpect-tolerance="),
......@@ -5362,6 +5617,7 @@ joinpd1("mstack-protector-guard-symbol="),
53625617 .psl = true,
53635618},
53645619joinpd1("miphonesimulator-version-min="),
5620joinpd1("fcaret-diagnostics-max-lines="),
53655621joinpd1("fobjc-nonfragile-abi-version="),
53665622joinpd1("fprofile-instrument-use-path="),
53675623joinpd1("fsanitize-coverage-allowlist="),
......@@ -5401,11 +5657,12 @@ joinpd1("mwatchsimulator-version-min="),
54015657 .psl = false,
54025658},
54035659joinpd1("objcmt-white-list-dir-path="),
5404joinpd1("fsanitize-system-blacklist="),
54055660joinpd1("error-on-deserialized-decl="),
5661joinpd1("fbfloat16-excess-precision="),
54065662joinpd1("fconstexpr-backtrace-limit="),
54075663joinpd1("fdiagnostics-show-category="),
54085664joinpd1("fdiagnostics-show-location="),
5665joinpd1("fno-modules-check-relocated"),
54095666joinpd1("fopenmp-cuda-blocks-per-sm="),
54105667.{
54115668 .name = "headerpad_max_install_names",
......@@ -5626,7 +5883,7 @@ joinpd1("fsanitize-blacklist="),
56265883joinpd1("coverage-notes-file="),
56275884.{
56285885 .name = "extract-api-ignores=",
5629 .syntax = .joined,
5886 .syntax = .comma_joined,
56305887 .zig_equivalent = .other,
56315888 .pd1 = false,
56325889 .pd2 = true,
......@@ -5636,6 +5893,7 @@ joinpd1("fbuild-session-file="),
56365893joinpd1("fdiagnostics-format="),
56375894joinpd1("fgpu-default-stream="),
56385895joinpd1("fmax-stack-var-size="),
5896joinpd1("fmemory-profile-use="),
56395897joinpd1("fmodules-cache-path="),
56405898joinpd1("fmodules-embed-file="),
56415899joinpd1("fms-omit-default-lib"),
......@@ -5731,6 +5989,14 @@ joinpd1("target-sdk-version="),
57315989 .pd2 = true,
57325990 .psl = false,
57335991},
5992.{
5993 .name = "emit-symbol-graph=",
5994 .syntax = .joined_or_separate,
5995 .zig_equivalent = .other,
5996 .pd1 = false,
5997 .pd2 = true,
5998 .psl = false,
5999},
57346000joinpd1("fbinutils-version="),
57356001joinpd1("fclang-abi-compat="),
57366002joinpd1("fcompile-resource="),
......@@ -5752,7 +6018,6 @@ joinpd1("fobjc-abi-version="),
57526018joinpd1("foutput-class-dir="),
57536019joinpd1("fproc-stat-report="),
57546020joinpd1("fprofile-generate="),
5755joinpd1("frewrite-map-file="),
57566021.{
57576022 .name = "fsanitize-recover=",
57586023 .syntax = .comma_joined,
......@@ -5799,8 +6064,10 @@ jspd1("iwithprefixbefore"),
57996064joinpd1("malign-functions="),
58006065joinpd1("mfunction-return="),
58016066joinpd1("mios-version-min="),
6067joinpd1("mrvv-vector-bits="),
58026068joinpd1("mstack-alignment="),
58036069joinpd1("msve-vector-bits="),
6070joinpd1("mzos-sys-include="),
58046071.{
58056072 .name = "no-cuda-gpu-arch=",
58066073 .syntax = .joined,
......@@ -5827,6 +6094,7 @@ joinpd1("object-file-name="),
58276094 .psl = true,
58286095},
58296096joinpd1("analyzer-output="),
6097joinpd1("ftemplate-depth-"),
58306098joinpd1("ast-dump-filter="),
58316099.{
58326100 .name = "config-user-dir=",
......@@ -5858,7 +6126,6 @@ joinpd1("fopenmp-version="),
58586126joinpd1("fprofile-update="),
58596127joinpd1("fshow-overloads="),
58606128joinpd1("fswift-async-fp="),
5861joinpd1("ftemplate-depth-"),
58626129joinpd1("ftemplate-depth="),
58636130joinpd1("fxray-attr-list="),
58646131.{
......@@ -5870,6 +6137,8 @@ joinpd1("fxray-attr-list="),
58706137 .psl = false,
58716138},
58726139joinpd1("mlinker-version="),
6140joinpd1("mxcoff-build-id="),
6141joinpd1("mzos-hlq-csslib="),
58736142.{
58746143 .name = "no-offload-arch=",
58756144 .syntax = .joined,
......@@ -5997,6 +6266,7 @@ joinpd1("gen-reproducer="),
59976266joinpd1("mdynamic-no-pic"),
59986267joinpd1("mframe-pointer="),
59996268joinpd1("mindirect-jump="),
6269joinpd1("mzos-hlq-clang="),
60006270joinpd1("preamble-bytes="),
60016271.{
60026272 .name = "Wundef-prefix=",
......@@ -6155,6 +6425,7 @@ joinpd1("malign-jumps="),
61556425joinpd1("malign-loops="),
61566426joinpd1("mframe-chain="),
61576427joinpd1("mimplicit-it="),
6428joinpd1("mprintf-kind="),
61586429.{
61596430 .name = "offload-arch=",
61606431 .syntax = .joined,
......@@ -6218,6 +6489,7 @@ joinpd1("mharden-sls="),
62186489joinpd1("mhvx-length="),
62196490joinpd1("mvscale-max="),
62206491joinpd1("mvscale-min="),
6492joinpd1("mzos-hlq-le="),
62216493.{
62226494 .name = "rsp-quoting=",
62236495 .syntax = .joined,
......@@ -6419,6 +6691,14 @@ joinpd1("segs_read_"),
64196691 .pd2 = true,
64206692 .psl = false,
64216693},
6694.{
6695 .name = "vfsoverlay",
6696 .syntax = .joined_or_separate,
6697 .zig_equivalent = .other,
6698 .pd1 = true,
6699 .pd2 = true,
6700 .psl = false,
6701},
64226702.{
64236703 .name = "cgthreads",
64246704 .syntax = .joined,
......@@ -6492,6 +6772,14 @@ joinpd1("segs_read_"),
64926772 .psl = false,
64936773},
64946774joinpd1("ast-dump="),
6775.{
6776 .name = "dxv-path=",
6777 .syntax = .joined,
6778 .zig_equivalent = .other,
6779 .pd1 = false,
6780 .pd2 = true,
6781 .psl = false,
6782},
64956783joinpd1("fcoarray="),
64966784joinpd1("fconvert="),
64976785joinpd1("fc++-abi="),
......@@ -6741,6 +7029,7 @@ joinpd1("Rpass="),
67417029 .pd2 = true,
67427030 .psl = false,
67437031},
7032joinpd1("mllvm="),
67447033joinpd1("fixit="),
67457034joinpd1("gstabs"),
67467035joinpd1("gxcoff"),
src/codegen/llvm.zig+40-12
......@@ -148,6 +148,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
148148 .watchos => "watchos",
149149 .driverkit => "driverkit",
150150 .shadermodel => "shadermodel",
151 .liteos => "liteos",
151152 .opencl,
152153 .glsl450,
153154 .vulkan,
......@@ -254,6 +255,7 @@ pub fn targetOs(os_tag: std.Target.Os.Tag) llvm.OSType {
254255 .emscripten => .Emscripten,
255256 .driverkit => .DriverKit,
256257 .shadermodel => .ShaderModel,
258 .liteos => .LiteOS,
257259 };
258260}
259261
......@@ -419,8 +421,12 @@ const DataLayoutBuilder = struct {
419421 if (idx != size) try writer.print(":{d}", .{idx});
420422 }
421423 }
422 if (self.target.cpu.arch.isArmOrThumb())
423 try writer.writeAll("-Fi8"); // for thumb interwork
424 if (self.target.cpu.arch.isArmOrThumb()) try writer.writeAll("-Fi8") // for thumb interwork
425 else if (self.target.cpu.arch == .powerpc64 and
426 self.target.os.tag != .freebsd and self.target.abi != .musl)
427 try writer.writeAll("-Fi64")
428 else if (self.target.cpu.arch.isPPC() or self.target.cpu.arch.isPPC64())
429 try writer.writeAll("-Fn32");
424430 if (self.target.cpu.arch != .hexagon) {
425431 if (self.target.cpu.arch == .arc or self.target.cpu.arch == .s390x)
426432 try self.typeAlignment(.integer, 1, 8, 8, false, writer);
......@@ -10507,16 +10513,17 @@ fn llvmAddrSpaceInfo(target: std.Target) []const AddrSpaceInfo {
1050710513 .{ .zig = .constant, .llvm = Builder.AddrSpace.amdgpu.constant, .force_in_data_layout = true },
1050810514 .{ .zig = .local, .llvm = Builder.AddrSpace.amdgpu.private, .size = 32, .abi = 32 },
1050910515 .{ .zig = null, .llvm = Builder.AddrSpace.amdgpu.constant_32bit, .size = 32, .abi = 32 },
10510 .{ .zig = null, .llvm = Builder.AddrSpace.amdgpu.buffer_fat_pointer, .non_integral = true },
10516 .{ .zig = null, .llvm = Builder.AddrSpace.amdgpu.buffer_fat_pointer, .non_integral = true, .size = 160, .abi = 256, .idx = 32 },
10517 .{ .zig = null, .llvm = Builder.AddrSpace.amdgpu.buffer_resource, .non_integral = true, .size = 128, .abi = 128 },
1051110518 },
1051210519 .avr => &.{
1051310520 .{ .zig = .generic, .llvm = .default, .abi = 8 },
10514 .{ .zig = .flash, .llvm = Builder.AddrSpace.avr.flash, .abi = 8 },
10515 .{ .zig = .flash1, .llvm = Builder.AddrSpace.avr.flash1, .abi = 8 },
10516 .{ .zig = .flash2, .llvm = Builder.AddrSpace.avr.flash2, .abi = 8 },
10517 .{ .zig = .flash3, .llvm = Builder.AddrSpace.avr.flash3, .abi = 8 },
10518 .{ .zig = .flash4, .llvm = Builder.AddrSpace.avr.flash4, .abi = 8 },
10519 .{ .zig = .flash5, .llvm = Builder.AddrSpace.avr.flash5, .abi = 8 },
10521 .{ .zig = .flash, .llvm = Builder.AddrSpace.avr.program, .abi = 8 },
10522 .{ .zig = .flash1, .llvm = Builder.AddrSpace.avr.program1, .abi = 8 },
10523 .{ .zig = .flash2, .llvm = Builder.AddrSpace.avr.program2, .abi = 8 },
10524 .{ .zig = .flash3, .llvm = Builder.AddrSpace.avr.program3, .abi = 8 },
10525 .{ .zig = .flash4, .llvm = Builder.AddrSpace.avr.program4, .abi = 8 },
10526 .{ .zig = .flash5, .llvm = Builder.AddrSpace.avr.program5, .abi = 8 },
1052010527 },
1052110528 .wasm32, .wasm64 => &.{
1052210529 .{ .zig = .generic, .llvm = .default, .force_in_data_layout = true },
......@@ -10667,6 +10674,17 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
1066710674 return o.builder.structType(.normal, &.{ .i64, .i64 });
1066810675 },
1066910676 .byval => return o.lowerType(return_type),
10677 .fields => {
10678 var types_len: usize = 0;
10679 var types: [8]Builder.Type = undefined;
10680 for (0..return_type.structFieldCount(mod)) |field_index| {
10681 const field_ty = return_type.structFieldType(field_index, mod);
10682 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
10683 types[types_len] = try o.lowerType(field_ty);
10684 types_len += 1;
10685 }
10686 return o.builder.structType(.normal, types[0..types_len]);
10687 },
1067010688 }
1067110689 },
1067210690 // TODO investigate C ABI for other architectures
......@@ -10880,14 +10898,24 @@ const ParamTypeIterator = struct {
1088010898 .riscv32, .riscv64 => {
1088110899 it.zig_index += 1;
1088210900 it.llvm_index += 1;
10883 if (ty.toIntern() == .f16_type) {
10884 return .as_u16;
10885 }
10901 if (ty.toIntern() == .f16_type and
10902 !std.Target.riscv.featureSetHas(target.cpu.features, .d)) return .as_u16;
1088610903 switch (riscv_c_abi.classifyType(ty, mod)) {
1088710904 .memory => return .byref_mut,
1088810905 .byval => return .byval,
1088910906 .integer => return .abi_sized_int,
1089010907 .double_integer => return Lowering{ .i64_array = 2 },
10908 .fields => {
10909 it.types_len = 0;
10910 for (0..ty.structFieldCount(mod)) |field_index| {
10911 const field_ty = ty.structFieldType(field_index, mod);
10912 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
10913 it.types_buffer[it.types_len] = try it.object.lowerType(field_ty);
10914 it.types_len += 1;
10915 }
10916 it.llvm_index += it.types_len - 1;
10917 return .multiple_llvm_types;
10918 },
1089110919 }
1089210920 },
1089310921 // TODO investigate C ABI for other architectures
src/codegen/llvm/Builder.zig+12-77
......@@ -1873,12 +1873,13 @@ pub const AddrSpace = enum(u24) {
18731873
18741874 // See llvm/lib/Target/AVR/AVR.h
18751875 pub const avr = struct {
1876 pub const flash: AddrSpace = @enumFromInt(1);
1877 pub const flash1: AddrSpace = @enumFromInt(2);
1878 pub const flash2: AddrSpace = @enumFromInt(3);
1879 pub const flash3: AddrSpace = @enumFromInt(4);
1880 pub const flash4: AddrSpace = @enumFromInt(5);
1881 pub const flash5: AddrSpace = @enumFromInt(6);
1876 pub const data: AddrSpace = @enumFromInt(0);
1877 pub const program: AddrSpace = @enumFromInt(1);
1878 pub const program1: AddrSpace = @enumFromInt(2);
1879 pub const program2: AddrSpace = @enumFromInt(3);
1880 pub const program3: AddrSpace = @enumFromInt(4);
1881 pub const program4: AddrSpace = @enumFromInt(5);
1882 pub const program5: AddrSpace = @enumFromInt(6);
18821883 };
18831884
18841885 // See llvm/lib/Target/NVPTX/NVPTX.h
......@@ -1901,6 +1902,7 @@ pub const AddrSpace = enum(u24) {
19011902 pub const private: AddrSpace = @enumFromInt(5);
19021903 pub const constant_32bit: AddrSpace = @enumFromInt(6);
19031904 pub const buffer_fat_pointer: AddrSpace = @enumFromInt(7);
1905 pub const buffer_resource: AddrSpace = @enumFromInt(8);
19041906 pub const param_d: AddrSpace = @enumFromInt(6);
19051907 pub const param_i: AddrSpace = @enumFromInt(7);
19061908 pub const constant_buffer_0: AddrSpace = @enumFromInt(8);
......@@ -1921,7 +1923,7 @@ pub const AddrSpace = enum(u24) {
19211923 pub const constant_buffer_15: AddrSpace = @enumFromInt(23);
19221924 };
19231925
1924 // See llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
1926 // See llvm/include/llvm/CodeGen/WasmAddressSpaces.h
19251927 pub const wasm = struct {
19261928 pub const variable: AddrSpace = @enumFromInt(1);
19271929 pub const externref: AddrSpace = @enumFromInt(10);
......@@ -7181,7 +7183,6 @@ pub const Constant = enum(u32) {
71817183 @"and",
71827184 @"or",
71837185 xor,
7184 select,
71857186 @"asm",
71867187 @"asm sideeffect",
71877188 @"asm alignstack",
......@@ -7293,12 +7294,6 @@ pub const Constant = enum(u32) {
72937294 rhs: Constant,
72947295 };
72957296
7296 pub const Select = extern struct {
7297 cond: Constant,
7298 lhs: Constant,
7299 rhs: Constant,
7300 };
7301
73027297 pub const Assembly = extern struct {
73037298 type: Type,
73047299 assembly: String,
......@@ -7430,7 +7425,6 @@ pub const Constant = enum(u32) {
74307425 .@"or",
74317426 .xor,
74327427 => builder.constantExtraData(Binary, item.data).lhs.typeOf(builder),
7433 .select => builder.constantExtraData(Select, item.data).lhs.typeOf(builder),
74347428 .@"asm",
74357429 .@"asm sideeffect",
74367430 .@"asm alignstack",
......@@ -7820,15 +7814,6 @@ pub const Constant = enum(u32) {
78207814 extra.rhs.fmt(data.builder),
78217815 });
78227816 },
7823 .select => |tag| {
7824 const extra = data.builder.constantExtraData(Select, item.data);
7825 try writer.print("{s} ({%}, {%}, {%})", .{
7826 @tagName(tag),
7827 extra.cond.fmt(data.builder),
7828 extra.lhs.fmt(data.builder),
7829 extra.rhs.fmt(data.builder),
7830 });
7831 },
78327817 .@"asm",
78337818 .@"asm sideeffect",
78347819 .@"asm alignstack",
......@@ -9224,20 +9209,6 @@ pub fn binValue(self: *Builder, tag: Constant.Tag, lhs: Constant, rhs: Constant)
92249209 return (try self.binConst(tag, lhs, rhs)).toValue();
92259210}
92269211
9227pub fn selectConst(
9228 self: *Builder,
9229 cond: Constant,
9230 lhs: Constant,
9231 rhs: Constant,
9232) Allocator.Error!Constant {
9233 try self.ensureUnusedConstantCapacity(1, Constant.Select, 0);
9234 return self.selectConstAssumeCapacity(cond, lhs, rhs);
9235}
9236
9237pub fn selectValue(self: *Builder, cond: Constant, lhs: Constant, rhs: Constant) Allocator.Error!Value {
9238 return (try self.selectConst(cond, lhs, rhs)).toValue();
9239}
9240
92419212pub fn asmConst(
92429213 self: *Builder,
92439214 ty: Type,
......@@ -10125,7 +10096,7 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {
1012510096 .data = self.addTypeExtraAssumeCapacity(data),
1012610097 });
1012710098 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
10128 child.toLlvm(self).arrayType(@intCast(len)),
10099 child.toLlvm(self).arrayType2(len),
1012910100 );
1013010101 }
1013110102 return @enumFromInt(gop.index);
......@@ -10158,7 +10129,7 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {
1015810129 .data = self.addTypeExtraAssumeCapacity(data),
1015910130 });
1016010131 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
10161 child.toLlvm(self).arrayType(@intCast(len)),
10132 child.toLlvm(self).arrayType2(len),
1016210133 );
1016310134 }
1016410135 return @enumFromInt(gop.index);
......@@ -10823,7 +10794,7 @@ fn arrayConstAssumeCapacity(
1082310794 for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);
1082410795
1082510796 self.llvm.constants.appendAssumeCapacity(
10826 type_extra.child.toLlvm(self).constArray(llvm_vals.ptr, @intCast(llvm_vals.len)),
10797 type_extra.child.toLlvm(self).constArray2(llvm_vals.ptr, llvm_vals.len),
1082710798 );
1082810799 }
1082910800 return result.constant;
......@@ -11536,42 +11507,6 @@ fn binConstAssumeCapacity(
1153611507 return @enumFromInt(gop.index);
1153711508}
1153811509
11539comptime {
11540 _ = &selectValue;
11541}
11542
11543fn selectConstAssumeCapacity(self: *Builder, cond: Constant, lhs: Constant, rhs: Constant) Constant {
11544 const Adapter = struct {
11545 builder: *const Builder,
11546 pub fn hash(_: @This(), key: Constant.Select) u32 {
11547 return @truncate(std.hash.Wyhash.hash(
11548 std.hash.uint32(@intFromEnum(Constant.Tag.select)),
11549 std.mem.asBytes(&key),
11550 ));
11551 }
11552 pub fn eql(ctx: @This(), lhs_key: Constant.Select, _: void, rhs_index: usize) bool {
11553 if (ctx.builder.constant_items.items(.tag)[rhs_index] != .select) return false;
11554 const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
11555 const rhs_extra = ctx.builder.constantExtraData(Constant.Select, rhs_data);
11556 return std.meta.eql(lhs_key, rhs_extra);
11557 }
11558 };
11559 const data = Constant.Select{ .cond = cond, .lhs = lhs, .rhs = rhs };
11560 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
11561 if (!gop.found_existing) {
11562 gop.key_ptr.* = {};
11563 gop.value_ptr.* = {};
11564 self.constant_items.appendAssumeCapacity(.{
11565 .tag = .select,
11566 .data = self.addConstantExtraAssumeCapacity(data),
11567 });
11568 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
11569 cond.toLlvm(self).constSelect(lhs.toLlvm(self), rhs.toLlvm(self)),
11570 );
11571 }
11572 return @enumFromInt(gop.index);
11573}
11574
1157511510fn asmConstAssumeCapacity(
1157611511 self: *Builder,
1157711512 ty: Type,
src/codegen/llvm/bindings.zig+6-11
......@@ -238,13 +238,6 @@ pub const Value = opaque {
238238 pub const constAddrSpaceCast = LLVMConstAddrSpaceCast;
239239 extern fn LLVMConstAddrSpaceCast(ConstantVal: *Value, ToType: *Type) *Value;
240240
241 pub const constSelect = LLVMConstSelect;
242 extern fn LLVMConstSelect(
243 ConstantCondition: *Value,
244 ConstantIfTrue: *Value,
245 ConstantIfFalse: *Value,
246 ) *Value;
247
248241 pub const constExtractElement = LLVMConstExtractElement;
249242 extern fn LLVMConstExtractElement(VectorConstant: *Value, IndexConstant: *Value) *Value;
250243
......@@ -336,8 +329,8 @@ pub const Type = opaque {
336329 pub const constReal = LLVMConstReal;
337330 extern fn LLVMConstReal(RealTy: *Type, N: f64) *Value;
338331
339 pub const constArray = LLVMConstArray;
340 extern fn LLVMConstArray(ElementTy: *Type, ConstantVals: [*]const *Value, Length: c_uint) *Value;
332 pub const constArray2 = LLVMConstArray2;
333 extern fn LLVMConstArray2(ElementTy: *Type, ConstantVals: [*]const *Value, Length: u64) *Value;
341334
342335 pub const constNamedStruct = LLVMConstNamedStruct;
343336 extern fn LLVMConstNamedStruct(
......@@ -352,8 +345,8 @@ pub const Type = opaque {
352345 pub const getPoison = LLVMGetPoison;
353346 extern fn LLVMGetPoison(Ty: *Type) *Value;
354347
355 pub const arrayType = LLVMArrayType;
356 extern fn LLVMArrayType(ElementType: *Type, ElementCount: c_uint) *Type;
348 pub const arrayType2 = LLVMArrayType2;
349 extern fn LLVMArrayType2(ElementType: *Type, ElementCount: u64) *Type;
357350
358351 pub const vectorType = LLVMVectorType;
359352 extern fn LLVMVectorType(ElementType: *Type, ElementCount: c_uint) *Type;
......@@ -1167,6 +1160,7 @@ pub const OSType = enum(c_int) {
11671160 NetBSD,
11681161 OpenBSD,
11691162 Solaris,
1163 UEFI,
11701164 Win32,
11711165 ZOS,
11721166 Haiku,
......@@ -1191,6 +1185,7 @@ pub const OSType = enum(c_int) {
11911185 WASI,
11921186 Emscripten,
11931187 ShaderModel,
1188 LiteOS,
11941189};
11951190
11961191pub const ArchType = enum(c_int) {
src/libcxx.zig+17-4
......@@ -46,15 +46,17 @@ const libcxx_files = [_][]const u8{
4646 "src/chrono.cpp",
4747 "src/condition_variable.cpp",
4848 "src/condition_variable_destructor.cpp",
49 "src/debug.cpp",
5049 "src/exception.cpp",
5150 "src/experimental/memory_resource.cpp",
51 "src/filesystem/directory_entry.cpp",
5252 "src/filesystem/directory_iterator.cpp",
53 "src/filesystem/filesystem_clock.cpp",
54 "src/filesystem/filesystem_error.cpp",
5355 // omit int128_builtins.cpp because it provides __muloti4 which is already provided
5456 // by compiler_rt and crashes on Windows x86_64: https://github.com/ziglang/zig/issues/10719
5557 //"src/filesystem/int128_builtins.cpp",
5658 "src/filesystem/operations.cpp",
57 "src/format.cpp",
59 "src/filesystem/path.cpp",
5860 "src/functional.cpp",
5961 "src/future.cpp",
6062 "src/hash.cpp",
......@@ -65,10 +67,14 @@ const libcxx_files = [_][]const u8{
6567 "src/legacy_pointer_safety.cpp",
6668 "src/locale.cpp",
6769 "src/memory.cpp",
70 "src/memory_resource.cpp",
6871 "src/mutex.cpp",
6972 "src/mutex_destructor.cpp",
7073 "src/new.cpp",
74 "src/new_handler.cpp",
75 "src/new_helpers.cpp",
7176 "src/optional.cpp",
77 "src/print.cpp",
7278 "src/random.cpp",
7379 "src/random_shuffle.cpp",
7480 "src/regex.cpp",
......@@ -82,14 +88,12 @@ const libcxx_files = [_][]const u8{
8288 "src/support/ibm/mbsnrtowcs.cpp",
8389 "src/support/ibm/wcsnrtombs.cpp",
8490 "src/support/ibm/xlocale_zos.cpp",
85 "src/support/solaris/xlocale.cpp",
8691 "src/support/win32/locale_win32.cpp",
8792 "src/support/win32/support.cpp",
8893 "src/support/win32/thread_win32.cpp",
8994 "src/system_error.cpp",
9095 "src/thread.cpp",
9196 "src/typeinfo.cpp",
92 "src/utility.cpp",
9397 "src/valarray.cpp",
9498 "src/variant.cpp",
9599 "src/vector.cpp",
......@@ -166,6 +170,13 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void {
166170 try cflags.append("-D_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS");
167171 try cflags.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS");
168172
173 // See libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h
174 // for potentially enabling some fancy features here, which would
175 // require corresponding changes in libcxx.zig, as well as
176 // Compilation.addCCArgs. This option makes it use serial backend which
177 // is simple and works everywhere.
178 try cflags.append("-D_LIBCPP_PSTL_CPU_BACKEND_SERIAL");
179
169180 try cflags.append(abi_version_arg);
170181 try cflags.append(abi_namespace_arg);
171182
......@@ -336,6 +347,8 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void {
336347 try cflags.append("-D_LIBCXXABI_BUILDING_LIBRARY");
337348 try cflags.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
338349 try cflags.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS");
350 // This must be coordinated with the same flag in libcxx
351 try cflags.append("-D_LIBCPP_PSTL_CPU_BACKEND_SERIAL");
339352
340353 try cflags.append(abi_version_arg);
341354 try cflags.append(abi_namespace_arg);
src/zig_clang.cpp+488-9
......@@ -1134,10 +1134,10 @@ void ZigClang_detect_enum_BuiltinTypeKind(clang::BuiltinType::Kind x) {
11341134 case clang::BuiltinType::OCLIntelSubgroupAVCImeResult:
11351135 case clang::BuiltinType::OCLIntelSubgroupAVCRefResult:
11361136 case clang::BuiltinType::OCLIntelSubgroupAVCSicResult:
1137 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout:
1138 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout:
1139 case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin:
1140 case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin:
1137 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleReferenceStreamout:
1138 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualReferenceStreamout:
1139 case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleReferenceStreamin:
1140 case clang::BuiltinType::OCLIntelSubgroupAVCImeDualReferenceStreamin:
11411141 case clang::BuiltinType::SveInt8:
11421142 case clang::BuiltinType::SveInt16:
11431143 case clang::BuiltinType::SveInt32:
......@@ -1187,6 +1187,9 @@ void ZigClang_detect_enum_BuiltinTypeKind(clang::BuiltinType::Kind x) {
11871187 case clang::BuiltinType::SveFloat64x4:
11881188 case clang::BuiltinType::SveBFloat16x4:
11891189 case clang::BuiltinType::SveBool:
1190 case clang::BuiltinType::SveBoolx2:
1191 case clang::BuiltinType::SveBoolx4:
1192 case clang::BuiltinType::SveCount:
11901193 case clang::BuiltinType::VectorQuad:
11911194 case clang::BuiltinType::VectorPair:
11921195 case clang::BuiltinType::RvvInt8mf8:
......@@ -1255,6 +1258,233 @@ void ZigClang_detect_enum_BuiltinTypeKind(clang::BuiltinType::Kind x) {
12551258 case clang::BuiltinType::RvvBool16:
12561259 case clang::BuiltinType::RvvBool32:
12571260 case clang::BuiltinType::RvvBool64:
1261 case clang::BuiltinType::RvvInt8mf8x2:
1262 case clang::BuiltinType::RvvInt8mf8x3:
1263 case clang::BuiltinType::RvvInt8mf8x4:
1264 case clang::BuiltinType::RvvInt8mf8x5:
1265 case clang::BuiltinType::RvvInt8mf8x6:
1266 case clang::BuiltinType::RvvInt8mf8x7:
1267 case clang::BuiltinType::RvvInt8mf8x8:
1268 case clang::BuiltinType::RvvInt8mf4x2:
1269 case clang::BuiltinType::RvvInt8mf4x3:
1270 case clang::BuiltinType::RvvInt8mf4x4:
1271 case clang::BuiltinType::RvvInt8mf4x5:
1272 case clang::BuiltinType::RvvInt8mf4x6:
1273 case clang::BuiltinType::RvvInt8mf4x7:
1274 case clang::BuiltinType::RvvInt8mf4x8:
1275 case clang::BuiltinType::RvvInt8mf2x2:
1276 case clang::BuiltinType::RvvInt8mf2x3:
1277 case clang::BuiltinType::RvvInt8mf2x4:
1278 case clang::BuiltinType::RvvInt8mf2x5:
1279 case clang::BuiltinType::RvvInt8mf2x6:
1280 case clang::BuiltinType::RvvInt8mf2x7:
1281 case clang::BuiltinType::RvvInt8mf2x8:
1282 case clang::BuiltinType::RvvInt8m1x2:
1283 case clang::BuiltinType::RvvInt8m1x3:
1284 case clang::BuiltinType::RvvInt8m1x4:
1285 case clang::BuiltinType::RvvInt8m1x5:
1286 case clang::BuiltinType::RvvInt8m1x6:
1287 case clang::BuiltinType::RvvInt8m1x7:
1288 case clang::BuiltinType::RvvInt8m1x8:
1289 case clang::BuiltinType::RvvInt8m2x2:
1290 case clang::BuiltinType::RvvInt8m2x3:
1291 case clang::BuiltinType::RvvInt8m2x4:
1292 case clang::BuiltinType::RvvInt8m4x2:
1293 case clang::BuiltinType::RvvUint8mf8x2:
1294 case clang::BuiltinType::RvvUint8mf8x3:
1295 case clang::BuiltinType::RvvUint8mf8x4:
1296 case clang::BuiltinType::RvvUint8mf8x5:
1297 case clang::BuiltinType::RvvUint8mf8x6:
1298 case clang::BuiltinType::RvvUint8mf8x7:
1299 case clang::BuiltinType::RvvUint8mf8x8:
1300 case clang::BuiltinType::RvvUint8mf4x2:
1301 case clang::BuiltinType::RvvUint8mf4x3:
1302 case clang::BuiltinType::RvvUint8mf4x4:
1303 case clang::BuiltinType::RvvUint8mf4x5:
1304 case clang::BuiltinType::RvvUint8mf4x6:
1305 case clang::BuiltinType::RvvUint8mf4x7:
1306 case clang::BuiltinType::RvvUint8mf4x8:
1307 case clang::BuiltinType::RvvUint8mf2x2:
1308 case clang::BuiltinType::RvvUint8mf2x3:
1309 case clang::BuiltinType::RvvUint8mf2x4:
1310 case clang::BuiltinType::RvvUint8mf2x5:
1311 case clang::BuiltinType::RvvUint8mf2x6:
1312 case clang::BuiltinType::RvvUint8mf2x7:
1313 case clang::BuiltinType::RvvUint8mf2x8:
1314 case clang::BuiltinType::RvvUint8m1x2:
1315 case clang::BuiltinType::RvvUint8m1x3:
1316 case clang::BuiltinType::RvvUint8m1x4:
1317 case clang::BuiltinType::RvvUint8m1x5:
1318 case clang::BuiltinType::RvvUint8m1x6:
1319 case clang::BuiltinType::RvvUint8m1x7:
1320 case clang::BuiltinType::RvvUint8m1x8:
1321 case clang::BuiltinType::RvvUint8m2x2:
1322 case clang::BuiltinType::RvvUint8m2x3:
1323 case clang::BuiltinType::RvvUint8m2x4:
1324 case clang::BuiltinType::RvvUint8m4x2:
1325 case clang::BuiltinType::RvvInt16mf4x2:
1326 case clang::BuiltinType::RvvInt16mf4x3:
1327 case clang::BuiltinType::RvvInt16mf4x4:
1328 case clang::BuiltinType::RvvInt16mf4x5:
1329 case clang::BuiltinType::RvvInt16mf4x6:
1330 case clang::BuiltinType::RvvInt16mf4x7:
1331 case clang::BuiltinType::RvvInt16mf4x8:
1332 case clang::BuiltinType::RvvInt16mf2x2:
1333 case clang::BuiltinType::RvvInt16mf2x3:
1334 case clang::BuiltinType::RvvInt16mf2x4:
1335 case clang::BuiltinType::RvvInt16mf2x5:
1336 case clang::BuiltinType::RvvInt16mf2x6:
1337 case clang::BuiltinType::RvvInt16mf2x7:
1338 case clang::BuiltinType::RvvInt16mf2x8:
1339 case clang::BuiltinType::RvvInt16m1x2:
1340 case clang::BuiltinType::RvvInt16m1x3:
1341 case clang::BuiltinType::RvvInt16m1x4:
1342 case clang::BuiltinType::RvvInt16m1x5:
1343 case clang::BuiltinType::RvvInt16m1x6:
1344 case clang::BuiltinType::RvvInt16m1x7:
1345 case clang::BuiltinType::RvvInt16m1x8:
1346 case clang::BuiltinType::RvvInt16m2x2:
1347 case clang::BuiltinType::RvvInt16m2x3:
1348 case clang::BuiltinType::RvvInt16m2x4:
1349 case clang::BuiltinType::RvvInt16m4x2:
1350 case clang::BuiltinType::RvvUint16mf4x2:
1351 case clang::BuiltinType::RvvUint16mf4x3:
1352 case clang::BuiltinType::RvvUint16mf4x4:
1353 case clang::BuiltinType::RvvUint16mf4x5:
1354 case clang::BuiltinType::RvvUint16mf4x6:
1355 case clang::BuiltinType::RvvUint16mf4x7:
1356 case clang::BuiltinType::RvvUint16mf4x8:
1357 case clang::BuiltinType::RvvUint16mf2x2:
1358 case clang::BuiltinType::RvvUint16mf2x3:
1359 case clang::BuiltinType::RvvUint16mf2x4:
1360 case clang::BuiltinType::RvvUint16mf2x5:
1361 case clang::BuiltinType::RvvUint16mf2x6:
1362 case clang::BuiltinType::RvvUint16mf2x7:
1363 case clang::BuiltinType::RvvUint16mf2x8:
1364 case clang::BuiltinType::RvvUint16m1x2:
1365 case clang::BuiltinType::RvvUint16m1x3:
1366 case clang::BuiltinType::RvvUint16m1x4:
1367 case clang::BuiltinType::RvvUint16m1x5:
1368 case clang::BuiltinType::RvvUint16m1x6:
1369 case clang::BuiltinType::RvvUint16m1x7:
1370 case clang::BuiltinType::RvvUint16m1x8:
1371 case clang::BuiltinType::RvvUint16m2x2:
1372 case clang::BuiltinType::RvvUint16m2x3:
1373 case clang::BuiltinType::RvvUint16m2x4:
1374 case clang::BuiltinType::RvvUint16m4x2:
1375 case clang::BuiltinType::RvvInt32mf2x2:
1376 case clang::BuiltinType::RvvInt32mf2x3:
1377 case clang::BuiltinType::RvvInt32mf2x4:
1378 case clang::BuiltinType::RvvInt32mf2x5:
1379 case clang::BuiltinType::RvvInt32mf2x6:
1380 case clang::BuiltinType::RvvInt32mf2x7:
1381 case clang::BuiltinType::RvvInt32mf2x8:
1382 case clang::BuiltinType::RvvInt32m1x2:
1383 case clang::BuiltinType::RvvInt32m1x3:
1384 case clang::BuiltinType::RvvInt32m1x4:
1385 case clang::BuiltinType::RvvInt32m1x5:
1386 case clang::BuiltinType::RvvInt32m1x6:
1387 case clang::BuiltinType::RvvInt32m1x7:
1388 case clang::BuiltinType::RvvInt32m1x8:
1389 case clang::BuiltinType::RvvInt32m2x2:
1390 case clang::BuiltinType::RvvInt32m2x3:
1391 case clang::BuiltinType::RvvInt32m2x4:
1392 case clang::BuiltinType::RvvInt32m4x2:
1393 case clang::BuiltinType::RvvUint32mf2x2:
1394 case clang::BuiltinType::RvvUint32mf2x3:
1395 case clang::BuiltinType::RvvUint32mf2x4:
1396 case clang::BuiltinType::RvvUint32mf2x5:
1397 case clang::BuiltinType::RvvUint32mf2x6:
1398 case clang::BuiltinType::RvvUint32mf2x7:
1399 case clang::BuiltinType::RvvUint32mf2x8:
1400 case clang::BuiltinType::RvvUint32m1x2:
1401 case clang::BuiltinType::RvvUint32m1x3:
1402 case clang::BuiltinType::RvvUint32m1x4:
1403 case clang::BuiltinType::RvvUint32m1x5:
1404 case clang::BuiltinType::RvvUint32m1x6:
1405 case clang::BuiltinType::RvvUint32m1x7:
1406 case clang::BuiltinType::RvvUint32m1x8:
1407 case clang::BuiltinType::RvvUint32m2x2:
1408 case clang::BuiltinType::RvvUint32m2x3:
1409 case clang::BuiltinType::RvvUint32m2x4:
1410 case clang::BuiltinType::RvvUint32m4x2:
1411 case clang::BuiltinType::RvvInt64m1x2:
1412 case clang::BuiltinType::RvvInt64m1x3:
1413 case clang::BuiltinType::RvvInt64m1x4:
1414 case clang::BuiltinType::RvvInt64m1x5:
1415 case clang::BuiltinType::RvvInt64m1x6:
1416 case clang::BuiltinType::RvvInt64m1x7:
1417 case clang::BuiltinType::RvvInt64m1x8:
1418 case clang::BuiltinType::RvvInt64m2x2:
1419 case clang::BuiltinType::RvvInt64m2x3:
1420 case clang::BuiltinType::RvvInt64m2x4:
1421 case clang::BuiltinType::RvvInt64m4x2:
1422 case clang::BuiltinType::RvvUint64m1x2:
1423 case clang::BuiltinType::RvvUint64m1x3:
1424 case clang::BuiltinType::RvvUint64m1x4:
1425 case clang::BuiltinType::RvvUint64m1x5:
1426 case clang::BuiltinType::RvvUint64m1x6:
1427 case clang::BuiltinType::RvvUint64m1x7:
1428 case clang::BuiltinType::RvvUint64m1x8:
1429 case clang::BuiltinType::RvvUint64m2x2:
1430 case clang::BuiltinType::RvvUint64m2x3:
1431 case clang::BuiltinType::RvvUint64m2x4:
1432 case clang::BuiltinType::RvvUint64m4x2:
1433 case clang::BuiltinType::RvvFloat16mf4x2:
1434 case clang::BuiltinType::RvvFloat16mf4x3:
1435 case clang::BuiltinType::RvvFloat16mf4x4:
1436 case clang::BuiltinType::RvvFloat16mf4x5:
1437 case clang::BuiltinType::RvvFloat16mf4x6:
1438 case clang::BuiltinType::RvvFloat16mf4x7:
1439 case clang::BuiltinType::RvvFloat16mf4x8:
1440 case clang::BuiltinType::RvvFloat16mf2x2:
1441 case clang::BuiltinType::RvvFloat16mf2x3:
1442 case clang::BuiltinType::RvvFloat16mf2x4:
1443 case clang::BuiltinType::RvvFloat16mf2x5:
1444 case clang::BuiltinType::RvvFloat16mf2x6:
1445 case clang::BuiltinType::RvvFloat16mf2x7:
1446 case clang::BuiltinType::RvvFloat16mf2x8:
1447 case clang::BuiltinType::RvvFloat16m1x2:
1448 case clang::BuiltinType::RvvFloat16m1x3:
1449 case clang::BuiltinType::RvvFloat16m1x4:
1450 case clang::BuiltinType::RvvFloat16m1x5:
1451 case clang::BuiltinType::RvvFloat16m1x6:
1452 case clang::BuiltinType::RvvFloat16m1x7:
1453 case clang::BuiltinType::RvvFloat16m1x8:
1454 case clang::BuiltinType::RvvFloat16m2x2:
1455 case clang::BuiltinType::RvvFloat16m2x3:
1456 case clang::BuiltinType::RvvFloat16m2x4:
1457 case clang::BuiltinType::RvvFloat16m4x2:
1458 case clang::BuiltinType::RvvFloat32mf2x2:
1459 case clang::BuiltinType::RvvFloat32mf2x3:
1460 case clang::BuiltinType::RvvFloat32mf2x4:
1461 case clang::BuiltinType::RvvFloat32mf2x5:
1462 case clang::BuiltinType::RvvFloat32mf2x6:
1463 case clang::BuiltinType::RvvFloat32mf2x7:
1464 case clang::BuiltinType::RvvFloat32mf2x8:
1465 case clang::BuiltinType::RvvFloat32m1x2:
1466 case clang::BuiltinType::RvvFloat32m1x3:
1467 case clang::BuiltinType::RvvFloat32m1x4:
1468 case clang::BuiltinType::RvvFloat32m1x5:
1469 case clang::BuiltinType::RvvFloat32m1x6:
1470 case clang::BuiltinType::RvvFloat32m1x7:
1471 case clang::BuiltinType::RvvFloat32m1x8:
1472 case clang::BuiltinType::RvvFloat32m2x2:
1473 case clang::BuiltinType::RvvFloat32m2x3:
1474 case clang::BuiltinType::RvvFloat32m2x4:
1475 case clang::BuiltinType::RvvFloat32m4x2:
1476 case clang::BuiltinType::RvvFloat64m1x2:
1477 case clang::BuiltinType::RvvFloat64m1x3:
1478 case clang::BuiltinType::RvvFloat64m1x4:
1479 case clang::BuiltinType::RvvFloat64m1x5:
1480 case clang::BuiltinType::RvvFloat64m1x6:
1481 case clang::BuiltinType::RvvFloat64m1x7:
1482 case clang::BuiltinType::RvvFloat64m1x8:
1483 case clang::BuiltinType::RvvFloat64m2x2:
1484 case clang::BuiltinType::RvvFloat64m2x3:
1485 case clang::BuiltinType::RvvFloat64m2x4:
1486 case clang::BuiltinType::RvvFloat64m4x2:
1487 case clang::BuiltinType::WasmExternRef:
12581488 case clang::BuiltinType::Void:
12591489 case clang::BuiltinType::Bool:
12601490 case clang::BuiltinType::Char_U:
......@@ -1376,10 +1606,10 @@ static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCMc
13761606static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResult == clang::BuiltinType::OCLIntelSubgroupAVCImeResult, "");
13771607static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCRefResult == clang::BuiltinType::OCLIntelSubgroupAVCRefResult, "");
13781608static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCSicResult == clang::BuiltinType::OCLIntelSubgroupAVCSicResult, "");
1379static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultSingleRefStreamout == clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout, "");
1380static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultDualRefStreamout == clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout, "");
1381static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeSingleRefStreamin == clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin, "");
1382static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeDualRefStreamin == clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin, "");
1609static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultSingleReferenceStreamout == clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleReferenceStreamout, "");
1610static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultDualReferenceStreamout == clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualReferenceStreamout, "");
1611static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeSingleReferenceStreamin == clang::BuiltinType::OCLIntelSubgroupAVCImeSingleReferenceStreamin, "");
1612static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeDualReferenceStreamin == clang::BuiltinType::OCLIntelSubgroupAVCImeDualReferenceStreamin, "");
13831613static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSveInt8 == clang::BuiltinType::SveInt8, "");
13841614static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSveInt16 == clang::BuiltinType::SveInt16, "");
13851615static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSveInt32 == clang::BuiltinType::SveInt32, "");
......@@ -1429,6 +1659,9 @@ static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSveFloat32x4 == clang
14291659static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSveFloat64x4 == clang::BuiltinType::SveFloat64x4, "");
14301660static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSveBFloat16x4 == clang::BuiltinType::SveBFloat16x4, "");
14311661static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSveBool == clang::BuiltinType::SveBool, "");
1662static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSveBoolx2 == clang::BuiltinType::SveBoolx2, "");
1663static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSveBoolx4 == clang::BuiltinType::SveBoolx4, "");
1664static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSveCount == clang::BuiltinType::SveCount, "");
14321665static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeVectorQuad == clang::BuiltinType::VectorQuad, "");
14331666static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeVectorPair == clang::BuiltinType::VectorPair, "");
14341667static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf8 == clang::BuiltinType::RvvInt8mf8, "");
......@@ -1497,6 +1730,233 @@ static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvBool8 == clang::Bu
14971730static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvBool16 == clang::BuiltinType::RvvBool16, "");
14981731static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvBool32 == clang::BuiltinType::RvvBool32, "");
14991732static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvBool64 == clang::BuiltinType::RvvBool64, "");
1733static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf8x2 == clang::BuiltinType::RvvInt8mf8x2, "");
1734static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf8x3 == clang::BuiltinType::RvvInt8mf8x3, "");
1735static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf8x4 == clang::BuiltinType::RvvInt8mf8x4, "");
1736static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf8x5 == clang::BuiltinType::RvvInt8mf8x5, "");
1737static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf8x6 == clang::BuiltinType::RvvInt8mf8x6, "");
1738static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf8x7 == clang::BuiltinType::RvvInt8mf8x7, "");
1739static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf8x8 == clang::BuiltinType::RvvInt8mf8x8, "");
1740static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf4x2 == clang::BuiltinType::RvvInt8mf4x2, "");
1741static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf4x3 == clang::BuiltinType::RvvInt8mf4x3, "");
1742static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf4x4 == clang::BuiltinType::RvvInt8mf4x4, "");
1743static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf4x5 == clang::BuiltinType::RvvInt8mf4x5, "");
1744static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf4x6 == clang::BuiltinType::RvvInt8mf4x6, "");
1745static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf4x7 == clang::BuiltinType::RvvInt8mf4x7, "");
1746static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf4x8 == clang::BuiltinType::RvvInt8mf4x8, "");
1747static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf2x2 == clang::BuiltinType::RvvInt8mf2x2, "");
1748static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf2x3 == clang::BuiltinType::RvvInt8mf2x3, "");
1749static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf2x4 == clang::BuiltinType::RvvInt8mf2x4, "");
1750static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf2x5 == clang::BuiltinType::RvvInt8mf2x5, "");
1751static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf2x6 == clang::BuiltinType::RvvInt8mf2x6, "");
1752static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf2x7 == clang::BuiltinType::RvvInt8mf2x7, "");
1753static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8mf2x8 == clang::BuiltinType::RvvInt8mf2x8, "");
1754static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8m1x2 == clang::BuiltinType::RvvInt8m1x2, "");
1755static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8m1x3 == clang::BuiltinType::RvvInt8m1x3, "");
1756static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8m1x4 == clang::BuiltinType::RvvInt8m1x4, "");
1757static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8m1x5 == clang::BuiltinType::RvvInt8m1x5, "");
1758static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8m1x6 == clang::BuiltinType::RvvInt8m1x6, "");
1759static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8m1x7 == clang::BuiltinType::RvvInt8m1x7, "");
1760static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8m1x8 == clang::BuiltinType::RvvInt8m1x8, "");
1761static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8m2x2 == clang::BuiltinType::RvvInt8m2x2, "");
1762static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8m2x3 == clang::BuiltinType::RvvInt8m2x3, "");
1763static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8m2x4 == clang::BuiltinType::RvvInt8m2x4, "");
1764static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt8m4x2 == clang::BuiltinType::RvvInt8m4x2, "");
1765static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf8x2 == clang::BuiltinType::RvvUint8mf8x2, "");
1766static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf8x3 == clang::BuiltinType::RvvUint8mf8x3, "");
1767static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf8x4 == clang::BuiltinType::RvvUint8mf8x4, "");
1768static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf8x5 == clang::BuiltinType::RvvUint8mf8x5, "");
1769static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf8x6 == clang::BuiltinType::RvvUint8mf8x6, "");
1770static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf8x7 == clang::BuiltinType::RvvUint8mf8x7, "");
1771static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf8x8 == clang::BuiltinType::RvvUint8mf8x8, "");
1772static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf4x2 == clang::BuiltinType::RvvUint8mf4x2, "");
1773static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf4x3 == clang::BuiltinType::RvvUint8mf4x3, "");
1774static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf4x4 == clang::BuiltinType::RvvUint8mf4x4, "");
1775static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf4x5 == clang::BuiltinType::RvvUint8mf4x5, "");
1776static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf4x6 == clang::BuiltinType::RvvUint8mf4x6, "");
1777static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf4x7 == clang::BuiltinType::RvvUint8mf4x7, "");
1778static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf4x8 == clang::BuiltinType::RvvUint8mf4x8, "");
1779static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf2x2 == clang::BuiltinType::RvvUint8mf2x2, "");
1780static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf2x3 == clang::BuiltinType::RvvUint8mf2x3, "");
1781static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf2x4 == clang::BuiltinType::RvvUint8mf2x4, "");
1782static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf2x5 == clang::BuiltinType::RvvUint8mf2x5, "");
1783static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf2x6 == clang::BuiltinType::RvvUint8mf2x6, "");
1784static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf2x7 == clang::BuiltinType::RvvUint8mf2x7, "");
1785static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8mf2x8 == clang::BuiltinType::RvvUint8mf2x8, "");
1786static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8m1x2 == clang::BuiltinType::RvvUint8m1x2, "");
1787static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8m1x3 == clang::BuiltinType::RvvUint8m1x3, "");
1788static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8m1x4 == clang::BuiltinType::RvvUint8m1x4, "");
1789static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8m1x5 == clang::BuiltinType::RvvUint8m1x5, "");
1790static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8m1x6 == clang::BuiltinType::RvvUint8m1x6, "");
1791static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8m1x7 == clang::BuiltinType::RvvUint8m1x7, "");
1792static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8m1x8 == clang::BuiltinType::RvvUint8m1x8, "");
1793static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8m2x2 == clang::BuiltinType::RvvUint8m2x2, "");
1794static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8m2x3 == clang::BuiltinType::RvvUint8m2x3, "");
1795static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8m2x4 == clang::BuiltinType::RvvUint8m2x4, "");
1796static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint8m4x2 == clang::BuiltinType::RvvUint8m4x2, "");
1797static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf4x2 == clang::BuiltinType::RvvInt16mf4x2, "");
1798static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf4x3 == clang::BuiltinType::RvvInt16mf4x3, "");
1799static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf4x4 == clang::BuiltinType::RvvInt16mf4x4, "");
1800static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf4x5 == clang::BuiltinType::RvvInt16mf4x5, "");
1801static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf4x6 == clang::BuiltinType::RvvInt16mf4x6, "");
1802static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf4x7 == clang::BuiltinType::RvvInt16mf4x7, "");
1803static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf4x8 == clang::BuiltinType::RvvInt16mf4x8, "");
1804static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf2x2 == clang::BuiltinType::RvvInt16mf2x2, "");
1805static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf2x3 == clang::BuiltinType::RvvInt16mf2x3, "");
1806static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf2x4 == clang::BuiltinType::RvvInt16mf2x4, "");
1807static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf2x5 == clang::BuiltinType::RvvInt16mf2x5, "");
1808static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf2x6 == clang::BuiltinType::RvvInt16mf2x6, "");
1809static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf2x7 == clang::BuiltinType::RvvInt16mf2x7, "");
1810static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16mf2x8 == clang::BuiltinType::RvvInt16mf2x8, "");
1811static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16m1x2 == clang::BuiltinType::RvvInt16m1x2, "");
1812static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16m1x3 == clang::BuiltinType::RvvInt16m1x3, "");
1813static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16m1x4 == clang::BuiltinType::RvvInt16m1x4, "");
1814static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16m1x5 == clang::BuiltinType::RvvInt16m1x5, "");
1815static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16m1x6 == clang::BuiltinType::RvvInt16m1x6, "");
1816static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16m1x7 == clang::BuiltinType::RvvInt16m1x7, "");
1817static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16m1x8 == clang::BuiltinType::RvvInt16m1x8, "");
1818static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16m2x2 == clang::BuiltinType::RvvInt16m2x2, "");
1819static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16m2x3 == clang::BuiltinType::RvvInt16m2x3, "");
1820static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16m2x4 == clang::BuiltinType::RvvInt16m2x4, "");
1821static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt16m4x2 == clang::BuiltinType::RvvInt16m4x2, "");
1822static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf4x2 == clang::BuiltinType::RvvUint16mf4x2, "");
1823static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf4x3 == clang::BuiltinType::RvvUint16mf4x3, "");
1824static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf4x4 == clang::BuiltinType::RvvUint16mf4x4, "");
1825static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf4x5 == clang::BuiltinType::RvvUint16mf4x5, "");
1826static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf4x6 == clang::BuiltinType::RvvUint16mf4x6, "");
1827static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf4x7 == clang::BuiltinType::RvvUint16mf4x7, "");
1828static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf4x8 == clang::BuiltinType::RvvUint16mf4x8, "");
1829static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf2x2 == clang::BuiltinType::RvvUint16mf2x2, "");
1830static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf2x3 == clang::BuiltinType::RvvUint16mf2x3, "");
1831static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf2x4 == clang::BuiltinType::RvvUint16mf2x4, "");
1832static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf2x5 == clang::BuiltinType::RvvUint16mf2x5, "");
1833static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf2x6 == clang::BuiltinType::RvvUint16mf2x6, "");
1834static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf2x7 == clang::BuiltinType::RvvUint16mf2x7, "");
1835static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16mf2x8 == clang::BuiltinType::RvvUint16mf2x8, "");
1836static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16m1x2 == clang::BuiltinType::RvvUint16m1x2, "");
1837static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16m1x3 == clang::BuiltinType::RvvUint16m1x3, "");
1838static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16m1x4 == clang::BuiltinType::RvvUint16m1x4, "");
1839static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16m1x5 == clang::BuiltinType::RvvUint16m1x5, "");
1840static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16m1x6 == clang::BuiltinType::RvvUint16m1x6, "");
1841static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16m1x7 == clang::BuiltinType::RvvUint16m1x7, "");
1842static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16m1x8 == clang::BuiltinType::RvvUint16m1x8, "");
1843static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16m2x2 == clang::BuiltinType::RvvUint16m2x2, "");
1844static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16m2x3 == clang::BuiltinType::RvvUint16m2x3, "");
1845static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16m2x4 == clang::BuiltinType::RvvUint16m2x4, "");
1846static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint16m4x2 == clang::BuiltinType::RvvUint16m4x2, "");
1847static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32mf2x2 == clang::BuiltinType::RvvInt32mf2x2, "");
1848static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32mf2x3 == clang::BuiltinType::RvvInt32mf2x3, "");
1849static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32mf2x4 == clang::BuiltinType::RvvInt32mf2x4, "");
1850static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32mf2x5 == clang::BuiltinType::RvvInt32mf2x5, "");
1851static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32mf2x6 == clang::BuiltinType::RvvInt32mf2x6, "");
1852static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32mf2x7 == clang::BuiltinType::RvvInt32mf2x7, "");
1853static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32mf2x8 == clang::BuiltinType::RvvInt32mf2x8, "");
1854static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32m1x2 == clang::BuiltinType::RvvInt32m1x2, "");
1855static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32m1x3 == clang::BuiltinType::RvvInt32m1x3, "");
1856static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32m1x4 == clang::BuiltinType::RvvInt32m1x4, "");
1857static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32m1x5 == clang::BuiltinType::RvvInt32m1x5, "");
1858static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32m1x6 == clang::BuiltinType::RvvInt32m1x6, "");
1859static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32m1x7 == clang::BuiltinType::RvvInt32m1x7, "");
1860static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32m1x8 == clang::BuiltinType::RvvInt32m1x8, "");
1861static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32m2x2 == clang::BuiltinType::RvvInt32m2x2, "");
1862static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32m2x3 == clang::BuiltinType::RvvInt32m2x3, "");
1863static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32m2x4 == clang::BuiltinType::RvvInt32m2x4, "");
1864static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt32m4x2 == clang::BuiltinType::RvvInt32m4x2, "");
1865static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32mf2x2 == clang::BuiltinType::RvvUint32mf2x2, "");
1866static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32mf2x3 == clang::BuiltinType::RvvUint32mf2x3, "");
1867static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32mf2x4 == clang::BuiltinType::RvvUint32mf2x4, "");
1868static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32mf2x5 == clang::BuiltinType::RvvUint32mf2x5, "");
1869static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32mf2x6 == clang::BuiltinType::RvvUint32mf2x6, "");
1870static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32mf2x7 == clang::BuiltinType::RvvUint32mf2x7, "");
1871static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32mf2x8 == clang::BuiltinType::RvvUint32mf2x8, "");
1872static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32m1x2 == clang::BuiltinType::RvvUint32m1x2, "");
1873static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32m1x3 == clang::BuiltinType::RvvUint32m1x3, "");
1874static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32m1x4 == clang::BuiltinType::RvvUint32m1x4, "");
1875static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32m1x5 == clang::BuiltinType::RvvUint32m1x5, "");
1876static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32m1x6 == clang::BuiltinType::RvvUint32m1x6, "");
1877static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32m1x7 == clang::BuiltinType::RvvUint32m1x7, "");
1878static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32m1x8 == clang::BuiltinType::RvvUint32m1x8, "");
1879static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32m2x2 == clang::BuiltinType::RvvUint32m2x2, "");
1880static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32m2x3 == clang::BuiltinType::RvvUint32m2x3, "");
1881static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32m2x4 == clang::BuiltinType::RvvUint32m2x4, "");
1882static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint32m4x2 == clang::BuiltinType::RvvUint32m4x2, "");
1883static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt64m1x2 == clang::BuiltinType::RvvInt64m1x2, "");
1884static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt64m1x3 == clang::BuiltinType::RvvInt64m1x3, "");
1885static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt64m1x4 == clang::BuiltinType::RvvInt64m1x4, "");
1886static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt64m1x5 == clang::BuiltinType::RvvInt64m1x5, "");
1887static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt64m1x6 == clang::BuiltinType::RvvInt64m1x6, "");
1888static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt64m1x7 == clang::BuiltinType::RvvInt64m1x7, "");
1889static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt64m1x8 == clang::BuiltinType::RvvInt64m1x8, "");
1890static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt64m2x2 == clang::BuiltinType::RvvInt64m2x2, "");
1891static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt64m2x3 == clang::BuiltinType::RvvInt64m2x3, "");
1892static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt64m2x4 == clang::BuiltinType::RvvInt64m2x4, "");
1893static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvInt64m4x2 == clang::BuiltinType::RvvInt64m4x2, "");
1894static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint64m1x2 == clang::BuiltinType::RvvUint64m1x2, "");
1895static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint64m1x3 == clang::BuiltinType::RvvUint64m1x3, "");
1896static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint64m1x4 == clang::BuiltinType::RvvUint64m1x4, "");
1897static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint64m1x5 == clang::BuiltinType::RvvUint64m1x5, "");
1898static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint64m1x6 == clang::BuiltinType::RvvUint64m1x6, "");
1899static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint64m1x7 == clang::BuiltinType::RvvUint64m1x7, "");
1900static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint64m1x8 == clang::BuiltinType::RvvUint64m1x8, "");
1901static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint64m2x2 == clang::BuiltinType::RvvUint64m2x2, "");
1902static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint64m2x3 == clang::BuiltinType::RvvUint64m2x3, "");
1903static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint64m2x4 == clang::BuiltinType::RvvUint64m2x4, "");
1904static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvUint64m4x2 == clang::BuiltinType::RvvUint64m4x2, "");
1905static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf4x2 == clang::BuiltinType::RvvFloat16mf4x2, "");
1906static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf4x3 == clang::BuiltinType::RvvFloat16mf4x3, "");
1907static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf4x4 == clang::BuiltinType::RvvFloat16mf4x4, "");
1908static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf4x5 == clang::BuiltinType::RvvFloat16mf4x5, "");
1909static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf4x6 == clang::BuiltinType::RvvFloat16mf4x6, "");
1910static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf4x7 == clang::BuiltinType::RvvFloat16mf4x7, "");
1911static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf4x8 == clang::BuiltinType::RvvFloat16mf4x8, "");
1912static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf2x2 == clang::BuiltinType::RvvFloat16mf2x2, "");
1913static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf2x3 == clang::BuiltinType::RvvFloat16mf2x3, "");
1914static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf2x4 == clang::BuiltinType::RvvFloat16mf2x4, "");
1915static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf2x5 == clang::BuiltinType::RvvFloat16mf2x5, "");
1916static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf2x6 == clang::BuiltinType::RvvFloat16mf2x6, "");
1917static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf2x7 == clang::BuiltinType::RvvFloat16mf2x7, "");
1918static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16mf2x8 == clang::BuiltinType::RvvFloat16mf2x8, "");
1919static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16m1x2 == clang::BuiltinType::RvvFloat16m1x2, "");
1920static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16m1x3 == clang::BuiltinType::RvvFloat16m1x3, "");
1921static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16m1x4 == clang::BuiltinType::RvvFloat16m1x4, "");
1922static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16m1x5 == clang::BuiltinType::RvvFloat16m1x5, "");
1923static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16m1x6 == clang::BuiltinType::RvvFloat16m1x6, "");
1924static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16m1x7 == clang::BuiltinType::RvvFloat16m1x7, "");
1925static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16m1x8 == clang::BuiltinType::RvvFloat16m1x8, "");
1926static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16m2x2 == clang::BuiltinType::RvvFloat16m2x2, "");
1927static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16m2x3 == clang::BuiltinType::RvvFloat16m2x3, "");
1928static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16m2x4 == clang::BuiltinType::RvvFloat16m2x4, "");
1929static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat16m4x2 == clang::BuiltinType::RvvFloat16m4x2, "");
1930static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32mf2x2 == clang::BuiltinType::RvvFloat32mf2x2, "");
1931static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32mf2x3 == clang::BuiltinType::RvvFloat32mf2x3, "");
1932static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32mf2x4 == clang::BuiltinType::RvvFloat32mf2x4, "");
1933static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32mf2x5 == clang::BuiltinType::RvvFloat32mf2x5, "");
1934static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32mf2x6 == clang::BuiltinType::RvvFloat32mf2x6, "");
1935static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32mf2x7 == clang::BuiltinType::RvvFloat32mf2x7, "");
1936static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32mf2x8 == clang::BuiltinType::RvvFloat32mf2x8, "");
1937static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32m1x2 == clang::BuiltinType::RvvFloat32m1x2, "");
1938static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32m1x3 == clang::BuiltinType::RvvFloat32m1x3, "");
1939static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32m1x4 == clang::BuiltinType::RvvFloat32m1x4, "");
1940static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32m1x5 == clang::BuiltinType::RvvFloat32m1x5, "");
1941static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32m1x6 == clang::BuiltinType::RvvFloat32m1x6, "");
1942static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32m1x7 == clang::BuiltinType::RvvFloat32m1x7, "");
1943static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32m1x8 == clang::BuiltinType::RvvFloat32m1x8, "");
1944static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32m2x2 == clang::BuiltinType::RvvFloat32m2x2, "");
1945static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32m2x3 == clang::BuiltinType::RvvFloat32m2x3, "");
1946static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32m2x4 == clang::BuiltinType::RvvFloat32m2x4, "");
1947static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat32m4x2 == clang::BuiltinType::RvvFloat32m4x2, "");
1948static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat64m1x2 == clang::BuiltinType::RvvFloat64m1x2, "");
1949static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat64m1x3 == clang::BuiltinType::RvvFloat64m1x3, "");
1950static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat64m1x4 == clang::BuiltinType::RvvFloat64m1x4, "");
1951static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat64m1x5 == clang::BuiltinType::RvvFloat64m1x5, "");
1952static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat64m1x6 == clang::BuiltinType::RvvFloat64m1x6, "");
1953static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat64m1x7 == clang::BuiltinType::RvvFloat64m1x7, "");
1954static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat64m1x8 == clang::BuiltinType::RvvFloat64m1x8, "");
1955static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat64m2x2 == clang::BuiltinType::RvvFloat64m2x2, "");
1956static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat64m2x3 == clang::BuiltinType::RvvFloat64m2x3, "");
1957static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat64m2x4 == clang::BuiltinType::RvvFloat64m2x4, "");
1958static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeRvvFloat64m4x2 == clang::BuiltinType::RvvFloat64m4x2, "");
1959static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeWasmExternRef == clang::BuiltinType::WasmExternRef, "");
15001960static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeVoid == clang::BuiltinType::Void, "");
15011961static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeBool == clang::BuiltinType::Bool, "");
15021962static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeChar_U == clang::BuiltinType::Char_U, "");
......@@ -2522,15 +2982,19 @@ ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char
25222982 bool single_file_parse = false;
25232983 bool for_serialization = false;
25242984 bool retain_excluded_conditional_blocks = false;
2985 bool store_preambles_in_memory = false;
2986 llvm::StringRef preamble_storage_path = llvm::StringRef();
25252987 clang::ArrayRef<clang::ASTUnit::RemappedFile> remapped_files = std::nullopt;
25262988 std::unique_ptr<clang::ASTUnit> err_unit;
25272989 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr;
25282990 std::optional<llvm::StringRef> ModuleFormat = std::nullopt;
2529 clang::ASTUnit *ast_unit = clang::ASTUnit::LoadFromCommandLine(
2991 std::unique_ptr<clang::ASTUnit> ast_unit_unique_ptr = clang::ASTUnit::LoadFromCommandLine(
25302992 args_begin, args_end,
25312993 pch_container_ops,
25322994 diags,
25332995 resources_path,
2996 store_preambles_in_memory,
2997 preamble_storage_path,
25342998 only_local_decls,
25352999 clang::CaptureDiagsKind::All,
25363000 remapped_files,
......@@ -2548,6 +3012,7 @@ ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char
25483012 ModuleFormat,
25493013 &err_unit,
25503014 VFS);
3015 clang::ASTUnit * ast_unit = ast_unit_unique_ptr.release();
25513016
25523017 *errors_len = 0;
25533018
......@@ -3521,3 +3986,17 @@ bool ZigClangIsLLVMUsingSeparateLibcxx() {
35213986 return EC.category() != std::generic_category();
35223987}
35233988
3989static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_IEEEhalf == llvm::APFloatBase::S_IEEEhalf, "");
3990static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_BFloat == llvm::APFloatBase::S_BFloat);
3991static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_IEEEsingle == llvm::APFloatBase::S_IEEEsingle);
3992static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_IEEEdouble == llvm::APFloatBase::S_IEEEdouble);
3993static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_IEEEquad == llvm::APFloatBase::S_IEEEquad);
3994static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_PPCDoubleDouble == llvm::APFloatBase::S_PPCDoubleDouble);
3995static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_Float8E5M2 == llvm::APFloatBase::S_Float8E5M2);
3996static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_Float8E5M2FNUZ == llvm::APFloatBase::S_Float8E5M2FNUZ);
3997static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_Float8E4M3FN == llvm::APFloatBase::S_Float8E4M3FN);
3998static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_Float8E4M3FNUZ == llvm::APFloatBase::S_Float8E4M3FNUZ);
3999static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_Float8E4M3B11FNUZ == llvm::APFloatBase::S_Float8E4M3B11FNUZ);
4000static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_FloatTF32 == llvm::APFloatBase::S_FloatTF32);
4001static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_x87DoubleExtended == llvm::APFloatBase::S_x87DoubleExtended);
4002static_assert((llvm::APFloatBase::Semantics)ZigClangAPFloatBase_Semantics_MaxSemantics == llvm::APFloatBase::S_MaxSemantics);
src/zig_clang.h+242-5
......@@ -740,10 +740,10 @@ enum ZigClangBuiltinTypeKind {
740740 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResult,
741741 ZigClangBuiltinTypeOCLIntelSubgroupAVCRefResult,
742742 ZigClangBuiltinTypeOCLIntelSubgroupAVCSicResult,
743 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultSingleRefStreamout,
744 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultDualRefStreamout,
745 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeSingleRefStreamin,
746 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeDualRefStreamin,
743 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultSingleReferenceStreamout,
744 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultDualReferenceStreamout,
745 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeSingleReferenceStreamin,
746 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeDualReferenceStreamin,
747747 ZigClangBuiltinTypeSveInt8,
748748 ZigClangBuiltinTypeSveInt16,
749749 ZigClangBuiltinTypeSveInt32,
......@@ -793,6 +793,9 @@ enum ZigClangBuiltinTypeKind {
793793 ZigClangBuiltinTypeSveFloat64x4,
794794 ZigClangBuiltinTypeSveBFloat16x4,
795795 ZigClangBuiltinTypeSveBool,
796 ZigClangBuiltinTypeSveBoolx2,
797 ZigClangBuiltinTypeSveBoolx4,
798 ZigClangBuiltinTypeSveCount,
796799 ZigClangBuiltinTypeVectorQuad,
797800 ZigClangBuiltinTypeVectorPair,
798801 ZigClangBuiltinTypeRvvInt8mf8,
......@@ -861,6 +864,233 @@ enum ZigClangBuiltinTypeKind {
861864 ZigClangBuiltinTypeRvvBool16,
862865 ZigClangBuiltinTypeRvvBool32,
863866 ZigClangBuiltinTypeRvvBool64,
867 ZigClangBuiltinTypeRvvInt8mf8x2,
868 ZigClangBuiltinTypeRvvInt8mf8x3,
869 ZigClangBuiltinTypeRvvInt8mf8x4,
870 ZigClangBuiltinTypeRvvInt8mf8x5,
871 ZigClangBuiltinTypeRvvInt8mf8x6,
872 ZigClangBuiltinTypeRvvInt8mf8x7,
873 ZigClangBuiltinTypeRvvInt8mf8x8,
874 ZigClangBuiltinTypeRvvInt8mf4x2,
875 ZigClangBuiltinTypeRvvInt8mf4x3,
876 ZigClangBuiltinTypeRvvInt8mf4x4,
877 ZigClangBuiltinTypeRvvInt8mf4x5,
878 ZigClangBuiltinTypeRvvInt8mf4x6,
879 ZigClangBuiltinTypeRvvInt8mf4x7,
880 ZigClangBuiltinTypeRvvInt8mf4x8,
881 ZigClangBuiltinTypeRvvInt8mf2x2,
882 ZigClangBuiltinTypeRvvInt8mf2x3,
883 ZigClangBuiltinTypeRvvInt8mf2x4,
884 ZigClangBuiltinTypeRvvInt8mf2x5,
885 ZigClangBuiltinTypeRvvInt8mf2x6,
886 ZigClangBuiltinTypeRvvInt8mf2x7,
887 ZigClangBuiltinTypeRvvInt8mf2x8,
888 ZigClangBuiltinTypeRvvInt8m1x2,
889 ZigClangBuiltinTypeRvvInt8m1x3,
890 ZigClangBuiltinTypeRvvInt8m1x4,
891 ZigClangBuiltinTypeRvvInt8m1x5,
892 ZigClangBuiltinTypeRvvInt8m1x6,
893 ZigClangBuiltinTypeRvvInt8m1x7,
894 ZigClangBuiltinTypeRvvInt8m1x8,
895 ZigClangBuiltinTypeRvvInt8m2x2,
896 ZigClangBuiltinTypeRvvInt8m2x3,
897 ZigClangBuiltinTypeRvvInt8m2x4,
898 ZigClangBuiltinTypeRvvInt8m4x2,
899 ZigClangBuiltinTypeRvvUint8mf8x2,
900 ZigClangBuiltinTypeRvvUint8mf8x3,
901 ZigClangBuiltinTypeRvvUint8mf8x4,
902 ZigClangBuiltinTypeRvvUint8mf8x5,
903 ZigClangBuiltinTypeRvvUint8mf8x6,
904 ZigClangBuiltinTypeRvvUint8mf8x7,
905 ZigClangBuiltinTypeRvvUint8mf8x8,
906 ZigClangBuiltinTypeRvvUint8mf4x2,
907 ZigClangBuiltinTypeRvvUint8mf4x3,
908 ZigClangBuiltinTypeRvvUint8mf4x4,
909 ZigClangBuiltinTypeRvvUint8mf4x5,
910 ZigClangBuiltinTypeRvvUint8mf4x6,
911 ZigClangBuiltinTypeRvvUint8mf4x7,
912 ZigClangBuiltinTypeRvvUint8mf4x8,
913 ZigClangBuiltinTypeRvvUint8mf2x2,
914 ZigClangBuiltinTypeRvvUint8mf2x3,
915 ZigClangBuiltinTypeRvvUint8mf2x4,
916 ZigClangBuiltinTypeRvvUint8mf2x5,
917 ZigClangBuiltinTypeRvvUint8mf2x6,
918 ZigClangBuiltinTypeRvvUint8mf2x7,
919 ZigClangBuiltinTypeRvvUint8mf2x8,
920 ZigClangBuiltinTypeRvvUint8m1x2,
921 ZigClangBuiltinTypeRvvUint8m1x3,
922 ZigClangBuiltinTypeRvvUint8m1x4,
923 ZigClangBuiltinTypeRvvUint8m1x5,
924 ZigClangBuiltinTypeRvvUint8m1x6,
925 ZigClangBuiltinTypeRvvUint8m1x7,
926 ZigClangBuiltinTypeRvvUint8m1x8,
927 ZigClangBuiltinTypeRvvUint8m2x2,
928 ZigClangBuiltinTypeRvvUint8m2x3,
929 ZigClangBuiltinTypeRvvUint8m2x4,
930 ZigClangBuiltinTypeRvvUint8m4x2,
931 ZigClangBuiltinTypeRvvInt16mf4x2,
932 ZigClangBuiltinTypeRvvInt16mf4x3,
933 ZigClangBuiltinTypeRvvInt16mf4x4,
934 ZigClangBuiltinTypeRvvInt16mf4x5,
935 ZigClangBuiltinTypeRvvInt16mf4x6,
936 ZigClangBuiltinTypeRvvInt16mf4x7,
937 ZigClangBuiltinTypeRvvInt16mf4x8,
938 ZigClangBuiltinTypeRvvInt16mf2x2,
939 ZigClangBuiltinTypeRvvInt16mf2x3,
940 ZigClangBuiltinTypeRvvInt16mf2x4,
941 ZigClangBuiltinTypeRvvInt16mf2x5,
942 ZigClangBuiltinTypeRvvInt16mf2x6,
943 ZigClangBuiltinTypeRvvInt16mf2x7,
944 ZigClangBuiltinTypeRvvInt16mf2x8,
945 ZigClangBuiltinTypeRvvInt16m1x2,
946 ZigClangBuiltinTypeRvvInt16m1x3,
947 ZigClangBuiltinTypeRvvInt16m1x4,
948 ZigClangBuiltinTypeRvvInt16m1x5,
949 ZigClangBuiltinTypeRvvInt16m1x6,
950 ZigClangBuiltinTypeRvvInt16m1x7,
951 ZigClangBuiltinTypeRvvInt16m1x8,
952 ZigClangBuiltinTypeRvvInt16m2x2,
953 ZigClangBuiltinTypeRvvInt16m2x3,
954 ZigClangBuiltinTypeRvvInt16m2x4,
955 ZigClangBuiltinTypeRvvInt16m4x2,
956 ZigClangBuiltinTypeRvvUint16mf4x2,
957 ZigClangBuiltinTypeRvvUint16mf4x3,
958 ZigClangBuiltinTypeRvvUint16mf4x4,
959 ZigClangBuiltinTypeRvvUint16mf4x5,
960 ZigClangBuiltinTypeRvvUint16mf4x6,
961 ZigClangBuiltinTypeRvvUint16mf4x7,
962 ZigClangBuiltinTypeRvvUint16mf4x8,
963 ZigClangBuiltinTypeRvvUint16mf2x2,
964 ZigClangBuiltinTypeRvvUint16mf2x3,
965 ZigClangBuiltinTypeRvvUint16mf2x4,
966 ZigClangBuiltinTypeRvvUint16mf2x5,
967 ZigClangBuiltinTypeRvvUint16mf2x6,
968 ZigClangBuiltinTypeRvvUint16mf2x7,
969 ZigClangBuiltinTypeRvvUint16mf2x8,
970 ZigClangBuiltinTypeRvvUint16m1x2,
971 ZigClangBuiltinTypeRvvUint16m1x3,
972 ZigClangBuiltinTypeRvvUint16m1x4,
973 ZigClangBuiltinTypeRvvUint16m1x5,
974 ZigClangBuiltinTypeRvvUint16m1x6,
975 ZigClangBuiltinTypeRvvUint16m1x7,
976 ZigClangBuiltinTypeRvvUint16m1x8,
977 ZigClangBuiltinTypeRvvUint16m2x2,
978 ZigClangBuiltinTypeRvvUint16m2x3,
979 ZigClangBuiltinTypeRvvUint16m2x4,
980 ZigClangBuiltinTypeRvvUint16m4x2,
981 ZigClangBuiltinTypeRvvInt32mf2x2,
982 ZigClangBuiltinTypeRvvInt32mf2x3,
983 ZigClangBuiltinTypeRvvInt32mf2x4,
984 ZigClangBuiltinTypeRvvInt32mf2x5,
985 ZigClangBuiltinTypeRvvInt32mf2x6,
986 ZigClangBuiltinTypeRvvInt32mf2x7,
987 ZigClangBuiltinTypeRvvInt32mf2x8,
988 ZigClangBuiltinTypeRvvInt32m1x2,
989 ZigClangBuiltinTypeRvvInt32m1x3,
990 ZigClangBuiltinTypeRvvInt32m1x4,
991 ZigClangBuiltinTypeRvvInt32m1x5,
992 ZigClangBuiltinTypeRvvInt32m1x6,
993 ZigClangBuiltinTypeRvvInt32m1x7,
994 ZigClangBuiltinTypeRvvInt32m1x8,
995 ZigClangBuiltinTypeRvvInt32m2x2,
996 ZigClangBuiltinTypeRvvInt32m2x3,
997 ZigClangBuiltinTypeRvvInt32m2x4,
998 ZigClangBuiltinTypeRvvInt32m4x2,
999 ZigClangBuiltinTypeRvvUint32mf2x2,
1000 ZigClangBuiltinTypeRvvUint32mf2x3,
1001 ZigClangBuiltinTypeRvvUint32mf2x4,
1002 ZigClangBuiltinTypeRvvUint32mf2x5,
1003 ZigClangBuiltinTypeRvvUint32mf2x6,
1004 ZigClangBuiltinTypeRvvUint32mf2x7,
1005 ZigClangBuiltinTypeRvvUint32mf2x8,
1006 ZigClangBuiltinTypeRvvUint32m1x2,
1007 ZigClangBuiltinTypeRvvUint32m1x3,
1008 ZigClangBuiltinTypeRvvUint32m1x4,
1009 ZigClangBuiltinTypeRvvUint32m1x5,
1010 ZigClangBuiltinTypeRvvUint32m1x6,
1011 ZigClangBuiltinTypeRvvUint32m1x7,
1012 ZigClangBuiltinTypeRvvUint32m1x8,
1013 ZigClangBuiltinTypeRvvUint32m2x2,
1014 ZigClangBuiltinTypeRvvUint32m2x3,
1015 ZigClangBuiltinTypeRvvUint32m2x4,
1016 ZigClangBuiltinTypeRvvUint32m4x2,
1017 ZigClangBuiltinTypeRvvInt64m1x2,
1018 ZigClangBuiltinTypeRvvInt64m1x3,
1019 ZigClangBuiltinTypeRvvInt64m1x4,
1020 ZigClangBuiltinTypeRvvInt64m1x5,
1021 ZigClangBuiltinTypeRvvInt64m1x6,
1022 ZigClangBuiltinTypeRvvInt64m1x7,
1023 ZigClangBuiltinTypeRvvInt64m1x8,
1024 ZigClangBuiltinTypeRvvInt64m2x2,
1025 ZigClangBuiltinTypeRvvInt64m2x3,
1026 ZigClangBuiltinTypeRvvInt64m2x4,
1027 ZigClangBuiltinTypeRvvInt64m4x2,
1028 ZigClangBuiltinTypeRvvUint64m1x2,
1029 ZigClangBuiltinTypeRvvUint64m1x3,
1030 ZigClangBuiltinTypeRvvUint64m1x4,
1031 ZigClangBuiltinTypeRvvUint64m1x5,
1032 ZigClangBuiltinTypeRvvUint64m1x6,
1033 ZigClangBuiltinTypeRvvUint64m1x7,
1034 ZigClangBuiltinTypeRvvUint64m1x8,
1035 ZigClangBuiltinTypeRvvUint64m2x2,
1036 ZigClangBuiltinTypeRvvUint64m2x3,
1037 ZigClangBuiltinTypeRvvUint64m2x4,
1038 ZigClangBuiltinTypeRvvUint64m4x2,
1039 ZigClangBuiltinTypeRvvFloat16mf4x2,
1040 ZigClangBuiltinTypeRvvFloat16mf4x3,
1041 ZigClangBuiltinTypeRvvFloat16mf4x4,
1042 ZigClangBuiltinTypeRvvFloat16mf4x5,
1043 ZigClangBuiltinTypeRvvFloat16mf4x6,
1044 ZigClangBuiltinTypeRvvFloat16mf4x7,
1045 ZigClangBuiltinTypeRvvFloat16mf4x8,
1046 ZigClangBuiltinTypeRvvFloat16mf2x2,
1047 ZigClangBuiltinTypeRvvFloat16mf2x3,
1048 ZigClangBuiltinTypeRvvFloat16mf2x4,
1049 ZigClangBuiltinTypeRvvFloat16mf2x5,
1050 ZigClangBuiltinTypeRvvFloat16mf2x6,
1051 ZigClangBuiltinTypeRvvFloat16mf2x7,
1052 ZigClangBuiltinTypeRvvFloat16mf2x8,
1053 ZigClangBuiltinTypeRvvFloat16m1x2,
1054 ZigClangBuiltinTypeRvvFloat16m1x3,
1055 ZigClangBuiltinTypeRvvFloat16m1x4,
1056 ZigClangBuiltinTypeRvvFloat16m1x5,
1057 ZigClangBuiltinTypeRvvFloat16m1x6,
1058 ZigClangBuiltinTypeRvvFloat16m1x7,
1059 ZigClangBuiltinTypeRvvFloat16m1x8,
1060 ZigClangBuiltinTypeRvvFloat16m2x2,
1061 ZigClangBuiltinTypeRvvFloat16m2x3,
1062 ZigClangBuiltinTypeRvvFloat16m2x4,
1063 ZigClangBuiltinTypeRvvFloat16m4x2,
1064 ZigClangBuiltinTypeRvvFloat32mf2x2,
1065 ZigClangBuiltinTypeRvvFloat32mf2x3,
1066 ZigClangBuiltinTypeRvvFloat32mf2x4,
1067 ZigClangBuiltinTypeRvvFloat32mf2x5,
1068 ZigClangBuiltinTypeRvvFloat32mf2x6,
1069 ZigClangBuiltinTypeRvvFloat32mf2x7,
1070 ZigClangBuiltinTypeRvvFloat32mf2x8,
1071 ZigClangBuiltinTypeRvvFloat32m1x2,
1072 ZigClangBuiltinTypeRvvFloat32m1x3,
1073 ZigClangBuiltinTypeRvvFloat32m1x4,
1074 ZigClangBuiltinTypeRvvFloat32m1x5,
1075 ZigClangBuiltinTypeRvvFloat32m1x6,
1076 ZigClangBuiltinTypeRvvFloat32m1x7,
1077 ZigClangBuiltinTypeRvvFloat32m1x8,
1078 ZigClangBuiltinTypeRvvFloat32m2x2,
1079 ZigClangBuiltinTypeRvvFloat32m2x3,
1080 ZigClangBuiltinTypeRvvFloat32m2x4,
1081 ZigClangBuiltinTypeRvvFloat32m4x2,
1082 ZigClangBuiltinTypeRvvFloat64m1x2,
1083 ZigClangBuiltinTypeRvvFloat64m1x3,
1084 ZigClangBuiltinTypeRvvFloat64m1x4,
1085 ZigClangBuiltinTypeRvvFloat64m1x5,
1086 ZigClangBuiltinTypeRvvFloat64m1x6,
1087 ZigClangBuiltinTypeRvvFloat64m1x7,
1088 ZigClangBuiltinTypeRvvFloat64m1x8,
1089 ZigClangBuiltinTypeRvvFloat64m2x2,
1090 ZigClangBuiltinTypeRvvFloat64m2x3,
1091 ZigClangBuiltinTypeRvvFloat64m2x4,
1092 ZigClangBuiltinTypeRvvFloat64m4x2,
1093 ZigClangBuiltinTypeWasmExternRef,
8641094 ZigClangBuiltinTypeVoid,
8651095 ZigClangBuiltinTypeBool,
8661096 ZigClangBuiltinTypeChar_U,
......@@ -989,9 +1219,16 @@ enum ZigClangAPFloatBase_Semantics {
9891219 ZigClangAPFloatBase_Semantics_BFloat,
9901220 ZigClangAPFloatBase_Semantics_IEEEsingle,
9911221 ZigClangAPFloatBase_Semantics_IEEEdouble,
992 ZigClangAPFloatBase_Semantics_x87DoubleExtended,
9931222 ZigClangAPFloatBase_Semantics_IEEEquad,
9941223 ZigClangAPFloatBase_Semantics_PPCDoubleDouble,
1224 ZigClangAPFloatBase_Semantics_Float8E5M2,
1225 ZigClangAPFloatBase_Semantics_Float8E5M2FNUZ,
1226 ZigClangAPFloatBase_Semantics_Float8E4M3FN,
1227 ZigClangAPFloatBase_Semantics_Float8E4M3FNUZ,
1228 ZigClangAPFloatBase_Semantics_Float8E4M3B11FNUZ,
1229 ZigClangAPFloatBase_Semantics_FloatTF32,
1230 ZigClangAPFloatBase_Semantics_x87DoubleExtended,
1231 ZigClangAPFloatBase_Semantics_MaxSemantics = ZigClangAPFloatBase_Semantics_x87DoubleExtended,
9951232};
9961233
9971234enum ZigClangStringLiteral_StringKind {
src/zig_clang_cc1_main.cpp+15-13
......@@ -213,9 +213,7 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
213213 bool Success = CompilerInvocation::CreateFromArgs(Clang->getInvocation(),
214214 Argv, Diags, Argv0);
215215
216 if (Clang->getFrontendOpts().TimeTrace ||
217 !Clang->getFrontendOpts().TimeTracePath.empty()) {
218 Clang->getFrontendOpts().TimeTrace = 1;
216 if (!Clang->getFrontendOpts().TimeTracePath.empty()) {
219217 llvm::timeTraceProfilerInitialize(
220218 Clang->getFrontendOpts().TimeTraceGranularity, Argv0);
221219 }
......@@ -257,17 +255,21 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
257255 llvm::TimerGroup::clearAll();
258256
259257 if (llvm::timeTraceProfilerEnabled()) {
260 SmallString<128> Path(Clang->getFrontendOpts().OutputFile);
261 llvm::sys::path::replace_extension(Path, "json");
262 if (!Clang->getFrontendOpts().TimeTracePath.empty()) {
263 // replace the suffix to '.json' directly
264 SmallString<128> TracePath(Clang->getFrontendOpts().TimeTracePath);
265 if (llvm::sys::fs::is_directory(TracePath))
266 llvm::sys::path::append(TracePath, llvm::sys::path::filename(Path));
267 Path.assign(TracePath);
268 }
258 // It is possible that the compiler instance doesn't own a file manager here
259 // if we're compiling a module unit. Since the file manager are owned by AST
260 // when we're compiling a module unit. So the file manager may be invalid
261 // here.
262 //
263 // It should be fine to create file manager here since the file system
264 // options are stored in the compiler invocation and we can recreate the VFS
265 // from the compiler invocation.
266 if (!Clang->hasFileManager())
267 Clang->createFileManager(createVFSFromCompilerInvocation(
268 Clang->getInvocation(), Clang->getDiagnostics()));
269
269270 if (auto profilerOutput = Clang->createOutputFile(
270 Path.str(), /*Binary=*/false, /*RemoveFileOnSignal=*/false,
271 Clang->getFrontendOpts().TimeTracePath, /*Binary=*/false,
272 /*RemoveFileOnSignal=*/false,
271273 /*useTemporary=*/false)) {
272274 llvm::timeTraceProfilerWrite(*profilerOutput);
273275 profilerOutput.reset();
src/zig_clang_cc1as_main.cpp+16-7
......@@ -19,8 +19,8 @@
1919#include "clang/Frontend/TextDiagnosticPrinter.h"
2020#include "clang/Frontend/Utils.h"
2121#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/StringExtras.h"
2223#include "llvm/ADT/StringSwitch.h"
23#include "llvm/ADT/Triple.h"
2424#include "llvm/IR/DataLayout.h"
2525#include "llvm/MC/MCAsmBackend.h"
2626#include "llvm/MC/MCAsmInfo.h"
......@@ -44,7 +44,6 @@
4444#include "llvm/Support/ErrorHandling.h"
4545#include "llvm/Support/FileSystem.h"
4646#include "llvm/Support/FormattedStream.h"
47#include "llvm/Support/Host.h"
4847#include "llvm/Support/MemoryBuffer.h"
4948#include "llvm/Support/Path.h"
5049#include "llvm/Support/Process.h"
......@@ -53,6 +52,8 @@
5352#include "llvm/Support/TargetSelect.h"
5453#include "llvm/Support/Timer.h"
5554#include "llvm/Support/raw_ostream.h"
55#include "llvm/TargetParser/Host.h"
56#include "llvm/TargetParser/Triple.h"
5657#include <memory>
5758#include <optional>
5859#include <system_error>
......@@ -97,7 +98,7 @@ struct AssemblerInvocation {
9798 std::string DwarfDebugFlags;
9899 std::string DwarfDebugProducer;
99100 std::string DebugCompilationDir;
100 std::map<const std::string, const std::string> DebugPrefixMap;
101 llvm::SmallVector<std::pair<std::string, std::string>, 0> DebugPrefixMap;
101102 llvm::DebugCompressionType CompressDebugSections =
102103 llvm::DebugCompressionType::None;
103104 std::string MainFileName;
......@@ -142,6 +143,10 @@ struct AssemblerInvocation {
142143 /// Whether to emit DWARF unwind info.
143144 EmitDwarfUnwindType EmitDwarfUnwind;
144145
146 // Whether to emit compact-unwind for non-canonical entries.
147 // Note: maybe overriden by other constraints.
148 unsigned EmitCompactUnwindNonCanonical : 1;
149
145150 /// The name of the relocation model to use.
146151 std::string RelocationModel;
147152
......@@ -181,6 +186,7 @@ public:
181186 DwarfVersion = 0;
182187 EmbedBitcode = 0;
183188 EmitDwarfUnwind = EmitDwarfUnwindType::Default;
189 EmitCompactUnwindNonCanonical = false;
184190 }
185191
186192 static bool CreateFromArgs(AssemblerInvocation &Res,
......@@ -275,8 +281,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
275281
276282 for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) {
277283 auto Split = StringRef(Arg).split('=');
278 Opts.DebugPrefixMap.insert(
279 {std::string(Split.first), std::string(Split.second)});
284 Opts.DebugPrefixMap.emplace_back(Split.first, Split.second);
280285 }
281286
282287 // Frontend Options
......@@ -349,6 +354,9 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
349354 .Case("default", EmitDwarfUnwindType::Default);
350355 }
351356
357 Opts.EmitCompactUnwindNonCanonical =
358 Args.hasArg(OPT_femit_compact_unwind_non_canonical);
359
352360 Opts.AsSecureLogFile = Args.getLastArgValue(OPT_as_secure_log_file);
353361
354362 return Success;
......@@ -384,8 +392,8 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
384392 MemoryBuffer::getFileOrSTDIN(Opts.InputFile, /*IsText=*/true);
385393
386394 if (std::error_code EC = Buffer.getError()) {
387 Error = EC.message();
388 return Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
395 return Diags.Report(diag::err_fe_error_reading)
396 << Opts.InputFile << EC.message();
389397 }
390398
391399 SourceMgr SrcMgr;
......@@ -402,6 +410,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
402410
403411 MCTargetOptions MCOptions;
404412 MCOptions.EmitDwarfUnwind = Opts.EmitDwarfUnwind;
413 MCOptions.EmitCompactUnwindNonCanonical = Opts.EmitCompactUnwindNonCanonical;
405414 MCOptions.AsSecureLogFile = Opts.AsSecureLogFile;
406415
407416 std::unique_ptr<MCAsmInfo> MAI(
src/zig_clang_driver.cpp+34-53
......@@ -36,8 +36,8 @@
3636#include "llvm/Support/CrashRecoveryContext.h"
3737#include "llvm/Support/ErrorHandling.h"
3838#include "llvm/Support/FileSystem.h"
39#include "llvm/Support/Host.h"
4039#include "llvm/Support/InitLLVM.h"
40#include "llvm/Support/LLVMDriver.h"
4141#include "llvm/Support/Path.h"
4242#include "llvm/Support/PrettyStackTrace.h"
4343#include "llvm/Support/Process.h"
......@@ -48,6 +48,7 @@
4848#include "llvm/Support/TargetSelect.h"
4949#include "llvm/Support/Timer.h"
5050#include "llvm/Support/raw_ostream.h"
51#include "llvm/TargetParser/Host.h"
5152#include <memory>
5253#include <optional>
5354#include <set>
......@@ -303,6 +304,9 @@ static bool SetBackdoorDriverOutputsFromEnvVars(Driver &TheDriver) {
303304 TheDriver.CCPrintProcessStats =
304305 checkEnvVar<bool>("CC_PRINT_PROC_STAT", "CC_PRINT_PROC_STAT_FILE",
305306 TheDriver.CCPrintStatReportFilename);
307 TheDriver.CCPrintInternalStats =
308 checkEnvVar<bool>("CC_PRINT_INTERNAL_STAT", "CC_PRINT_INTERNAL_STAT_FILE",
309 TheDriver.CCPrintInternalStatReportFilename);
306310
307311 return true;
308312}
......@@ -339,7 +343,8 @@ static void SetInstallDir(SmallVectorImpl<const char *> &argv,
339343 TheDriver.setInstalledDir(InstalledPathParent);
340344}
341345
342static int ExecuteCC1Tool(SmallVectorImpl<const char *> &ArgV) {
346static int ExecuteCC1Tool(SmallVectorImpl<const char *> &ArgV,
347 const llvm::ToolContext &ToolContext) {
343348 // If we call the cc1 tool from the clangDriver library (through
344349 // Driver::CC1Main), we need to clean up the options usage count. The options
345350 // are currently global, and they might have been used previously by the
......@@ -364,8 +369,7 @@ static int ExecuteCC1Tool(SmallVectorImpl<const char *> &ArgV) {
364369 return 1;
365370}
366371
367extern "C" int ZigClang_main(int Argc, const char **Argv);
368int ZigClang_main(int Argc, const char **Argv) {
372static int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) {
369373 noteBottomOfStack();
370374 // ZIG PATCH: On Windows, InitLLVM calls GetCommandLineW(),
371375 // and overwrites the args. We don't want it to do that,
......@@ -389,55 +393,20 @@ int ZigClang_main(int Argc, const char **Argv) {
389393 llvm::BumpPtrAllocator A;
390394 llvm::StringSaver Saver(A);
391395
392 // Parse response files using the GNU syntax, unless we're in CL mode. There
393 // are two ways to put clang in CL compatibility mode: Args[0] is either
394 // clang-cl or cl, or --driver-mode=cl is on the command line. The normal
395 // command line parsing can't happen until after response file parsing, so we
396 // have to manually search for a --driver-mode=cl argument the hard way.
397 // Finally, our -cc1 tools don't care which tokenization mode we use because
398 // response files written by clang will tokenize the same way in either mode.
396 const char *ProgName =
397 ToolContext.NeedsPrependArg ? ToolContext.PrependArg : ToolContext.Path;
398
399399 bool ClangCLMode =
400 IsClangCL(getDriverMode(Args[0], llvm::ArrayRef(Args).slice(1)));
401 enum { Default, POSIX, Windows } RSPQuoting = Default;
402 for (const char *F : Args) {
403 if (strcmp(F, "--rsp-quoting=posix") == 0)
404 RSPQuoting = POSIX;
405 else if (strcmp(F, "--rsp-quoting=windows") == 0)
406 RSPQuoting = Windows;
407 }
400 IsClangCL(getDriverMode(ProgName, llvm::ArrayRef(Args).slice(1)));
408401
409 // Determines whether we want nullptr markers in Args to indicate response
410 // files end-of-lines. We only use this for the /LINK driver argument with
411 // clang-cl.exe on Windows.
412 bool MarkEOLs = ClangCLMode;
413
414 llvm::cl::TokenizerCallback Tokenizer;
415 if (RSPQuoting == Windows || (RSPQuoting == Default && ClangCLMode))
416 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
417 else
418 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
419
420 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).startswith("-cc1"))
421 MarkEOLs = false;
422 llvm::cl::ExpansionContext ECtx(A, Tokenizer);
423 ECtx.setMarkEOLs(MarkEOLs);
424 if (llvm::Error Err = ECtx.expandResponseFiles(Args)) {
402 if (llvm::Error Err = expandResponseFiles(Args, ClangCLMode, A)) {
425403 llvm::errs() << toString(std::move(Err)) << '\n';
426404 return 1;
427405 }
428406
429 // Handle -cc1 integrated tools, even if -cc1 was expanded from a response
430 // file.
431 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
432 [](const char *A) { return A != nullptr; });
433 if (FirstArg != Args.end() && StringRef(*FirstArg).startswith("-cc1")) {
434 // If -cc1 came from a response file, remove the EOL sentinels.
435 if (MarkEOLs) {
436 auto newEnd = std::remove(Args.begin(), Args.end(), nullptr);
437 Args.resize(newEnd - Args.begin());
438 }
439 return ExecuteCC1Tool(Args);
440 }
407 // Handle -cc1 integrated tools.
408 if (Args.size() >= 2 && StringRef(Args[1]).startswith("-cc1"))
409 return ExecuteCC1Tool(Args, ToolContext);
441410
442411 // Handle options that need handling before the real command line parsing in
443412 // Driver::BuildCompilation()
......@@ -483,9 +452,7 @@ int ZigClang_main(int Argc, const char **Argv) {
483452 ApplyQAOverride(Args, OverrideStr, SavedStrings);
484453 }
485454
486 // Pass local param `Argv[0]` as fallback.
487 // See https://github.com/ziglang/zig/pull/3292 .
488 std::string Path = GetExecutablePath(Argv[0], CanonicalPrefixes);
455 std::string Path = GetExecutablePath(ToolContext.Path, CanonicalPrefixes);
489456
490457 // Whether the cc1 tool should be called inside the current process, or if we
491458 // should spawn a new clang subprocess (old behavior).
......@@ -503,7 +470,7 @@ int ZigClang_main(int Argc, const char **Argv) {
503470
504471 TextDiagnosticPrinter *DiagClient
505472 = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
506 FixupDiagPrefixExeName(DiagClient, Path);
473 FixupDiagPrefixExeName(DiagClient, ProgName);
507474
508475 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
509476
......@@ -521,8 +488,15 @@ int ZigClang_main(int Argc, const char **Argv) {
521488
522489 Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
523490 SetInstallDir(Args, TheDriver, CanonicalPrefixes);
524 auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(Args[0]);
491 auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(ProgName);
525492 TheDriver.setTargetAndMode(TargetAndMode);
493 // If -canonical-prefixes is set, GetExecutablePath will have resolved Path
494 // to the llvm driver binary, not clang. In this case, we need to use
495 // PrependArg which should be clang-*. Checking just CanonicalPrefixes is
496 // safe even in the normal case because PrependArg will be null so
497 // setPrependArg will be a no-op.
498 if (ToolContext.NeedsPrependArg || CanonicalPrefixes)
499 TheDriver.setPrependArg(ToolContext.PrependArg);
526500
527501 insertTargetAndModeArgs(TargetAndMode, Args, SavedStrings);
528502
......@@ -530,7 +504,9 @@ int ZigClang_main(int Argc, const char **Argv) {
530504 return 1;
531505
532506 if (!UseNewCC1Process) {
533 TheDriver.CC1Main = &ExecuteCC1Tool;
507 TheDriver.CC1Main = [ToolContext](SmallVectorImpl<const char *> &ArgV) {
508 return ExecuteCC1Tool(ArgV, ToolContext);
509 };
534510 // Ensure the CC1Command actually catches cc1 crashes
535511 llvm::CrashRecoveryContext::Enable();
536512 }
......@@ -629,3 +605,8 @@ int ZigClang_main(int Argc, const char **Argv) {
629605 // failing command.
630606 return Res;
631607}
608
609extern "C" int ZigClang_main(int, char **);
610int ZigClang_main(int argc, char **argv) {
611 return clang_main(argc, argv, {argv[0], nullptr, false});
612}
src/zig_llvm-ar.cpp+10-32
......@@ -13,20 +13,11 @@
1313
1414#include "llvm/ADT/StringExtras.h"
1515#include "llvm/ADT/StringSwitch.h"
16#include "llvm/ADT/Triple.h"
1716#include "llvm/BinaryFormat/Magic.h"
1817#include "llvm/IR/LLVMContext.h"
1918#include "llvm/Object/Archive.h"
2019#include "llvm/Object/ArchiveWriter.h"
21#include "llvm/Object/COFFImportFile.h"
22#include "llvm/Object/ELFObjectFile.h"
23#include "llvm/Object/IRObjectFile.h"
24#include "llvm/Object/MachO.h"
25#include "llvm/Object/ObjectFile.h"
2620#include "llvm/Object/SymbolicFile.h"
27#include "llvm/Object/TapiFile.h"
28#include "llvm/Object/Wasm.h"
29#include "llvm/Object/XCOFFObjectFile.h"
3021#include "llvm/Support/Chrono.h"
3122#include "llvm/Support/CommandLine.h"
3223#include "llvm/Support/ConvertUTF.h"
......@@ -34,8 +25,8 @@
3425#include "llvm/Support/FileSystem.h"
3526#include "llvm/Support/Format.h"
3627#include "llvm/Support/FormatVariadic.h"
37#include "llvm/Support/Host.h"
3828#include "llvm/Support/InitLLVM.h"
29#include "llvm/Support/LLVMDriver.h"
3930#include "llvm/Support/LineIterator.h"
4031#include "llvm/Support/MemoryBuffer.h"
4132#include "llvm/Support/Path.h"
......@@ -45,6 +36,8 @@
4536#include "llvm/Support/ToolOutputFile.h"
4637#include "llvm/Support/WithColor.h"
4738#include "llvm/Support/raw_ostream.h"
39#include "llvm/TargetParser/Host.h"
40#include "llvm/TargetParser/Triple.h"
4841#include "llvm/ToolDrivers/llvm-dlltool/DlltoolDriver.h"
4942#include "llvm/ToolDrivers/llvm-lib/LibDriver.h"
5043
......@@ -646,31 +639,12 @@ static bool shouldCreateArchive(ArchiveOperation Op) {
646639 llvm_unreachable("Missing entry in covered switch.");
647640}
648641
649static bool is64BitSymbolicFile(SymbolicFile &Obj) {
650 if (auto *IRObj = dyn_cast<IRObjectFile>(&Obj))
651 return Triple(IRObj->getTargetTriple()).isArch64Bit();
652 if (isa<COFFObjectFile>(Obj) || isa<COFFImportFile>(Obj))
653 return false;
654 if (XCOFFObjectFile *XCOFFObj = dyn_cast<XCOFFObjectFile>(&Obj))
655 return XCOFFObj->is64Bit();
656 if (isa<WasmObjectFile>(Obj))
657 return false;
658 if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj))
659 return Tapi->is64Bit();
660 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
661 return MachO->is64Bit();
662 if (ELFObjectFileBase *ElfO = dyn_cast<ELFObjectFileBase>(&Obj))
663 return ElfO->getBytesInAddress() == 8;
664
665 fail("unsupported file format");
666}
667
668642static bool isValidInBitMode(Binary &Bin) {
669643 if (BitMode == BitModeTy::Bit32_64 || BitMode == BitModeTy::Any)
670644 return true;
671645
672646 if (SymbolicFile *SymFile = dyn_cast<SymbolicFile>(&Bin)) {
673 bool Is64Bit = is64BitSymbolicFile(*SymFile);
647 bool Is64Bit = SymFile->is64Bit();
674648 if ((Is64Bit && (BitMode == BitModeTy::Bit32)) ||
675649 (!Is64Bit && (BitMode == BitModeTy::Bit64)))
676650 return false;
......@@ -1452,8 +1426,7 @@ static int ranlib_main(int argc, char **argv) {
14521426 return 0;
14531427}
14541428
1455extern "C" int ZigLlvmAr_main(int argc, char **argv);
1456int ZigLlvmAr_main(int argc, char **argv) {
1429static int llvm_ar_main(int argc, char **argv, const llvm::ToolContext &) {
14571430 // ZIG PATCH: On Windows, InitLLVM calls GetCommandLineW(),
14581431 // and overwrites the args. We don't want it to do that,
14591432 // and we also don't need the signal handlers it installs
......@@ -1491,3 +1464,8 @@ int ZigLlvmAr_main(int argc, char **argv) {
14911464
14921465 fail("not ranlib, ar, lib or dlltool");
14931466}
1467
1468extern "C" int ZigLlvmAr_main(int, char **);
1469int ZigLlvmAr_main(int argc, char **argv) {
1470 return llvm_ar_main(argc, argv, {argv[0], nullptr, false});
1471}
src/zig_llvm.cpp+39-6
......@@ -35,7 +35,6 @@
3535#include <llvm/IR/PassManager.h>
3636#include <llvm/IR/Verifier.h>
3737#include <llvm/InitializePasses.h>
38#include <llvm/MC/SubtargetFeature.h>
3938#include <llvm/MC/TargetRegistry.h>
4039#include <llvm/Passes/OptimizationLevel.h>
4140#include <llvm/Passes/PassBuilder.h>
......@@ -47,10 +46,8 @@
4746#include <llvm/Object/COFFModuleDefinition.h>
4847#include <llvm/PassRegistry.h>
4948#include <llvm/Support/CommandLine.h>
50#include <llvm/Support/Host.h>
5149#include <llvm/Support/FileSystem.h>
5250#include <llvm/Support/Process.h>
53#include <llvm/Support/TargetParser.h>
5451#include <llvm/Support/TimeProfiler.h>
5552#include <llvm/Support/Timer.h>
5653#include <llvm/Support/raw_ostream.h>
......@@ -58,7 +55,6 @@
5855#include <llvm/Target/CodeGenCWrappers.h>
5956#include <llvm/Transforms/IPO.h>
6057#include <llvm/Transforms/IPO/AlwaysInliner.h>
61#include <llvm/Transforms/IPO/PassManagerBuilder.h>
6258#include <llvm/Transforms/Instrumentation/ThreadSanitizer.h>
6359#include <llvm/Transforms/Scalar.h>
6460#include <llvm/Transforms/Utils.h>
......@@ -1103,6 +1099,24 @@ bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size
11031099 return false;
11041100}
11051101
1102// The header file in LLD 16 exposed these functions. As of 17 they are only
1103// exposed via a macro ("LLD_HAS_DRIVER") which I have copied and pasted the
1104// body of here so that you don't have to wonder what it is doing.
1105namespace lld {
1106 namespace coff {
1107 bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
1108 llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput);
1109 }
1110 namespace elf {
1111 bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
1112 llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput);
1113 }
1114 namespace wasm {
1115 bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
1116 llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput);
1117 }
1118}
1119
11061120bool ZigLLDLinkCOFF(int argc, const char **argv, bool can_exit_early, bool disable_output) {
11071121 std::vector<const char *> args(argv, argv + argc);
11081122 return lld::coff::link(args, llvm::outs(), llvm::errs(), can_exit_early, disable_output);
......@@ -1249,6 +1263,7 @@ static_assert((Triple::OSType)ZigLLVM_MacOSX == Triple::MacOSX, "");
12491263static_assert((Triple::OSType)ZigLLVM_NetBSD == Triple::NetBSD, "");
12501264static_assert((Triple::OSType)ZigLLVM_OpenBSD == Triple::OpenBSD, "");
12511265static_assert((Triple::OSType)ZigLLVM_Solaris == Triple::Solaris, "");
1266static_assert((Triple::OSType)ZigLLVM_UEFI == Triple::UEFI, "");
12521267static_assert((Triple::OSType)ZigLLVM_Win32 == Triple::Win32, "");
12531268static_assert((Triple::OSType)ZigLLVM_ZOS == Triple::ZOS, "");
12541269static_assert((Triple::OSType)ZigLLVM_Haiku == Triple::Haiku, "");
......@@ -1270,6 +1285,8 @@ static_assert((Triple::OSType)ZigLLVM_HermitCore == Triple::HermitCore, "");
12701285static_assert((Triple::OSType)ZigLLVM_Hurd == Triple::Hurd, "");
12711286static_assert((Triple::OSType)ZigLLVM_WASI == Triple::WASI, "");
12721287static_assert((Triple::OSType)ZigLLVM_Emscripten == Triple::Emscripten, "");
1288static_assert((Triple::OSType)ZigLLVM_ShaderModel == Triple::ShaderModel, "");
1289static_assert((Triple::OSType)ZigLLVM_LiteOS == Triple::LiteOS, "");
12731290static_assert((Triple::OSType)ZigLLVM_LastOSType == Triple::LastOSType, "");
12741291
12751292static_assert((Triple::EnvironmentType)ZigLLVM_UnknownEnvironment == Triple::UnknownEnvironment, "");
......@@ -1297,6 +1314,22 @@ static_assert((Triple::EnvironmentType)ZigLLVM_Cygnus == Triple::Cygnus, "");
12971314static_assert((Triple::EnvironmentType)ZigLLVM_CoreCLR == Triple::CoreCLR, "");
12981315static_assert((Triple::EnvironmentType)ZigLLVM_Simulator == Triple::Simulator, "");
12991316static_assert((Triple::EnvironmentType)ZigLLVM_MacABI == Triple::MacABI, "");
1317static_assert((Triple::EnvironmentType)ZigLLVM_Pixel == Triple::Pixel, "");
1318static_assert((Triple::EnvironmentType)ZigLLVM_Vertex == Triple::Vertex, "");
1319static_assert((Triple::EnvironmentType)ZigLLVM_Geometry == Triple::Geometry, "");
1320static_assert((Triple::EnvironmentType)ZigLLVM_Hull == Triple::Hull, "");
1321static_assert((Triple::EnvironmentType)ZigLLVM_Domain == Triple::Domain, "");
1322static_assert((Triple::EnvironmentType)ZigLLVM_Compute == Triple::Compute, "");
1323static_assert((Triple::EnvironmentType)ZigLLVM_Library == Triple::Library, "");
1324static_assert((Triple::EnvironmentType)ZigLLVM_RayGeneration == Triple::RayGeneration, "");
1325static_assert((Triple::EnvironmentType)ZigLLVM_Intersection == Triple::Intersection, "");
1326static_assert((Triple::EnvironmentType)ZigLLVM_AnyHit == Triple::AnyHit, "");
1327static_assert((Triple::EnvironmentType)ZigLLVM_ClosestHit == Triple::ClosestHit, "");
1328static_assert((Triple::EnvironmentType)ZigLLVM_Miss == Triple::Miss, "");
1329static_assert((Triple::EnvironmentType)ZigLLVM_Callable == Triple::Callable, "");
1330static_assert((Triple::EnvironmentType)ZigLLVM_Mesh == Triple::Mesh, "");
1331static_assert((Triple::EnvironmentType)ZigLLVM_Amplification == Triple::Amplification, "");
1332static_assert((Triple::EnvironmentType)ZigLLVM_OpenHOS == Triple::OpenHOS, "");
13001333static_assert((Triple::EnvironmentType)ZigLLVM_LastEnvironmentType == Triple::LastEnvironmentType, "");
13011334
13021335static_assert((Triple::ObjectFormatType)ZigLLVM_UnknownObjectFormat == Triple::UnknownObjectFormat, "");
......@@ -1334,8 +1367,8 @@ static_assert((CallingConv::ID)ZigLLVM_Intel_OCL_BI == llvm::CallingConv::Intel_
13341367static_assert((CallingConv::ID)ZigLLVM_X86_64_SysV == llvm::CallingConv::X86_64_SysV, "");
13351368static_assert((CallingConv::ID)ZigLLVM_Win64 == llvm::CallingConv::Win64, "");
13361369static_assert((CallingConv::ID)ZigLLVM_X86_VectorCall == llvm::CallingConv::X86_VectorCall, "");
1337static_assert((CallingConv::ID)ZigLLVM_HHVM == llvm::CallingConv::HHVM, "");
1338static_assert((CallingConv::ID)ZigLLVM_HHVM_C == llvm::CallingConv::HHVM_C, "");
1370static_assert((CallingConv::ID)ZigLLVM_DUMMY_HHVM == llvm::CallingConv::DUMMY_HHVM, "");
1371static_assert((CallingConv::ID)ZigLLVM_DUMMY_HHVM_C == llvm::CallingConv::DUMMY_HHVM_C, "");
13391372static_assert((CallingConv::ID)ZigLLVM_X86_INTR == llvm::CallingConv::X86_INTR, "");
13401373static_assert((CallingConv::ID)ZigLLVM_AVR_INTR == llvm::CallingConv::AVR_INTR, "");
13411374static_assert((CallingConv::ID)ZigLLVM_AVR_SIGNAL == llvm::CallingConv::AVR_SIGNAL, "");
src/zig_llvm.h+7-5
......@@ -13,7 +13,6 @@
1313#include <llvm-c/Core.h>
1414#include <llvm-c/Analysis.h>
1515#include <llvm-c/Target.h>
16#include <llvm-c/Initialization.h>
1716#include <llvm-c/TargetMachine.h>
1817
1918#ifdef __cplusplus
......@@ -102,8 +101,8 @@ enum ZigLLVM_CallingConv {
102101 ZigLLVM_X86_64_SysV = 78,
103102 ZigLLVM_Win64 = 79,
104103 ZigLLVM_X86_VectorCall = 80,
105 ZigLLVM_HHVM = 81,
106 ZigLLVM_HHVM_C = 82,
104 ZigLLVM_DUMMY_HHVM = 81,
105 ZigLLVM_DUMMY_HHVM_C = 82,
107106 ZigLLVM_X86_INTR = 83,
108107 ZigLLVM_AVR_INTR = 84,
109108 ZigLLVM_AVR_SIGNAL = 85,
......@@ -402,6 +401,7 @@ enum ZigLLVM_OSType {
402401 ZigLLVM_NetBSD,
403402 ZigLLVM_OpenBSD,
404403 ZigLLVM_Solaris,
404 ZigLLVM_UEFI,
405405 ZigLLVM_Win32,
406406 ZigLLVM_ZOS,
407407 ZigLLVM_Haiku,
......@@ -426,7 +426,8 @@ enum ZigLLVM_OSType {
426426 ZigLLVM_WASI, // Experimental WebAssembly OS
427427 ZigLLVM_Emscripten,
428428 ZigLLVM_ShaderModel, // DirectX ShaderModel
429 ZigLLVM_LastOSType = ZigLLVM_ShaderModel
429 ZigLLVM_LiteOS,
430 ZigLLVM_LastOSType = ZigLLVM_LiteOS
430431};
431432
432433// Synchronize with target.cpp::abi_list
......@@ -474,8 +475,9 @@ enum ZigLLVM_EnvironmentType {
474475 ZigLLVM_Callable,
475476 ZigLLVM_Mesh,
476477 ZigLLVM_Amplification,
478 ZigLLVM_OpenHOS,
477479
478 ZigLLVM_LastEnvironmentType = ZigLLVM_Amplification
480 ZigLLVM_LastEnvironmentType = ZigLLVM_OpenHOS
479481};
480482
481483enum ZigLLVM_ObjectFormatType {
test/behavior/align.zig+6-2
......@@ -546,11 +546,15 @@ test "align(N) on functions" {
546546 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
547547 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
548548 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
549 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
550549 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
551550
552 // This is not supported on MSVC
551 if (builtin.zig_backend == .stage2_c) {
552 // https://github.com/ziglang/zig/issues/16845
553 return error.SkipZigTest;
554 }
555
553556 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) {
557 // This is not supported on MSVC.
554558 return error.SkipZigTest;
555559 }
556560
test/behavior/atomics.zig+5
......@@ -243,6 +243,11 @@ test "atomicrmw with ints" {
243243 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
244244 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
245245
246 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
247 // https://github.com/ziglang/zig/issues/16846
248 return error.SkipZigTest;
249 }
250
246251 try testAtomicRmwInts();
247252 try comptime testAtomicRmwInts();
248253}
test/behavior/cast.zig+5
......@@ -1157,6 +1157,11 @@ fn foobar(func: PFN_void) !void {
11571157test "cast function with an opaque parameter" {
11581158 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
11591159
1160 if (builtin.zig_backend == .stage2_c) {
1161 // https://github.com/ziglang/zig/issues/16845
1162 return error.SkipZigTest;
1163 }
1164
11601165 const Container = struct {
11611166 const Ctx = opaque {};
11621167 ctx: *Ctx,
test/behavior/floatop.zig+5
......@@ -877,6 +877,11 @@ test "another, possibly redundant, @trunc test" {
877877 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
878878 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
879879
880 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
881 // https://github.com/ziglang/zig/issues/16846
882 return error.SkipZigTest;
883 }
884
880885 try testTruncLegacy(f64, 12.0);
881886 try comptime testTruncLegacy(f64, 12.0);
882887 try testTruncLegacy(f32, 12.0);
test/behavior/math.zig+10
......@@ -417,6 +417,11 @@ test "division" {
417417 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
418418 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
419419
420 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
421 // https://github.com/ziglang/zig/issues/16846
422 return error.SkipZigTest;
423 }
424
420425 try testDivision();
421426 try comptime testDivision();
422427}
......@@ -591,6 +596,11 @@ test "unsigned 64-bit division" {
591596 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
592597 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
593598
599 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
600 // https://github.com/ziglang/zig/issues/16846
601 return error.SkipZigTest;
602 }
603
594604 try test_u64_div();
595605 try comptime test_u64_div();
596606}
test/behavior/usingnamespace/import_segregation.zig+5
......@@ -7,6 +7,11 @@ usingnamespace @import("bar.zig");
77test "no clobbering happened" {
88 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
99
10 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
11 // https://github.com/ziglang/zig/issues/16846
12 return error.SkipZigTest;
13 }
14
1015 @This().foo_function();
1116 @This().bar_function();
1217 try expect(@This().saw_foo_function);
test/behavior/var_args.zig+4-1
......@@ -232,7 +232,10 @@ test "unused VaList arg" {
232232 // https://github.com/ziglang/zig/issues/14096
233233 return error.SkipZigTest;
234234 }
235 if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) return error.SkipZigTest; // TODO
235 if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) {
236 // https://github.com/ziglang/zig/issues/16961
237 return error.SkipZigTest; // TODO
238 }
236239
237240 const S = struct {
238241 fn thirdArg(dummy: c_int, ...) callconv(.C) c_int {
test/link.zig+10-8
......@@ -30,10 +30,11 @@ pub const cases = [_]Case{
3030 },
3131
3232 // WASM Cases
33 .{
34 .build_root = "test/link/wasm/archive",
35 .import = @import("link/wasm/archive/build.zig"),
36 },
33 // https://github.com/ziglang/zig/issues/16938
34 //.{
35 // .build_root = "test/link/wasm/archive",
36 // .import = @import("link/wasm/archive/build.zig"),
37 //},
3738 .{
3839 .build_root = "test/link/wasm/basic-features",
3940 .import = @import("link/wasm/basic-features/build.zig"),
......@@ -46,10 +47,11 @@ pub const cases = [_]Case{
4647 .build_root = "test/link/wasm/export",
4748 .import = @import("link/wasm/export/build.zig"),
4849 },
49 .{
50 .build_root = "test/link/wasm/export-data",
51 .import = @import("link/wasm/export-data/build.zig"),
52 },
50 // https://github.com/ziglang/zig/issues/16937
51 //.{
52 // .build_root = "test/link/wasm/export-data",
53 // .import = @import("link/wasm/export-data/build.zig"),
54 //},
5355 .{
5456 .build_root = "test/link/wasm/extern",
5557 .import = @import("link/wasm/extern/build.zig"),
test/standalone/c_compiler/build.zig+18-7
......@@ -5,17 +5,28 @@ pub fn build(b: *std.Build) void {
55 const test_step = b.step("test", "Test it");
66 b.default_step = test_step;
77
8 add(b, test_step, .Debug);
9 add(b, test_step, .ReleaseFast);
10 add(b, test_step, .ReleaseSmall);
11 add(b, test_step, .ReleaseSafe);
8 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64) {
9 // https://github.com/ziglang/zig/issues/16965
10 return;
11 }
12
13 add(b, test_step, "test_c_Debug", "test_cpp_Debug", .Debug);
14 add(b, test_step, "test_c_ReleaseFast", "test_cpp_ReleaseFast", .ReleaseFast);
15 add(b, test_step, "test_c_ReleaseSmall", "test_cpp_ReleaseSmall", .ReleaseSmall);
16 add(b, test_step, "test_c_ReleaseSafe", "test_cpp_ReleaseSafe", .ReleaseSafe);
1217}
1318
14fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
19fn add(
20 b: *std.Build,
21 test_step: *std.Build.Step,
22 c_name: []const u8,
23 cpp_name: []const u8,
24 optimize: std.builtin.OptimizeMode,
25) void {
1526 const target: std.zig.CrossTarget = .{};
1627
1728 const exe_c = b.addExecutable(.{
18 .name = "test_c",
29 .name = c_name,
1930 .optimize = optimize,
2031 .target = target,
2132 });
......@@ -23,7 +34,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
2334 exe_c.linkLibC();
2435
2536 const exe_cpp = b.addExecutable(.{
26 .name = "test_cpp",
37 .name = cpp_name,
2738 .optimize = optimize,
2839 .target = target,
2940 });
test/standalone/load_dynamic_library/build.zig+5
......@@ -10,6 +10,11 @@ pub fn build(b: *std.Build) void {
1010
1111 if (builtin.os.tag == .wasi) return;
1212
13 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64) {
14 // https://github.com/ziglang/zig/issues/16960
15 return;
16 }
17
1318 const lib = b.addSharedLibrary(.{
1419 .name = "add",
1520 .root_source_file = .{ .path = "add.zig" },
test/standalone/shared_library/build.zig+7
......@@ -4,6 +4,13 @@ pub fn build(b: *std.Build) void {
44 const test_step = b.step("test", "Test it");
55 b.default_step = test_step;
66
7 if (@import("builtin").os.tag == .windows and
8 @import("builtin").cpu.arch == .aarch64)
9 {
10 // https://github.com/ziglang/zig/issues/16959
11 return;
12 }
13
714 const optimize: std.builtin.OptimizeMode = .Debug;
815 const target: std.zig.CrossTarget = .{};
916 const lib = b.addSharedLibrary(.{
test/tests.zig+34-30
......@@ -275,22 +275,24 @@ const test_targets = blk: {
275275 // .link_libc = true,
276276 //},
277277
278 .{
279 .target = .{
280 .cpu_arch = .mips,
281 .os_tag = .linux,
282 .abi = .none,
283 },
284 },
278 // https://github.com/ziglang/zig/issues/16846
279 //.{
280 // .target = .{
281 // .cpu_arch = .mips,
282 // .os_tag = .linux,
283 // .abi = .none,
284 // },
285 //},
285286
286 .{
287 .target = .{
288 .cpu_arch = .mips,
289 .os_tag = .linux,
290 .abi = .musl,
291 },
292 .link_libc = true,
293 },
287 // https://github.com/ziglang/zig/issues/16846
288 //.{
289 // .target = .{
290 // .cpu_arch = .mips,
291 // .os_tag = .linux,
292 // .abi = .musl,
293 // },
294 // .link_libc = true,
295 //},
294296
295297 // https://github.com/ziglang/zig/issues/4927
296298 //.{
......@@ -302,22 +304,24 @@ const test_targets = blk: {
302304 // .link_libc = true,
303305 //},
304306
305 .{
306 .target = .{
307 .cpu_arch = .mipsel,
308 .os_tag = .linux,
309 .abi = .none,
310 },
311 },
307 // https://github.com/ziglang/zig/issues/16846
308 //.{
309 // .target = .{
310 // .cpu_arch = .mipsel,
311 // .os_tag = .linux,
312 // .abi = .none,
313 // },
314 //},
312315
313 .{
314 .target = .{
315 .cpu_arch = .mipsel,
316 .os_tag = .linux,
317 .abi = .musl,
318 },
319 .link_libc = true,
320 },
316 // https://github.com/ziglang/zig/issues/16846
317 //.{
318 // .target = .{
319 // .cpu_arch = .mipsel,
320 // .os_tag = .linux,
321 // .abi = .musl,
322 // },
323 // .link_libc = true,
324 //},
321325
322326 // https://github.com/ziglang/zig/issues/4927
323327 //.{
tools/update_cpu_features.zig+38
......@@ -40,6 +40,7 @@ const LlvmTarget = struct {
4040 feature_overrides: []const FeatureOverride = &.{},
4141 extra_cpus: []const Cpu = &.{},
4242 extra_features: []const Feature = &.{},
43 omit_cpus: []const []const u8 = &.{},
4344 branch_quota: ?usize = null,
4445};
4546
......@@ -915,6 +916,39 @@ const llvm_targets = [_]LlvmTarget{
915916 .extra_deps = &.{"soft_float"},
916917 },
917918 },
919 .omit_cpus = &.{
920 // LLVM defines a bunch of dumb aliases with foreach loops in X86.td.
921 "pentium_mmx",
922 "pentium_pro",
923 "pentium_ii",
924 "pentium_3m",
925 "pentium_iii_no_xmm_regs",
926 "pentium_iii",
927 "pentium_m",
928 "pentium4m",
929 "pentium_4",
930 "pentium_4_sse3",
931 "core_2_duo_ssse3",
932 "core_2_duo_sse4_1",
933 "atom_sse4_2",
934 "goldmont_plus",
935 "core_i7_sse4_2",
936 "core_aes_pclmulqdq",
937 "corei7-avx",
938 "core_2nd_gen_avx",
939 "core-avx-i",
940 "core_3rd_gen_avx",
941 "core-avx2",
942 "core_4th_gen_avx",
943 "core_4th_gen_avx_tsx",
944 "core_5th_gen_avx",
945 "core_5th_gen_avx_tsx",
946 "mic_avx512",
947 "skylake_avx512",
948 "icelake_client",
949 "icelake_server",
950 "graniterapids_d",
951 },
918952 },
919953 .{
920954 .zig_name = "xcore",
......@@ -1129,6 +1163,10 @@ fn processOneTarget(job: Job) anyerror!void {
11291163 if (hasSuperclass(&kv.value_ptr.object, "Processor")) {
11301164 const llvm_name = kv.value_ptr.object.get("Name").?.string;
11311165 if (llvm_name.len == 0) continue;
1166 const omitted = for (llvm_target.omit_cpus) |omit_cpu_name| {
1167 if (mem.eql(u8, omit_cpu_name, llvm_name)) break true;
1168 } else false;
1169 if (omitted) continue;
11321170
11331171 var zig_name = try llvmNameToZigName(arena, llvm_name);
11341172 var deps = std.ArrayList([]const u8).init(arena);