Add libcxx and libunwind
This commit is contained in:
parent
809de4411d
commit
f7e0435931
@ -166,7 +166,7 @@ const MuslContext = struct {
|
||||
}
|
||||
};
|
||||
|
||||
const CSourceKind = enum{
|
||||
const CSourceKind = enum {
|
||||
c,
|
||||
cpp,
|
||||
};
|
||||
@ -264,16 +264,40 @@ pub fn compileCSourceFile(context: *const Context, arguments: [][*:0]u8, kind: C
|
||||
try clang_args.append(context.my_allocator, context.executable_absolute_path);
|
||||
try clang_args.append(context.my_allocator, "clang");
|
||||
|
||||
if (kind == .cpp) {
|
||||
try clang_args.append(context.my_allocator, "-nostdinc++");
|
||||
|
||||
try clang_args.append_slice(context.my_allocator, &.{
|
||||
"-isystem", try context.pathFromCompiler("lib/libcxx/include"),
|
||||
"-isystem", try context.pathFromCompiler("lib/libcxxabi/include"),
|
||||
"-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
|
||||
"-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
|
||||
"-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS",
|
||||
"-D_LIBCPP_PSTL_CPU_BACKEND_SERIAL",
|
||||
"-D_LIBCPP_ABI_VERSION=1",
|
||||
"-D_LIBCPP_ABI_NAMESPACE=__1",
|
||||
});
|
||||
switch (@import("builtin").os.tag) {
|
||||
.linux => {},
|
||||
.macos => {},
|
||||
else => @compileError("Operating system not supported"),
|
||||
}
|
||||
}
|
||||
|
||||
if (kind == .c or kind == .cpp) {
|
||||
try clang_args.append(context.my_allocator, "-nostdinc");
|
||||
|
||||
switch (@import("builtin").os.tag) {
|
||||
.linux => {
|
||||
try clang_args.append_slice(context.my_allocator, &.{ "-isystem", "/home/david/dev/zig/lib/include", "-isystem", "/home/david/dev/zig/lib/libc/include/x86_64-linux-gnu", "-isystem", "/home/david/dev/zig/lib/libc/include/generic-glibc", "-isystem", "/home/david/dev/zig/lib/libc/include/x86-linux-any", "-isystem", "/home/david/dev/zig/lib/libc/include/any-linux-any" });
|
||||
try clang_args.append(context.my_allocator, "-isystem");
|
||||
try clang_args.append(context.my_allocator, "/usr/include");
|
||||
try clang_args.append(context.my_allocator, "-isystem");
|
||||
try clang_args.append(context.my_allocator, "/usr/include/linux");
|
||||
try clang_args.append_slice(context.my_allocator, &.{
|
||||
"-isystem", try context.pathFromCompiler("lib/include"),
|
||||
"-isystem", try context.pathFromCompiler("lib/libc/include/x86_64-linux-gnu"),
|
||||
"-isystem", try context.pathFromCompiler("lib/libc/include/generic-glibc"),
|
||||
"-isystem", try context.pathFromCompiler("lib/libc/include/x86-linux-any"),
|
||||
"-isystem", try context.pathFromCompiler("lib/libc/include/any-linux-any"),
|
||||
"-isystem", "/usr/include",
|
||||
"-isystem", "/usr/include/linux",
|
||||
});
|
||||
},
|
||||
.macos => {
|
||||
try clang_args.append_slice(context.my_allocator, &.{
|
||||
@ -286,21 +310,6 @@ pub fn compileCSourceFile(context: *const Context, arguments: [][*:0]u8, kind: C
|
||||
}
|
||||
}
|
||||
|
||||
if (kind == .cpp) {
|
||||
try clang_args.append(context.my_allocator, "-nostdinc++");
|
||||
switch (@import("builtin").os.tag) {
|
||||
.linux => {
|
||||
},
|
||||
.macos => {
|
||||
try clang_args.append_slice(context.my_allocator, &.{
|
||||
"-isystem", try context.pathFromCompiler("lib/libcxx/include"),
|
||||
"-isystem", try context.pathFromCompiler("lib/libcxxabi/include"),
|
||||
});
|
||||
},
|
||||
else => @compileError("Operating system not supported"),
|
||||
}
|
||||
}
|
||||
|
||||
for (arguments) |arg| {
|
||||
try clang_args.append(context.my_allocator, span(arg));
|
||||
}
|
||||
@ -2973,7 +2982,7 @@ pub const Instruction = union(enum) {
|
||||
trap,
|
||||
@"unreachable",
|
||||
|
||||
const Memcpy = struct{
|
||||
const Memcpy = struct {
|
||||
destination: V,
|
||||
source: V,
|
||||
destination_alignment: ?u32,
|
||||
@ -6533,7 +6542,7 @@ pub const Builder = struct {
|
||||
for (0..array.count) |_| {
|
||||
const element_classes = builder.classify_systemv_x86_64(unit, context, array.type, offset);
|
||||
offset += element_size;
|
||||
const merge_result = [2]Class_SystemVx86_64{Class_SystemVx86_64.merge(result[0], element_classes[0]), Class_SystemVx86_64.merge(result[1], element_classes[1])};
|
||||
const merge_result = [2]Class_SystemVx86_64{ Class_SystemVx86_64.merge(result[0], element_classes[0]), Class_SystemVx86_64.merge(result[1], element_classes[1]) };
|
||||
result = merge_result;
|
||||
if (result[0] == .memory or result[1] == .memory) {
|
||||
break;
|
||||
@ -6890,7 +6899,7 @@ pub const Builder = struct {
|
||||
.pointer = pointer_type,
|
||||
.alignment = alignment,
|
||||
},
|
||||
},
|
||||
},
|
||||
.attributes = .{
|
||||
.by_value = true,
|
||||
},
|
||||
@ -11576,7 +11585,7 @@ pub const Builder = struct {
|
||||
.destination = argument_alloca,
|
||||
.source = argument_value,
|
||||
},
|
||||
});
|
||||
});
|
||||
try builder.appendInstruction(unit, context, store);
|
||||
|
||||
const target_type = unit.types.get(coerced_type_index);
|
||||
@ -11595,7 +11604,7 @@ pub const Builder = struct {
|
||||
.value = argument_alloca,
|
||||
.type = coerced_type_index,
|
||||
},
|
||||
});
|
||||
});
|
||||
try builder.appendInstruction(unit, context, load);
|
||||
|
||||
argument_list.append_with_capacity(V{
|
||||
@ -11634,7 +11643,7 @@ pub const Builder = struct {
|
||||
.type = coerced_type_index,
|
||||
.alignment = alignment,
|
||||
},
|
||||
});
|
||||
});
|
||||
try builder.appendInstruction(unit, context, load);
|
||||
|
||||
argument_list.append_with_capacity(V{
|
||||
@ -11730,11 +11739,10 @@ pub const Builder = struct {
|
||||
.destination = coerced_pointer,
|
||||
.source = argument_value,
|
||||
},
|
||||
});
|
||||
});
|
||||
try builder.appendInstruction(unit, context, coerced_store);
|
||||
|
||||
break :b coerced_pointer;
|
||||
|
||||
} else b: {
|
||||
const pointer_type = try unit.getPointerType(context, .{
|
||||
.type = argument_type_index,
|
||||
@ -11756,7 +11764,7 @@ pub const Builder = struct {
|
||||
.destination = argument_alloca,
|
||||
.source = argument_value,
|
||||
},
|
||||
});
|
||||
});
|
||||
try builder.appendInstruction(unit, context, store);
|
||||
|
||||
break :b argument_alloca;
|
||||
@ -11772,12 +11780,12 @@ pub const Builder = struct {
|
||||
.constant_int = .{
|
||||
.value = 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
.type = .u32,
|
||||
},
|
||||
},
|
||||
});
|
||||
.type = .u32,
|
||||
},
|
||||
},
|
||||
});
|
||||
try builder.appendInstruction(unit, context, gep0);
|
||||
|
||||
const load0 = try unit.instructions.append(context.my_allocator, .{
|
||||
@ -11796,7 +11804,7 @@ pub const Builder = struct {
|
||||
},
|
||||
.type = pair[0],
|
||||
},
|
||||
});
|
||||
});
|
||||
try builder.appendInstruction(unit, context, load0);
|
||||
|
||||
const gep1 = try unit.instructions.append(context.my_allocator, .{
|
||||
@ -11810,12 +11818,12 @@ pub const Builder = struct {
|
||||
.constant_int = .{
|
||||
.value = 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
.type = .u32,
|
||||
},
|
||||
},
|
||||
});
|
||||
.type = .u32,
|
||||
},
|
||||
},
|
||||
});
|
||||
try builder.appendInstruction(unit, context, gep1);
|
||||
|
||||
const load1 = try unit.instructions.append(context.my_allocator, .{
|
||||
@ -11834,10 +11842,9 @@ pub const Builder = struct {
|
||||
},
|
||||
.type = pair[1],
|
||||
},
|
||||
});
|
||||
});
|
||||
try builder.appendInstruction(unit, context, load1);
|
||||
|
||||
|
||||
argument_list.append_with_capacity(V{
|
||||
.value = .{
|
||||
.runtime = load0,
|
||||
@ -14014,7 +14021,7 @@ pub const Builder = struct {
|
||||
.type = struct_type_index,
|
||||
.alignment = alignment,
|
||||
},
|
||||
});
|
||||
});
|
||||
try builder.appendInstruction(unit, context, load);
|
||||
|
||||
break :b V{
|
||||
@ -15091,8 +15098,11 @@ pub const Unit = struct {
|
||||
const dot_index = data_structures.last(c_src, '.') orelse unreachable;
|
||||
const path_without_extension = c_src[0..dot_index];
|
||||
const basename = std.fs.path.basename(path_without_extension);
|
||||
const o_file = try std.mem.concat(context.allocator, u8, &.{ basename, ".o"});
|
||||
const basename_z = try std.mem.joinZ(context.allocator, "/", &.{ "nat", o_file, });
|
||||
const o_file = try std.mem.concat(context.allocator, u8, &.{ basename, ".o" });
|
||||
const basename_z = try std.mem.joinZ(context.allocator, "/", &.{
|
||||
"nat",
|
||||
o_file,
|
||||
});
|
||||
var c_flag = "-c".*;
|
||||
var o_flag = "-o".*;
|
||||
var g_flag = "-g".*;
|
||||
|
311
lib/libcxx/LICENSE.TXT
Normal file
311
lib/libcxx/LICENSE.TXT
Normal file
@ -0,0 +1,311 @@
|
||||
==============================================================================
|
||||
The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
|
||||
==============================================================================
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
---- LLVM Exceptions to the Apache 2.0 License ----
|
||||
|
||||
As an exception, if, as a result of your compiling your source code, portions
|
||||
of this Software are embedded into an Object form of such source code, you
|
||||
may redistribute such embedded portions in such Object form without complying
|
||||
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
|
||||
|
||||
In addition, if you combine or link compiled forms of this Software with
|
||||
software that is licensed under the GPLv2 ("Combined Software") and if a
|
||||
court of competent jurisdiction determines that the patent provision (Section
|
||||
3), the indemnity provision (Section 9) or other Section of the License
|
||||
conflicts with the conditions of the GPLv2, you may retroactively and
|
||||
prospectively choose to deem waived or otherwise exclude such Section(s) of
|
||||
the License, but only in their entirety and only with respect to the Combined
|
||||
Software.
|
||||
|
||||
==============================================================================
|
||||
Software from third parties included in the LLVM Project:
|
||||
==============================================================================
|
||||
The LLVM Project contains third party software which is under different license
|
||||
terms. All such code will be identified clearly using at least one of two
|
||||
mechanisms:
|
||||
1) It will be in a separate directory tree with its own `LICENSE.txt` or
|
||||
`LICENSE` file at the top containing the specific license and restrictions
|
||||
which apply to that software, or
|
||||
2) It will contain specific license and restriction terms at the top of every
|
||||
file.
|
||||
|
||||
==============================================================================
|
||||
Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
|
||||
==============================================================================
|
||||
|
||||
The libc++ library is dual licensed under both the University of Illinois
|
||||
"BSD-Like" license and the MIT license. As a user of this code you may choose
|
||||
to use it under either license. As a contributor, you agree to allow your code
|
||||
to be used under both.
|
||||
|
||||
Full text of the relevant licenses is included below.
|
||||
|
||||
==============================================================================
|
||||
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2009-2019 by the contributors listed in CREDITS.TXT
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
||||
LLVM Team
|
||||
|
||||
University of Illinois at Urbana-Champaign
|
||||
|
||||
http://llvm.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal with
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimers.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimers in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of the LLVM Team, University of Illinois at
|
||||
Urbana-Champaign, nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this Software without specific
|
||||
prior written permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
||||
SOFTWARE.
|
||||
|
||||
==============================================================================
|
||||
|
||||
Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
58
lib/libcxx/include/__algorithm/adjacent_find.h
Normal file
58
lib/libcxx/include/__algorithm/adjacent_find.h
Normal file
@ -0,0 +1,58 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_ADJACENT_FIND_H
|
||||
#define _LIBCPP___ALGORITHM_ADJACENT_FIND_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Iter, class _Sent, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter
|
||||
__adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) {
|
||||
if (__first == __last)
|
||||
return __first;
|
||||
_Iter __i = __first;
|
||||
while (++__i != __last) {
|
||||
if (__pred(*__first, *__i))
|
||||
return __first;
|
||||
__first = __i;
|
||||
}
|
||||
return __i;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) {
|
||||
return std::__adjacent_find(std::move(__first), std::move(__last), __pred);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
adjacent_find(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
return std::adjacent_find(std::move(__first), std::move(__last), __equal_to());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_ADJACENT_FIND_H
|
32
lib/libcxx/include/__algorithm/all_of.h
Normal file
32
lib/libcxx/include/__algorithm/all_of.h
Normal file
@ -0,0 +1,32 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_ALL_OF_H
|
||||
#define _LIBCPP___ALGORITHM_ALL_OF_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||
for (; __first != __last; ++__first)
|
||||
if (!__pred(*__first))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_ALL_OF_H
|
32
lib/libcxx/include/__algorithm/any_of.h
Normal file
32
lib/libcxx/include/__algorithm/any_of.h
Normal file
@ -0,0 +1,32 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_ANY_OF_H
|
||||
#define _LIBCPP___ALGORITHM_ANY_OF_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||
for (; __first != __last; ++__first)
|
||||
if (__pred(*__first))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_ANY_OF_H
|
45
lib/libcxx/include/__algorithm/binary_search.h
Normal file
45
lib/libcxx/include/__algorithm/binary_search.h
Normal file
@ -0,0 +1,45 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_BINARY_SEARCH_H
|
||||
#define _LIBCPP___ALGORITHM_BINARY_SEARCH_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/lower_bound.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator, class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
bool
|
||||
binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp)
|
||||
{
|
||||
__first = std::lower_bound<_ForwardIterator, _Tp, __comp_ref_type<_Compare> >(__first, __last, __value, __comp);
|
||||
return __first != __last && !__comp(__value, *__first);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Tp>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
bool
|
||||
binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
|
||||
{
|
||||
return std::binary_search(__first, __last, __value, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_BINARY_SEARCH_H
|
46
lib/libcxx/include/__algorithm/clamp.h
Normal file
46
lib/libcxx/include/__algorithm/clamp.h
Normal file
@ -0,0 +1,46 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_CLAMP_H
|
||||
#define _LIBCPP___ALGORITHM_CLAMP_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__assert>
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
template<class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY constexpr
|
||||
const _Tp&
|
||||
clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp)
|
||||
{
|
||||
_LIBCPP_ASSERT_UNCATEGORIZED(!__comp(__hi, __lo), "Bad bounds passed to std::clamp");
|
||||
return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v;
|
||||
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY constexpr
|
||||
const _Tp&
|
||||
clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi)
|
||||
{
|
||||
return _VSTD::clamp(__v, __lo, __hi, __less<>());
|
||||
}
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_CLAMP_H
|
47
lib/libcxx/include/__algorithm/comp.h
Normal file
47
lib/libcxx/include/__algorithm/comp.h
Normal file
@ -0,0 +1,47 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_COMP_H
|
||||
#define _LIBCPP___ALGORITHM_COMP_H
|
||||
|
||||
#include <__config>
|
||||
#include <__type_traits/integral_constant.h>
|
||||
#include <__type_traits/predicate_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
struct __equal_to {
|
||||
template <class _T1, class _T2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _T1& __x, const _T2& __y) const {
|
||||
return __x == __y;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Lhs, class _Rhs>
|
||||
struct __is_trivial_equality_predicate<__equal_to, _Lhs, _Rhs> : true_type {};
|
||||
|
||||
// The definition is required because __less is part of the ABI, but it's empty
|
||||
// because all comparisons should be transparent.
|
||||
template <class _T1 = void, class _T2 = _T1>
|
||||
struct __less {};
|
||||
|
||||
template <>
|
||||
struct __less<void, void> {
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __lhs, const _Up& __rhs) const {
|
||||
return __lhs < __rhs;
|
||||
}
|
||||
};
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COMP_H
|
78
lib/libcxx/include/__algorithm/comp_ref_type.h
Normal file
78
lib/libcxx/include/__algorithm/comp_ref_type.h
Normal file
@ -0,0 +1,78 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
|
||||
#define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
|
||||
|
||||
#include <__assert>
|
||||
#include <__config>
|
||||
#include <__utility/declval.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare>
|
||||
struct __debug_less
|
||||
{
|
||||
_Compare &__comp_;
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI __debug_less(_Compare& __c) : __comp_(__c) {}
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
|
||||
bool operator()(const _Tp& __x, const _Up& __y)
|
||||
{
|
||||
bool __r = __comp_(__x, __y);
|
||||
if (__r)
|
||||
__do_compare_assert(0, __y, __x);
|
||||
return __r;
|
||||
}
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
|
||||
bool operator()(_Tp& __x, _Up& __y)
|
||||
{
|
||||
bool __r = __comp_(__x, __y);
|
||||
if (__r)
|
||||
__do_compare_assert(0, __y, __x);
|
||||
return __r;
|
||||
}
|
||||
|
||||
template <class _LHS, class _RHS>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
decltype((void)std::declval<_Compare&>()(
|
||||
std::declval<_LHS &>(), std::declval<_RHS &>()))
|
||||
__do_compare_assert(int, _LHS & __l, _RHS & __r) {
|
||||
_LIBCPP_ASSERT_UNCATEGORIZED(!__comp_(__l, __r),
|
||||
"Comparator does not induce a strict weak ordering");
|
||||
(void)__l;
|
||||
(void)__r;
|
||||
}
|
||||
|
||||
template <class _LHS, class _RHS>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void __do_compare_assert(long, _LHS &, _RHS &) {}
|
||||
};
|
||||
|
||||
// Pass the comparator by lvalue reference. Or in debug mode, using a
|
||||
// debugging wrapper that stores a reference.
|
||||
#if _LIBCPP_ENABLE_DEBUG_MODE
|
||||
template <class _Comp>
|
||||
using __comp_ref_type = __debug_less<_Comp>;
|
||||
#else
|
||||
template <class _Comp>
|
||||
using __comp_ref_type = _Comp&;
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
|
124
lib/libcxx/include/__algorithm/copy.h
Normal file
124
lib/libcxx/include/__algorithm/copy.h
Normal file
@ -0,0 +1,124 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_COPY_H
|
||||
#define _LIBCPP___ALGORITHM_COPY_H
|
||||
|
||||
#include <__algorithm/copy_move_common.h>
|
||||
#include <__algorithm/for_each_segment.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__config>
|
||||
#include <__iterator/segmented_iterator.h>
|
||||
#include <__type_traits/common_type.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class, class _InIter, class _Sent, class _OutIter>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __copy(_InIter, _Sent, _OutIter);
|
||||
|
||||
template <class _AlgPolicy>
|
||||
struct __copy_loop {
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result) const {
|
||||
while (__first != __last) {
|
||||
*__result = *__first;
|
||||
++__first;
|
||||
++__result;
|
||||
}
|
||||
|
||||
return std::make_pair(std::move(__first), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter, class _OutIter>
|
||||
struct _CopySegment {
|
||||
using _Traits = __segmented_iterator_traits<_InIter>;
|
||||
|
||||
_OutIter& __result_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _CopySegment(_OutIter& __result) : __result_(__result) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
|
||||
__result_ = std::__copy<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
std::__for_each_segment(__first, __last, _CopySegment<_InIter, _OutIter>(__result));
|
||||
return std::make_pair(__last, std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter,
|
||||
class _OutIter,
|
||||
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
||||
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
using _Traits = __segmented_iterator_traits<_OutIter>;
|
||||
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
|
||||
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__first), std::move(__result));
|
||||
|
||||
auto __local_first = _Traits::__local(__result);
|
||||
auto __segment_iterator = _Traits::__segment(__result);
|
||||
while (true) {
|
||||
auto __local_last = _Traits::__end(__segment_iterator);
|
||||
auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
|
||||
auto __iters = std::__copy<_AlgPolicy>(__first, __first + __size, __local_first);
|
||||
__first = std::move(__iters.first);
|
||||
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.second)));
|
||||
|
||||
__local_first = _Traits::__begin(++__segment_iterator);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct __copy_trivial {
|
||||
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
|
||||
template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
|
||||
operator()(_In* __first, _In* __last, _Out* __result) const {
|
||||
return std::__copy_trivial_impl(__first, __last, __result);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
|
||||
pair<_InIter, _OutIter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
__copy(_InIter __first, _Sent __last, _OutIter __result) {
|
||||
return std::__dispatch_copy_or_move<_AlgPolicy, __copy_loop<_AlgPolicy>, __copy_trivial>(
|
||||
std::move(__first), std::move(__last), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _OutputIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||
copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
|
||||
return std::__copy<_ClassicAlgPolicy>(__first, __last, __result).second;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COPY_H
|
143
lib/libcxx/include/__algorithm/copy_backward.h
Normal file
143
lib/libcxx/include/__algorithm/copy_backward.h
Normal file
@ -0,0 +1,143 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_COPY_BACKWARD_H
|
||||
#define _LIBCPP___ALGORITHM_COPY_BACKWARD_H
|
||||
|
||||
#include <__algorithm/copy_move_common.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__config>
|
||||
#include <__iterator/segmented_iterator.h>
|
||||
#include <__type_traits/common_type.h>
|
||||
#include <__type_traits/is_copy_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
|
||||
__copy_backward(_InIter __first, _Sent __last, _OutIter __result);
|
||||
|
||||
template <class _AlgPolicy>
|
||||
struct __copy_backward_loop {
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result) const {
|
||||
auto __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
|
||||
auto __original_last_iter = __last_iter;
|
||||
|
||||
while (__first != __last_iter) {
|
||||
*--__result = *--__last_iter;
|
||||
}
|
||||
|
||||
return std::make_pair(std::move(__original_last_iter), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
using _Traits = __segmented_iterator_traits<_InIter>;
|
||||
auto __sfirst = _Traits::__segment(__first);
|
||||
auto __slast = _Traits::__segment(__last);
|
||||
if (__sfirst == __slast) {
|
||||
auto __iters =
|
||||
std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
|
||||
return std::make_pair(__last, __iters.second);
|
||||
}
|
||||
|
||||
__result =
|
||||
std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
|
||||
.second;
|
||||
--__slast;
|
||||
while (__sfirst != __slast) {
|
||||
__result =
|
||||
std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
|
||||
.second;
|
||||
--__slast;
|
||||
}
|
||||
__result = std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
|
||||
.second;
|
||||
return std::make_pair(__last, std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter,
|
||||
class _OutIter,
|
||||
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
||||
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
using _Traits = __segmented_iterator_traits<_OutIter>;
|
||||
auto __orig_last = __last;
|
||||
auto __segment_iterator = _Traits::__segment(__result);
|
||||
|
||||
// When the range contains no elements, __result might not be a valid iterator
|
||||
if (__first == __last)
|
||||
return std::make_pair(__first, __result);
|
||||
|
||||
auto __local_last = _Traits::__local(__result);
|
||||
while (true) {
|
||||
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
|
||||
|
||||
auto __local_first = _Traits::__begin(__segment_iterator);
|
||||
auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
|
||||
auto __iter = std::__copy_backward<_AlgPolicy>(__last - __size, __last, __local_last).second;
|
||||
__last -= __size;
|
||||
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter)));
|
||||
--__segment_iterator;
|
||||
__local_last = _Traits::__end(__segment_iterator);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct __copy_backward_trivial {
|
||||
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
|
||||
template <class _In, class _Out,
|
||||
__enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
|
||||
operator()(_In* __first, _In* __last, _Out* __result) const {
|
||||
return std::__copy_backward_trivial_impl(__first, __last, __result);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, class _BidirectionalIterator2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
|
||||
__copy_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) {
|
||||
return std::__dispatch_copy_or_move<_AlgPolicy, __copy_backward_loop<_AlgPolicy>, __copy_backward_trivial>(
|
||||
std::move(__first), std::move(__last), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator1, class _BidirectionalIterator2>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_BidirectionalIterator2
|
||||
copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
|
||||
_BidirectionalIterator2 __result)
|
||||
{
|
||||
static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value &&
|
||||
std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible.");
|
||||
|
||||
return std::__copy_backward<_ClassicAlgPolicy>(
|
||||
std::move(__first), std::move(__last), std::move(__result)).second;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COPY_BACKWARD_H
|
39
lib/libcxx/include/__algorithm/copy_if.h
Normal file
39
lib/libcxx/include/__algorithm/copy_if.h
Normal file
@ -0,0 +1,39 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_COPY_IF_H
|
||||
#define _LIBCPP___ALGORITHM_COPY_IF_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template<class _InputIterator, class _OutputIterator, class _Predicate>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_OutputIterator
|
||||
copy_if(_InputIterator __first, _InputIterator __last,
|
||||
_OutputIterator __result, _Predicate __pred)
|
||||
{
|
||||
for (; __first != __last; ++__first)
|
||||
{
|
||||
if (__pred(*__first))
|
||||
{
|
||||
*__result = *__first;
|
||||
++__result;
|
||||
}
|
||||
}
|
||||
return __result;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COPY_IF_H
|
138
lib/libcxx/include/__algorithm/copy_move_common.h
Normal file
138
lib/libcxx/include/__algorithm/copy_move_common.h
Normal file
@ -0,0 +1,138 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H
|
||||
#define _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/unwrap_iter.h>
|
||||
#include <__algorithm/unwrap_range.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__memory/pointer_traits.h>
|
||||
#include <__string/constexpr_c_functions.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_always_bitcastable.h>
|
||||
#include <__type_traits/is_constant_evaluated.h>
|
||||
#include <__type_traits/is_copy_constructible.h>
|
||||
#include <__type_traits/is_trivially_assignable.h>
|
||||
#include <__type_traits/is_trivially_copyable.h>
|
||||
#include <__type_traits/is_volatile.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// Type traits.
|
||||
|
||||
template <class _From, class _To>
|
||||
struct __can_lower_copy_assignment_to_memmove {
|
||||
static const bool value =
|
||||
// If the types are always bitcastable, it's valid to do a bitwise copy between them.
|
||||
__is_always_bitcastable<_From, _To>::value &&
|
||||
// Reject conversions that wouldn't be performed by the regular built-in assignment (e.g. between arrays).
|
||||
is_trivially_assignable<_To&, const _From&>::value &&
|
||||
// `memmove` doesn't accept `volatile` pointers, make sure the optimization SFINAEs away in that case.
|
||||
!is_volatile<_From>::value &&
|
||||
!is_volatile<_To>::value;
|
||||
};
|
||||
|
||||
template <class _From, class _To>
|
||||
struct __can_lower_move_assignment_to_memmove {
|
||||
static const bool value =
|
||||
__is_always_bitcastable<_From, _To>::value &&
|
||||
is_trivially_assignable<_To&, _From&&>::value &&
|
||||
!is_volatile<_From>::value &&
|
||||
!is_volatile<_To>::value;
|
||||
};
|
||||
|
||||
// `memmove` algorithms implementation.
|
||||
|
||||
template <class _In, class _Out>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
|
||||
__copy_trivial_impl(_In* __first, _In* __last, _Out* __result) {
|
||||
const size_t __n = static_cast<size_t>(__last - __first);
|
||||
|
||||
std::__constexpr_memmove(__result, __first, __element_count(__n));
|
||||
|
||||
return std::make_pair(__last, __result + __n);
|
||||
}
|
||||
|
||||
template <class _In, class _Out>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
|
||||
__copy_backward_trivial_impl(_In* __first, _In* __last, _Out* __result) {
|
||||
const size_t __n = static_cast<size_t>(__last - __first);
|
||||
__result -= __n;
|
||||
|
||||
std::__constexpr_memmove(__result, __first, __element_count(__n));
|
||||
|
||||
return std::make_pair(__last, __result);
|
||||
}
|
||||
|
||||
// Iterator unwrapping and dispatching to the correct overload.
|
||||
|
||||
template <class _F1, class _F2>
|
||||
struct __overload : _F1, _F2 {
|
||||
using _F1::operator();
|
||||
using _F2::operator();
|
||||
};
|
||||
|
||||
template <class _InIter, class _Sent, class _OutIter, class = void>
|
||||
struct __can_rewrap : false_type {};
|
||||
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
struct __can_rewrap<_InIter,
|
||||
_Sent,
|
||||
_OutIter,
|
||||
// Note that sentinels are always copy-constructible.
|
||||
__enable_if_t< is_copy_constructible<_InIter>::value &&
|
||||
is_copy_constructible<_OutIter>::value > > : true_type {};
|
||||
|
||||
template <class _Algorithm,
|
||||
class _InIter,
|
||||
class _Sent,
|
||||
class _OutIter,
|
||||
__enable_if_t<__can_rewrap<_InIter, _Sent, _OutIter>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
|
||||
__unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) {
|
||||
auto __range = std::__unwrap_range(__first, std::move(__last));
|
||||
auto __result = _Algorithm()(std::move(__range.first), std::move(__range.second), std::__unwrap_iter(__out_first));
|
||||
return std::make_pair(std::__rewrap_range<_Sent>(std::move(__first), std::move(__result.first)),
|
||||
std::__rewrap_iter(std::move(__out_first), std::move(__result.second)));
|
||||
}
|
||||
|
||||
template <class _Algorithm,
|
||||
class _InIter,
|
||||
class _Sent,
|
||||
class _OutIter,
|
||||
__enable_if_t<!__can_rewrap<_InIter, _Sent, _OutIter>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
|
||||
__unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) {
|
||||
return _Algorithm()(std::move(__first), std::move(__last), std::move(__out_first));
|
||||
}
|
||||
|
||||
template <class _AlgPolicy,
|
||||
class _NaiveAlgorithm,
|
||||
class _OptimizedAlgorithm,
|
||||
class _InIter,
|
||||
class _Sent,
|
||||
class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
|
||||
__dispatch_copy_or_move(_InIter __first, _Sent __last, _OutIter __out_first) {
|
||||
using _Algorithm = __overload<_NaiveAlgorithm, _OptimizedAlgorithm>;
|
||||
return std::__unwrap_and_dispatch<_Algorithm>(std::move(__first), std::move(__last), std::move(__out_first));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H
|
67
lib/libcxx/include/__algorithm/copy_n.h
Normal file
67
lib/libcxx/include/__algorithm/copy_n.h
Normal file
@ -0,0 +1,67 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_COPY_N_H
|
||||
#define _LIBCPP___ALGORITHM_COPY_N_H
|
||||
|
||||
#include <__algorithm/copy.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__utility/convert_to_integral.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template<class _InputIterator, class _Size, class _OutputIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
typename enable_if
|
||||
<
|
||||
__has_input_iterator_category<_InputIterator>::value &&
|
||||
!__has_random_access_iterator_category<_InputIterator>::value,
|
||||
_OutputIterator
|
||||
>::type
|
||||
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
|
||||
{
|
||||
typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
|
||||
_IntegralSize __n = __orig_n;
|
||||
if (__n > 0)
|
||||
{
|
||||
*__result = *__first;
|
||||
++__result;
|
||||
for (--__n; __n > 0; --__n)
|
||||
{
|
||||
++__first;
|
||||
*__result = *__first;
|
||||
++__result;
|
||||
}
|
||||
}
|
||||
return __result;
|
||||
}
|
||||
|
||||
template<class _InputIterator, class _Size, class _OutputIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
typename enable_if
|
||||
<
|
||||
__has_random_access_iterator_category<_InputIterator>::value,
|
||||
_OutputIterator
|
||||
>::type
|
||||
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
|
||||
{
|
||||
typedef typename iterator_traits<_InputIterator>::difference_type difference_type;
|
||||
typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
|
||||
_IntegralSize __n = __orig_n;
|
||||
return _VSTD::copy(__first, __first + difference_type(__n), __result);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COPY_N_H
|
35
lib/libcxx/include/__algorithm/count.h
Normal file
35
lib/libcxx/include/__algorithm/count.h
Normal file
@ -0,0 +1,35 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_COUNT_H
|
||||
#define _LIBCPP___ALGORITHM_COUNT_H
|
||||
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Tp>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
typename iterator_traits<_InputIterator>::difference_type
|
||||
count(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
|
||||
typename iterator_traits<_InputIterator>::difference_type __r(0);
|
||||
for (; __first != __last; ++__first)
|
||||
if (*__first == __value)
|
||||
++__r;
|
||||
return __r;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COUNT_H
|
35
lib/libcxx/include/__algorithm/count_if.h
Normal file
35
lib/libcxx/include/__algorithm/count_if.h
Normal file
@ -0,0 +1,35 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_COUNT_IF_H
|
||||
#define _LIBCPP___ALGORITHM_COUNT_IF_H
|
||||
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
typename iterator_traits<_InputIterator>::difference_type
|
||||
count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||
typename iterator_traits<_InputIterator>::difference_type __r(0);
|
||||
for (; __first != __last; ++__first)
|
||||
if (__pred(*__first))
|
||||
++__r;
|
||||
return __r;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COUNT_IF_H
|
149
lib/libcxx/include/__algorithm/equal.h
Normal file
149
lib/libcxx/include/__algorithm/equal.h
Normal file
@ -0,0 +1,149 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_EQUAL_H
|
||||
#define _LIBCPP___ALGORITHM_EQUAL_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/unwrap_iter.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__string/constexpr_c_functions.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/integral_constant.h>
|
||||
#include <__type_traits/is_constant_evaluated.h>
|
||||
#include <__type_traits/is_equality_comparable.h>
|
||||
#include <__type_traits/is_volatile.h>
|
||||
#include <__type_traits/predicate_traits.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(
|
||||
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate& __pred) {
|
||||
for (; __first1 != __last1; ++__first1, (void)++__first2)
|
||||
if (!__pred(*__first1, *__first2))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <
|
||||
class _Tp,
|
||||
class _Up,
|
||||
class _BinaryPredicate,
|
||||
__enable_if_t<__is_trivial_equality_predicate<_BinaryPredicate, _Tp, _Up>::value && !is_volatile<_Tp>::value &&
|
||||
!is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) {
|
||||
return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
|
||||
return std::__equal_iter_impl(
|
||||
std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred);
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
|
||||
return std::equal(__first1, __last1, __first2, __equal_to());
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER >= 14
|
||||
template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
|
||||
_BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) {
|
||||
for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
|
||||
if (!__pred(*__first1, *__first2))
|
||||
return false;
|
||||
return __first1 == __last1 && __first2 == __last2;
|
||||
}
|
||||
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
|
||||
_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __comp, _Proj1& __proj1, _Proj2& __proj2) {
|
||||
while (__first1 != __last1 && __first2 != __last2) {
|
||||
if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
|
||||
return false;
|
||||
++__first1;
|
||||
++__first2;
|
||||
}
|
||||
return __first1 == __last1 && __first2 == __last2;
|
||||
}
|
||||
|
||||
template <class _Tp,
|
||||
class _Up,
|
||||
class _Pred,
|
||||
class _Proj1,
|
||||
class _Proj2,
|
||||
__enable_if_t<__is_trivial_equality_predicate<_Pred, _Tp, _Up>::value && __is_identity<_Proj1>::value &&
|
||||
__is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value &&
|
||||
__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
|
||||
_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) {
|
||||
return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
|
||||
}
|
||||
|
||||
template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
|
||||
_RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag,
|
||||
random_access_iterator_tag) {
|
||||
if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
|
||||
return false;
|
||||
__identity __proj;
|
||||
return std::__equal_impl(
|
||||
std::__unwrap_iter(__first1),
|
||||
std::__unwrap_iter(__last1),
|
||||
std::__unwrap_iter(__first2),
|
||||
std::__unwrap_iter(__last2),
|
||||
__pred,
|
||||
__proj,
|
||||
__proj);
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
|
||||
_BinaryPredicate __pred) {
|
||||
return _VSTD::__equal<_BinaryPredicate&>(
|
||||
__first1, __last1, __first2, __last2, __pred, typename iterator_traits<_InputIterator1>::iterator_category(),
|
||||
typename iterator_traits<_InputIterator2>::iterator_category());
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
|
||||
return std::__equal(
|
||||
__first1,
|
||||
__last1,
|
||||
__first2,
|
||||
__last2,
|
||||
__equal_to(),
|
||||
typename iterator_traits<_InputIterator1>::iterator_category(),
|
||||
typename iterator_traits<_InputIterator2>::iterator_category());
|
||||
}
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_EQUAL_H
|
83
lib/libcxx/include/__algorithm/equal_range.h
Normal file
83
lib/libcxx/include/__algorithm/equal_range.h
Normal file
@ -0,0 +1,83 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_EQUAL_RANGE_H
|
||||
#define _LIBCPP___ALGORITHM_EQUAL_RANGE_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/half_positive.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/lower_bound.h>
|
||||
#include <__algorithm/upper_bound.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__type_traits/is_copy_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _Iter, class _Sent, class _Tp, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter, _Iter>
|
||||
__equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp, _Proj&& __proj) {
|
||||
auto __len = _IterOps<_AlgPolicy>::distance(__first, __last);
|
||||
_Iter __end = _IterOps<_AlgPolicy>::next(__first, __last);
|
||||
while (__len != 0) {
|
||||
auto __half_len = std::__half_positive(__len);
|
||||
_Iter __mid = _IterOps<_AlgPolicy>::next(__first, __half_len);
|
||||
if (std::__invoke(__comp, std::__invoke(__proj, *__mid), __value)) {
|
||||
__first = ++__mid;
|
||||
__len -= __half_len + 1;
|
||||
} else if (std::__invoke(__comp, __value, std::__invoke(__proj, *__mid))) {
|
||||
__end = __mid;
|
||||
__len = __half_len;
|
||||
} else {
|
||||
_Iter __mp1 = __mid;
|
||||
return pair<_Iter, _Iter>(
|
||||
std::__lower_bound<_AlgPolicy>(__first, __mid, __value, __comp, __proj),
|
||||
std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj));
|
||||
}
|
||||
}
|
||||
return pair<_Iter, _Iter>(__first, __first);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
|
||||
equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) {
|
||||
static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value,
|
||||
"The comparator has to be callable");
|
||||
static_assert(is_copy_constructible<_ForwardIterator>::value,
|
||||
"Iterator has to be copy constructible");
|
||||
return std::__equal_range<_ClassicAlgPolicy>(
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
__value,
|
||||
static_cast<__comp_ref_type<_Compare> >(__comp),
|
||||
std::__identity());
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Tp>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
|
||||
equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||
return std::equal_range(std::move(__first), std::move(__last), __value, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_EQUAL_RANGE_H
|
51
lib/libcxx/include/__algorithm/fill.h
Normal file
51
lib/libcxx/include/__algorithm/fill.h
Normal file
@ -0,0 +1,51 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_FILL_H
|
||||
#define _LIBCPP___ALGORITHM_FILL_H
|
||||
|
||||
#include <__algorithm/fill_n.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
|
||||
|
||||
template <class _ForwardIterator, class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
void
|
||||
__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, forward_iterator_tag)
|
||||
{
|
||||
for (; __first != __last; ++__first)
|
||||
*__first = __value;
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
void
|
||||
__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, random_access_iterator_tag)
|
||||
{
|
||||
_VSTD::fill_n(__first, __last - __first, __value);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
void
|
||||
fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
|
||||
{
|
||||
_VSTD::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FILL_H
|
44
lib/libcxx/include/__algorithm/fill_n.h
Normal file
44
lib/libcxx/include/__algorithm/fill_n.h
Normal file
@ -0,0 +1,44 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_FILL_N_H
|
||||
#define _LIBCPP___ALGORITHM_FILL_N_H
|
||||
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/convert_to_integral.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
|
||||
|
||||
template <class _OutputIterator, class _Size, class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_OutputIterator
|
||||
__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value)
|
||||
{
|
||||
for (; __n > 0; ++__first, (void) --__n)
|
||||
*__first = __value;
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <class _OutputIterator, class _Size, class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_OutputIterator
|
||||
fill_n(_OutputIterator __first, _Size __n, const _Tp& __value)
|
||||
{
|
||||
return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FILL_N_H
|
77
lib/libcxx/include/__algorithm/find.h
Normal file
77
lib/libcxx/include/__algorithm/find.h
Normal file
@ -0,0 +1,77 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_FIND_H
|
||||
#define _LIBCPP___ALGORITHM_FIND_H
|
||||
|
||||
#include <__algorithm/unwrap_iter.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__string/constexpr_c_functions.h>
|
||||
#include <__type_traits/is_same.h>
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
# include <cwchar>
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Iter, class _Sent, class _Tp, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
|
||||
__find_impl(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
|
||||
for (; __first != __last; ++__first)
|
||||
if (std::__invoke(__proj, *__first) == __value)
|
||||
break;
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <class _Tp,
|
||||
class _Up,
|
||||
class _Proj,
|
||||
__enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
|
||||
sizeof(_Tp) == 1,
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
|
||||
__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
|
||||
if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first))
|
||||
return __ret;
|
||||
return __last;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
template <class _Tp,
|
||||
class _Up,
|
||||
class _Proj,
|
||||
__enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
|
||||
sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t),
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
|
||||
__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
|
||||
if (auto __ret = std::__constexpr_wmemchr(__first, __value, __last - __first))
|
||||
return __ret;
|
||||
return __last;
|
||||
}
|
||||
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
|
||||
template <class _InputIterator, class _Tp>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
|
||||
find(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
|
||||
__identity __proj;
|
||||
return std::__rewrap_iter(
|
||||
__first, std::__find_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value, __proj));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FIND_H
|
227
lib/libcxx/include/__algorithm/find_end.h
Normal file
227
lib/libcxx/include/__algorithm/find_end.h
Normal file
@ -0,0 +1,227 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_FIND_END_OF_H
|
||||
#define _LIBCPP___ALGORITHM_FIND_END_OF_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/search.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__iterator/reverse_iterator.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <
|
||||
class _AlgPolicy,
|
||||
class _Iter1,
|
||||
class _Sent1,
|
||||
class _Iter2,
|
||||
class _Sent2,
|
||||
class _Pred,
|
||||
class _Proj1,
|
||||
class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __find_end_impl(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred& __pred,
|
||||
_Proj1& __proj1,
|
||||
_Proj2& __proj2,
|
||||
forward_iterator_tag,
|
||||
forward_iterator_tag) {
|
||||
// modeled after search algorithm
|
||||
_Iter1 __match_first = _IterOps<_AlgPolicy>::next(__first1, __last1); // __last1 is the "default" answer
|
||||
_Iter1 __match_last = __match_first;
|
||||
if (__first2 == __last2)
|
||||
return pair<_Iter1, _Iter1>(__match_last, __match_last);
|
||||
while (true) {
|
||||
while (true) {
|
||||
if (__first1 == __last1) // if source exhausted return last correct answer (or __last1 if never found)
|
||||
return pair<_Iter1, _Iter1>(__match_first, __match_last);
|
||||
if (std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
|
||||
break;
|
||||
++__first1;
|
||||
}
|
||||
// *__first1 matches *__first2, now match elements after here
|
||||
_Iter1 __m1 = __first1;
|
||||
_Iter2 __m2 = __first2;
|
||||
while (true) {
|
||||
if (++__m2 == __last2) { // Pattern exhaused, record answer and search for another one
|
||||
__match_first = __first1;
|
||||
__match_last = ++__m1;
|
||||
++__first1;
|
||||
break;
|
||||
}
|
||||
if (++__m1 == __last1) // Source exhausted, return last answer
|
||||
return pair<_Iter1, _Iter1>(__match_first, __match_last);
|
||||
// mismatch, restart with a new __first
|
||||
if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2)))
|
||||
{
|
||||
++__first1;
|
||||
break;
|
||||
} // else there is a match, check next elements
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
class _IterOps,
|
||||
class _Pred,
|
||||
class _Iter1,
|
||||
class _Sent1,
|
||||
class _Iter2,
|
||||
class _Sent2,
|
||||
class _Proj1,
|
||||
class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __sent1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __sent2,
|
||||
_Pred& __pred,
|
||||
_Proj1& __proj1,
|
||||
_Proj2& __proj2,
|
||||
bidirectional_iterator_tag,
|
||||
bidirectional_iterator_tag) {
|
||||
auto __last1 = _IterOps::next(__first1, __sent1);
|
||||
auto __last2 = _IterOps::next(__first2, __sent2);
|
||||
// modeled after search algorithm (in reverse)
|
||||
if (__first2 == __last2)
|
||||
return __last1; // Everything matches an empty sequence
|
||||
_Iter1 __l1 = __last1;
|
||||
_Iter2 __l2 = __last2;
|
||||
--__l2;
|
||||
while (true) {
|
||||
// Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks
|
||||
while (true) {
|
||||
if (__first1 == __l1) // return __last1 if no element matches *__first2
|
||||
return __last1;
|
||||
if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
|
||||
break;
|
||||
}
|
||||
// *__l1 matches *__l2, now match elements before here
|
||||
_Iter1 __m1 = __l1;
|
||||
_Iter2 __m2 = __l2;
|
||||
while (true) {
|
||||
if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern)
|
||||
return __m1;
|
||||
if (__m1 == __first1) // Otherwise if source exhaused, pattern not found
|
||||
return __last1;
|
||||
|
||||
// if there is a mismatch, restart with a new __l1
|
||||
if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2)))
|
||||
{
|
||||
break;
|
||||
} // else there is a match, check next elements
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
class _AlgPolicy,
|
||||
class _Pred,
|
||||
class _Iter1,
|
||||
class _Sent1,
|
||||
class _Iter2,
|
||||
class _Sent2,
|
||||
class _Proj1,
|
||||
class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __sent1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __sent2,
|
||||
_Pred& __pred,
|
||||
_Proj1& __proj1,
|
||||
_Proj2& __proj2,
|
||||
random_access_iterator_tag,
|
||||
random_access_iterator_tag) {
|
||||
typedef typename iterator_traits<_Iter1>::difference_type _D1;
|
||||
auto __last1 = _IterOps<_AlgPolicy>::next(__first1, __sent1);
|
||||
auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __sent2);
|
||||
// Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
|
||||
auto __len2 = __last2 - __first2;
|
||||
if (__len2 == 0)
|
||||
return __last1;
|
||||
auto __len1 = __last1 - __first1;
|
||||
if (__len1 < __len2)
|
||||
return __last1;
|
||||
const _Iter1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here
|
||||
_Iter1 __l1 = __last1;
|
||||
_Iter2 __l2 = __last2;
|
||||
--__l2;
|
||||
while (true) {
|
||||
while (true) {
|
||||
if (__s == __l1)
|
||||
return __last1;
|
||||
if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
|
||||
break;
|
||||
}
|
||||
_Iter1 __m1 = __l1;
|
||||
_Iter2 __m2 = __l2;
|
||||
while (true) {
|
||||
if (__m2 == __first2)
|
||||
return __m1;
|
||||
// no need to check range on __m1 because __s guarantees we have enough source
|
||||
if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(*--__m2))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
_ForwardIterator1 __find_end_classic(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2, _ForwardIterator2 __last2,
|
||||
_BinaryPredicate& __pred) {
|
||||
auto __proj = __identity();
|
||||
return std::__find_end_impl<_ClassicAlgPolicy>(
|
||||
__first1,
|
||||
__last1,
|
||||
__first2,
|
||||
__last2,
|
||||
__pred,
|
||||
__proj,
|
||||
__proj,
|
||||
typename iterator_traits<_ForwardIterator1>::iterator_category(),
|
||||
typename iterator_traits<_ForwardIterator2>::iterator_category())
|
||||
.first;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2, _ForwardIterator2 __last2,
|
||||
_BinaryPredicate __pred) {
|
||||
return std::__find_end_classic(__first1, __last1, __first2, __last2, __pred);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2, _ForwardIterator2 __last2) {
|
||||
return std::find_end(__first1, __last1, __first2, __last2, __equal_to());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FIND_END_OF_H
|
52
lib/libcxx/include/__algorithm/find_first_of.h
Normal file
52
lib/libcxx/include/__algorithm/find_first_of.h
Normal file
@ -0,0 +1,52 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_FIND_FIRST_OF_H
|
||||
#define _LIBCPP___ALGORITHM_FIND_FIRST_OF_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_first_of_ce(_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2,
|
||||
_BinaryPredicate&& __pred) {
|
||||
for (; __first1 != __last1; ++__first1)
|
||||
for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
|
||||
if (__pred(*__first1, *__j))
|
||||
return __first1;
|
||||
return __last1;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1
|
||||
find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2, _BinaryPredicate __pred) {
|
||||
return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of(
|
||||
_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
|
||||
return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FIND_FIRST_OF_H
|
32
lib/libcxx/include/__algorithm/find_if.h
Normal file
32
lib/libcxx/include/__algorithm/find_if.h
Normal file
@ -0,0 +1,32 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_FIND_IF_H
|
||||
#define _LIBCPP___ALGORITHM_FIND_IF_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
|
||||
find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||
for (; __first != __last; ++__first)
|
||||
if (__pred(*__first))
|
||||
break;
|
||||
return __first;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FIND_IF_H
|
32
lib/libcxx/include/__algorithm/find_if_not.h
Normal file
32
lib/libcxx/include/__algorithm/find_if_not.h
Normal file
@ -0,0 +1,32 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_FIND_IF_NOT_H
|
||||
#define _LIBCPP___ALGORITHM_FIND_IF_NOT_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
|
||||
find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||
for (; __first != __last; ++__first)
|
||||
if (!__pred(*__first))
|
||||
break;
|
||||
return __first;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FIND_IF_NOT_H
|
32
lib/libcxx/include/__algorithm/for_each.h
Normal file
32
lib/libcxx/include/__algorithm/for_each.h
Normal file
@ -0,0 +1,32 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_FOR_EACH_H
|
||||
#define _LIBCPP___ALGORITHM_FOR_EACH_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Function>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _Function for_each(_InputIterator __first,
|
||||
_InputIterator __last,
|
||||
_Function __f) {
|
||||
for (; __first != __last; ++__first)
|
||||
__f(*__first);
|
||||
return __f;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FOR_EACH_H
|
42
lib/libcxx/include/__algorithm/for_each_n.h
Normal file
42
lib/libcxx/include/__algorithm/for_each_n.h
Normal file
@ -0,0 +1,42 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_FOR_EACH_N_H
|
||||
#define _LIBCPP___ALGORITHM_FOR_EACH_N_H
|
||||
|
||||
#include <__config>
|
||||
#include <__utility/convert_to_integral.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
|
||||
template <class _InputIterator, class _Size, class _Function>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator for_each_n(_InputIterator __first,
|
||||
_Size __orig_n,
|
||||
_Function __f) {
|
||||
typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
|
||||
_IntegralSize __n = __orig_n;
|
||||
while (__n > 0) {
|
||||
__f(*__first);
|
||||
++__first;
|
||||
--__n;
|
||||
}
|
||||
return __first;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FOR_EACH_N_H
|
53
lib/libcxx/include/__algorithm/for_each_segment.h
Normal file
53
lib/libcxx/include/__algorithm/for_each_segment.h
Normal file
@ -0,0 +1,53 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
|
||||
#define _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
|
||||
|
||||
#include <__config>
|
||||
#include <__iterator/segmented_iterator.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// __for_each_segment is a utility function for optimizing iterating over segmented iterators linearly.
|
||||
// __first and __last are expected to be a segmented range. __func is expected to take a range of local iterators.
|
||||
// Anything that is returned from __func is ignored.
|
||||
|
||||
template <class _SegmentedIterator, class _Functor>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
||||
__for_each_segment(_SegmentedIterator __first, _SegmentedIterator __last, _Functor __func) {
|
||||
using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
|
||||
|
||||
auto __sfirst = _Traits::__segment(__first);
|
||||
auto __slast = _Traits::__segment(__last);
|
||||
|
||||
// We are in a single segment, so we might not be at the beginning or end
|
||||
if (__sfirst == __slast) {
|
||||
__func(_Traits::__local(__first), _Traits::__local(__last));
|
||||
return;
|
||||
}
|
||||
|
||||
// We have more than one segment. Iterate over the first segment, since we might not start at the beginning
|
||||
__func(_Traits::__local(__first), _Traits::__end(__sfirst));
|
||||
++__sfirst;
|
||||
// iterate over the segments which are guaranteed to be completely in the range
|
||||
while (__sfirst != __slast) {
|
||||
__func(_Traits::__begin(__sfirst), _Traits::__end(__sfirst));
|
||||
++__sfirst;
|
||||
}
|
||||
// iterate over the last segment
|
||||
__func(_Traits::__begin(__sfirst), _Traits::__local(__last));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
|
31
lib/libcxx/include/__algorithm/generate.h
Normal file
31
lib/libcxx/include/__algorithm/generate.h
Normal file
@ -0,0 +1,31 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_GENERATE_H
|
||||
#define _LIBCPP___ALGORITHM_GENERATE_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator, class _Generator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
void
|
||||
generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen)
|
||||
{
|
||||
for (; __first != __last; ++__first)
|
||||
*__first = __gen();
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_GENERATE_H
|
35
lib/libcxx/include/__algorithm/generate_n.h
Normal file
35
lib/libcxx/include/__algorithm/generate_n.h
Normal file
@ -0,0 +1,35 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_GENERATE_N_H
|
||||
#define _LIBCPP___ALGORITHM_GENERATE_N_H
|
||||
|
||||
#include <__config>
|
||||
#include <__utility/convert_to_integral.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _OutputIterator, class _Size, class _Generator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_OutputIterator
|
||||
generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen)
|
||||
{
|
||||
typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
|
||||
_IntegralSize __n = __orig_n;
|
||||
for (; __n > 0; ++__first, (void) --__n)
|
||||
*__first = __gen();
|
||||
return __first;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_GENERATE_N_H
|
51
lib/libcxx/include/__algorithm/half_positive.h
Normal file
51
lib/libcxx/include/__algorithm/half_positive.h
Normal file
@ -0,0 +1,51 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_HALF_POSITIVE_H
|
||||
#define _LIBCPP___ALGORITHM_HALF_POSITIVE_H
|
||||
|
||||
#include <__config>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_integral.h>
|
||||
#include <__type_traits/make_unsigned.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// Perform division by two quickly for positive integers (llvm.org/PR39129)
|
||||
|
||||
template <typename _Integral>
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
|
||||
typename enable_if
|
||||
<
|
||||
is_integral<_Integral>::value,
|
||||
_Integral
|
||||
>::type
|
||||
__half_positive(_Integral __value)
|
||||
{
|
||||
return static_cast<_Integral>(static_cast<__make_unsigned_t<_Integral> >(__value) / 2);
|
||||
}
|
||||
|
||||
template <typename _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
|
||||
typename enable_if
|
||||
<
|
||||
!is_integral<_Tp>::value,
|
||||
_Tp
|
||||
>::type
|
||||
__half_positive(_Tp __value)
|
||||
{
|
||||
return __value / 2;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_HALF_POSITIVE_H
|
49
lib/libcxx/include/__algorithm/in_found_result.h
Normal file
49
lib/libcxx/include/__algorithm/in_found_result.h
Normal file
@ -0,0 +1,49 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
template <class _InIter1>
|
||||
struct in_found_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in;
|
||||
bool found;
|
||||
|
||||
template <class _InIter2>
|
||||
requires convertible_to<const _InIter1&, _InIter2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() const & {
|
||||
return {in, found};
|
||||
}
|
||||
|
||||
template <class _InIter2>
|
||||
requires convertible_to<_InIter1, _InIter2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() && {
|
||||
return {std::move(in), found};
|
||||
}
|
||||
};
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H
|
49
lib/libcxx/include/__algorithm/in_fun_result.h
Normal file
49
lib/libcxx/include/__algorithm/in_fun_result.h
Normal file
@ -0,0 +1,49 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_IN_FUN_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_IN_FUN_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template <class _InIter1, class _Func1>
|
||||
struct in_fun_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Func1 fun;
|
||||
|
||||
template <class _InIter2, class _Func2>
|
||||
requires convertible_to<const _InIter1&, _InIter2> && convertible_to<const _Func1&, _Func2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() const & {
|
||||
return {in, fun};
|
||||
}
|
||||
|
||||
template <class _InIter2, class _Func2>
|
||||
requires convertible_to<_InIter1, _InIter2> && convertible_to<_Func1, _Func2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() && {
|
||||
return {std::move(in), std::move(fun)};
|
||||
}
|
||||
};
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IN_FUN_RESULT_H
|
56
lib/libcxx/include/__algorithm/in_in_out_result.h
Normal file
56
lib/libcxx/include/__algorithm/in_in_out_result.h
Normal file
@ -0,0 +1,56 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _InIter1, class _InIter2, class _OutIter1>
|
||||
struct in_in_out_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in1;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter2 in2;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out;
|
||||
|
||||
template <class _InIter3, class _InIter4, class _OutIter2>
|
||||
requires convertible_to<const _InIter1&, _InIter3>
|
||||
&& convertible_to<const _InIter2&, _InIter4> && convertible_to<const _OutIter1&, _OutIter2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() const& {
|
||||
return {in1, in2, out};
|
||||
}
|
||||
|
||||
template <class _InIter3, class _InIter4, class _OutIter2>
|
||||
requires convertible_to<_InIter1, _InIter3>
|
||||
&& convertible_to<_InIter2, _InIter4> && convertible_to<_OutIter1, _OutIter2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() && {
|
||||
return {std::move(in1), std::move(in2), std::move(out)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H
|
53
lib/libcxx/include/__algorithm/in_in_result.h
Normal file
53
lib/libcxx/include/__algorithm/in_in_result.h
Normal file
@ -0,0 +1,53 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_IN_IN_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_IN_IN_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _InIter1, class _InIter2>
|
||||
struct in_in_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in1;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter2 in2;
|
||||
|
||||
template <class _InIter3, class _InIter4>
|
||||
requires convertible_to<const _InIter1&, _InIter3> && convertible_to<const _InIter2&, _InIter4>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
operator in_in_result<_InIter3, _InIter4>() const & {
|
||||
return {in1, in2};
|
||||
}
|
||||
|
||||
template <class _InIter3, class _InIter4>
|
||||
requires convertible_to<_InIter1, _InIter3> && convertible_to<_InIter2, _InIter4>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
operator in_in_result<_InIter3, _InIter4>() && {
|
||||
return {std::move(in1), std::move(in2)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IN_IN_RESULT_H
|
54
lib/libcxx/include/__algorithm/in_out_out_result.h
Normal file
54
lib/libcxx/include/__algorithm/in_out_out_result.h
Normal file
@ -0,0 +1,54 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template <class _InIter1, class _OutIter1, class _OutIter2>
|
||||
struct in_out_out_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out1;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _OutIter2 out2;
|
||||
|
||||
template <class _InIter2, class _OutIter3, class _OutIter4>
|
||||
requires convertible_to<const _InIter1&, _InIter2>
|
||||
&& convertible_to<const _OutIter1&, _OutIter3> && convertible_to<const _OutIter2&, _OutIter4>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() const& {
|
||||
return {in, out1, out2};
|
||||
}
|
||||
|
||||
template <class _InIter2, class _OutIter3, class _OutIter4>
|
||||
requires convertible_to<_InIter1, _InIter2>
|
||||
&& convertible_to<_OutIter1, _OutIter3> && convertible_to<_OutIter2, _OutIter4>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() && {
|
||||
return {std::move(in), std::move(out1), std::move(out2)};
|
||||
}
|
||||
};
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H
|
58
lib/libcxx/include/__algorithm/in_out_result.h
Normal file
58
lib/libcxx/include/__algorithm/in_out_result.h
Normal file
@ -0,0 +1,58 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_IN_OUT_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_IN_OUT_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template<class _InIter1, class _OutIter1>
|
||||
struct in_out_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out;
|
||||
|
||||
template <class _InIter2, class _OutIter2>
|
||||
requires convertible_to<const _InIter1&, _InIter2> && convertible_to<const _OutIter1&, _OutIter2>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr operator in_out_result<_InIter2, _OutIter2>() const & {
|
||||
return {in, out};
|
||||
}
|
||||
|
||||
template <class _InIter2, class _OutIter2>
|
||||
requires convertible_to<_InIter1, _InIter2> && convertible_to<_OutIter1, _OutIter2>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr operator in_out_result<_InIter2, _OutIter2>() && {
|
||||
return {std::move(in), std::move(out)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H
|
69
lib/libcxx/include/__algorithm/includes.h
Normal file
69
lib/libcxx/include/__algorithm/includes.h
Normal file
@ -0,0 +1,69 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_INCLUDES_H
|
||||
#define _LIBCPP___ALGORITHM_INCLUDES_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Comp, class _Proj1, class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__includes(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
|
||||
_Comp&& __comp, _Proj1&& __proj1, _Proj2&& __proj2) {
|
||||
for (; __first2 != __last2; ++__first1) {
|
||||
if (__first1 == __last1 || std::__invoke(
|
||||
__comp, std::__invoke(__proj2, *__first2), std::__invoke(__proj1, *__first1)))
|
||||
return false;
|
||||
if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
|
||||
++__first2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool includes(
|
||||
_InputIterator1 __first1,
|
||||
_InputIterator1 __last1,
|
||||
_InputIterator2 __first2,
|
||||
_InputIterator2 __last2,
|
||||
_Compare __comp) {
|
||||
static_assert(__is_callable<_Compare, decltype(*__first1), decltype(*__first2)>::value,
|
||||
"Comparator has to be callable");
|
||||
|
||||
return std::__includes(
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
static_cast<__comp_ref_type<_Compare> >(__comp),
|
||||
__identity(),
|
||||
__identity());
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
|
||||
return std::includes(std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_INCLUDES_H
|
256
lib/libcxx/include/__algorithm/inplace_merge.h
Normal file
256
lib/libcxx/include/__algorithm/inplace_merge.h
Normal file
@ -0,0 +1,256 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_INPLACE_MERGE_H
|
||||
#define _LIBCPP___ALGORITHM_INPLACE_MERGE_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/lower_bound.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__algorithm/move.h>
|
||||
#include <__algorithm/rotate.h>
|
||||
#include <__algorithm/upper_bound.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/reverse_iterator.h>
|
||||
#include <__memory/destruct_n.h>
|
||||
#include <__memory/temporary_buffer.h>
|
||||
#include <__memory/unique_ptr.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <new>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Predicate>
|
||||
class __invert // invert the sense of a comparison
|
||||
{
|
||||
private:
|
||||
_Predicate __p_;
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY __invert() {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit __invert(_Predicate __p) : __p_(__p) {}
|
||||
|
||||
template <class _T1>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _T1& __x) {return !__p_(__x);}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);}
|
||||
};
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _InputIterator1, class _Sent1,
|
||||
class _InputIterator2, class _Sent2, class _OutputIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
void __half_inplace_merge(_InputIterator1 __first1, _Sent1 __last1,
|
||||
_InputIterator2 __first2, _Sent2 __last2,
|
||||
_OutputIterator __result, _Compare&& __comp)
|
||||
{
|
||||
for (; __first1 != __last1; ++__result)
|
||||
{
|
||||
if (__first2 == __last2)
|
||||
{
|
||||
std::__move<_AlgPolicy>(__first1, __last1, __result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (__comp(*__first2, *__first1))
|
||||
{
|
||||
*__result = _IterOps<_AlgPolicy>::__iter_move(__first2);
|
||||
++__first2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*__result = _IterOps<_AlgPolicy>::__iter_move(__first1);
|
||||
++__first1;
|
||||
}
|
||||
}
|
||||
// __first2 through __last2 are already in the right spot.
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
void __buffered_inplace_merge(
|
||||
_BidirectionalIterator __first,
|
||||
_BidirectionalIterator __middle,
|
||||
_BidirectionalIterator __last,
|
||||
_Compare&& __comp,
|
||||
typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
|
||||
typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
|
||||
typename iterator_traits<_BidirectionalIterator>::value_type* __buff) {
|
||||
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
|
||||
__destruct_n __d(0);
|
||||
unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
|
||||
if (__len1 <= __len2)
|
||||
{
|
||||
value_type* __p = __buff;
|
||||
for (_BidirectionalIterator __i = __first; __i != __middle; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p)
|
||||
::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i));
|
||||
std::__half_inplace_merge<_AlgPolicy>(__buff, __p, __middle, __last, __first, __comp);
|
||||
}
|
||||
else
|
||||
{
|
||||
value_type* __p = __buff;
|
||||
for (_BidirectionalIterator __i = __middle; __i != __last; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p)
|
||||
::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i));
|
||||
typedef __unconstrained_reverse_iterator<_BidirectionalIterator> _RBi;
|
||||
typedef __unconstrained_reverse_iterator<value_type*> _Rv;
|
||||
typedef __invert<_Compare> _Inverted;
|
||||
std::__half_inplace_merge<_AlgPolicy>(_Rv(__p), _Rv(__buff),
|
||||
_RBi(__middle), _RBi(__first),
|
||||
_RBi(__last), _Inverted(__comp));
|
||||
}
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
|
||||
void __inplace_merge(
|
||||
_BidirectionalIterator __first,
|
||||
_BidirectionalIterator __middle,
|
||||
_BidirectionalIterator __last,
|
||||
_Compare&& __comp,
|
||||
typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
|
||||
typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
|
||||
typename iterator_traits<_BidirectionalIterator>::value_type* __buff,
|
||||
ptrdiff_t __buff_size) {
|
||||
using _Ops = _IterOps<_AlgPolicy>;
|
||||
|
||||
typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
|
||||
while (true)
|
||||
{
|
||||
// if __middle == __last, we're done
|
||||
if (__len2 == 0)
|
||||
return;
|
||||
if (__len1 <= __buff_size || __len2 <= __buff_size)
|
||||
return std::__buffered_inplace_merge<_AlgPolicy>
|
||||
(__first, __middle, __last, __comp, __len1, __len2, __buff);
|
||||
// shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0
|
||||
for (; true; ++__first, (void) --__len1)
|
||||
{
|
||||
if (__len1 == 0)
|
||||
return;
|
||||
if (__comp(*__middle, *__first))
|
||||
break;
|
||||
}
|
||||
// __first < __middle < __last
|
||||
// *__first > *__middle
|
||||
// partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that
|
||||
// all elements in:
|
||||
// [__first, __m1) <= [__middle, __m2)
|
||||
// [__middle, __m2) < [__m1, __middle)
|
||||
// [__m1, __middle) <= [__m2, __last)
|
||||
// and __m1 or __m2 is in the middle of its range
|
||||
_BidirectionalIterator __m1; // "median" of [__first, __middle)
|
||||
_BidirectionalIterator __m2; // "median" of [__middle, __last)
|
||||
difference_type __len11; // distance(__first, __m1)
|
||||
difference_type __len21; // distance(__middle, __m2)
|
||||
// binary search smaller range
|
||||
if (__len1 < __len2)
|
||||
{ // __len >= 1, __len2 >= 2
|
||||
__len21 = __len2 / 2;
|
||||
__m2 = __middle;
|
||||
_Ops::advance(__m2, __len21);
|
||||
__m1 = std::__upper_bound<_AlgPolicy>(__first, __middle, *__m2, __comp, std::__identity());
|
||||
__len11 = _Ops::distance(__first, __m1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__len1 == 1)
|
||||
{ // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1
|
||||
// It is known *__first > *__middle
|
||||
_Ops::iter_swap(__first, __middle);
|
||||
return;
|
||||
}
|
||||
// __len1 >= 2, __len2 >= 1
|
||||
__len11 = __len1 / 2;
|
||||
__m1 = __first;
|
||||
_Ops::advance(__m1, __len11);
|
||||
__m2 = std::lower_bound(__middle, __last, *__m1, __comp);
|
||||
__len21 = _Ops::distance(__middle, __m2);
|
||||
}
|
||||
difference_type __len12 = __len1 - __len11; // distance(__m1, __middle)
|
||||
difference_type __len22 = __len2 - __len21; // distance(__m2, __last)
|
||||
// [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last)
|
||||
// swap middle two partitions
|
||||
__middle = std::__rotate<_AlgPolicy>(__m1, __middle, __m2).first;
|
||||
// __len12 and __len21 now have swapped meanings
|
||||
// merge smaller range with recursive call and larger with tail recursion elimination
|
||||
if (__len11 + __len21 < __len12 + __len22)
|
||||
{
|
||||
std::__inplace_merge<_AlgPolicy>(
|
||||
__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
|
||||
__first = __middle;
|
||||
__middle = __m2;
|
||||
__len1 = __len12;
|
||||
__len2 = __len22;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::__inplace_merge<_AlgPolicy>(
|
||||
__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
|
||||
__last = __middle;
|
||||
__middle = __m1;
|
||||
__len1 = __len11;
|
||||
__len2 = __len21;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _BidirectionalIterator, class _Compare>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
void
|
||||
__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
|
||||
_Compare&& __comp)
|
||||
{
|
||||
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
|
||||
typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
|
||||
difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle);
|
||||
difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last);
|
||||
difference_type __buf_size = _VSTD::min(__len1, __len2);
|
||||
// TODO: Remove the use of std::get_temporary_buffer
|
||||
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
|
||||
pair<value_type*, ptrdiff_t> __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size);
|
||||
_LIBCPP_SUPPRESS_DEPRECATED_POP
|
||||
unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first);
|
||||
return std::__inplace_merge<_AlgPolicy>(
|
||||
std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second);
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI void inplace_merge(
|
||||
_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare __comp) {
|
||||
std::__inplace_merge<_ClassicAlgPolicy>(
|
||||
std::move(__first), std::move(__middle), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp));
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
void
|
||||
inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last)
|
||||
{
|
||||
std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_INPLACE_MERGE_H
|
44
lib/libcxx/include/__algorithm/is_heap.h
Normal file
44
lib/libcxx/include/__algorithm/is_heap.h
Normal file
@ -0,0 +1,44 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_IS_HEAP_H
|
||||
#define _LIBCPP___ALGORITHM_IS_HEAP_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/is_heap_until.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
bool
|
||||
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
|
||||
{
|
||||
return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)) == __last;
|
||||
}
|
||||
|
||||
template<class _RandomAccessIterator>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
bool
|
||||
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
|
||||
{
|
||||
return _VSTD::is_heap(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IS_HEAP_H
|
66
lib/libcxx/include/__algorithm/is_heap_until.h
Normal file
66
lib/libcxx/include/__algorithm/is_heap_until.h
Normal file
@ -0,0 +1,66 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H
|
||||
#define _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare, class _RandomAccessIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
|
||||
__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp)
|
||||
{
|
||||
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
|
||||
difference_type __len = __last - __first;
|
||||
difference_type __p = 0;
|
||||
difference_type __c = 1;
|
||||
_RandomAccessIterator __pp = __first;
|
||||
while (__c < __len)
|
||||
{
|
||||
_RandomAccessIterator __cp = __first + __c;
|
||||
if (__comp(*__pp, *__cp))
|
||||
return __cp;
|
||||
++__c;
|
||||
++__cp;
|
||||
if (__c == __len)
|
||||
return __last;
|
||||
if (__comp(*__pp, *__cp))
|
||||
return __cp;
|
||||
++__p;
|
||||
++__pp;
|
||||
__c = 2 * __p + 1;
|
||||
}
|
||||
return __last;
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
|
||||
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
|
||||
{
|
||||
return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp));
|
||||
}
|
||||
|
||||
template<class _RandomAccessIterator>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
|
||||
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
|
||||
{
|
||||
return _VSTD::__is_heap_until(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H
|
38
lib/libcxx/include/__algorithm/is_partitioned.h
Normal file
38
lib/libcxx/include/__algorithm/is_partitioned.h
Normal file
@ -0,0 +1,38 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_IS_PARTITIONED_H
|
||||
#define _LIBCPP___ALGORITHM_IS_PARTITIONED_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred)
|
||||
{
|
||||
for (; __first != __last; ++__first)
|
||||
if (!__pred(*__first))
|
||||
break;
|
||||
if ( __first == __last )
|
||||
return true;
|
||||
++__first;
|
||||
for (; __first != __last; ++__first)
|
||||
if (__pred(*__first))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IS_PARTITIONED_H
|
243
lib/libcxx/include/__algorithm/is_permutation.h
Normal file
243
lib/libcxx/include/__algorithm/is_permutation.h
Normal file
@ -0,0 +1,243 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_IS_PERMUTATION_H
|
||||
#define _LIBCPP___ALGORITHM_IS_PERMUTATION_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class = void>
|
||||
struct _ConstTimeDistance : false_type {};
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2>
|
||||
struct _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2, __enable_if_t<
|
||||
sized_sentinel_for<_Sent1, _Iter1> &&
|
||||
sized_sentinel_for<_Sent2, _Iter2>
|
||||
>> : true_type {};
|
||||
|
||||
#else
|
||||
|
||||
template <class _Iter1, class _Iter2>
|
||||
struct _ConstTimeDistance<_Iter1, _Iter1, _Iter2, _Iter2, __enable_if_t<
|
||||
is_same<typename iterator_traits<_Iter1>::iterator_category, random_access_iterator_tag>::value &&
|
||||
is_same<typename iterator_traits<_Iter2>::iterator_category, random_access_iterator_tag>::value
|
||||
> > : true_type {};
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
// Internal functions
|
||||
|
||||
// For each element in [f1, l1) see if there are the same number of equal elements in [f2, l2)
|
||||
template <class _AlgPolicy,
|
||||
class _Iter1, class _Sent1, class _Iter2, class _Sent2,
|
||||
class _Proj1, class _Proj2, class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__is_permutation_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
|
||||
_Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) {
|
||||
using _D1 = __iter_diff_t<_Iter1>;
|
||||
|
||||
for (auto __i = __first1; __i != __last1; ++__i) {
|
||||
// Have we already counted the number of *__i in [f1, l1)?
|
||||
auto __match = __first1;
|
||||
for (; __match != __i; ++__match) {
|
||||
if (std::__invoke(__pred, std::__invoke(__proj1, *__match), std::__invoke(__proj1, *__i)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (__match == __i) {
|
||||
// Count number of *__i in [f2, l2)
|
||||
_D1 __c2 = 0;
|
||||
for (auto __j = __first2; __j != __last2; ++__j) {
|
||||
if (std::__invoke(__pred, std::__invoke(__proj1, *__i), std::__invoke(__proj2, *__j)))
|
||||
++__c2;
|
||||
}
|
||||
if (__c2 == 0)
|
||||
return false;
|
||||
|
||||
// Count number of *__i in [__i, l1) (we can start with 1)
|
||||
_D1 __c1 = 1;
|
||||
for (auto __j = _IterOps<_AlgPolicy>::next(__i); __j != __last1; ++__j) {
|
||||
if (std::__invoke(__pred, std::__invoke(__proj1, *__i), std::__invoke(__proj1, *__j)))
|
||||
++__c1;
|
||||
}
|
||||
if (__c1 != __c2)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2+1 iterators, predicate. Not used by range algorithms.
|
||||
template <class _AlgPolicy, class _ForwardIterator1, class _Sentinel1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__is_permutation(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2,
|
||||
_BinaryPredicate&& __pred) {
|
||||
// Shorten sequences as much as possible by lopping of any equal prefix.
|
||||
for (; __first1 != __last1; ++__first1, (void)++__first2) {
|
||||
if (!__pred(*__first1, *__first2))
|
||||
break;
|
||||
}
|
||||
|
||||
if (__first1 == __last1)
|
||||
return true;
|
||||
|
||||
// __first1 != __last1 && *__first1 != *__first2
|
||||
using _D1 = __iter_diff_t<_ForwardIterator1>;
|
||||
_D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1);
|
||||
if (__l1 == _D1(1))
|
||||
return false;
|
||||
auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __l1);
|
||||
|
||||
return std::__is_permutation_impl<_AlgPolicy>(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
|
||||
__pred, __identity(), __identity());
|
||||
}
|
||||
|
||||
// 2+2 iterators, predicate, non-constant time `distance`.
|
||||
template <class _AlgPolicy,
|
||||
class _Iter1, class _Sent1, class _Iter2, class _Sent2,
|
||||
class _Proj1, class _Proj2, class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
|
||||
_Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2,
|
||||
/*_ConstTimeDistance=*/false_type) {
|
||||
// Shorten sequences as much as possible by lopping of any equal prefix.
|
||||
while (__first1 != __last1 && __first2 != __last2) {
|
||||
if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
|
||||
break;
|
||||
++__first1;
|
||||
++__first2;
|
||||
}
|
||||
|
||||
if (__first1 == __last1)
|
||||
return __first2 == __last2;
|
||||
if (__first2 == __last2) // Second range is shorter
|
||||
return false;
|
||||
|
||||
using _D1 = __iter_diff_t<_Iter1>;
|
||||
_D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1);
|
||||
|
||||
using _D2 = __iter_diff_t<_Iter2>;
|
||||
_D2 __l2 = _IterOps<_AlgPolicy>::distance(__first2, __last2);
|
||||
if (__l1 != __l2)
|
||||
return false;
|
||||
|
||||
return std::__is_permutation_impl<_AlgPolicy>(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
|
||||
__pred, __proj1, __proj2);
|
||||
}
|
||||
|
||||
// 2+2 iterators, predicate, specialization for constant-time `distance` call.
|
||||
template <class _AlgPolicy,
|
||||
class _Iter1, class _Sent1, class _Iter2, class _Sent2,
|
||||
class _Proj1, class _Proj2, class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
|
||||
_Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2,
|
||||
/*_ConstTimeDistance=*/true_type) {
|
||||
if (std::distance(__first1, __last1) != std::distance(__first2, __last2))
|
||||
return false;
|
||||
return std::__is_permutation<_AlgPolicy>(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
|
||||
__pred, __proj1, __proj2,
|
||||
/*_ConstTimeDistance=*/false_type());
|
||||
}
|
||||
|
||||
// 2+2 iterators, predicate
|
||||
template <class _AlgPolicy,
|
||||
class _Iter1, class _Sent1, class _Iter2, class _Sent2,
|
||||
class _Proj1, class _Proj2, class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
|
||||
_Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) {
|
||||
return std::__is_permutation<_AlgPolicy>(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
|
||||
__pred, __proj1, __proj2,
|
||||
_ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2>());
|
||||
}
|
||||
|
||||
// Public interface
|
||||
|
||||
// 2+1 iterators, predicate
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
||||
_BinaryPredicate __pred) {
|
||||
static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value,
|
||||
"The predicate has to be callable");
|
||||
|
||||
return std::__is_permutation<_ClassicAlgPolicy>(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), __pred);
|
||||
}
|
||||
|
||||
// 2+1 iterators
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
|
||||
return std::is_permutation(__first1, __last1, __first2, __equal_to());
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER >= 14
|
||||
|
||||
// 2+2 iterators
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(
|
||||
_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
|
||||
return std::__is_permutation<_ClassicAlgPolicy>(
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
__equal_to(),
|
||||
__identity(),
|
||||
__identity());
|
||||
}
|
||||
|
||||
// 2+2 iterators, predicate
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2, _BinaryPredicate __pred) {
|
||||
static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value,
|
||||
"The predicate has to be callable");
|
||||
|
||||
return std::__is_permutation<_ClassicAlgPolicy>(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
|
||||
__pred, __identity(), __identity());
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 14
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IS_PERMUTATION_H
|
44
lib/libcxx/include/__algorithm/is_sorted.h
Normal file
44
lib/libcxx/include/__algorithm/is_sorted.h
Normal file
@ -0,0 +1,44 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_IS_SORTED_H
|
||||
#define _LIBCPP___ALGORITHM_IS_SORTED_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/is_sorted_until.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
bool
|
||||
is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
return _VSTD::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp) == __last;
|
||||
}
|
||||
|
||||
template<class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
bool
|
||||
is_sorted(_ForwardIterator __first, _ForwardIterator __last)
|
||||
{
|
||||
return _VSTD::is_sorted(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IS_SORTED_H
|
56
lib/libcxx/include/__algorithm/is_sorted_until.h
Normal file
56
lib/libcxx/include/__algorithm/is_sorted_until.h
Normal file
@ -0,0 +1,56 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H
|
||||
#define _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare, class _ForwardIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
if (__first != __last)
|
||||
{
|
||||
_ForwardIterator __i = __first;
|
||||
while (++__i != __last)
|
||||
{
|
||||
if (__comp(*__i, *__first))
|
||||
return __i;
|
||||
__first = __i;
|
||||
}
|
||||
}
|
||||
return __last;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
return _VSTD::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp);
|
||||
}
|
||||
|
||||
template<class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
|
||||
{
|
||||
return _VSTD::is_sorted_until(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H
|
32
lib/libcxx/include/__algorithm/iter_swap.h
Normal file
32
lib/libcxx/include/__algorithm/iter_swap.h
Normal file
@ -0,0 +1,32 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_ITER_SWAP_H
|
||||
#define _LIBCPP___ALGORITHM_ITER_SWAP_H
|
||||
|
||||
#include <__config>
|
||||
#include <__utility/declval.h>
|
||||
#include <__utility/swap.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void iter_swap(_ForwardIterator1 __a,
|
||||
_ForwardIterator2 __b)
|
||||
// _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b)))
|
||||
_NOEXCEPT_(_NOEXCEPT_(swap(*std::declval<_ForwardIterator1>(), *std::declval<_ForwardIterator2>()))) {
|
||||
swap(*__a, *__b);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_ITER_SWAP_H
|
180
lib/libcxx/include/__algorithm/iterator_operations.h
Normal file
180
lib/libcxx/include/__algorithm/iterator_operations.h
Normal file
@ -0,0 +1,180 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H
|
||||
#define _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H
|
||||
|
||||
#include <__algorithm/iter_swap.h>
|
||||
#include <__algorithm/ranges_iterator_concept.h>
|
||||
#include <__config>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/incrementable_traits.h>
|
||||
#include <__iterator/iter_move.h>
|
||||
#include <__iterator/iter_swap.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__iterator/prev.h>
|
||||
#include <__iterator/readable_traits.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_reference.h>
|
||||
#include <__type_traits/is_same.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/declval.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy> struct _IterOps;
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
struct _RangeAlgPolicy {};
|
||||
|
||||
template <>
|
||||
struct _IterOps<_RangeAlgPolicy> {
|
||||
|
||||
template <class _Iter>
|
||||
using __value_type = iter_value_t<_Iter>;
|
||||
|
||||
template <class _Iter>
|
||||
using __iterator_category = ranges::__iterator_concept<_Iter>;
|
||||
|
||||
template <class _Iter>
|
||||
using __difference_type = iter_difference_t<_Iter>;
|
||||
|
||||
static constexpr auto advance = ranges::advance;
|
||||
static constexpr auto distance = ranges::distance;
|
||||
static constexpr auto __iter_move = ranges::iter_move;
|
||||
static constexpr auto iter_swap = ranges::iter_swap;
|
||||
static constexpr auto next = ranges::next;
|
||||
static constexpr auto prev = ranges::prev;
|
||||
static constexpr auto __advance_to = ranges::advance;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct _ClassicAlgPolicy {};
|
||||
|
||||
template <>
|
||||
struct _IterOps<_ClassicAlgPolicy> {
|
||||
|
||||
template <class _Iter>
|
||||
using __value_type = typename iterator_traits<_Iter>::value_type;
|
||||
|
||||
template <class _Iter>
|
||||
using __iterator_category = typename iterator_traits<_Iter>::iterator_category;
|
||||
|
||||
template <class _Iter>
|
||||
using __difference_type = typename iterator_traits<_Iter>::difference_type;
|
||||
|
||||
// advance
|
||||
template <class _Iter, class _Distance>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
static void advance(_Iter& __iter, _Distance __count) {
|
||||
std::advance(__iter, __count);
|
||||
}
|
||||
|
||||
// distance
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
static typename iterator_traits<_Iter>::difference_type distance(_Iter __first, _Iter __last) {
|
||||
return std::distance(__first, __last);
|
||||
}
|
||||
|
||||
template <class _Iter>
|
||||
using __deref_t = decltype(*std::declval<_Iter&>());
|
||||
|
||||
template <class _Iter>
|
||||
using __move_t = decltype(std::move(*std::declval<_Iter&>()));
|
||||
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
static void __validate_iter_reference() {
|
||||
static_assert(is_same<__deref_t<_Iter>, typename iterator_traits<__remove_cvref_t<_Iter> >::reference>::value,
|
||||
"It looks like your iterator's `iterator_traits<It>::reference` does not match the return type of "
|
||||
"dereferencing the iterator, i.e., calling `*it`. This is undefined behavior according to [input.iterators] "
|
||||
"and can lead to dangling reference issues at runtime, so we are flagging this.");
|
||||
}
|
||||
|
||||
// iter_move
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static
|
||||
// If the result of dereferencing `_Iter` is a reference type, deduce the result of calling `std::move` on it. Note
|
||||
// that the C++03 mode doesn't support `decltype(auto)` as the return type.
|
||||
__enable_if_t<
|
||||
is_reference<__deref_t<_Iter> >::value,
|
||||
__move_t<_Iter> >
|
||||
__iter_move(_Iter&& __i) {
|
||||
__validate_iter_reference<_Iter>();
|
||||
|
||||
return std::move(*std::forward<_Iter>(__i));
|
||||
}
|
||||
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static
|
||||
// If the result of dereferencing `_Iter` is a value type, deduce the return value of this function to also be a
|
||||
// value -- otherwise, after `operator*` returns a temporary, this function would return a dangling reference to that
|
||||
// temporary. Note that the C++03 mode doesn't support `auto` as the return type.
|
||||
__enable_if_t<
|
||||
!is_reference<__deref_t<_Iter> >::value,
|
||||
__deref_t<_Iter> >
|
||||
__iter_move(_Iter&& __i) {
|
||||
__validate_iter_reference<_Iter>();
|
||||
|
||||
return *std::forward<_Iter>(__i);
|
||||
}
|
||||
|
||||
// iter_swap
|
||||
template <class _Iter1, class _Iter2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
static void iter_swap(_Iter1&& __a, _Iter2&& __b) {
|
||||
std::iter_swap(std::forward<_Iter1>(__a), std::forward<_Iter2>(__b));
|
||||
}
|
||||
|
||||
// next
|
||||
template <class _Iterator>
|
||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
_Iterator next(_Iterator, _Iterator __last) {
|
||||
return __last;
|
||||
}
|
||||
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
__remove_cvref_t<_Iter> next(_Iter&& __it,
|
||||
typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) {
|
||||
return std::next(std::forward<_Iter>(__it), __n);
|
||||
}
|
||||
|
||||
// prev
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
__remove_cvref_t<_Iter> prev(_Iter&& __iter,
|
||||
typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) {
|
||||
return std::prev(std::forward<_Iter>(__iter), __n);
|
||||
}
|
||||
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
void __advance_to(_Iter& __first, _Iter __last) {
|
||||
__first = __last;
|
||||
}
|
||||
};
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H
|
60
lib/libcxx/include/__algorithm/lexicographical_compare.h
Normal file
60
lib/libcxx/include/__algorithm/lexicographical_compare.h
Normal file
@ -0,0 +1,60 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H
|
||||
#define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare, class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
|
||||
_InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
|
||||
{
|
||||
for (; __first2 != __last2; ++__first1, (void) ++__first2)
|
||||
{
|
||||
if (__first1 == __last1 || __comp(*__first1, *__first2))
|
||||
return true;
|
||||
if (__comp(*__first2, *__first1))
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
bool
|
||||
lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
|
||||
_InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
|
||||
{
|
||||
return _VSTD::__lexicographical_compare<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __comp);
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
bool
|
||||
lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
|
||||
_InputIterator2 __first2, _InputIterator2 __last2)
|
||||
{
|
||||
return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H
|
@ -0,0 +1,125 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
|
||||
#define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
|
||||
|
||||
#include <__algorithm/min.h>
|
||||
#include <__algorithm/three_way_comp_ref_type.h>
|
||||
#include <__compare/compare_three_way.h>
|
||||
#include <__compare/ordering.h>
|
||||
#include <__concepts/arithmetic.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/common_type.h>
|
||||
#include <__type_traits/is_copy_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
// Fast path for random access iterators which computes the number of loop iterations up-front and
|
||||
// then skips the iterator comparisons inside the loop.
|
||||
template <class _InputIterator1, class _InputIterator2, class _Cmp>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_fast_path(
|
||||
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp)
|
||||
-> decltype(__comp(*__first1, *__first2)) {
|
||||
static_assert(
|
||||
signed_integral<__iter_diff_t<_InputIterator1>>, "Using a non-integral difference_type is undefined behavior.");
|
||||
static_assert(
|
||||
signed_integral<__iter_diff_t<_InputIterator2>>, "Using a non-integral difference_type is undefined behavior.");
|
||||
|
||||
using _Len1 = __iter_diff_t<_InputIterator1>;
|
||||
using _Len2 = __iter_diff_t<_InputIterator2>;
|
||||
using _Common = common_type_t<_Len1, _Len2>;
|
||||
|
||||
_Len1 __len1 = __last1 - __first1;
|
||||
_Len2 __len2 = __last2 - __first2;
|
||||
_Common __min_len = std::min<_Common>(__len1, __len2);
|
||||
|
||||
for (_Common __i = 0; __i < __min_len; ++__i) {
|
||||
auto __c = __comp(*__first1, *__first2);
|
||||
if (__c != 0) {
|
||||
return __c;
|
||||
}
|
||||
++__first1;
|
||||
++__first2;
|
||||
}
|
||||
|
||||
return __len1 <=> __len2;
|
||||
}
|
||||
|
||||
// Unoptimized implementation which compares the iterators against the end in every loop iteration
|
||||
template <class _InputIterator1, class _InputIterator2, class _Cmp>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_slow_path(
|
||||
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp)
|
||||
-> decltype(__comp(*__first1, *__first2)) {
|
||||
while (true) {
|
||||
bool __exhausted1 = __first1 == __last1;
|
||||
bool __exhausted2 = __first2 == __last2;
|
||||
|
||||
if (__exhausted1 || __exhausted2) {
|
||||
if (!__exhausted1)
|
||||
return strong_ordering::greater;
|
||||
if (!__exhausted2)
|
||||
return strong_ordering::less;
|
||||
return strong_ordering::equal;
|
||||
}
|
||||
|
||||
auto __c = __comp(*__first1, *__first2);
|
||||
if (__c != 0) {
|
||||
return __c;
|
||||
}
|
||||
|
||||
++__first1;
|
||||
++__first2;
|
||||
}
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _Cmp>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way(
|
||||
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp __comp)
|
||||
-> decltype(__comp(*__first1, *__first2)) {
|
||||
static_assert(__comparison_category<decltype(__comp(*__first1, *__first2))>,
|
||||
"The comparator passed to lexicographical_compare_three_way must return a comparison category type.");
|
||||
static_assert(std::is_copy_constructible_v<_InputIterator1>, "Iterators must be copy constructible.");
|
||||
static_assert(std::is_copy_constructible_v<_InputIterator2>, "Iterators must be copy constructible.");
|
||||
__three_way_comp_ref_type<_Cmp> __wrapped_comp_ref(__comp);
|
||||
if constexpr (__has_random_access_iterator_category<_InputIterator1>::value &&
|
||||
__has_random_access_iterator_category<_InputIterator2>::value) {
|
||||
return std::__lexicographical_compare_three_way_fast_path(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __wrapped_comp_ref);
|
||||
} else {
|
||||
// Unoptimized implementation which compares the iterators against the end in every loop iteration
|
||||
return std::__lexicographical_compare_three_way_slow_path(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __wrapped_comp_ref);
|
||||
}
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way(
|
||||
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
|
||||
return std::lexicographical_compare_three_way(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::compare_three_way());
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
|
66
lib/libcxx/include/__algorithm/lower_bound.h
Normal file
66
lib/libcxx/include/__algorithm/lower_bound.h
Normal file
@ -0,0 +1,66 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_LOWER_BOUND_H
|
||||
#define _LIBCPP___ALGORITHM_LOWER_BOUND_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/half_positive.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__type_traits/remove_reference.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Iter, class _Sent, class _Type, class _Proj, class _Comp>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_Iter __lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
|
||||
auto __len = _IterOps<_AlgPolicy>::distance(__first, __last);
|
||||
|
||||
while (__len != 0) {
|
||||
auto __l2 = std::__half_positive(__len);
|
||||
_Iter __m = __first;
|
||||
_IterOps<_AlgPolicy>::advance(__m, __l2);
|
||||
if (std::__invoke(__comp, std::__invoke(__proj, *__m), __value)) {
|
||||
__first = ++__m;
|
||||
__len -= __l2 + 1;
|
||||
} else {
|
||||
__len = __l2;
|
||||
}
|
||||
}
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) {
|
||||
static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value,
|
||||
"The comparator has to be callable");
|
||||
auto __proj = std::__identity();
|
||||
return std::__lower_bound<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Tp>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||
return std::lower_bound(__first, __last, __value, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_LOWER_BOUND_H
|
60
lib/libcxx/include/__algorithm/make_heap.h
Normal file
60
lib/libcxx/include/__algorithm/make_heap.h
Normal file
@ -0,0 +1,60 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_MAKE_HEAP_H
|
||||
#define _LIBCPP___ALGORITHM_MAKE_HEAP_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/sift_down.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) {
|
||||
__comp_ref_type<_Compare> __comp_ref = __comp;
|
||||
|
||||
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
|
||||
difference_type __n = __last - __first;
|
||||
if (__n > 1) {
|
||||
// start from the first parent, there is no need to consider children
|
||||
for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) {
|
||||
std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
|
||||
std::__make_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp);
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
|
||||
std::make_heap(std::move(__first), std::move(__last), __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MAKE_HEAP_H
|
113
lib/libcxx/include/__algorithm/make_projected.h
Normal file
113
lib/libcxx/include/__algorithm/make_projected.h
Normal file
@ -0,0 +1,113 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_MAKE_PROJECTED_H
|
||||
#define _LIBCPP___ALGORITHM_MAKE_PROJECTED_H
|
||||
|
||||
#include <__concepts/same_as.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__type_traits/decay.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/integral_constant.h>
|
||||
#include <__type_traits/is_member_pointer.h>
|
||||
#include <__type_traits/is_same.h>
|
||||
#include <__utility/declval.h>
|
||||
#include <__utility/forward.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Pred, class _Proj>
|
||||
struct _ProjectedPred {
|
||||
_Pred& __pred; // Can be a unary or a binary predicate.
|
||||
_Proj& __proj;
|
||||
|
||||
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg)
|
||||
: __pred(__pred_arg), __proj(__proj_arg) {}
|
||||
|
||||
template <class _Tp>
|
||||
typename __invoke_of<_Pred&,
|
||||
decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>()))
|
||||
>::type
|
||||
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_Tp&& __v) const {
|
||||
return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v)));
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
typename __invoke_of<_Pred&,
|
||||
decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())),
|
||||
decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>()))
|
||||
>::type
|
||||
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_T1&& __lhs, _T2&& __rhs) const {
|
||||
return std::__invoke(__pred,
|
||||
std::__invoke(__proj, std::forward<_T1>(__lhs)),
|
||||
std::__invoke(__proj, std::forward<_T2>(__rhs)));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class _Pred,
|
||||
class _Proj,
|
||||
__enable_if_t<!(!is_member_pointer<__decay_t<_Pred> >::value &&
|
||||
__is_identity<__decay_t<_Proj> >::value),
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj>
|
||||
__make_projected(_Pred& __pred, _Proj& __proj) {
|
||||
return _ProjectedPred<_Pred, _Proj>(__pred, __proj);
|
||||
}
|
||||
|
||||
// Avoid creating the functor and just use the pristine comparator -- for certain algorithms, this would enable
|
||||
// optimizations that rely on the type of the comparator. Additionally, this results in less layers of indirection in
|
||||
// the call stack when the comparator is invoked, even in an unoptimized build.
|
||||
template <class _Pred,
|
||||
class _Proj,
|
||||
__enable_if_t<!is_member_pointer<__decay_t<_Pred> >::value &&
|
||||
__is_identity<__decay_t<_Proj> >::value,
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Pred& __make_projected(_Pred& __pred, _Proj&) {
|
||||
return __pred;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _Comp, class _Proj1, class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
|
||||
if constexpr (__is_identity<decay_t<_Proj1>>::value && __is_identity<decay_t<_Proj2>>::value &&
|
||||
!is_member_pointer_v<decay_t<_Comp>>) {
|
||||
// Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable
|
||||
// optimizations that rely on the type of the comparator.
|
||||
return __comp;
|
||||
|
||||
} else {
|
||||
return [&](auto&& __lhs, auto&& __rhs) {
|
||||
return std::invoke(__comp,
|
||||
std::invoke(__proj1, std::forward<decltype(__lhs)>(__lhs)),
|
||||
std::invoke(__proj2, std::forward<decltype(__rhs)>(__rhs)));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MAKE_PROJECTED_H
|
71
lib/libcxx/include/__algorithm/max.h
Normal file
71
lib/libcxx/include/__algorithm/max.h
Normal file
@ -0,0 +1,71 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_MAX_H
|
||||
#define _LIBCPP___ALGORITHM_MAX_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/max_element.h>
|
||||
#include <__config>
|
||||
#include <initializer_list>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
const _Tp&
|
||||
max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
|
||||
{
|
||||
return __comp(__a, __b) ? __b : __a;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
const _Tp&
|
||||
max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
|
||||
{
|
||||
return _VSTD::max(__a, __b, __less<>());
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
|
||||
template<class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
_Tp
|
||||
max(initializer_list<_Tp> __t, _Compare __comp)
|
||||
{
|
||||
return *_VSTD::__max_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp);
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
_Tp
|
||||
max(initializer_list<_Tp> __t)
|
||||
{
|
||||
return *_VSTD::max_element(__t.begin(), __t.end(), __less<>());
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_CXX03_LANG
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MAX_H
|
56
lib/libcxx/include/__algorithm/max_element.h
Normal file
56
lib/libcxx/include/__algorithm/max_element.h
Normal file
@ -0,0 +1,56 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_MAX_ELEMENT_H
|
||||
#define _LIBCPP___ALGORITHM_MAX_ELEMENT_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare, class _ForwardIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
|
||||
__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
|
||||
"std::max_element requires a ForwardIterator");
|
||||
if (__first != __last)
|
||||
{
|
||||
_ForwardIterator __i = __first;
|
||||
while (++__i != __last)
|
||||
if (__comp(*__first, *__i))
|
||||
__first = __i;
|
||||
}
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
|
||||
max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
return _VSTD::__max_element<__comp_ref_type<_Compare> >(__first, __last, __comp);
|
||||
}
|
||||
|
||||
|
||||
template <class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
|
||||
max_element(_ForwardIterator __first, _ForwardIterator __last)
|
||||
{
|
||||
return _VSTD::max_element(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MAX_ELEMENT_H
|
68
lib/libcxx/include/__algorithm/merge.h
Normal file
68
lib/libcxx/include/__algorithm/merge.h
Normal file
@ -0,0 +1,68 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_MERGE_H
|
||||
#define _LIBCPP___ALGORITHM_MERGE_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/copy.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_OutputIterator
|
||||
__merge(_InputIterator1 __first1, _InputIterator1 __last1,
|
||||
_InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
|
||||
{
|
||||
for (; __first1 != __last1; ++__result)
|
||||
{
|
||||
if (__first2 == __last2)
|
||||
return _VSTD::copy(__first1, __last1, __result);
|
||||
if (__comp(*__first2, *__first1))
|
||||
{
|
||||
*__result = *__first2;
|
||||
++__first2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*__result = *__first1;
|
||||
++__first1;
|
||||
}
|
||||
}
|
||||
return _VSTD::copy(__first2, __last2, __result);
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_OutputIterator
|
||||
merge(_InputIterator1 __first1, _InputIterator1 __last1,
|
||||
_InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
|
||||
{
|
||||
return _VSTD::__merge<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __result, __comp);
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_OutputIterator
|
||||
merge(_InputIterator1 __first1, _InputIterator1 __last1,
|
||||
_InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
|
||||
{
|
||||
return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MERGE_H
|
71
lib/libcxx/include/__algorithm/min.h
Normal file
71
lib/libcxx/include/__algorithm/min.h
Normal file
@ -0,0 +1,71 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_MIN_H
|
||||
#define _LIBCPP___ALGORITHM_MIN_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/min_element.h>
|
||||
#include <__config>
|
||||
#include <initializer_list>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
const _Tp&
|
||||
min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
|
||||
{
|
||||
return __comp(__b, __a) ? __b : __a;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
const _Tp&
|
||||
min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
|
||||
{
|
||||
return _VSTD::min(__a, __b, __less<>());
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
|
||||
template<class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
_Tp
|
||||
min(initializer_list<_Tp> __t, _Compare __comp)
|
||||
{
|
||||
return *_VSTD::__min_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp);
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
_Tp
|
||||
min(initializer_list<_Tp> __t)
|
||||
{
|
||||
return *_VSTD::min_element(__t.begin(), __t.end(), __less<>());
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_CXX03_LANG
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MIN_H
|
74
lib/libcxx/include/__algorithm/min_element.h
Normal file
74
lib/libcxx/include/__algorithm/min_element.h
Normal file
@ -0,0 +1,74 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_MIN_ELEMENT_H
|
||||
#define _LIBCPP___ALGORITHM_MIN_ELEMENT_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Comp, class _Iter, class _Sent, class _Proj>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
_Iter __min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) {
|
||||
if (__first == __last)
|
||||
return __first;
|
||||
|
||||
_Iter __i = __first;
|
||||
while (++__i != __last)
|
||||
if (std::__invoke(__comp, std::__invoke(__proj, *__i), std::__invoke(__proj, *__first)))
|
||||
__first = __i;
|
||||
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <class _Comp, class _Iter, class _Sent>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
_Iter __min_element(_Iter __first, _Sent __last, _Comp __comp) {
|
||||
auto __proj = __identity();
|
||||
return std::__min_element<_Comp>(std::move(__first), std::move(__last), __comp, __proj);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
|
||||
min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
|
||||
"std::min_element requires a ForwardIterator");
|
||||
static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value,
|
||||
"The comparator has to be callable");
|
||||
|
||||
return std::__min_element<__comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
|
||||
min_element(_ForwardIterator __first, _ForwardIterator __last)
|
||||
{
|
||||
return _VSTD::min_element(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MIN_ELEMENT_H
|
56
lib/libcxx/include/__algorithm/min_max_result.h
Normal file
56
lib/libcxx/include/__algorithm/min_max_result.h
Normal file
@ -0,0 +1,56 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _T1>
|
||||
struct min_max_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _T1 min;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _T1 max;
|
||||
|
||||
template <class _T2>
|
||||
requires convertible_to<const _T1&, _T2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() const & {
|
||||
return {min, max};
|
||||
}
|
||||
|
||||
template <class _T2>
|
||||
requires convertible_to<_T1, _T2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() && {
|
||||
return {std::move(min), std::move(max)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H
|
69
lib/libcxx/include/__algorithm/minmax.h
Normal file
69
lib/libcxx/include/__algorithm/minmax.h
Normal file
@ -0,0 +1,69 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_MINMAX_H
|
||||
#define _LIBCPP___ALGORITHM_MINMAX_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/minmax_element.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <initializer_list>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template<class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
pair<const _Tp&, const _Tp&>
|
||||
minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
|
||||
{
|
||||
return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) :
|
||||
pair<const _Tp&, const _Tp&>(__a, __b);
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
pair<const _Tp&, const _Tp&>
|
||||
minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
|
||||
{
|
||||
return std::minmax(__a, __b, __less<>());
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
|
||||
template<class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t, _Compare __comp) {
|
||||
static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable");
|
||||
__identity __proj;
|
||||
auto __ret = std::__minmax_element_impl(__t.begin(), __t.end(), __comp, __proj);
|
||||
return pair<_Tp, _Tp>(*__ret.first, *__ret.second);
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
pair<_Tp, _Tp>
|
||||
minmax(initializer_list<_Tp> __t)
|
||||
{
|
||||
return std::minmax(__t, __less<>());
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_CXX03_LANG
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MINMAX_H
|
102
lib/libcxx/include/__algorithm/minmax_element.h
Normal file
102
lib/libcxx/include/__algorithm/minmax_element.h
Normal file
@ -0,0 +1,102 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H
|
||||
#define _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Comp, class _Proj>
|
||||
class _MinmaxElementLessFunc {
|
||||
_Comp& __comp_;
|
||||
_Proj& __proj_;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
|
||||
_MinmaxElementLessFunc(_Comp& __comp, _Proj& __proj) : __comp_(__comp), __proj_(__proj) {}
|
||||
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
bool operator()(_Iter& __it1, _Iter& __it2) {
|
||||
return std::__invoke(__comp_, std::__invoke(__proj_, *__it1), std::__invoke(__proj_, *__it2));
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Iter, class _Sent, class _Proj, class _Comp>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
|
||||
auto __less = _MinmaxElementLessFunc<_Comp, _Proj>(__comp, __proj);
|
||||
|
||||
pair<_Iter, _Iter> __result(__first, __first);
|
||||
if (__first == __last || ++__first == __last)
|
||||
return __result;
|
||||
|
||||
if (__less(__first, __result.first))
|
||||
__result.first = __first;
|
||||
else
|
||||
__result.second = __first;
|
||||
|
||||
while (++__first != __last) {
|
||||
_Iter __i = __first;
|
||||
if (++__first == __last) {
|
||||
if (__less(__i, __result.first))
|
||||
__result.first = __i;
|
||||
else if (!__less(__i, __result.second))
|
||||
__result.second = __i;
|
||||
return __result;
|
||||
}
|
||||
|
||||
if (__less(__first, __i)) {
|
||||
if (__less(__first, __result.first))
|
||||
__result.first = __first;
|
||||
if (!__less(__i, __result.second))
|
||||
__result.second = __i;
|
||||
} else {
|
||||
if (__less(__i, __result.first))
|
||||
__result.first = __i;
|
||||
if (!__less(__first, __result.second))
|
||||
__result.second = __first;
|
||||
}
|
||||
}
|
||||
|
||||
return __result;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
pair<_ForwardIterator, _ForwardIterator>
|
||||
minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
|
||||
static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
|
||||
"std::minmax_element requires a ForwardIterator");
|
||||
static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value,
|
||||
"The comparator has to be callable");
|
||||
auto __proj = __identity();
|
||||
return std::__minmax_element_impl(__first, __last, __comp, __proj);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
return std::minmax_element(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H
|
63
lib/libcxx/include/__algorithm/mismatch.h
Normal file
63
lib/libcxx/include/__algorithm/mismatch.h
Normal file
@ -0,0 +1,63 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_MISMATCH_H
|
||||
#define _LIBCPP___ALGORITHM_MISMATCH_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
|
||||
mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
|
||||
for (; __first1 != __last1; ++__first1, (void)++__first2)
|
||||
if (!__pred(*__first1, *__first2))
|
||||
break;
|
||||
return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
|
||||
mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
|
||||
return std::mismatch(__first1, __last1, __first2, __equal_to());
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER >= 14
|
||||
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
|
||||
mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
|
||||
_BinaryPredicate __pred) {
|
||||
for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
|
||||
if (!__pred(*__first1, *__first2))
|
||||
break;
|
||||
return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
|
||||
mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
|
||||
return std::mismatch(__first1, __last1, __first2, __last2, __equal_to());
|
||||
}
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MISMATCH_H
|
129
lib/libcxx/include/__algorithm/move.h
Normal file
129
lib/libcxx/include/__algorithm/move.h
Normal file
@ -0,0 +1,129 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_MOVE_H
|
||||
#define _LIBCPP___ALGORITHM_MOVE_H
|
||||
|
||||
#include <__algorithm/copy_move_common.h>
|
||||
#include <__algorithm/for_each_segment.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__config>
|
||||
#include <__iterator/segmented_iterator.h>
|
||||
#include <__type_traits/common_type.h>
|
||||
#include <__type_traits/is_copy_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
__move(_InIter __first, _Sent __last, _OutIter __result);
|
||||
|
||||
template <class _AlgPolicy>
|
||||
struct __move_loop {
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result) const {
|
||||
while (__first != __last) {
|
||||
*__result = _IterOps<_AlgPolicy>::__iter_move(__first);
|
||||
++__first;
|
||||
++__result;
|
||||
}
|
||||
return std::make_pair(std::move(__first), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter, class _OutIter>
|
||||
struct _MoveSegment {
|
||||
using _Traits = __segmented_iterator_traits<_InIter>;
|
||||
|
||||
_OutIter& __result_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _MoveSegment(_OutIter& __result) : __result_(__result) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
|
||||
__result_ = std::__move<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
std::__for_each_segment(__first, __last, _MoveSegment<_InIter, _OutIter>(__result));
|
||||
return std::make_pair(__last, std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter,
|
||||
class _OutIter,
|
||||
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
||||
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
using _Traits = __segmented_iterator_traits<_OutIter>;
|
||||
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
|
||||
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__first), std::move(__result));
|
||||
|
||||
auto __local_first = _Traits::__local(__result);
|
||||
auto __segment_iterator = _Traits::__segment(__result);
|
||||
while (true) {
|
||||
auto __local_last = _Traits::__end(__segment_iterator);
|
||||
auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
|
||||
auto __iters = std::__move<_AlgPolicy>(__first, __first + __size, __local_first);
|
||||
__first = std::move(__iters.first);
|
||||
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.second)));
|
||||
|
||||
__local_first = _Traits::__begin(++__segment_iterator);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct __move_trivial {
|
||||
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
|
||||
template <class _In, class _Out,
|
||||
__enable_if_t<__can_lower_move_assignment_to_memmove<_In, _Out>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
|
||||
operator()(_In* __first, _In* __last, _Out* __result) const {
|
||||
return std::__copy_trivial_impl(__first, __last, __result);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
__move(_InIter __first, _Sent __last, _OutIter __result) {
|
||||
return std::__dispatch_copy_or_move<_AlgPolicy, __move_loop<_AlgPolicy>, __move_trivial>(
|
||||
std::move(__first), std::move(__last), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _OutputIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||
move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
|
||||
static_assert(is_copy_constructible<_InputIterator>::value, "Iterators has to be copy constructible.");
|
||||
static_assert(is_copy_constructible<_OutputIterator>::value, "The output iterator has to be copy constructible.");
|
||||
|
||||
return std::__move<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MOVE_H
|
139
lib/libcxx/include/__algorithm/move_backward.h
Normal file
139
lib/libcxx/include/__algorithm/move_backward.h
Normal file
@ -0,0 +1,139 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
|
||||
#define _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
|
||||
|
||||
#include <__algorithm/copy_move_common.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__config>
|
||||
#include <__iterator/segmented_iterator.h>
|
||||
#include <__type_traits/common_type.h>
|
||||
#include <__type_traits/is_copy_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, class _BidirectionalIterator2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
|
||||
__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result);
|
||||
|
||||
template <class _AlgPolicy>
|
||||
struct __move_backward_loop {
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result) const {
|
||||
auto __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
|
||||
auto __original_last_iter = __last_iter;
|
||||
|
||||
while (__first != __last_iter) {
|
||||
*--__result = _IterOps<_AlgPolicy>::__iter_move(--__last_iter);
|
||||
}
|
||||
|
||||
return std::make_pair(std::move(__original_last_iter), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
using _Traits = __segmented_iterator_traits<_InIter>;
|
||||
auto __sfirst = _Traits::__segment(__first);
|
||||
auto __slast = _Traits::__segment(__last);
|
||||
if (__sfirst == __slast) {
|
||||
auto __iters =
|
||||
std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
|
||||
return std::make_pair(__last, __iters.second);
|
||||
}
|
||||
|
||||
__result =
|
||||
std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
|
||||
.second;
|
||||
--__slast;
|
||||
while (__sfirst != __slast) {
|
||||
__result =
|
||||
std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
|
||||
.second;
|
||||
--__slast;
|
||||
}
|
||||
__result = std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
|
||||
.second;
|
||||
return std::make_pair(__last, std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter,
|
||||
class _OutIter,
|
||||
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
||||
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
using _Traits = __segmented_iterator_traits<_OutIter>;
|
||||
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
|
||||
|
||||
// When the range contains no elements, __result might not be a valid iterator
|
||||
if (__first == __last)
|
||||
return std::make_pair(__first, __result);
|
||||
|
||||
auto __orig_last = __last;
|
||||
|
||||
auto __local_last = _Traits::__local(__result);
|
||||
auto __segment_iterator = _Traits::__segment(__result);
|
||||
while (true) {
|
||||
auto __local_first = _Traits::__begin(__segment_iterator);
|
||||
auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
|
||||
auto __iter = std::__move_backward<_AlgPolicy>(__last - __size, __last, __local_last).second;
|
||||
__last -= __size;
|
||||
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter)));
|
||||
|
||||
__local_last = _Traits::__end(--__segment_iterator);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct __move_backward_trivial {
|
||||
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
|
||||
template <class _In, class _Out,
|
||||
__enable_if_t<__can_lower_move_assignment_to_memmove<_In, _Out>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
|
||||
operator()(_In* __first, _In* __last, _Out* __result) const {
|
||||
return std::__copy_backward_trivial_impl(__first, __last, __result);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, class _BidirectionalIterator2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
|
||||
__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) {
|
||||
static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value &&
|
||||
std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible.");
|
||||
|
||||
return std::__dispatch_copy_or_move<_AlgPolicy, __move_backward_loop<_AlgPolicy>, __move_backward_trivial>(
|
||||
std::move(__first), std::move(__last), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator1, class _BidirectionalIterator2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2
|
||||
move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) {
|
||||
return std::__move_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
|
77
lib/libcxx/include/__algorithm/next_permutation.h
Normal file
77
lib/libcxx/include/__algorithm/next_permutation.h
Normal file
@ -0,0 +1,77 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H
|
||||
#define _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/reverse.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool>
|
||||
__next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp)
|
||||
{
|
||||
using _Result = pair<_BidirectionalIterator, bool>;
|
||||
|
||||
_BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
|
||||
_BidirectionalIterator __i = __last_iter;
|
||||
if (__first == __last || __first == --__i)
|
||||
return _Result(std::move(__last_iter), false);
|
||||
|
||||
while (true)
|
||||
{
|
||||
_BidirectionalIterator __ip1 = __i;
|
||||
if (__comp(*--__i, *__ip1))
|
||||
{
|
||||
_BidirectionalIterator __j = __last_iter;
|
||||
while (!__comp(*__i, *--__j))
|
||||
;
|
||||
_IterOps<_AlgPolicy>::iter_swap(__i, __j);
|
||||
std::__reverse<_AlgPolicy>(__ip1, __last_iter);
|
||||
return _Result(std::move(__last_iter), true);
|
||||
}
|
||||
if (__i == __first)
|
||||
{
|
||||
std::__reverse<_AlgPolicy>(__first, __last_iter);
|
||||
return _Result(std::move(__last_iter), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator, class _Compare>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
bool
|
||||
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
|
||||
{
|
||||
return std::__next_permutation<_ClassicAlgPolicy>(
|
||||
std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second;
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
bool
|
||||
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
|
||||
{
|
||||
return _VSTD::next_permutation(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H
|
32
lib/libcxx/include/__algorithm/none_of.h
Normal file
32
lib/libcxx/include/__algorithm/none_of.h
Normal file
@ -0,0 +1,32 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_NONE_OF_H
|
||||
#define _LIBCPP___ALGORITHM_NONE_OF_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||
for (; __first != __last; ++__first)
|
||||
if (__pred(*__first))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_NONE_OF_H
|
256
lib/libcxx/include/__algorithm/nth_element.h
Normal file
256
lib/libcxx/include/__algorithm/nth_element.h
Normal file
@ -0,0 +1,256 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_NTH_ELEMENT_H
|
||||
#define _LIBCPP___ALGORITHM_NTH_ELEMENT_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/sort.h>
|
||||
#include <__config>
|
||||
#include <__debug_utils/randomize_range.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template<class _Compare, class _RandomAccessIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
|
||||
__nth_element_find_guard(_RandomAccessIterator& __i, _RandomAccessIterator& __j,
|
||||
_RandomAccessIterator __m, _Compare __comp)
|
||||
{
|
||||
// manually guard downward moving __j against __i
|
||||
while (true) {
|
||||
if (__i == --__j) {
|
||||
return false;
|
||||
}
|
||||
if (__comp(*__j, *__m)) {
|
||||
return true; // found guard for downward moving __j, now use unguarded partition
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
||||
__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
|
||||
{
|
||||
using _Ops = _IterOps<_AlgPolicy>;
|
||||
|
||||
// _Compare is known to be a reference type
|
||||
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
|
||||
const difference_type __limit = 7;
|
||||
while (true)
|
||||
{
|
||||
if (__nth == __last)
|
||||
return;
|
||||
difference_type __len = __last - __first;
|
||||
switch (__len)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
return;
|
||||
case 2:
|
||||
if (__comp(*--__last, *__first))
|
||||
_Ops::iter_swap(__first, __last);
|
||||
return;
|
||||
case 3:
|
||||
{
|
||||
_RandomAccessIterator __m = __first;
|
||||
std::__sort3<_AlgPolicy, _Compare>(__first, ++__m, --__last, __comp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (__len <= __limit)
|
||||
{
|
||||
std::__selection_sort<_AlgPolicy, _Compare>(__first, __last, __comp);
|
||||
return;
|
||||
}
|
||||
// __len > __limit >= 3
|
||||
_RandomAccessIterator __m = __first + __len/2;
|
||||
_RandomAccessIterator __lm1 = __last;
|
||||
unsigned __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, --__lm1, __comp);
|
||||
// *__m is median
|
||||
// partition [__first, __m) < *__m and *__m <= [__m, __last)
|
||||
// (this inhibits tossing elements equivalent to __m around unnecessarily)
|
||||
_RandomAccessIterator __i = __first;
|
||||
_RandomAccessIterator __j = __lm1;
|
||||
// j points beyond range to be tested, *__lm1 is known to be <= *__m
|
||||
// The search going up is known to be guarded but the search coming down isn't.
|
||||
// Prime the downward search with a guard.
|
||||
if (!__comp(*__i, *__m)) // if *__first == *__m
|
||||
{
|
||||
// *__first == *__m, *__first doesn't go in first part
|
||||
if (_VSTD::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) {
|
||||
_Ops::iter_swap(__i, __j);
|
||||
++__n_swaps;
|
||||
} else {
|
||||
// *__first == *__m, *__m <= all other elements
|
||||
// Partition instead into [__first, __i) == *__first and *__first < [__i, __last)
|
||||
++__i; // __first + 1
|
||||
__j = __last;
|
||||
if (!__comp(*__first, *--__j)) { // we need a guard if *__first == *(__last-1)
|
||||
while (true) {
|
||||
if (__i == __j) {
|
||||
return; // [__first, __last) all equivalent elements
|
||||
} else if (__comp(*__first, *__i)) {
|
||||
_Ops::iter_swap(__i, __j);
|
||||
++__n_swaps;
|
||||
++__i;
|
||||
break;
|
||||
}
|
||||
++__i;
|
||||
}
|
||||
}
|
||||
// [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
|
||||
if (__i == __j) {
|
||||
return;
|
||||
}
|
||||
while (true) {
|
||||
while (!__comp(*__first, *__i))
|
||||
++__i;
|
||||
while (__comp(*__first, *--__j))
|
||||
;
|
||||
if (__i >= __j)
|
||||
break;
|
||||
_Ops::iter_swap(__i, __j);
|
||||
++__n_swaps;
|
||||
++__i;
|
||||
}
|
||||
// [__first, __i) == *__first and *__first < [__i, __last)
|
||||
// The first part is sorted,
|
||||
if (__nth < __i) {
|
||||
return;
|
||||
}
|
||||
// __nth_element the second part
|
||||
// _VSTD::__nth_element<_Compare>(__i, __nth, __last, __comp);
|
||||
__first = __i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++__i;
|
||||
// j points beyond range to be tested, *__lm1 is known to be <= *__m
|
||||
// if not yet partitioned...
|
||||
if (__i < __j)
|
||||
{
|
||||
// known that *(__i - 1) < *__m
|
||||
while (true)
|
||||
{
|
||||
// __m still guards upward moving __i
|
||||
while (__comp(*__i, *__m))
|
||||
++__i;
|
||||
// It is now known that a guard exists for downward moving __j
|
||||
while (!__comp(*--__j, *__m))
|
||||
;
|
||||
if (__i >= __j)
|
||||
break;
|
||||
_Ops::iter_swap(__i, __j);
|
||||
++__n_swaps;
|
||||
// It is known that __m != __j
|
||||
// If __m just moved, follow it
|
||||
if (__m == __i)
|
||||
__m = __j;
|
||||
++__i;
|
||||
}
|
||||
}
|
||||
// [__first, __i) < *__m and *__m <= [__i, __last)
|
||||
if (__i != __m && __comp(*__m, *__i))
|
||||
{
|
||||
_Ops::iter_swap(__i, __m);
|
||||
++__n_swaps;
|
||||
}
|
||||
// [__first, __i) < *__i and *__i <= [__i+1, __last)
|
||||
if (__nth == __i)
|
||||
return;
|
||||
if (__n_swaps == 0)
|
||||
{
|
||||
// We were given a perfectly partitioned sequence. Coincidence?
|
||||
if (__nth < __i)
|
||||
{
|
||||
// Check for [__first, __i) already sorted
|
||||
__j = __m = __first;
|
||||
while (true) {
|
||||
if (++__j == __i) {
|
||||
// [__first, __i) sorted
|
||||
return;
|
||||
}
|
||||
if (__comp(*__j, *__m)) {
|
||||
// not yet sorted, so sort
|
||||
break;
|
||||
}
|
||||
__m = __j;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for [__i, __last) already sorted
|
||||
__j = __m = __i;
|
||||
while (true) {
|
||||
if (++__j == __last) {
|
||||
// [__i, __last) sorted
|
||||
return;
|
||||
}
|
||||
if (__comp(*__j, *__m)) {
|
||||
// not yet sorted, so sort
|
||||
break;
|
||||
}
|
||||
__m = __j;
|
||||
}
|
||||
}
|
||||
}
|
||||
// __nth_element on range containing __nth
|
||||
if (__nth < __i)
|
||||
{
|
||||
// _VSTD::__nth_element<_Compare>(__first, __nth, __i, __comp);
|
||||
__last = __i;
|
||||
}
|
||||
else
|
||||
{
|
||||
// _VSTD::__nth_element<_Compare>(__i+1, __nth, __last, __comp);
|
||||
__first = ++__i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
void __nth_element_impl(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last,
|
||||
_Compare& __comp) {
|
||||
if (__nth == __last)
|
||||
return;
|
||||
|
||||
std::__debug_randomize_range<_AlgPolicy>(__first, __last);
|
||||
|
||||
std::__nth_element<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __nth, __last, __comp);
|
||||
|
||||
std::__debug_randomize_range<_AlgPolicy>(__first, __nth);
|
||||
if (__nth != __last) {
|
||||
std::__debug_randomize_range<_AlgPolicy>(++__nth, __last);
|
||||
}
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last,
|
||||
_Compare __comp) {
|
||||
std::__nth_element_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__nth), std::move(__last), __comp);
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) {
|
||||
std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_NTH_ELEMENT_H
|
95
lib/libcxx/include/__algorithm/partial_sort.h
Normal file
95
lib/libcxx/include/__algorithm/partial_sort.h
Normal file
@ -0,0 +1,95 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_H
|
||||
#define _LIBCPP___ALGORITHM_PARTIAL_SORT_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/make_heap.h>
|
||||
#include <__algorithm/sift_down.h>
|
||||
#include <__algorithm/sort_heap.h>
|
||||
#include <__config>
|
||||
#include <__debug_utils/randomize_range.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_copy_assignable.h>
|
||||
#include <__type_traits/is_copy_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_RandomAccessIterator __partial_sort_impl(
|
||||
_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare&& __comp) {
|
||||
if (__first == __middle) {
|
||||
return _IterOps<_AlgPolicy>::next(__middle, __last);
|
||||
}
|
||||
|
||||
std::__make_heap<_AlgPolicy>(__first, __middle, __comp);
|
||||
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;
|
||||
_RandomAccessIterator __i = __middle;
|
||||
for (; __i != __last; ++__i)
|
||||
{
|
||||
if (__comp(*__i, *__first))
|
||||
{
|
||||
_IterOps<_AlgPolicy>::iter_swap(__i, __first);
|
||||
std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first);
|
||||
}
|
||||
}
|
||||
std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp);
|
||||
|
||||
return __i;
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last,
|
||||
_Compare& __comp) {
|
||||
if (__first == __middle)
|
||||
return _IterOps<_AlgPolicy>::next(__middle, __last);
|
||||
|
||||
std::__debug_randomize_range<_AlgPolicy>(__first, __last);
|
||||
|
||||
auto __last_iter =
|
||||
std::__partial_sort_impl<_AlgPolicy>(__first, __middle, __last, static_cast<__comp_ref_type<_Compare> >(__comp));
|
||||
|
||||
std::__debug_randomize_range<_AlgPolicy>(__middle, __last);
|
||||
|
||||
return __last_iter;
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
void
|
||||
partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
|
||||
_Compare __comp)
|
||||
{
|
||||
static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible.");
|
||||
static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable.");
|
||||
|
||||
(void)std::__partial_sort<_ClassicAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last), __comp);
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
void
|
||||
partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
|
||||
{
|
||||
_VSTD::partial_sort(__first, __middle, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_H
|
87
lib/libcxx/include/__algorithm/partial_sort_copy.h
Normal file
87
lib/libcxx/include/__algorithm/partial_sort_copy.h
Normal file
@ -0,0 +1,87 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H
|
||||
#define _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/make_heap.h>
|
||||
#include <__algorithm/make_projected.h>
|
||||
#include <__algorithm/sift_down.h>
|
||||
#include <__algorithm/sort_heap.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare,
|
||||
class _InputIterator, class _Sentinel1, class _RandomAccessIterator, class _Sentinel2,
|
||||
class _Proj1, class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _RandomAccessIterator>
|
||||
__partial_sort_copy(_InputIterator __first, _Sentinel1 __last,
|
||||
_RandomAccessIterator __result_first, _Sentinel2 __result_last,
|
||||
_Compare&& __comp, _Proj1&& __proj1, _Proj2&& __proj2)
|
||||
{
|
||||
_RandomAccessIterator __r = __result_first;
|
||||
auto&& __projected_comp = std::__make_projected(__comp, __proj2);
|
||||
|
||||
if (__r != __result_last)
|
||||
{
|
||||
for (; __first != __last && __r != __result_last; ++__first, (void) ++__r)
|
||||
*__r = *__first;
|
||||
std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first;
|
||||
for (; __first != __last; ++__first)
|
||||
if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) {
|
||||
*__result_first = *__first;
|
||||
std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first);
|
||||
}
|
||||
std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
|
||||
}
|
||||
|
||||
return pair<_InputIterator, _RandomAccessIterator>(
|
||||
_IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r));
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_RandomAccessIterator
|
||||
partial_sort_copy(_InputIterator __first, _InputIterator __last,
|
||||
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
|
||||
{
|
||||
static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value,
|
||||
"Comparator has to be callable");
|
||||
|
||||
auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>(__first, __last, __result_first, __result_last,
|
||||
static_cast<__comp_ref_type<_Compare> >(__comp), __identity(), __identity());
|
||||
return __result.second;
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _RandomAccessIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_RandomAccessIterator
|
||||
partial_sort_copy(_InputIterator __first, _InputIterator __last,
|
||||
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last)
|
||||
{
|
||||
return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H
|
97
lib/libcxx/include/__algorithm/partition.h
Normal file
97
lib/libcxx/include/__algorithm/partition.h
Normal file
@ -0,0 +1,97 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PARTITION_H
|
||||
#define _LIBCPP___ALGORITHM_PARTITION_H
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Predicate, class _AlgPolicy, class _ForwardIterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
|
||||
__partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__first), std::move(__first));
|
||||
if (!__pred(*__first))
|
||||
break;
|
||||
++__first;
|
||||
}
|
||||
|
||||
_ForwardIterator __p = __first;
|
||||
while (++__p != __last)
|
||||
{
|
||||
if (__pred(*__p))
|
||||
{
|
||||
_IterOps<_AlgPolicy>::iter_swap(__first, __p);
|
||||
++__first;
|
||||
}
|
||||
}
|
||||
return std::make_pair(std::move(__first), std::move(__p));
|
||||
}
|
||||
|
||||
template <class _Predicate, class _AlgPolicy, class _BidirectionalIterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, _BidirectionalIterator>
|
||||
__partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred,
|
||||
bidirectional_iterator_tag)
|
||||
{
|
||||
_BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel);
|
||||
_BidirectionalIterator __last = __original_last;
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__first), std::move(__original_last));
|
||||
if (!__pred(*__first))
|
||||
break;
|
||||
++__first;
|
||||
}
|
||||
do
|
||||
{
|
||||
if (__first == --__last)
|
||||
return std::make_pair(std::move(__first), std::move(__original_last));
|
||||
} while (!__pred(*__last));
|
||||
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
|
||||
++__first;
|
||||
}
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _ForwardIterator, class _Sentinel, class _Predicate, class _IterCategory>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
pair<_ForwardIterator, _ForwardIterator> __partition(
|
||||
_ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) {
|
||||
return std::__partition_impl<__remove_cvref_t<_Predicate>&, _AlgPolicy>(
|
||||
std::move(__first), std::move(__last), __pred, __iter_category);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Predicate>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
_ForwardIterator
|
||||
partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
|
||||
{
|
||||
using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category;
|
||||
auto __result = std::__partition<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred, _IterCategory());
|
||||
return __result.first;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PARTITION_H
|
47
lib/libcxx/include/__algorithm/partition_copy.h
Normal file
47
lib/libcxx/include/__algorithm/partition_copy.h
Normal file
@ -0,0 +1,47 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PARTITION_COPY_H
|
||||
#define _LIBCPP___ALGORITHM_PARTITION_COPY_H
|
||||
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _OutputIterator1,
|
||||
class _OutputIterator2, class _Predicate>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_OutputIterator1, _OutputIterator2>
|
||||
partition_copy(_InputIterator __first, _InputIterator __last,
|
||||
_OutputIterator1 __out_true, _OutputIterator2 __out_false,
|
||||
_Predicate __pred)
|
||||
{
|
||||
for (; __first != __last; ++__first)
|
||||
{
|
||||
if (__pred(*__first))
|
||||
{
|
||||
*__out_true = *__first;
|
||||
++__out_true;
|
||||
}
|
||||
else
|
||||
{
|
||||
*__out_false = *__first;
|
||||
++__out_false;
|
||||
}
|
||||
}
|
||||
return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PARTITION_COPY_H
|
48
lib/libcxx/include/__algorithm/partition_point.h
Normal file
48
lib/libcxx/include/__algorithm/partition_point.h
Normal file
@ -0,0 +1,48 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PARTITION_POINT_H
|
||||
#define _LIBCPP___ALGORITHM_PARTITION_POINT_H
|
||||
|
||||
#include <__algorithm/half_positive.h>
|
||||
#include <__config>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template<class _ForwardIterator, class _Predicate>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
|
||||
difference_type __len = _VSTD::distance(__first, __last);
|
||||
while (__len != 0)
|
||||
{
|
||||
difference_type __l2 = _VSTD::__half_positive(__len);
|
||||
_ForwardIterator __m = __first;
|
||||
_VSTD::advance(__m, __l2);
|
||||
if (__pred(*__m))
|
||||
{
|
||||
__first = ++__m;
|
||||
__len -= __l2 + 1;
|
||||
}
|
||||
else
|
||||
__len = __l2;
|
||||
}
|
||||
return __first;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PARTITION_POINT_H
|
78
lib/libcxx/include/__algorithm/pop_heap.h
Normal file
78
lib/libcxx/include/__algorithm/pop_heap.h
Normal file
@ -0,0 +1,78 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_POP_HEAP_H
|
||||
#define _LIBCPP___ALGORITHM_POP_HEAP_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/push_heap.h>
|
||||
#include <__algorithm/sift_down.h>
|
||||
#include <__assert>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_copy_assignable.h>
|
||||
#include <__type_traits/is_copy_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp,
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
|
||||
_LIBCPP_ASSERT_UNCATEGORIZED(__len > 0, "The heap given to pop_heap must be non-empty");
|
||||
|
||||
__comp_ref_type<_Compare> __comp_ref = __comp;
|
||||
|
||||
using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
|
||||
if (__len > 1) {
|
||||
value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first
|
||||
_RandomAccessIterator __hole = std::__floyd_sift_down<_AlgPolicy>(__first, __comp_ref, __len);
|
||||
--__last;
|
||||
|
||||
if (__hole == __last) {
|
||||
*__hole = std::move(__top);
|
||||
} else {
|
||||
*__hole = _IterOps<_AlgPolicy>::__iter_move(__last);
|
||||
++__hole;
|
||||
*__last = std::move(__top);
|
||||
std::__sift_up<_AlgPolicy>(__first, __hole, __comp_ref, __hole - __first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
|
||||
static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible.");
|
||||
static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable.");
|
||||
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first;
|
||||
std::__pop_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp, __len);
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
|
||||
std::pop_heap(std::move(__first), std::move(__last), __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_POP_HEAP_H
|
78
lib/libcxx/include/__algorithm/prev_permutation.h
Normal file
78
lib/libcxx/include/__algorithm/prev_permutation.h
Normal file
@ -0,0 +1,78 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
|
||||
#define _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/reverse.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
pair<_BidirectionalIterator, bool>
|
||||
__prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp)
|
||||
{
|
||||
using _Result = pair<_BidirectionalIterator, bool>;
|
||||
|
||||
_BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
|
||||
_BidirectionalIterator __i = __last_iter;
|
||||
if (__first == __last || __first == --__i)
|
||||
return _Result(std::move(__last_iter), false);
|
||||
|
||||
while (true)
|
||||
{
|
||||
_BidirectionalIterator __ip1 = __i;
|
||||
if (__comp(*__ip1, *--__i))
|
||||
{
|
||||
_BidirectionalIterator __j = __last_iter;
|
||||
while (!__comp(*--__j, *__i))
|
||||
;
|
||||
_IterOps<_AlgPolicy>::iter_swap(__i, __j);
|
||||
std::__reverse<_AlgPolicy>(__ip1, __last_iter);
|
||||
return _Result(std::move(__last_iter), true);
|
||||
}
|
||||
if (__i == __first)
|
||||
{
|
||||
std::__reverse<_AlgPolicy>(__first, __last_iter);
|
||||
return _Result(std::move(__last_iter), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator, class _Compare>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
bool
|
||||
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
|
||||
{
|
||||
return std::__prev_permutation<_ClassicAlgPolicy>(
|
||||
std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second;
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
bool
|
||||
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
|
||||
{
|
||||
return _VSTD::prev_permutation(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
|
100
lib/libcxx/include/__algorithm/pstl_any_all_none_of.h
Normal file
100
lib/libcxx/include/__algorithm/pstl_any_all_none_of.h
Normal file
@ -0,0 +1,100 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
|
||||
|
||||
#include <__algorithm/pstl_find.h>
|
||||
#include <__algorithm/pstl_frontend_dispatch.h>
|
||||
#include <__config>
|
||||
#include <__iterator/cpp17_iterator_concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class>
|
||||
void __pstl_any_of(); // declaration needed for the frontend dispatch below
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Predicate,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
|
||||
any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
|
||||
return std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_any_of),
|
||||
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
|
||||
return std::find_if(__policy, __g_first, __g_last, __g_pred) != __g_last;
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__pred));
|
||||
}
|
||||
|
||||
template <class>
|
||||
void __pstl_all_of(); // declaration needed for the frontend dispatch below
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Pred,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
|
||||
all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
|
||||
return std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_all_of),
|
||||
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) {
|
||||
return !std::any_of(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) {
|
||||
return !__g_pred(__value);
|
||||
});
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__pred));
|
||||
}
|
||||
|
||||
template <class>
|
||||
void __pstl_none_of(); // declaration needed for the frontend dispatch below
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Pred,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
|
||||
none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
|
||||
return std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_none_of),
|
||||
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) {
|
||||
return !std::any_of(__policy, __g_first, __g_last, __g_pred);
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__pred));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
|
198
lib/libcxx/include/__algorithm/pstl_backend.h
Normal file
198
lib/libcxx/include/__algorithm/pstl_backend.h
Normal file
@ -0,0 +1,198 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKEND_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKEND_H
|
||||
|
||||
#include <__algorithm/pstl_backends/cpu_backend.h>
|
||||
#include <__config>
|
||||
#include <execution>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
/*
|
||||
TODO: Documentation of how backends work
|
||||
|
||||
A PSTL parallel backend is a tag type to which the following functions are associated, at minimum:
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Func>
|
||||
void __pstl_for_each(_Backend, _ExecutionPolicy&&, _Iterator __first, _Iterator __last, _Func __f);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
|
||||
_Iterator __pstl_find_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
|
||||
|
||||
template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp>
|
||||
void __pstl_stable_sort(_Backend, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp);
|
||||
|
||||
template <class _ExecutionPolicy, class _InIterator, class _OutIterator, class _UnaryOperation>
|
||||
_OutIterator __pstl_transform(_InIterator __first, _InIterator __last, _OutIterator __result, _UnaryOperation __op);
|
||||
|
||||
template <class _ExecutionPolicy, class _InIterator1, class _InIterator2, class _OutIterator, class _BinaryOperation>
|
||||
_OutIterator __pstl_transform(_InIterator1 __first1,
|
||||
_InIterator1 __last1,
|
||||
_InIterator2 __first2,
|
||||
_OutIterator __result,
|
||||
_BinaryOperation __op);
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _Iterator1,
|
||||
class _Iterator2,
|
||||
class _Tp,
|
||||
class _BinaryOperation1,
|
||||
class _BinaryOperation2>
|
||||
_Tp __pstl_transform_reduce(_Backend,
|
||||
_Iterator1 __first1,
|
||||
_Iterator1 __last1,
|
||||
_Iterator2 __first2,
|
||||
_Iterator2 __last2,
|
||||
_Tp __init,
|
||||
_BinaryOperation1 __reduce,
|
||||
_BinaryOperation2 __transform);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
|
||||
_Tp __pstl_transform_reduce(_Backend,
|
||||
_Iterator __first,
|
||||
_Iterator __last,
|
||||
_Tp __init,
|
||||
_BinaryOperation __reduce,
|
||||
_UnaryOperation __transform);
|
||||
|
||||
// TODO: Complete this list
|
||||
|
||||
The following functions are optional but can be provided. If provided, they are used by the corresponding
|
||||
algorithms, otherwise they are implemented in terms of other algorithms. If none of the optional algorithms are
|
||||
implemented, all the algorithms will eventually forward to the basis algorithms listed above:
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Size, class _Func>
|
||||
void __pstl_for_each_n(_Backend, _Iterator __first, _Size __n, _Func __f);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
|
||||
bool __pstl_any_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
|
||||
bool __pstl_all_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
|
||||
bool __pstl_none_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Tp>
|
||||
_Iterator __pstl_find(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
|
||||
_Iterator __pstl_find_if_not(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Tp>
|
||||
void __pstl_fill(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _SizeT, class _Tp>
|
||||
void __pstl_fill_n(_Backend, _Iterator __first, _SizeT __n, const _Tp& __value);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Generator>
|
||||
void __pstl_generate(_Backend, _Iterator __first, _Iterator __last, _Generator __gen);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
|
||||
void __pstl_is_partitioned(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Size, class _Generator>
|
||||
void __pstl_generator_n(_Backend, _Iterator __first, _Size __n, _Generator __gen);
|
||||
|
||||
template <class _ExecutionPolicy, class _terator1, class _Iterator2, class _OutIterator, class _Comp>
|
||||
_OutIterator __pstl_merge(_Backend,
|
||||
_Iterator1 __first1,
|
||||
_Iterator1 __last1,
|
||||
_Iterator2 __first2,
|
||||
_Iterator2 __last2,
|
||||
_OutIterator __result,
|
||||
_Comp __comp);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation>
|
||||
_Tp __pstl_reduce(_Backend, _Iterator __first, _Iterator __last, _Tp __init, _BinaryOperation __op);
|
||||
|
||||
temlate <class _ExecutionPolicy, class _Iterator>
|
||||
__iter_value_type<_Iterator> __pstl_reduce(_Backend, _Iterator __first, _Iterator __last);
|
||||
|
||||
template <class _ExecuitonPolicy, class _Iterator, class _Tp>
|
||||
__iter_diff_t<_Iterator> __pstl_count(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
|
||||
__iter_diff_t<_Iterator> __pstl_count_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Tp>
|
||||
void __pstl_replace(_Backend, _Iterator __first, _Iterator __last, const _Tp& __old_value, const _Tp& __new_value);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Pred, class _Tp>
|
||||
void __pstl_replace_if(_Backend, _Iterator __first, _Iterator __last, _Pred __pred, const _Tp& __new_value);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Tp>
|
||||
void __pstl_replace_copy(_Backend,
|
||||
_Iterator __first,
|
||||
_Iterator __last,
|
||||
_OutIterator __result,
|
||||
const _Tp& __old_value,
|
||||
const _Tp& __new_value);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Pred, class _Tp>
|
||||
void __pstl_replace_copy_if(_Backend,
|
||||
_Iterator __first,
|
||||
_Iterator __last,
|
||||
_OutIterator __result,
|
||||
_Pred __pred,
|
||||
const _Tp& __new_value);
|
||||
|
||||
template <class _ExecutionPolicy, class _Iterator, class _Comp>
|
||||
void __pstl_sort(_Backend, _Iterator __first, _Iterator __last, _Comp __comp);
|
||||
|
||||
// TODO: Complete this list
|
||||
|
||||
*/
|
||||
|
||||
template <class _ExecutionPolicy>
|
||||
struct __select_backend;
|
||||
|
||||
template <>
|
||||
struct __select_backend<std::execution::sequenced_policy> {
|
||||
using type = __cpu_backend_tag;
|
||||
};
|
||||
|
||||
# if _LIBCPP_STD_VER >= 20
|
||||
template <>
|
||||
struct __select_backend<std::execution::unsequenced_policy> {
|
||||
using type = __cpu_backend_tag;
|
||||
};
|
||||
# endif
|
||||
|
||||
# if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL) || defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD) || \
|
||||
defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH)
|
||||
template <>
|
||||
struct __select_backend<std::execution::parallel_policy> {
|
||||
using type = __cpu_backend_tag;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct __select_backend<std::execution::parallel_unsequenced_policy> {
|
||||
using type = __cpu_backend_tag;
|
||||
};
|
||||
|
||||
# else
|
||||
|
||||
// ...New vendors can add parallel backends here...
|
||||
|
||||
# error "Invalid choice of a PSTL parallel backend"
|
||||
# endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKEND_H
|
59
lib/libcxx/include/__algorithm/pstl_backends/cpu_backend.h
Normal file
59
lib/libcxx/include/__algorithm/pstl_backends/cpu_backend.h
Normal file
@ -0,0 +1,59 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
/*
|
||||
|
||||
// _Functor takes a subrange for [__first, __last) that should be executed in serial
|
||||
template <class _RandomAccessIterator, class _Functor>
|
||||
void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func);
|
||||
|
||||
template <class _Iterator, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduction>
|
||||
_Tp __parallel_transform_reduce(_Iterator __first, _Iterator __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduction);
|
||||
|
||||
// Cancel the execution of other jobs - they aren't needed anymore
|
||||
void __cancel_execution();
|
||||
|
||||
template <class _RandomAccessIterator1,
|
||||
class _RandomAccessIterator2,
|
||||
class _RandomAccessIterator3,
|
||||
class _Compare,
|
||||
class _LeafMerge>
|
||||
void __parallel_merge(
|
||||
_RandomAccessIterator1 __first1,
|
||||
_RandomAccessIterator1 __last1,
|
||||
_RandomAccessIterator2 __first2,
|
||||
_RandomAccessIterator2 __last2,
|
||||
_RandomAccessIterator3 __outit,
|
||||
_Compare __comp,
|
||||
_LeafMerge __leaf_merge);
|
||||
|
||||
template <class _RandomAccessIterator, class _Comp, class _LeafSort>
|
||||
void __parallel_stable_sort(_RandomAccessIterator __first,
|
||||
_RandomAccessIterator __last,
|
||||
_Comp __comp,
|
||||
_LeafSort __leaf_sort);
|
||||
|
||||
TODO: Document the parallel backend
|
||||
*/
|
||||
|
||||
#include <__algorithm/pstl_backends/cpu_backends/any_of.h>
|
||||
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
|
||||
#include <__algorithm/pstl_backends/cpu_backends/fill.h>
|
||||
#include <__algorithm/pstl_backends/cpu_backends/find_if.h>
|
||||
#include <__algorithm/pstl_backends/cpu_backends/for_each.h>
|
||||
#include <__algorithm/pstl_backends/cpu_backends/merge.h>
|
||||
#include <__algorithm/pstl_backends/cpu_backends/stable_sort.h>
|
||||
#include <__algorithm/pstl_backends/cpu_backends/transform.h>
|
||||
#include <__algorithm/pstl_backends/cpu_backends/transform_reduce.h>
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
|
@ -0,0 +1,90 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
|
||||
|
||||
#include <__algorithm/any_of.h>
|
||||
#include <__algorithm/find_if.h>
|
||||
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
|
||||
#include <__atomic/atomic.h>
|
||||
#include <__atomic/memory_order.h>
|
||||
#include <__config>
|
||||
#include <__functional/operations.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
#include <cstdint>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Index, class _Brick>
|
||||
_LIBCPP_HIDE_FROM_ABI bool __parallel_or(_Index __first, _Index __last, _Brick __f) {
|
||||
std::atomic<bool> __found(false);
|
||||
__par_backend::__parallel_for(__first, __last, [__f, &__found](_Index __i, _Index __j) {
|
||||
if (!__found.load(std::memory_order_relaxed) && __f(__i, __j)) {
|
||||
__found.store(true, std::memory_order_relaxed);
|
||||
__par_backend::__cancel_execution();
|
||||
}
|
||||
});
|
||||
return __found;
|
||||
}
|
||||
|
||||
// TODO: check whether __simd_first() can be used here
|
||||
template <class _Index, class _DifferenceType, class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI bool __simd_or(_Index __first, _DifferenceType __n, _Pred __pred) noexcept {
|
||||
_DifferenceType __block_size = 4 < __n ? 4 : __n;
|
||||
const _Index __last = __first + __n;
|
||||
while (__last != __first) {
|
||||
int32_t __flag = 1;
|
||||
_PSTL_PRAGMA_SIMD_REDUCTION(& : __flag)
|
||||
for (_DifferenceType __i = 0; __i < __block_size; ++__i)
|
||||
if (__pred(*(__first + __i)))
|
||||
__flag = 0;
|
||||
if (!__flag)
|
||||
return true;
|
||||
|
||||
__first += __block_size;
|
||||
if (__last - __first >= __block_size << 1) {
|
||||
// Double the block _Size. Any unnecessary iterations can be amortized against work done so far.
|
||||
__block_size <<= 1;
|
||||
} else {
|
||||
__block_size = __last - __first;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
__pstl_any_of(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator>::value) {
|
||||
return std::__terminate_on_exception([&] {
|
||||
return std::__parallel_or(
|
||||
__first, __last, [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
|
||||
return std::__pstl_any_of<__remove_parallel_policy_t<_ExecutionPolicy>>(
|
||||
__cpu_backend_tag{}, __brick_first, __brick_last, __pred);
|
||||
});
|
||||
});
|
||||
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator>::value) {
|
||||
return std::__simd_or(__first, __last - __first, __pred);
|
||||
} else {
|
||||
return std::any_of(__first, __last, __pred);
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
|
@ -0,0 +1,41 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
|
||||
|
||||
#include <__config>
|
||||
#include <cstddef>
|
||||
|
||||
#if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL)
|
||||
# include <__algorithm/pstl_backends/cpu_backends/serial.h>
|
||||
#elif defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD)
|
||||
# include <__algorithm/pstl_backends/cpu_backends/thread.h>
|
||||
#elif defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH)
|
||||
# include <__algorithm/pstl_backends/cpu_backends/libdispatch.h>
|
||||
#else
|
||||
# error "Invalid CPU backend choice"
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
struct __cpu_backend_tag {};
|
||||
|
||||
inline constexpr size_t __lane_size = 64;
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
|
@ -0,0 +1,60 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
|
||||
|
||||
#include <__algorithm/fill.h>
|
||||
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Index, class _DifferenceType, class _Tp>
|
||||
_LIBCPP_HIDE_FROM_ABI _Index __simd_fill_n(_Index __first, _DifferenceType __n, const _Tp& __value) noexcept {
|
||||
_PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
|
||||
_PSTL_PRAGMA_SIMD
|
||||
for (_DifferenceType __i = 0; __i < __n; ++__i)
|
||||
__first[__i] = __value;
|
||||
return __first + __n;
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
__pstl_fill(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator>::value) {
|
||||
std::__terminate_on_exception([&] {
|
||||
__par_backend::__parallel_for(
|
||||
__first, __last, [&__value](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
|
||||
std::__pstl_fill<__remove_parallel_policy_t<_ExecutionPolicy>>(
|
||||
__cpu_backend_tag{}, __brick_first, __brick_last, __value);
|
||||
});
|
||||
});
|
||||
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator>::value) {
|
||||
std::__simd_fill_n(__first, __last - __first, __value);
|
||||
} else {
|
||||
std::fill(__first, __last, __value);
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
|
@ -0,0 +1,123 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
|
||||
|
||||
#include <__algorithm/find_if.h>
|
||||
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
|
||||
#include <__atomic/atomic.h>
|
||||
#include <__config>
|
||||
#include <__functional/operations.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Index, class _Brick, class _Compare>
|
||||
_LIBCPP_HIDE_FROM_ABI _Index
|
||||
__parallel_find(_Index __first, _Index __last, _Brick __f, _Compare __comp, bool __b_first) {
|
||||
typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType;
|
||||
const _DifferenceType __n = __last - __first;
|
||||
_DifferenceType __initial_dist = __b_first ? __n : -1;
|
||||
std::atomic<_DifferenceType> __extremum(__initial_dist);
|
||||
// TODO: find out what is better here: parallel_for or parallel_reduce
|
||||
__par_backend::__parallel_for(__first, __last, [__comp, __f, __first, &__extremum](_Index __i, _Index __j) {
|
||||
// See "Reducing Contention Through Priority Updates", PPoPP '13, for discussion of
|
||||
// why using a shared variable scales fairly well in this situation.
|
||||
if (__comp(__i - __first, __extremum)) {
|
||||
_Index __res = __f(__i, __j);
|
||||
// If not '__last' returned then we found what we want so put this to extremum
|
||||
if (__res != __j) {
|
||||
const _DifferenceType __k = __res - __first;
|
||||
for (_DifferenceType __old = __extremum; __comp(__k, __old); __old = __extremum) {
|
||||
__extremum.compare_exchange_weak(__old, __k);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return __extremum != __initial_dist ? __first + __extremum : __last;
|
||||
}
|
||||
|
||||
template <class _Index, class _DifferenceType, class _Compare>
|
||||
_LIBCPP_HIDE_FROM_ABI _Index
|
||||
__simd_first(_Index __first, _DifferenceType __begin, _DifferenceType __end, _Compare __comp) noexcept {
|
||||
// Experiments show good block sizes like this
|
||||
const _DifferenceType __block_size = 8;
|
||||
alignas(__lane_size) _DifferenceType __lane[__block_size] = {0};
|
||||
while (__end - __begin >= __block_size) {
|
||||
_DifferenceType __found = 0;
|
||||
_PSTL_PRAGMA_SIMD_REDUCTION(| : __found) for (_DifferenceType __i = __begin; __i < __begin + __block_size; ++__i) {
|
||||
const _DifferenceType __t = __comp(__first, __i);
|
||||
__lane[__i - __begin] = __t;
|
||||
__found |= __t;
|
||||
}
|
||||
if (__found) {
|
||||
_DifferenceType __i;
|
||||
// This will vectorize
|
||||
for (__i = 0; __i < __block_size; ++__i) {
|
||||
if (__lane[__i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return __first + __begin + __i;
|
||||
}
|
||||
__begin += __block_size;
|
||||
}
|
||||
|
||||
// Keep remainder scalar
|
||||
while (__begin != __end) {
|
||||
if (__comp(__first, __begin)) {
|
||||
return __first + __begin;
|
||||
}
|
||||
++__begin;
|
||||
}
|
||||
return __first + __end;
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
||||
__pstl_find_if(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator>::value) {
|
||||
return std::__terminate_on_exception([&] {
|
||||
return std::__parallel_find(
|
||||
__first,
|
||||
__last,
|
||||
[&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
|
||||
return std::__pstl_find_if<__remove_parallel_policy_t<_ExecutionPolicy>>(
|
||||
__cpu_backend_tag{}, __brick_first, __brick_last, __pred);
|
||||
},
|
||||
less<>{},
|
||||
true);
|
||||
});
|
||||
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator>::value) {
|
||||
using __diff_t = __iter_diff_t<_ForwardIterator>;
|
||||
return std::__simd_first(__first, __diff_t(0), __last - __first, [&__pred](_ForwardIterator __iter, __diff_t __i) {
|
||||
return __pred(__iter[__i]);
|
||||
});
|
||||
} else {
|
||||
return std::find_if(__first, __last, __pred);
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
|
@ -0,0 +1,60 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
|
||||
|
||||
#include <__algorithm/for_each.h>
|
||||
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Iterator, class _DifferenceType, class _Function>
|
||||
_LIBCPP_HIDE_FROM_ABI _Iterator __simd_walk_1(_Iterator __first, _DifferenceType __n, _Function __f) noexcept {
|
||||
_PSTL_PRAGMA_SIMD
|
||||
for (_DifferenceType __i = 0; __i < __n; ++__i)
|
||||
__f(__first[__i]);
|
||||
|
||||
return __first + __n;
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _Functor>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
__pstl_for_each(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Functor __func) {
|
||||
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator>::value) {
|
||||
std::__terminate_on_exception([&] {
|
||||
std::__par_backend::__parallel_for(
|
||||
__first, __last, [__func](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
|
||||
std::__pstl_for_each<__remove_parallel_policy_t<_ExecutionPolicy>>(
|
||||
__cpu_backend_tag{}, __brick_first, __brick_last, __func);
|
||||
});
|
||||
});
|
||||
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator>::value) {
|
||||
std::__simd_walk_1(__first, __last - __first, __func);
|
||||
} else {
|
||||
std::for_each(__first, __last, __func);
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
|
@ -0,0 +1,241 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
|
||||
|
||||
#include <__algorithm/lower_bound.h>
|
||||
#include <__algorithm/max.h>
|
||||
#include <__algorithm/upper_bound.h>
|
||||
#include <__atomic/atomic.h>
|
||||
#include <__config>
|
||||
#include <__exception/terminate.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/move_iterator.h>
|
||||
#include <__memory/allocator.h>
|
||||
#include <__memory/construct_at.h>
|
||||
#include <__memory/unique_ptr.h>
|
||||
#include <__numeric/reduce.h>
|
||||
#include <__utility/exception_guard.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace __par_backend {
|
||||
inline namespace __libdispatch {
|
||||
|
||||
// ::dispatch_apply is marked as __attribute__((nothrow)) because it doesn't let exceptions propagate, and neither do
|
||||
// we.
|
||||
// TODO: Do we want to add [[_Clang::__callback__(__func, __context, __)]]?
|
||||
_LIBCPP_EXPORTED_FROM_ABI void
|
||||
__dispatch_apply(size_t __chunk_count, void* __context, void (*__func)(void* __context, size_t __chunk)) noexcept;
|
||||
|
||||
template <class _Func>
|
||||
_LIBCPP_HIDE_FROM_ABI void __dispatch_apply(size_t __chunk_count, _Func __func) noexcept {
|
||||
__libdispatch::__dispatch_apply(__chunk_count, &__func, [](void* __context, size_t __chunk) {
|
||||
(*static_cast<_Func*>(__context))(__chunk);
|
||||
});
|
||||
}
|
||||
|
||||
struct __chunk_partitions {
|
||||
ptrdiff_t __chunk_count_; // includes the first chunk
|
||||
ptrdiff_t __chunk_size_;
|
||||
ptrdiff_t __first_chunk_size_;
|
||||
};
|
||||
|
||||
[[__gnu__::__const__]] _LIBCPP_EXPORTED_FROM_ABI __chunk_partitions __partition_chunks(ptrdiff_t __size);
|
||||
|
||||
template <class _RandomAccessIterator, class _Functor>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
__parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func) {
|
||||
auto __partitions = __libdispatch::__partition_chunks(__last - __first);
|
||||
|
||||
// Perform the chunked execution.
|
||||
__libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) {
|
||||
auto __this_chunk_size = __chunk == 0 ? __partitions.__first_chunk_size_ : __partitions.__chunk_size_;
|
||||
auto __index =
|
||||
__chunk == 0
|
||||
? 0
|
||||
: (__chunk * __partitions.__chunk_size_) + (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
|
||||
__func(__first + __index, __first + __index + __this_chunk_size);
|
||||
});
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIteratorOut>
|
||||
struct __merge_range {
|
||||
__merge_range(_RandomAccessIterator1 __mid1, _RandomAccessIterator2 __mid2, _RandomAccessIteratorOut __result)
|
||||
: __mid1_(__mid1), __mid2_(__mid2), __result_(__result) {}
|
||||
|
||||
_RandomAccessIterator1 __mid1_;
|
||||
_RandomAccessIterator2 __mid2_;
|
||||
_RandomAccessIteratorOut __result_;
|
||||
};
|
||||
|
||||
template <typename _RandomAccessIterator1,
|
||||
typename _RandomAccessIterator2,
|
||||
typename _RandomAccessIterator3,
|
||||
typename _Compare,
|
||||
typename _LeafMerge>
|
||||
_LIBCPP_HIDE_FROM_ABI void __parallel_merge(
|
||||
_RandomAccessIterator1 __first1,
|
||||
_RandomAccessIterator1 __last1,
|
||||
_RandomAccessIterator2 __first2,
|
||||
_RandomAccessIterator2 __last2,
|
||||
_RandomAccessIterator3 __result,
|
||||
_Compare __comp,
|
||||
_LeafMerge __leaf_merge) {
|
||||
__chunk_partitions __partitions =
|
||||
__libdispatch::__partition_chunks(std::max<ptrdiff_t>(__last1 - __first1, __last2 - __first2));
|
||||
|
||||
if (__partitions.__chunk_count_ == 0)
|
||||
return;
|
||||
|
||||
if (__partitions.__chunk_count_ == 1) {
|
||||
__leaf_merge(__first1, __last1, __first2, __last2, __result, __comp);
|
||||
return;
|
||||
}
|
||||
|
||||
using __merge_range_t = __merge_range<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3>;
|
||||
auto const __n_ranges = __partitions.__chunk_count_ + 1;
|
||||
|
||||
// TODO: use __uninitialized_buffer
|
||||
auto __destroy = [=](__merge_range_t* __ptr) {
|
||||
std::destroy_n(__ptr, __n_ranges);
|
||||
std::allocator<__merge_range_t>().deallocate(__ptr, __n_ranges);
|
||||
};
|
||||
unique_ptr<__merge_range_t[], decltype(__destroy)> __ranges(
|
||||
std::allocator<__merge_range_t>().allocate(__n_ranges), __destroy);
|
||||
|
||||
// TODO: Improve the case where the smaller range is merged into just a few (or even one) chunks of the larger case
|
||||
std::__terminate_on_exception([&] {
|
||||
__merge_range_t* __r = __ranges.get();
|
||||
std::__construct_at(__r++, __first1, __first2, __result);
|
||||
|
||||
bool __iterate_first_range = __last1 - __first1 > __last2 - __first2;
|
||||
|
||||
auto __compute_chunk = [&](size_t __chunk_size) -> __merge_range_t {
|
||||
auto [__mid1, __mid2] = [&] {
|
||||
if (__iterate_first_range) {
|
||||
auto __m1 = __first1 + __chunk_size;
|
||||
auto __m2 = std::lower_bound(__first2, __last2, __m1[-1], __comp);
|
||||
return std::make_pair(__m1, __m2);
|
||||
} else {
|
||||
auto __m2 = __first2 + __chunk_size;
|
||||
auto __m1 = std::lower_bound(__first1, __last1, __m2[-1], __comp);
|
||||
return std::make_pair(__m1, __m2);
|
||||
}
|
||||
}();
|
||||
|
||||
__result += (__mid1 - __first1) + (__mid2 - __first2);
|
||||
__first1 = __mid1;
|
||||
__first2 = __mid2;
|
||||
return {std::move(__mid1), std::move(__mid2), __result};
|
||||
};
|
||||
|
||||
// handle first chunk
|
||||
std::__construct_at(__r++, __compute_chunk(__partitions.__first_chunk_size_));
|
||||
|
||||
// handle 2 -> N - 1 chunks
|
||||
for (ptrdiff_t __i = 0; __i != __partitions.__chunk_count_ - 2; ++__i)
|
||||
std::__construct_at(__r++, __compute_chunk(__partitions.__chunk_size_));
|
||||
|
||||
// handle last chunk
|
||||
std::__construct_at(__r, __last1, __last2, __result);
|
||||
|
||||
__libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __index) {
|
||||
auto __first_iters = __ranges[__index];
|
||||
auto __last_iters = __ranges[__index + 1];
|
||||
__leaf_merge(
|
||||
__first_iters.__mid1_,
|
||||
__last_iters.__mid1_,
|
||||
__first_iters.__mid2_,
|
||||
__last_iters.__mid2_,
|
||||
__first_iters.__result_,
|
||||
__comp);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Transform, class _Value, class _Combiner, class _Reduction>
|
||||
_LIBCPP_HIDE_FROM_ABI _Value __parallel_transform_reduce(
|
||||
_RandomAccessIterator __first,
|
||||
_RandomAccessIterator __last,
|
||||
_Transform __transform,
|
||||
_Value __init,
|
||||
_Combiner __combiner,
|
||||
_Reduction __reduction) {
|
||||
if (__first == __last)
|
||||
return __init;
|
||||
|
||||
auto __partitions = __libdispatch::__partition_chunks(__last - __first);
|
||||
|
||||
auto __destroy = [__count = __partitions.__chunk_count_](_Value* __ptr) {
|
||||
std::destroy_n(__ptr, __count);
|
||||
std::allocator<_Value>().deallocate(__ptr, __count);
|
||||
};
|
||||
|
||||
// TODO: use __uninitialized_buffer
|
||||
// TODO: allocate one element per worker instead of one element per chunk
|
||||
unique_ptr<_Value[], decltype(__destroy)> __values(
|
||||
std::allocator<_Value>().allocate(__partitions.__chunk_count_), __destroy);
|
||||
|
||||
// __dispatch_apply is noexcept
|
||||
__libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) {
|
||||
auto __this_chunk_size = __chunk == 0 ? __partitions.__first_chunk_size_ : __partitions.__chunk_size_;
|
||||
auto __index =
|
||||
__chunk == 0
|
||||
? 0
|
||||
: (__chunk * __partitions.__chunk_size_) + (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
|
||||
if (__this_chunk_size != 1) {
|
||||
std::__construct_at(
|
||||
__values.get() + __chunk,
|
||||
__reduction(__first + __index + 2,
|
||||
__first + __index + __this_chunk_size,
|
||||
__combiner(__transform(__first + __index), __transform(__first + __index + 1))));
|
||||
} else {
|
||||
std::__construct_at(__values.get() + __chunk, __transform(__first + __index));
|
||||
}
|
||||
});
|
||||
|
||||
return std::__terminate_on_exception([&] {
|
||||
return std::reduce(
|
||||
std::make_move_iterator(__values.get()),
|
||||
std::make_move_iterator(__values.get() + __partitions.__chunk_count_),
|
||||
std::move(__init),
|
||||
__combiner);
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: parallelize this
|
||||
template <class _RandomAccessIterator, class _Comp, class _LeafSort>
|
||||
_LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort(
|
||||
_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp, _LeafSort __leaf_sort) {
|
||||
__leaf_sort(__first, __last, __comp);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
|
||||
|
||||
} // namespace __libdispatch
|
||||
} // namespace __par_backend
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
|
@ -0,0 +1,79 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
|
||||
|
||||
#include <__algorithm/merge.h>
|
||||
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator1,
|
||||
class _ForwardIterator2,
|
||||
class _ForwardOutIterator,
|
||||
class _Comp>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_merge(
|
||||
__cpu_backend_tag,
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2,
|
||||
_ForwardOutIterator __result,
|
||||
_Comp __comp) {
|
||||
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator1>::value &&
|
||||
__has_random_access_iterator_category<_ForwardIterator2>::value &&
|
||||
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
|
||||
return std::__terminate_on_exception([&] {
|
||||
__par_backend::__parallel_merge(
|
||||
__first1,
|
||||
__last1,
|
||||
__first2,
|
||||
__last2,
|
||||
__result,
|
||||
__comp,
|
||||
[](_ForwardIterator1 __g_first1,
|
||||
_ForwardIterator1 __g_last1,
|
||||
_ForwardIterator2 __g_first2,
|
||||
_ForwardIterator2 __g_last2,
|
||||
_ForwardOutIterator __g_result,
|
||||
_Comp __g_comp) {
|
||||
return std::__pstl_merge<__remove_parallel_policy_t<_ExecutionPolicy>>(
|
||||
__cpu_backend_tag{},
|
||||
std::move(__g_first1),
|
||||
std::move(__g_last1),
|
||||
std::move(__g_first2),
|
||||
std::move(__g_last2),
|
||||
std::move(__g_result),
|
||||
std::move(__g_comp));
|
||||
});
|
||||
return __result + (__last1 - __first1) + (__last2 - __first2);
|
||||
});
|
||||
} else {
|
||||
return std::merge(__first1, __last1, __first2, __last2, __result, __comp);
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
|
@ -0,0 +1,72 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
|
||||
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace __par_backend {
|
||||
inline namespace __serial_cpu_backend {
|
||||
|
||||
template <class _RandomAccessIterator, class _Fp>
|
||||
_LIBCPP_HIDE_FROM_ABI void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) {
|
||||
__f(__first, __last);
|
||||
}
|
||||
|
||||
template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp
|
||||
__parallel_transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) {
|
||||
return __reduce(std::move(__first), std::move(__last), std::move(__init));
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare, class _LeafSort>
|
||||
_LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort(
|
||||
_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) {
|
||||
__leaf_sort(__first, __last, __comp);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
|
||||
|
||||
template <class _RandomAccessIterator1,
|
||||
class _RandomAccessIterator2,
|
||||
class _RandomAccessIterator3,
|
||||
class _Compare,
|
||||
class _LeafMerge>
|
||||
_LIBCPP_HIDE_FROM_ABI void __parallel_merge(
|
||||
_RandomAccessIterator1 __first1,
|
||||
_RandomAccessIterator1 __last1,
|
||||
_RandomAccessIterator2 __first2,
|
||||
_RandomAccessIterator2 __last2,
|
||||
_RandomAccessIterator3 __outit,
|
||||
_Compare __comp,
|
||||
_LeafMerge __leaf_merge) {
|
||||
__leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
|
||||
}
|
||||
|
||||
// TODO: Complete this list
|
||||
|
||||
} // namespace __serial_cpu_backend
|
||||
} // namespace __par_backend
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
|
@ -0,0 +1,45 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
|
||||
|
||||
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
|
||||
#include <__algorithm/stable_sort.h>
|
||||
#include <__config>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
__pstl_stable_sort(__cpu_backend_tag, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
|
||||
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy>) {
|
||||
std::__terminate_on_exception([&] {
|
||||
__par_backend::__parallel_stable_sort(
|
||||
__first, __last, __comp, [](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) {
|
||||
std::stable_sort(__g_first, __g_last, __g_comp);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
std::stable_sort(__first, __last, __comp);
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
|
@ -0,0 +1,78 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
|
||||
|
||||
#include <__assert>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
// This backend implementation is for testing purposes only and not meant for production use. This will be replaced
|
||||
// by a proper implementation once the PSTL implementation is somewhat stable.
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace __par_backend {
|
||||
inline namespace __thread_cpu_backend {
|
||||
|
||||
template <class _RandomAccessIterator, class _Fp>
|
||||
_LIBCPP_HIDE_FROM_ABI void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) {
|
||||
__f(__first, __last);
|
||||
}
|
||||
|
||||
template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp
|
||||
__parallel_transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) {
|
||||
return __reduce(std::move(__first), std::move(__last), std::move(__init));
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare, class _LeafSort>
|
||||
_LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort(
|
||||
_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) {
|
||||
__leaf_sort(__first, __last, __comp);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
|
||||
|
||||
template <class _RandomAccessIterator1,
|
||||
class _RandomAccessIterator2,
|
||||
class _RandomAccessIterator3,
|
||||
class _Compare,
|
||||
class _LeafMerge>
|
||||
_LIBCPP_HIDE_FROM_ABI void __parallel_merge(
|
||||
_RandomAccessIterator1 __first1,
|
||||
_RandomAccessIterator1 __last1,
|
||||
_RandomAccessIterator2 __first2,
|
||||
_RandomAccessIterator2 __last2,
|
||||
_RandomAccessIterator3 __outit,
|
||||
_Compare __comp,
|
||||
_LeafMerge __leaf_merge) {
|
||||
__leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
|
||||
}
|
||||
|
||||
} // namespace __thread_cpu_backend
|
||||
} // namespace __par_backend
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
|
@ -0,0 +1,132 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
|
||||
|
||||
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
|
||||
#include <__algorithm/transform.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Function>
|
||||
_LIBCPP_HIDE_FROM_ABI _Iterator2
|
||||
__simd_walk_2(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Function __f) noexcept {
|
||||
_PSTL_PRAGMA_SIMD
|
||||
for (_DifferenceType __i = 0; __i < __n; ++__i)
|
||||
__f(__first1[__i], __first2[__i]);
|
||||
return __first2 + __n;
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _ForwardOutIterator, class _UnaryOperation>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform(
|
||||
__cpu_backend_tag,
|
||||
_ForwardIterator __first,
|
||||
_ForwardIterator __last,
|
||||
_ForwardOutIterator __result,
|
||||
_UnaryOperation __op) {
|
||||
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator>::value &&
|
||||
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
|
||||
std::__terminate_on_exception([&] {
|
||||
std::__par_backend::__parallel_for(
|
||||
__first, __last, [__op, __first, __result](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
|
||||
return std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>(
|
||||
__cpu_backend_tag{}, __brick_first, __brick_last, __result + (__brick_first - __first), __op);
|
||||
});
|
||||
});
|
||||
return __result + (__last - __first);
|
||||
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator>::value &&
|
||||
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
|
||||
return std::__simd_walk_2(
|
||||
__first,
|
||||
__last - __first,
|
||||
__result,
|
||||
[&](__iter_reference<_ForwardIterator> __in_value, __iter_reference<_ForwardOutIterator> __out_value) {
|
||||
__out_value = __op(__in_value);
|
||||
});
|
||||
} else {
|
||||
return std::transform(__first, __last, __result, __op);
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Iterator3, class _Function>
|
||||
_LIBCPP_HIDE_FROM_ABI _Iterator3 __simd_walk_3(
|
||||
_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Iterator3 __first3, _Function __f) noexcept {
|
||||
_PSTL_PRAGMA_SIMD
|
||||
for (_DifferenceType __i = 0; __i < __n; ++__i)
|
||||
__f(__first1[__i], __first2[__i], __first3[__i]);
|
||||
return __first3 + __n;
|
||||
}
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator1,
|
||||
class _ForwardIterator2,
|
||||
class _ForwardOutIterator,
|
||||
class _BinaryOperation,
|
||||
enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform(
|
||||
__cpu_backend_tag,
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardOutIterator __result,
|
||||
_BinaryOperation __op) {
|
||||
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator1>::value &&
|
||||
__has_random_access_iterator_category<_ForwardIterator2>::value &&
|
||||
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
|
||||
std::__terminate_on_exception([&] {
|
||||
std::__par_backend::__parallel_for(
|
||||
__first1,
|
||||
__last1,
|
||||
[__op, __first1, __first2, __result](_ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last) {
|
||||
return std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>(
|
||||
__cpu_backend_tag{},
|
||||
__brick_first,
|
||||
__brick_last,
|
||||
__first2 + (__brick_first - __first1),
|
||||
__result + (__brick_first - __first1),
|
||||
__op);
|
||||
});
|
||||
});
|
||||
return __result + (__last1 - __first1);
|
||||
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator1>::value &&
|
||||
__has_random_access_iterator_category<_ForwardIterator2>::value &&
|
||||
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
|
||||
return std::__simd_walk_3(
|
||||
__first1,
|
||||
__last1 - __first1,
|
||||
__first2,
|
||||
__result,
|
||||
[&](__iter_reference<_ForwardIterator1> __in1,
|
||||
__iter_reference<_ForwardIterator2> __in2,
|
||||
__iter_reference<_ForwardOutIterator> __out_value) { __out_value = __op(__in1, __in2); });
|
||||
} else {
|
||||
return std::transform(__first1, __last1, __first2, __result, __op);
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
|
@ -0,0 +1,194 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
|
||||
|
||||
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__numeric/transform_reduce.h>
|
||||
#include <__type_traits/is_arithmetic.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__type_traits/operation_traits.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
#include <new>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <
|
||||
typename _DifferenceType,
|
||||
typename _Tp,
|
||||
typename _BinaryOperation,
|
||||
typename _UnaryOperation,
|
||||
__enable_if_t<__is_trivial_plus_operation<_BinaryOperation, _Tp, _Tp>::value && is_arithmetic_v<_Tp>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp
|
||||
__simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _UnaryOperation __f) noexcept {
|
||||
_PSTL_PRAGMA_SIMD_REDUCTION(+ : __init)
|
||||
for (_DifferenceType __i = 0; __i < __n; ++__i)
|
||||
__init += __f(__i);
|
||||
return __init;
|
||||
}
|
||||
|
||||
template <
|
||||
typename _Size,
|
||||
typename _Tp,
|
||||
typename _BinaryOperation,
|
||||
typename _UnaryOperation,
|
||||
__enable_if_t<!(__is_trivial_plus_operation<_BinaryOperation, _Tp, _Tp>::value && is_arithmetic_v<_Tp>), int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp
|
||||
__simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __f) noexcept {
|
||||
const _Size __block_size = __lane_size / sizeof(_Tp);
|
||||
if (__n > 2 * __block_size && __block_size > 1) {
|
||||
alignas(__lane_size) char __lane_buffer[__lane_size];
|
||||
_Tp* __lane = reinterpret_cast<_Tp*>(__lane_buffer);
|
||||
|
||||
// initializer
|
||||
_PSTL_PRAGMA_SIMD
|
||||
for (_Size __i = 0; __i < __block_size; ++__i) {
|
||||
::new (__lane + __i) _Tp(__binary_op(__f(__i), __f(__block_size + __i)));
|
||||
}
|
||||
// main loop
|
||||
_Size __i = 2 * __block_size;
|
||||
const _Size __last_iteration = __block_size * (__n / __block_size);
|
||||
for (; __i < __last_iteration; __i += __block_size) {
|
||||
_PSTL_PRAGMA_SIMD
|
||||
for (_Size __j = 0; __j < __block_size; ++__j) {
|
||||
__lane[__j] = __binary_op(std::move(__lane[__j]), __f(__i + __j));
|
||||
}
|
||||
}
|
||||
// remainder
|
||||
_PSTL_PRAGMA_SIMD
|
||||
for (_Size __j = 0; __j < __n - __last_iteration; ++__j) {
|
||||
__lane[__j] = __binary_op(std::move(__lane[__j]), __f(__last_iteration + __j));
|
||||
}
|
||||
// combiner
|
||||
for (_Size __j = 0; __j < __block_size; ++__j) {
|
||||
__init = __binary_op(std::move(__init), std::move(__lane[__j]));
|
||||
}
|
||||
// destroyer
|
||||
_PSTL_PRAGMA_SIMD
|
||||
for (_Size __j = 0; __j < __block_size; ++__j) {
|
||||
__lane[__j].~_Tp();
|
||||
}
|
||||
} else {
|
||||
for (_Size __i = 0; __i < __n; ++__i) {
|
||||
__init = __binary_op(std::move(__init), __f(__i));
|
||||
}
|
||||
}
|
||||
return __init;
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator1,
|
||||
class _ForwardIterator2,
|
||||
class _Tp,
|
||||
class _BinaryOperation1,
|
||||
class _BinaryOperation2>
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce(
|
||||
__cpu_backend_tag,
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_Tp __init,
|
||||
_BinaryOperation1 __reduce,
|
||||
_BinaryOperation2 __transform) {
|
||||
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator1>::value &&
|
||||
__has_random_access_iterator_category<_ForwardIterator2>::value) {
|
||||
return std::__terminate_on_exception([&] {
|
||||
return __par_backend::__parallel_transform_reduce(
|
||||
__first1,
|
||||
std::move(__last1),
|
||||
[__first1, __first2, __transform](_ForwardIterator1 __iter) {
|
||||
return __transform(*__iter, *(__first2 + (__iter - __first1)));
|
||||
},
|
||||
std::move(__init),
|
||||
std::move(__reduce),
|
||||
[__first1, __first2, __reduce, __transform](
|
||||
_ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last, _Tp __brick_init) {
|
||||
return std::__pstl_transform_reduce<__remove_parallel_policy_t<_ExecutionPolicy>>(
|
||||
__cpu_backend_tag{},
|
||||
__brick_first,
|
||||
std::move(__brick_last),
|
||||
__first2 + (__brick_first - __first1),
|
||||
std::move(__brick_init),
|
||||
std::move(__reduce),
|
||||
std::move(__transform));
|
||||
});
|
||||
});
|
||||
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator1>::value &&
|
||||
__has_random_access_iterator_category<_ForwardIterator2>::value) {
|
||||
return std::__simd_transform_reduce(
|
||||
__last1 - __first1, std::move(__init), std::move(__reduce), [&](__iter_diff_t<_ForwardIterator1> __i) {
|
||||
return __transform(__first1[__i], __first2[__i]);
|
||||
});
|
||||
} else {
|
||||
return std::transform_reduce(
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__init),
|
||||
std::move(__reduce),
|
||||
std::move(__transform));
|
||||
}
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce(
|
||||
__cpu_backend_tag,
|
||||
_ForwardIterator __first,
|
||||
_ForwardIterator __last,
|
||||
_Tp __init,
|
||||
_BinaryOperation __reduce,
|
||||
_UnaryOperation __transform) {
|
||||
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator>::value) {
|
||||
return std::__terminate_on_exception([&] {
|
||||
return __par_backend::__parallel_transform_reduce(
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
[__transform](_ForwardIterator __iter) { return __transform(*__iter); },
|
||||
std::move(__init),
|
||||
__reduce,
|
||||
[__transform, __reduce](auto __brick_first, auto __brick_last, _Tp __brick_init) {
|
||||
return std::__pstl_transform_reduce<__remove_parallel_policy_t<_ExecutionPolicy>>(
|
||||
__cpu_backend_tag{},
|
||||
std::move(__brick_first),
|
||||
std::move(__brick_last),
|
||||
std::move(__brick_init),
|
||||
std::move(__reduce),
|
||||
std::move(__transform));
|
||||
});
|
||||
});
|
||||
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
|
||||
__has_random_access_iterator_category<_ForwardIterator>::value) {
|
||||
return std::__simd_transform_reduce(
|
||||
__last - __first,
|
||||
std::move(__init),
|
||||
std::move(__reduce),
|
||||
[=, &__transform](__iter_diff_t<_ForwardIterator> __i) { return __transform(__first[__i]); });
|
||||
} else {
|
||||
return std::transform_reduce(
|
||||
std::move(__first), std::move(__last), std::move(__init), std::move(__reduce), std::move(__transform));
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
|
59
lib/libcxx/include/__algorithm/pstl_copy.h
Normal file
59
lib/libcxx/include/__algorithm/pstl_copy.h
Normal file
@ -0,0 +1,59 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_COPY_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_COPY_H
|
||||
|
||||
#include <__algorithm/copy_n.h>
|
||||
#include <__algorithm/pstl_transform.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_constant_evaluated.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__type_traits/is_trivially_copyable.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// TODO: Use the std::copy/move shenanigans to forward to std::memmove
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _ForwardOutIterator,
|
||||
enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
|
||||
copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) {
|
||||
return std::transform(__policy, __first, __last, __result, __identity());
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _ForwardOutIterator,
|
||||
class _Size,
|
||||
enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
|
||||
copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __result) {
|
||||
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value)
|
||||
return std::copy(__policy, __first, __first + __n, __result);
|
||||
else
|
||||
return std::copy_n(__first, __n, __result);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_COPY_H
|
89
lib/libcxx/include/__algorithm/pstl_count.h
Normal file
89
lib/libcxx/include/__algorithm/pstl_count.h
Normal file
@ -0,0 +1,89 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_COUNT_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_COUNT_H
|
||||
|
||||
#include <__algorithm/count.h>
|
||||
#include <__algorithm/for_each.h>
|
||||
#include <__algorithm/pstl_backend.h>
|
||||
#include <__algorithm/pstl_for_each.h>
|
||||
#include <__algorithm/pstl_frontend_dispatch.h>
|
||||
#include <__atomic/atomic.h>
|
||||
#include <__config>
|
||||
#include <__functional/operations.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__numeric/pstl_transform_reduce.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class>
|
||||
void __pstl_count_if(); // declaration needed for the frontend dispatch below
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Predicate,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
|
||||
count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
using __diff_t = __iter_diff_t<_ForwardIterator>;
|
||||
return std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count_if),
|
||||
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
|
||||
return std::transform_reduce(
|
||||
__policy,
|
||||
std::move(__g_first),
|
||||
std::move(__g_last),
|
||||
__diff_t(),
|
||||
std::plus{},
|
||||
[&](__iter_reference<_ForwardIterator> __element) -> bool { return __g_pred(__element); });
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__pred));
|
||||
}
|
||||
|
||||
template <class>
|
||||
void __pstl_count(); // declaration needed for the frontend dispatch below
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
|
||||
count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||
return std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count),
|
||||
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
|
||||
return std::count_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __v) {
|
||||
return __v == __g_value;
|
||||
});
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
__value);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_COUNT_H
|
84
lib/libcxx/include/__algorithm/pstl_fill.h
Normal file
84
lib/libcxx/include/__algorithm/pstl_fill.h
Normal file
@ -0,0 +1,84 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_FILL_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_FILL_H
|
||||
|
||||
#include <__algorithm/fill_n.h>
|
||||
#include <__algorithm/pstl_for_each.h>
|
||||
#include <__algorithm/pstl_frontend_dispatch.h>
|
||||
#include <__config>
|
||||
#include <__iterator/cpp17_iterator_concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class>
|
||||
void __pstl_fill(); // declaration needed for the frontend dispatch below
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
|
||||
std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill),
|
||||
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
|
||||
std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
|
||||
__element = __g_value;
|
||||
});
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
__value);
|
||||
}
|
||||
|
||||
template <class>
|
||||
void __pstl_fill_n(); // declaration needed for the frontend dispatch below
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _SizeT,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _SizeT __n, const _Tp& __value) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
|
||||
std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill_n),
|
||||
[&](_ForwardIterator __g_first, _SizeT __g_n, const _Tp& __g_value) {
|
||||
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value)
|
||||
std::fill(__policy, __g_first, __g_first + __g_n, __g_value);
|
||||
else
|
||||
std::fill_n(__g_first, __g_n, __g_value);
|
||||
},
|
||||
std::move(__first),
|
||||
__n,
|
||||
__value);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_FILL_H
|
95
lib/libcxx/include/__algorithm/pstl_find.h
Normal file
95
lib/libcxx/include/__algorithm/pstl_find.h
Normal file
@ -0,0 +1,95 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_FIND_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_FIND_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/find.h>
|
||||
#include <__algorithm/pstl_backend.h>
|
||||
#include <__algorithm/pstl_frontend_dispatch.h>
|
||||
#include <__config>
|
||||
#include <__iterator/cpp17_iterator_concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Predicate,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
||||
find_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
|
||||
using _Backend = typename __select_backend<_RawPolicy>::type;
|
||||
return std::__pstl_find_if<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__pred));
|
||||
}
|
||||
|
||||
template <class>
|
||||
void __pstl_find_if_not();
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Predicate,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
||||
find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
|
||||
return std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find_if_not),
|
||||
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
|
||||
return std::find_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) {
|
||||
return !__g_pred(__value);
|
||||
});
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__pred));
|
||||
}
|
||||
|
||||
template <class>
|
||||
void __pstl_find();
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
||||
find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
|
||||
return std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find),
|
||||
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
|
||||
return std::find_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
|
||||
return __element == __g_value;
|
||||
});
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
__value);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_FIND_H
|
76
lib/libcxx/include/__algorithm/pstl_for_each.h
Normal file
76
lib/libcxx/include/__algorithm/pstl_for_each.h
Normal file
@ -0,0 +1,76 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
|
||||
|
||||
#include <__algorithm/for_each.h>
|
||||
#include <__algorithm/for_each_n.h>
|
||||
#include <__algorithm/pstl_backend.h>
|
||||
#include <__algorithm/pstl_frontend_dispatch.h>
|
||||
#include <__config>
|
||||
#include <__iterator/cpp17_iterator_concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__type_traits/void_t.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/terminate_on_exception.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Function,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
for_each(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __func) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
|
||||
using _Backend = typename __select_backend<_RawPolicy>::type;
|
||||
std::__pstl_for_each<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__func));
|
||||
}
|
||||
|
||||
template <class>
|
||||
void __pstl_for_each_n(); // declaration needed for the frontend dispatch below
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Size,
|
||||
class _Function,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
|
||||
return std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_for_each_n),
|
||||
[&](_ForwardIterator __g_first, _Size __g_size, _Function __g_func) {
|
||||
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
|
||||
std::for_each(__policy, std::move(__g_first), __g_first + __g_size, std::move(__g_func));
|
||||
} else {
|
||||
std::for_each_n(std::move(__g_first), __g_size, std::move(__g_func));
|
||||
}
|
||||
},
|
||||
__first,
|
||||
__size,
|
||||
std::move(__func));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
|
45
lib/libcxx/include/__algorithm/pstl_frontend_dispatch.h
Normal file
45
lib/libcxx/include/__algorithm/pstl_frontend_dispatch.h
Normal file
@ -0,0 +1,45 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH
|
||||
#define _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH
|
||||
|
||||
#include <__config>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__utility/forward.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
# define _LIBCPP_PSTL_CUSTOMIZATION_POINT(name) \
|
||||
[](auto&&... __args) -> decltype(std::name<_RawPolicy>(typename __select_backend<_RawPolicy>::type{}, \
|
||||
std::forward<decltype(__args)>(__args)...)) { \
|
||||
return std::name<_RawPolicy>( \
|
||||
typename __select_backend<_RawPolicy>::type{}, std::forward<decltype(__args)>(__args)...); \
|
||||
}
|
||||
|
||||
template <class _SpecializedImpl, class _GenericImpl, class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI decltype(auto)
|
||||
__pstl_frontend_dispatch(_SpecializedImpl __specialized_impl, _GenericImpl __generic_impl, _Args&&... __args) {
|
||||
if constexpr (__is_callable<_SpecializedImpl, _Args...>::value) {
|
||||
return __specialized_impl(std::forward<_Args>(__args)...);
|
||||
} else {
|
||||
return __generic_impl(std::forward<_Args>(__args)...);
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH
|
82
lib/libcxx/include/__algorithm/pstl_generate.h
Normal file
82
lib/libcxx/include/__algorithm/pstl_generate.h
Normal file
@ -0,0 +1,82 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_GENERATE_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_GENERATE_H
|
||||
|
||||
#include <__algorithm/pstl_backend.h>
|
||||
#include <__algorithm/pstl_for_each.h>
|
||||
#include <__algorithm/pstl_frontend_dispatch.h>
|
||||
#include <__config>
|
||||
#include <__iterator/cpp17_iterator_concepts.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class>
|
||||
void __pstl_generate();
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Generator,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
generate(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
|
||||
std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate),
|
||||
[&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Generator __g_gen) {
|
||||
std::for_each(
|
||||
__policy, std::move(__g_first), std::move(__g_last), [&](__iter_reference<_ForwardIterator> __element) {
|
||||
__element = __g_gen();
|
||||
});
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__gen));
|
||||
}
|
||||
|
||||
template <class>
|
||||
void __pstl_generate_n();
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Size,
|
||||
class _Generator,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
generate_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Generator __gen) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
|
||||
std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate_n),
|
||||
[&__policy](_ForwardIterator __g_first, _Size __g_n, _Generator __g_gen) {
|
||||
std::for_each_n(__policy, std::move(__g_first), __g_n, [&](__iter_reference<_ForwardIterator> __element) {
|
||||
__element = __g_gen();
|
||||
});
|
||||
},
|
||||
std::move(__first),
|
||||
__n,
|
||||
std::move(__gen));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_GENERATE_H
|
58
lib/libcxx/include/__algorithm/pstl_is_partitioned.h
Normal file
58
lib/libcxx/include/__algorithm/pstl_is_partitioned.h
Normal file
@ -0,0 +1,58 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
|
||||
#define _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
|
||||
|
||||
#include <__algorithm/pstl_any_all_none_of.h>
|
||||
#include <__algorithm/pstl_backend.h>
|
||||
#include <__algorithm/pstl_find.h>
|
||||
#include <__algorithm/pstl_frontend_dispatch.h>
|
||||
#include <__config>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class>
|
||||
void __pstl_is_partitioned();
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Predicate,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
|
||||
is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
return std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_is_partitioned),
|
||||
[&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
|
||||
__g_first = std::find_if_not(__policy, __g_first, __g_last, __g_pred);
|
||||
if (__g_first == __g_last)
|
||||
return true;
|
||||
++__g_first;
|
||||
return std::none_of(__policy, __g_first, __g_last, __g_pred);
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__pred));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
|
58
lib/libcxx/include/__algorithm/pstl_merge.h
Normal file
58
lib/libcxx/include/__algorithm/pstl_merge.h
Normal file
@ -0,0 +1,58 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_MERGE_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_MERGE_H
|
||||
|
||||
#include <__algorithm/pstl_backend.h>
|
||||
#include <__config>
|
||||
#include <__functional/operations.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator1,
|
||||
class _ForwardIterator2,
|
||||
class _ForwardOutIterator,
|
||||
class _Comp = std::less<>,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
|
||||
merge(_ExecutionPolicy&&,
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2,
|
||||
_ForwardOutIterator __result,
|
||||
_Comp __comp = {}) {
|
||||
using _Backend = typename __select_backend<_RawPolicy>::type;
|
||||
return std::__pstl_merge<_RawPolicy>(
|
||||
_Backend{},
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
std::move(__result),
|
||||
std::move(__comp));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_MERGE_H
|
167
lib/libcxx/include/__algorithm/pstl_replace.h
Normal file
167
lib/libcxx/include/__algorithm/pstl_replace.h
Normal file
@ -0,0 +1,167 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_REPLACE_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_REPLACE_H
|
||||
|
||||
#include <__algorithm/pstl_backend.h>
|
||||
#include <__algorithm/pstl_for_each.h>
|
||||
#include <__algorithm/pstl_frontend_dispatch.h>
|
||||
#include <__algorithm/pstl_transform.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class>
|
||||
void __pstl_replace_if();
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Pred,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
replace_if(_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator __first,
|
||||
_ForwardIterator __last,
|
||||
_Pred __pred,
|
||||
const _Tp& __new_value) {
|
||||
std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_if),
|
||||
[&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred, const _Tp& __g_new_value) {
|
||||
std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
|
||||
if (__g_pred(__element))
|
||||
__element = __g_new_value;
|
||||
});
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__pred),
|
||||
__new_value);
|
||||
}
|
||||
|
||||
template <class>
|
||||
void __pstl_replace();
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
replace(_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator __first,
|
||||
_ForwardIterator __last,
|
||||
const _Tp& __old_value,
|
||||
const _Tp& __new_value) {
|
||||
std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace),
|
||||
[&__policy](
|
||||
_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_old_value, const _Tp& __g_new_value) {
|
||||
std::replace_if(
|
||||
__policy,
|
||||
std::move(__g_first),
|
||||
std::move(__g_last),
|
||||
[&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; },
|
||||
__g_new_value);
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
__old_value,
|
||||
__new_value);
|
||||
}
|
||||
|
||||
template <class>
|
||||
void __pstl_replace_copy_if();
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _ForwardOutIterator,
|
||||
class _Pred,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void replace_copy_if(
|
||||
_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator __first,
|
||||
_ForwardIterator __last,
|
||||
_ForwardOutIterator __result,
|
||||
_Pred __pred,
|
||||
const _Tp& __new_value) {
|
||||
std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy_if),
|
||||
[&__policy](_ForwardIterator __g_first,
|
||||
_ForwardIterator __g_last,
|
||||
_ForwardOutIterator __g_result,
|
||||
_Pred __g_pred,
|
||||
const _Tp& __g_new_value) {
|
||||
std::transform(__policy, __g_first, __g_last, __g_result, [&](__iter_reference<_ForwardIterator> __element) {
|
||||
return __g_pred(__element) ? __g_new_value : __element;
|
||||
});
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__result),
|
||||
std::move(__pred),
|
||||
__new_value);
|
||||
}
|
||||
|
||||
template <class>
|
||||
void __pstl_replace_copy();
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _ForwardOutIterator,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void replace_copy(
|
||||
_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator __first,
|
||||
_ForwardIterator __last,
|
||||
_ForwardOutIterator __result,
|
||||
const _Tp& __old_value,
|
||||
const _Tp& __new_value) {
|
||||
std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy),
|
||||
[&__policy](_ForwardIterator __g_first,
|
||||
_ForwardIterator __g_last,
|
||||
_ForwardOutIterator __g_result,
|
||||
const _Tp& __g_old_value,
|
||||
const _Tp& __g_new_value) {
|
||||
return std::replace_copy_if(
|
||||
__policy,
|
||||
std::move(__g_first),
|
||||
std::move(__g_last),
|
||||
std::move(__g_result),
|
||||
[&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; },
|
||||
__g_new_value);
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__result),
|
||||
__old_value,
|
||||
__new_value);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_REPLACE_H
|
63
lib/libcxx/include/__algorithm/pstl_sort.h
Normal file
63
lib/libcxx/include/__algorithm/pstl_sort.h
Normal file
@ -0,0 +1,63 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_SORT_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_SORT_H
|
||||
|
||||
#include <__algorithm/pstl_backend.h>
|
||||
#include <__algorithm/pstl_frontend_dispatch.h>
|
||||
#include <__algorithm/pstl_stable_sort.h>
|
||||
#include <__config>
|
||||
#include <__functional/operations.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class>
|
||||
void __pstl_sort();
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _RandomAccessIterator,
|
||||
class _Comp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
|
||||
std::__pstl_frontend_dispatch(
|
||||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_sort),
|
||||
[&__policy](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) {
|
||||
std::stable_sort(__policy, std::move(__g_first), std::move(__g_last), std::move(__g_comp));
|
||||
},
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__comp));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _RandomAccessIterator,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
|
||||
std::sort(std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_SORT_H
|
43
lib/libcxx/include/__algorithm/pstl_stable_sort.h
Normal file
43
lib/libcxx/include/__algorithm/pstl_stable_sort.h
Normal file
@ -0,0 +1,43 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
|
||||
|
||||
#include <__algorithm/pstl_backend.h>
|
||||
#include <__config>
|
||||
#include <__functional/operations.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_execution_policy.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _RandomAccessIterator,
|
||||
class _Comp = less<>,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp = {}) {
|
||||
using _Backend = typename __select_backend<_RawPolicy>::type;
|
||||
std::__pstl_stable_sort<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__comp));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user